svelte wallet mechanism

allelo
Niko PLP 7 hours ago
parent fa84d07c3b
commit 443e08b9c5
  1. 329
      app/allelo/bun.lock
  2. 27
      app/allelo/package.json
  3. 2
      app/allelo/src-tauri/Cargo.toml
  4. 20
      app/allelo/src-tauri/capabilities/bsp-registration.json
  5. 3
      app/allelo/src-tauri/capabilities/default.json
  6. 21
      app/allelo/src-tauri/src/lib.rs
  7. 4
      app/allelo/src-tauri/tauri.conf.json
  8. 4
      app/allelo/src/.auth-react/api.ts
  9. 69
      app/allelo/src/.auth-react/createBrowserNGReactMethods.tsx
  10. 172
      app/allelo/src/App.tsx
  11. 2
      app/allelo/src/hooks/contacts/useContacts.ts
  12. 2
      app/allelo/src/hooks/contacts/useSaveContacts.ts
  13. 2
      app/allelo/src/hooks/useUpdateProfile.ts
  14. 240
      app/allelo/src/index.css
  15. 4
      app/allelo/src/main-web.tsx
  16. 4
      app/allelo/src/main.tsx
  17. 26
      app/allelo/src/native-api.ts
  18. 8
      app/allelo/src/services/nextgraphDataService.ts
  19. 18
      app/allelo/src/svelte/Invitation.svelte
  20. 502
      app/allelo/src/svelte/WalletCreate.svelte
  21. 592
      app/allelo/src/svelte/WalletLogin.svelte
  22. 16
      app/allelo/src/svelte/assets/nextgraph.svg
  23. 59
      app/allelo/src/svelte/base64url.js
  24. 962
      app/allelo/src/svelte/classes.ts
  25. 21
      app/allelo/src/svelte/index.ts
  26. 50
      app/allelo/src/svelte/lang.ts
  27. 110
      app/allelo/src/svelte/lib/CenteredLayout.svelte
  28. 197
      app/allelo/src/svelte/lib/Install.svelte
  29. 379
      app/allelo/src/svelte/lib/Login.svelte
  30. 95
      app/allelo/src/svelte/lib/NoWallet.svelte
  31. 33
      app/allelo/src/svelte/lib/Test.svelte
  32. 1
      app/allelo/src/svelte/lib/component.ts
  33. 91
      app/allelo/src/svelte/lib/components/CopyToClipboard.svelte
  34. 40
      app/allelo/src/svelte/lib/components/Logo.svelte
  35. 23
      app/allelo/src/svelte/lib/components/LogoSimple.svelte
  36. 64
      app/allelo/src/svelte/lib/components/Message.svelte
  37. 98
      app/allelo/src/svelte/lib/components/PasswordInput.svelte
  38. 38
      app/allelo/src/svelte/lib/components/Spinner.svelte
  39. 3
      app/allelo/src/svelte/lib/icons/BrailleIcon.svelte
  40. 13
      app/allelo/src/svelte/lib/icons/BranchIcon.svelte
  41. 8
      app/allelo/src/svelte/lib/icons/ChemistryIcon.svelte
  42. 191
      app/allelo/src/svelte/lib/icons/DataClassIcon.svelte
  43. 57
      app/allelo/src/svelte/lib/icons/DeviceIcon.svelte
  44. 3
      app/allelo/src/svelte/lib/icons/GraphQLIcon.svelte
  45. 4
      app/allelo/src/svelte/lib/icons/GuitarIcon.svelte
  46. 3
      app/allelo/src/svelte/lib/icons/JsIcon.svelte
  47. 4
      app/allelo/src/svelte/lib/icons/JsonIcon.svelte
  48. 10
      app/allelo/src/svelte/lib/icons/JsonLdIcon.svelte
  49. 6
      app/allelo/src/svelte/lib/icons/MarkdownIcon.svelte
  50. 64
      app/allelo/src/svelte/lib/icons/NavIcon.svelte
  51. 3
      app/allelo/src/svelte/lib/icons/PdfIcon.svelte
  52. 9
      app/allelo/src/svelte/lib/icons/RdfIcon.svelte
  53. 3
      app/allelo/src/svelte/lib/icons/ReactIcon.svelte
  54. 3
      app/allelo/src/svelte/lib/icons/RustIcon.svelte
  55. 3
      app/allelo/src/svelte/lib/icons/SvelteIcon.svelte
  56. 3
      app/allelo/src/svelte/lib/icons/TsIcon.svelte
  57. 35
      app/allelo/src/svelte/lib/icons/TurtleIcon.svelte
  58. 5
      app/allelo/src/svelte/lib/icons/TxtIcon.svelte
  59. 130
      app/allelo/src/svelte/lib/icons/ZeraIcon.svelte
  60. 2
      app/allelo/src/svelte/lib/index.ts
  61. 956
      app/allelo/src/svelte/locales/en.json
  62. 1039
      app/allelo/src/svelte/store.ts
  63. 667
      app/allelo/src/svelte/tab.ts
  64. 776
      app/allelo/src/svelte/zeras.ts
  65. 11
      app/allelo/svelte.config.js
  66. 5
      app/allelo/tailwind.config.js
  67. 2
      app/allelo/tsconfig.json
  68. 26
      app/allelo/vite.config.ts
  69. 370
      pnpm-lock.yaml
  70. 1
      sdk/js/api-web/main.ts
  71. 5
      sdk/js/api-web/package.json
  72. 2
      sdk/js/api-web/worker.js
  73. 1
      sdk/js/lib-wasm/src/lib.rs

@ -19,6 +19,9 @@
"@tauri-apps/plugin-opener": "^2",
"async-proxy": "^0.4.1",
"dotenv": "^17.1.0",
"flowbite": "^3.1.2",
"flowbite-svelte": "^1.19.0",
"html5-qrcode": "^2.3.8",
"leaflet": "^1.9.4",
"libphonenumber-js": "^1.12.17",
"qrcode.react": "^4.2.0",
@ -28,15 +31,23 @@
"react-leaflet": "^5.0.0",
"react-router-dom": "^7.6.3",
"react-waypoint": "^10.3.0",
"svelte-heros-v2": "^3.0.0",
"svelte-i18n": "^4.0.1",
"svelte-in-react": "^0.2.0",
"svelte-time": "^1.0.0",
"zustand": "^5.0.6",
},
"devDependencies": {
"@eslint/js": "^9.30.1",
"@hazycora/vite-plugin-svelte-svg": "^2.4.3",
"@ldo/cli": "1.0.0-alpha.15",
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@tailwindcss/vite": "^4.1.14",
"@tauri-apps/cli": "^2.9.1",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@testing-library/user-event": "^14.5.2",
"@tsconfig/svelte": "^5.0.5",
"@types/jest": "^29.5.12",
"@types/jsonld": "^1.5.15",
"@types/leaflet": "^1.9.20",
@ -53,6 +64,8 @@
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"node-gzip": "^1.1.2",
"svelte": "^5.39.13",
"tailwindcss": "^4.1.14",
"ts-jest": "^29.1.2",
"typescript": "~5.8.3",
"typescript-eslint": "^8.35.1",
@ -242,6 +255,24 @@
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.0", "", { "dependencies": { "@eslint/core": "^0.16.0", "levn": "^0.4.1" } }, "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A=="],
"@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="],
"@floating-ui/dom": ["@floating-ui/dom@1.7.4", "", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA=="],
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
"@formatjs/ecma402-abstract": ["@formatjs/ecma402-abstract@2.3.6", "", { "dependencies": { "@formatjs/fast-memoize": "2.2.7", "@formatjs/intl-localematcher": "0.6.2", "decimal.js": "^10.4.3", "tslib": "^2.8.0" } }, "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw=="],
"@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ=="],
"@formatjs/icu-messageformat-parser": ["@formatjs/icu-messageformat-parser@2.11.4", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/icu-skeleton-parser": "1.8.16", "tslib": "^2.8.0" } }, "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw=="],
"@formatjs/icu-skeleton-parser": ["@formatjs/icu-skeleton-parser@1.8.16", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "tslib": "^2.8.0" } }, "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ=="],
"@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.2", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA=="],
"@hazycora/vite-plugin-svelte-svg": ["@hazycora/vite-plugin-svelte-svg@2.4.3", "", { "dependencies": { "svgo": "^3.0.0" }, "peerDependencies": { "svelte": ">= 3.0.0 < 6.0.0", "vite": "< 7.0.0" } }, "sha512-/YUo1f36bHGZ6kbJKwyuz6QdfL9O0Aw0xIx+Ghlh5Gg9+Nwo+XdVbHEiPPnanuXF17G87ej0YVCvCH9uUpnybg=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
@ -354,8 +385,12 @@
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
"@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@15.3.1", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA=="],
"@rollup/plugin-virtual": ["@rollup/plugin-virtual@3.0.2", "", { "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A=="],
"@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.5", "", { "os": "android", "cpu": "arm" }, "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.52.5", "", { "os": "android", "cpu": "arm64" }, "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA=="],
@ -418,6 +453,22 @@
"@solid-notifications/subscription": ["@solid-notifications/subscription@0.1.2", "", { "dependencies": { "@janeirodigital/interop-utils": "^1.0.0-rc.24", "@solid-notifications/discovery": "^0.1.2", "n3": "^1.17.2" } }, "sha512-XnnqNsLOIdUAzB11aROzfRiJLHJjTOaHMSrnn3teQRtE0BwpbnAJtzGG/m3JNUR+QqyjKkB3jfibxJjzvI/HQg=="],
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.6", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ=="],
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@6.2.1", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "debug": "^4.4.1", "deepmerge": "^4.3.1", "magic-string": "^0.30.17", "vitefu": "^1.1.1" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ=="],
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@5.0.1", "", { "dependencies": { "debug": "^4.4.1" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA=="],
"@svgdotjs/svg.draggable.js": ["@svgdotjs/svg.draggable.js@3.0.6", "", { "peerDependencies": { "@svgdotjs/svg.js": "^3.2.4" } }, "sha512-7iJFm9lL3C40HQcqzEfezK2l+dW2CpoVY3b77KQGqc8GXWa6LhhmX5Ckv7alQfUXBuZbjpICZ+Dvq1czlGx7gA=="],
"@svgdotjs/svg.filter.js": ["@svgdotjs/svg.filter.js@3.0.9", "", { "dependencies": { "@svgdotjs/svg.js": "^3.2.4" } }, "sha512-/69XMRCDoam2HgC4ldHIaDgeQf1ViHIsa0Ld4uWgiXtZ+E24DWHe/9Ib6kbNiZ7WRIdlVokUDR1Fg0kjIpkfbw=="],
"@svgdotjs/svg.js": ["@svgdotjs/svg.js@3.2.5", "", {}, "sha512-/VNHWYhNu+BS7ktbYoVGrCmsXDh+chFMaONMwGNdIBcFHrWqk2jY8fNyr3DLdtQUIalvkPfM554ZSFa3dm3nxQ=="],
"@svgdotjs/svg.resize.js": ["@svgdotjs/svg.resize.js@2.0.5", "", { "peerDependencies": { "@svgdotjs/svg.js": "^3.2.4", "@svgdotjs/svg.select.js": "^4.0.1" } }, "sha512-4heRW4B1QrJeENfi7326lUPYBCevj78FJs8kfeDxn5st0IYPIRXoTtOSYvTzFWgaWWXd3YCDE6ao4fmv91RthA=="],
"@svgdotjs/svg.select.js": ["@svgdotjs/svg.select.js@4.0.3", "", { "peerDependencies": { "@svgdotjs/svg.js": "^3.2.4" } }, "sha512-qkMgso1sd2hXKd1FZ1weO7ANq12sNmQJeGDjs46QwDVsxSRcHmvWKL2NDF7Yimpwf3sl5esOLkPqtV2bQ3v/Jg=="],
"@swc/core": ["@swc/core@1.13.5", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.24" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.13.5", "@swc/core-darwin-x64": "1.13.5", "@swc/core-linux-arm-gnueabihf": "1.13.5", "@swc/core-linux-arm64-gnu": "1.13.5", "@swc/core-linux-arm64-musl": "1.13.5", "@swc/core-linux-x64-gnu": "1.13.5", "@swc/core-linux-x64-musl": "1.13.5", "@swc/core-win32-arm64-msvc": "1.13.5", "@swc/core-win32-ia32-msvc": "1.13.5", "@swc/core-win32-x64-msvc": "1.13.5" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ=="],
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.13.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ=="],
@ -446,6 +497,36 @@
"@swc/wasm": ["@swc/wasm@1.13.20", "", {}, "sha512-NJzN+QrbdwXeVTfTYiHkqv13zleOCQA52NXBOrwKvjxWJQecRqakjUhUP2z8lqs7eWVthko4Cilqs+VeBrwo3Q=="],
"@tailwindcss/node": ["@tailwindcss/node@4.1.16", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.19", "source-map-js": "^1.2.1", "tailwindcss": "4.1.16" } }, "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw=="],
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.16", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.16", "@tailwindcss/oxide-darwin-arm64": "4.1.16", "@tailwindcss/oxide-darwin-x64": "4.1.16", "@tailwindcss/oxide-freebsd-x64": "4.1.16", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", "@tailwindcss/oxide-linux-x64-musl": "4.1.16", "@tailwindcss/oxide-wasm32-wasi": "4.1.16", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" } }, "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg=="],
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.16", "", { "os": "android", "cpu": "arm64" }, "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA=="],
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA=="],
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg=="],
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.16", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg=="],
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16", "", { "os": "linux", "cpu": "arm" }, "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw=="],
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w=="],
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ=="],
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew=="],
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw=="],
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.16", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q=="],
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A=="],
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.16", "", { "os": "win32", "cpu": "x64" }, "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg=="],
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.16", "", { "dependencies": { "@tailwindcss/node": "4.1.16", "@tailwindcss/oxide": "4.1.16", "tailwindcss": "4.1.16" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg=="],
"@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="],
"@tauri-apps/cli": ["@tauri-apps/cli@2.9.1", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.9.1", "@tauri-apps/cli-darwin-x64": "2.9.1", "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.1", "@tauri-apps/cli-linux-arm64-gnu": "2.9.1", "@tauri-apps/cli-linux-arm64-musl": "2.9.1", "@tauri-apps/cli-linux-riscv64-gnu": "2.9.1", "@tauri-apps/cli-linux-x64-gnu": "2.9.1", "@tauri-apps/cli-linux-x64-musl": "2.9.1", "@tauri-apps/cli-win32-arm64-msvc": "2.9.1", "@tauri-apps/cli-win32-ia32-msvc": "2.9.1", "@tauri-apps/cli-win32-x64-msvc": "2.9.1" }, "bin": { "tauri": "tauri.js" } }, "sha512-kKi2/WWsNXKoMdatBl4xrT7e1Ce27JvsetBVfWuIb6D3ep/Y0WO5SIr70yarXOSWam8NyDur4ipzjZkg6m7VDg=="],
@ -486,6 +567,8 @@
"@tootallnate/once": ["@tootallnate/once@2.0.0", "", {}, "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="],
"@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
"@ts-jison/common": ["@ts-jison/common@0.4.1-alpha.1", "", {}, "sha512-SDbHzq+UMD+V3ciKVBHwCEgVqSeyQPTCjOsd/ZNTGySUVg4x3EauR9ZcEfdVFAsYRR38XWgDI+spq5LDY46KvQ=="],
"@ts-jison/lexer": ["@ts-jison/lexer@0.4.1-alpha.1", "", { "dependencies": { "@ts-jison/common": "^0.4.1-alpha.1" } }, "sha512-5C1Wr+wixAzn2MOFtgy7KbT6N6j9mhmbjAtyvOqZKsikKtNOQj22MM5HxT+ooRexG2NbtxnDSXYdhHR1Lg58ow=="],
@ -494,6 +577,8 @@
"@ts-morph/common": ["@ts-morph/common@0.25.0", "", { "dependencies": { "minimatch": "^9.0.4", "path-browserify": "^1.0.1", "tinyglobby": "^0.2.9" } }, "sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg=="],
"@tsconfig/svelte": ["@tsconfig/svelte@5.0.5", "", {}, "sha512-48fAnUjKye38FvMiNOj0J9I/4XlQQiZlpe9xaNPfe8vy2Y1hFBt8g1yqf2EGjVvHavo4jf2lC+TQyENCr4BJBQ=="],
"@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="],
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
@ -554,6 +639,8 @@
"@types/readable-stream": ["@types/readable-stream@2.3.15", "", { "dependencies": { "@types/node": "*", "safe-buffer": "~5.1.1" } }, "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ=="],
"@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="],
"@types/shexj": ["@types/shexj@2.1.7", "", {}, "sha512-pu/0vIZxFTMPVjTlo5MJKFkBL/EbAuFhtCXpmBB7ZdUiyNpc6pt8GxfyRPqdf6q2SsWu71a/vbhvGK2IZN2Eug=="],
"@types/stack-utils": ["@types/stack-utils@2.0.3", "", {}, "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="],
@ -586,6 +673,8 @@
"@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="],
"@yr/monotone-cubic-spline": ["@yr/monotone-cubic-spline@1.0.3", "", {}, "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="],
"abab": ["abab@2.0.6", "", {}, "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA=="],
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
@ -610,6 +699,8 @@
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
"apexcharts": ["apexcharts@5.3.5", "", { "dependencies": { "@svgdotjs/svg.draggable.js": "^3.0.4", "@svgdotjs/svg.filter.js": "^3.0.8", "@svgdotjs/svg.js": "^3.2.4", "@svgdotjs/svg.resize.js": "^2.0.2", "@svgdotjs/svg.select.js": "^4.0.1", "@yr/monotone-cubic-spline": "^1.0.3" } }, "sha512-I04DY/WBZbJgJD2uixeV5EzyiL+J5LgKQXEu8rctqAwyRmKv44aDVeofJoLdTJe3ao4r2KEQfCgtVzXn6pqirg=="],
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
@ -626,6 +717,8 @@
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
"babel-jest": ["babel-jest@29.7.0", "", { "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" }, "peerDependencies": { "@babel/core": "^7.8.0" } }, "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg=="],
"babel-plugin-istanbul": ["babel-plugin-istanbul@6.1.1", "", { "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" } }, "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA=="],
@ -644,6 +737,8 @@
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.19", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ=="],
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
@ -684,6 +779,8 @@
"cjs-module-lexer": ["cjs-module-lexer@1.4.3", "", {}, "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q=="],
"cli-color": ["cli-color@2.0.4", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.64", "es6-iterator": "^2.0.3", "memoizee": "^0.4.15", "timers-ext": "^0.1.7" } }, "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA=="],
"cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
@ -726,16 +823,30 @@
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
"css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="],
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
"css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="],
"csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="],
"cssom": ["cssom@0.5.0", "", {}, "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="],
"cssstyle": ["cssstyle@2.3.0", "", { "dependencies": { "cssom": "~0.3.6" } }, "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"d": ["d@1.0.2", "", { "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" } }, "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw=="],
"data-urls": ["data-urls@3.0.2", "", { "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0" } }, "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ=="],
"date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],
"dayjs": ["dayjs@1.11.18", "", {}, "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="],
@ -754,6 +865,8 @@
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"detect-newline": ["detect-newline@3.1.0", "", {}, "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA=="],
"diff-sequences": ["diff-sequences@29.6.3", "", {}, "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q=="],
@ -762,8 +875,16 @@
"dom-helpers": ["dom-helpers@5.2.1", "", { "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA=="],
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
"domexception": ["domexception@4.0.0", "", { "dependencies": { "webidl-conversions": "^7.0.0" } }, "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw=="],
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
"dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
"dts-dom": ["dts-dom@3.6.0", "", {}, "sha512-on5jxTgt+A6r0Zyyz6ZRHXaAO7J1VPnOd6+AmvI1vH440AlAZZNc5rUHzgPuTjGlrVr1rOWQYNl7ZJK6rDohbw=="],
@ -778,6 +899,8 @@
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
"error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="],
@ -792,6 +915,14 @@
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
"es5-ext": ["es5-ext@0.10.64", "", { "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", "esniff": "^2.0.1", "next-tick": "^1.1.0" } }, "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg=="],
"es6-iterator": ["es6-iterator@2.0.3", "", { "dependencies": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g=="],
"es6-symbol": ["es6-symbol@3.1.4", "", { "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" } }, "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg=="],
"es6-weak-map": ["es6-weak-map@2.0.3", "", { "dependencies": { "d": "1", "es5-ext": "^0.10.46", "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.1" } }, "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA=="],
"esbuild": ["esbuild@0.25.11", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.11", "@esbuild/android-arm": "0.25.11", "@esbuild/android-arm64": "0.25.11", "@esbuild/android-x64": "0.25.11", "@esbuild/darwin-arm64": "0.25.11", "@esbuild/darwin-x64": "0.25.11", "@esbuild/freebsd-arm64": "0.25.11", "@esbuild/freebsd-x64": "0.25.11", "@esbuild/linux-arm": "0.25.11", "@esbuild/linux-arm64": "0.25.11", "@esbuild/linux-ia32": "0.25.11", "@esbuild/linux-loong64": "0.25.11", "@esbuild/linux-mips64el": "0.25.11", "@esbuild/linux-ppc64": "0.25.11", "@esbuild/linux-riscv64": "0.25.11", "@esbuild/linux-s390x": "0.25.11", "@esbuild/linux-x64": "0.25.11", "@esbuild/netbsd-arm64": "0.25.11", "@esbuild/netbsd-x64": "0.25.11", "@esbuild/openbsd-arm64": "0.25.11", "@esbuild/openbsd-x64": "0.25.11", "@esbuild/openharmony-arm64": "0.25.11", "@esbuild/sunos-x64": "0.25.11", "@esbuild/win32-arm64": "0.25.11", "@esbuild/win32-ia32": "0.25.11", "@esbuild/win32-x64": "0.25.11" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q=="],
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
@ -810,18 +941,28 @@
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
"esniff": ["esniff@2.0.1", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", "event-emitter": "^0.3.5", "type": "^2.7.2" } }, "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg=="],
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
"esrap": ["esrap@2.1.0", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA=="],
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
"event-emitter": ["event-emitter@0.3.5", "", { "dependencies": { "d": "1", "es5-ext": "~0.10.14" } }, "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA=="],
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
@ -832,6 +973,8 @@
"expect": ["expect@29.7.0", "", { "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" } }, "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw=="],
"ext": ["ext@1.7.0", "", { "dependencies": { "type": "^2.7.2" } }, "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"fast-glob": ["fast-glob@3.3.3", "", { "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.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
@ -860,6 +1003,12 @@
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
"flowbite": ["flowbite@3.1.2", "", { "dependencies": { "@popperjs/core": "^2.9.3", "flowbite-datepicker": "^1.3.1", "mini-svg-data-uri": "^1.4.3", "postcss": "^8.5.1" } }, "sha512-MkwSgbbybCYgMC+go6Da5idEKUFfMqc/AmSjm/2ZbdmvoKf5frLPq/eIhXc9P+rC8t9boZtUXzHDgt5whZ6A/Q=="],
"flowbite-datepicker": ["flowbite-datepicker@1.3.2", "", { "dependencies": { "@rollup/plugin-node-resolve": "^15.2.3", "flowbite": "^2.0.0" } }, "sha512-6Nfm0MCVX3mpaR7YSCjmEO2GO8CDt6CX8ZpQnGdeu03WUCWtEPQ/uy0PUiNtIJjJZWnX0Cm3H55MOhbD1g+E/g=="],
"flowbite-svelte": ["flowbite-svelte@1.19.0", "", { "dependencies": { "@floating-ui/dom": "^1.7.4", "@floating-ui/utils": "^0.2.10", "apexcharts": "^5.3.5", "clsx": "^2.1.1", "date-fns": "^4.1.0", "esm-env": "^1.2.2", "flowbite": "^3.1.2", "tailwind-merge": "^3.3.1", "tailwind-variants": "^3.1.1" }, "peerDependencies": { "svelte": "^5.29.0", "tailwindcss": "^4.1.4" } }, "sha512-/Y65iDzTCT/OD5lPqV9TTMgfDLuvlts/1lX6i2d3C2WbZPJicbcYyL2pppgiG/uSrrdzN4n7lPFL9lS4G4gqQg=="],
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
"form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
@ -888,12 +1037,18 @@
"get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
"get-tsconfig": ["get-tsconfig@4.13.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ=="],
"glob": ["glob@7.2.3", "", { "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" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
"globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
"globalyzer": ["globalyzer@0.1.0", "", {}, "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q=="],
"globrex": ["globrex@0.1.2", "", {}, "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
@ -922,6 +1077,8 @@
"html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="],
"html5-qrcode": ["html5-qrcode@2.3.8", "", {}, "sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ=="],
"http-basic": ["http-basic@8.1.3", "", { "dependencies": { "caseless": "^0.12.0", "concat-stream": "^1.6.2", "http-response-object": "^3.0.1", "parse-cache-control": "^1.0.1" } }, "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw=="],
"http-link-header": ["http-link-header@1.1.3", "", {}, "sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ=="],
@ -954,6 +1111,8 @@
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
"intl-messageformat": ["intl-messageformat@10.7.18", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/fast-memoize": "2.2.7", "@formatjs/icu-messageformat-parser": "2.11.4", "tslib": "^2.8.0" } }, "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g=="],
"is-arguments": ["is-arguments@1.2.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA=="],
"is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
@ -980,12 +1139,18 @@
"is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
"is-module": ["is-module@1.0.0", "", {}, "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="],
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="],
"is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="],
"is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="],
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
"is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="],
"is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="],
@ -1072,6 +1237,8 @@
"jest-worker": ["jest-worker@29.7.0", "", { "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw=="],
"jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="],
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
@ -1110,10 +1277,36 @@
"libphonenumber-js": ["libphonenumber-js@1.12.24", "", {}, "sha512-l5IlyL9AONj4voSd7q9xkuQOL4u8Ty44puTic7J88CmdXkxfGsRfoVLXHCxppwehgpb/Chdb80FFehHqjN3ItQ=="],
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
"loading-cli": ["loading-cli@1.1.2", "", { "dependencies": { "colors-cli": "^1.0.26" } }, "sha512-M1ntfXHpdGoQxfaqKBOQPwSrTr9EIoTgj664Q9UVSbSnJvAFdribo+Ij//1jvACgrGHaTvfKoD9PG3NOxGj44g=="],
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
"lodash.memoize": ["lodash.memoize@4.1.2", "", {}, "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="],
@ -1124,8 +1317,12 @@
"lru-cache": ["lru-cache@4.1.5", "", { "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="],
"lru-queue": ["lru-queue@0.1.0", "", { "dependencies": { "es5-ext": "~0.10.2" } }, "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ=="],
"lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="],
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
"make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="],
"make-error": ["make-error@1.3.6", "", {}, "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="],
@ -1134,6 +1331,10 @@
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
"mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="],
"memoizee": ["memoizee@0.4.17", "", { "dependencies": { "d": "^1.0.2", "es5-ext": "^0.10.64", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" } }, "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA=="],
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
@ -1148,10 +1349,14 @@
"min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="],
"mini-svg-data-uri": ["mini-svg-data-uri@1.4.4", "", { "bin": { "mini-svg-data-uri": "cli.js" } }, "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg=="],
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"n3": ["n3@1.26.0", "", { "dependencies": { "buffer": "^6.0.3", "readable-stream": "^4.0.0" } }, "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w=="],
@ -1162,6 +1367,8 @@
"neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
"next-tick": ["next-tick@1.1.0", "", {}, "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="],
"node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
"node-gzip": ["node-gzip@1.1.2", "", {}, "sha512-ZB6zWpfZHGtxZnPMrJSKHVPrRjURoUzaDbLFj3VO70mpLTW5np96vXyHwft4Id0o+PYIzgDkBUjIzaNHhQ8srw=="],
@ -1176,6 +1383,8 @@
"npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
"nwsapi": ["nwsapi@2.2.22", "", {}, "sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ=="],
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
@ -1312,6 +1521,8 @@
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
"resolve.exports": ["resolve.exports@2.0.3", "", {}, "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A=="],
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
@ -1320,6 +1531,8 @@
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="],
@ -1390,16 +1603,40 @@
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
"svelte": ["svelte@5.42.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-gc0yfYY7OcuFbK2k/R/cHYYoN7A3SvYsnWHiWYayEV7OZpjSKyVHA1Ex0tW5eEbfQui6guN+sZ2whvhuz+qHpg=="],
"svelte-heros-v2": ["svelte-heros-v2@3.0.0", "", { "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-m+jPRTQK9nMEhEisf0Kh3guYdTUoF9ZuZxCT/u1peRemac8UnfZwaiu2c4DAMblsNYD/plznAo/Uszhm00J5lg=="],
"svelte-i18n": ["svelte-i18n@4.0.1", "", { "dependencies": { "cli-color": "^2.0.3", "deepmerge": "^4.2.2", "esbuild": "^0.19.2", "estree-walker": "^2", "intl-messageformat": "^10.5.3", "sade": "^1.8.1", "tiny-glob": "^0.2.9" }, "peerDependencies": { "svelte": "^3 || ^4 || ^5" }, "bin": { "svelte-i18n": "dist/cli.js" } }, "sha512-jaykGlGT5PUaaq04JWbJREvivlCnALtT+m87Kbm0fxyYHynkQaxQMnIKHLm2WeIuBRoljzwgyvz0Z6/CMwfdmQ=="],
"svelte-in-react": ["svelte-in-react@0.2.0", "", { "peerDependencies": { "next": ">=12.0.0", "react": ">=17.0.0", "react-dom": ">=17.0.0", "svelte": "^5.0.0", "svelte-loader": ">=3.1.0" }, "optionalPeers": ["next", "svelte-loader"] }, "sha512-bGqENHUEvv3/3Yyat6PAvIKIVZAKK1JkFbaiQMelJYC3eWDJYSEYt+Cb7JzhK0zXF2zPekDr+NgQJ5CSz11/pA=="],
"svelte-time": ["svelte-time@1.0.0", "", { "dependencies": { "dayjs": "^1.11.13" } }, "sha512-Igcx5odkvgnQ+jSawFdKFJT4mFVxvZzj2nJs6onHyp9ooDZpph8Vg6G42lUHBoqMxX/3hcKHw8/Orecp+OedHg=="],
"svgo": ["svgo@3.3.2", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, "bin": "./bin/svgo" }, "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw=="],
"symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="],
"sync-request": ["sync-request@6.1.0", "", { "dependencies": { "http-response-object": "^3.0.1", "sync-rpc": "^1.2.1", "then-request": "^6.0.0" } }, "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw=="],
"sync-rpc": ["sync-rpc@1.3.6", "", { "dependencies": { "get-port": "^3.1.0" } }, "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw=="],
"tailwind-merge": ["tailwind-merge@3.3.1", "", {}, "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g=="],
"tailwind-variants": ["tailwind-variants@3.1.1", "", { "peerDependencies": { "tailwind-merge": ">=3.0.0", "tailwindcss": "*" }, "optionalPeers": ["tailwind-merge"] }, "sha512-ftLXe3krnqkMHsuBTEmaVUXYovXtPyTK7ckEfDRXS8PBZx0bAUas+A0jYxuKA5b8qg++wvQ3d2MQ7l/xeZxbZQ=="],
"tailwindcss": ["tailwindcss@4.1.16", "", {}, "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA=="],
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
"test-exclude": ["test-exclude@6.0.0", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" } }, "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w=="],
"then-request": ["then-request@6.0.2", "", { "dependencies": { "@types/concat-stream": "^1.6.0", "@types/form-data": "0.0.33", "@types/node": "^8.0.0", "@types/qs": "^6.2.31", "caseless": "~0.12.0", "concat-stream": "^1.6.0", "form-data": "^2.2.0", "http-basic": "^8.1.1", "http-response-object": "^3.0.1", "promise": "^8.0.0", "qs": "^6.4.0" } }, "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA=="],
"timers-ext": ["timers-ext@0.1.8", "", { "dependencies": { "es5-ext": "^0.10.64", "next-tick": "^1.1.0" } }, "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww=="],
"tiny-glob": ["tiny-glob@0.2.9", "", { "dependencies": { "globalyzer": "0.1.0", "globrex": "^0.1.2" } }, "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg=="],
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
"tmpl": ["tmpl@1.0.5", "", {}, "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="],
@ -1416,6 +1653,12 @@
"ts-morph": ["ts-morph@24.0.0", "", { "dependencies": { "@ts-morph/common": "~0.25.0", "code-block-writer": "^13.0.3" } }, "sha512-2OAOg/Ob5yx9Et7ZX4CvTCc0UFoZHwLEJ+dpDPSUi5TgwwlTlX47w+iFRrEwzUZwYACjq83cgjS/Da50Ga37uw=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"tsx": ["tsx@4.20.6", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg=="],
"type": ["type@2.7.3", "", {}, "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="],
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
"type-detect": ["type-detect@4.0.8", "", {}, "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="],
@ -1454,6 +1697,8 @@
"vite-plugin-wasm": ["vite-plugin-wasm@3.5.0", "", { "peerDependencies": { "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" } }, "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ=="],
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
"w3c-xmlserializer": ["w3c-xmlserializer@4.0.0", "", { "dependencies": { "xml-name-validator": "^4.0.0" } }, "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw=="],
"walker": ["walker@1.0.8", "", { "dependencies": { "makeerror": "1.0.12" } }, "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ=="],
@ -1494,7 +1739,7 @@
"yallist": ["yallist@2.1.2", "", {}, "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="],
"yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
"yaml": ["yaml@2.8.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="],
"yargs": ["yargs@17.7.2", "", { "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" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
@ -1502,6 +1747,8 @@
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
"zimmerframe": ["zimmerframe@1.1.4", "", {}, "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ=="],
"zustand": ["zustand@5.0.8", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw=="],
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
@ -1526,14 +1773,34 @@
"@istanbuljs/load-nyc-config/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
"@ldo/cli/@ldo/ldo": ["@ldo/ldo@1.0.0-alpha.32", "", { "dependencies": { "@ldo/dataset": "^1.0.0-alpha.30", "@ldo/jsonld-dataset-proxy": "^1.0.0-alpha.32", "@ldo/subscribable-dataset": "^1.0.0-alpha.32", "buffer": "^6.0.3", "readable-stream": "^4.3.0" } }, "sha512-B5yEKAjpQA4VbXOv3faxYYxjgDZUSxTy4vCSATpVvGt96RxolJzewJ7ELl0C2KG0EANcWoHyUB0ac7oOJrmUCQ=="],
"@ldo/connected/@ldo/ldo": ["@ldo/ldo@1.0.0-alpha.32", "", { "dependencies": { "@ldo/dataset": "^1.0.0-alpha.30", "@ldo/jsonld-dataset-proxy": "^1.0.0-alpha.32", "@ldo/subscribable-dataset": "^1.0.0-alpha.32", "buffer": "^6.0.3", "readable-stream": "^4.3.0" } }, "sha512-B5yEKAjpQA4VbXOv3faxYYxjgDZUSxTy4vCSATpVvGt96RxolJzewJ7ELl0C2KG0EANcWoHyUB0ac7oOJrmUCQ=="],
"@ldo/connected-nextgraph/@ldo/ldo": ["@ldo/ldo@1.0.0-alpha.32", "", { "dependencies": { "@ldo/dataset": "^1.0.0-alpha.30", "@ldo/jsonld-dataset-proxy": "^1.0.0-alpha.32", "@ldo/subscribable-dataset": "^1.0.0-alpha.32", "buffer": "^6.0.3", "readable-stream": "^4.3.0" } }, "sha512-B5yEKAjpQA4VbXOv3faxYYxjgDZUSxTy4vCSATpVvGt96RxolJzewJ7ELl0C2KG0EANcWoHyUB0ac7oOJrmUCQ=="],
"@ldo/jsonld-dataset-proxy/jsonld2graphobject": ["jsonld2graphobject@0.0.4", "", { "dependencies": { "@rdfjs/types": "^1.0.1", "@types/jsonld": "^1.5.6", "jsonld-context-parser": "^2.1.5", "uuid": "^8.3.2" } }, "sha512-7siWYw9/EaD9lWyMbHr2uLMy8kbNVyOtDlsAWJUlUjVfXpcJcwLN6f0qeNt0ySV4fDoAJOjJXNvo7V/McrubAg=="],
"@ldo/react/@ldo/ldo": ["@ldo/ldo@1.0.0-alpha.32", "", { "dependencies": { "@ldo/dataset": "^1.0.0-alpha.30", "@ldo/jsonld-dataset-proxy": "^1.0.0-alpha.32", "@ldo/subscribable-dataset": "^1.0.0-alpha.32", "buffer": "^6.0.3", "readable-stream": "^4.3.0" } }, "sha512-B5yEKAjpQA4VbXOv3faxYYxjgDZUSxTy4vCSATpVvGt96RxolJzewJ7ELl0C2KG0EANcWoHyUB0ac7oOJrmUCQ=="],
"@ldo/subscribable-dataset/uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
"@ldo/type-traverser/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
"@tailwindcss/node/jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="],
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@testing-library/dom/aria-query": ["aria-query@5.1.3", "", { "dependencies": { "deep-equal": "^2.0.5" } }, "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ=="],
"@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="],
@ -1562,12 +1829,20 @@
"concat-stream/readable-stream": ["readable-stream@2.3.8", "", { "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" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"cosmiconfig/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
"csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="],
"cssstyle/cssom": ["cssom@0.3.8", "", {}, "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="],
"dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"filelist/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
"flowbite-datepicker/flowbite": ["flowbite@2.5.2", "", { "dependencies": { "@popperjs/core": "^2.9.3", "flowbite-datepicker": "^1.3.0", "mini-svg-data-uri": "^1.4.3" } }, "sha512-kwFD3n8/YW4EG8GlY3Od9IoKND97kitO+/ejISHSqpn3vw2i5K/+ZI8Jm2V+KC4fGdnfi0XZ+TzYqQb4Q1LshA=="],
"hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
"http-response-object/@types/node": ["@types/node@10.17.60", "", {}, "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="],
@ -1596,6 +1871,10 @@
"stack-utils/escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="],
"svelte-i18n/esbuild": ["esbuild@0.19.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.19.12", "@esbuild/android-arm": "0.19.12", "@esbuild/android-arm64": "0.19.12", "@esbuild/android-x64": "0.19.12", "@esbuild/darwin-arm64": "0.19.12", "@esbuild/darwin-x64": "0.19.12", "@esbuild/freebsd-arm64": "0.19.12", "@esbuild/freebsd-x64": "0.19.12", "@esbuild/linux-arm": "0.19.12", "@esbuild/linux-arm64": "0.19.12", "@esbuild/linux-ia32": "0.19.12", "@esbuild/linux-loong64": "0.19.12", "@esbuild/linux-mips64el": "0.19.12", "@esbuild/linux-ppc64": "0.19.12", "@esbuild/linux-riscv64": "0.19.12", "@esbuild/linux-s390x": "0.19.12", "@esbuild/linux-x64": "0.19.12", "@esbuild/netbsd-x64": "0.19.12", "@esbuild/openbsd-x64": "0.19.12", "@esbuild/sunos-x64": "0.19.12", "@esbuild/win32-arm64": "0.19.12", "@esbuild/win32-ia32": "0.19.12", "@esbuild/win32-x64": "0.19.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg=="],
"svgo/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
"then-request/@types/node": ["@types/node@8.10.66", "", {}, "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw=="],
"then-request/form-data": ["form-data@2.5.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.35", "safe-buffer": "^5.2.1" } }, "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A=="],
@ -1630,6 +1909,8 @@
"concat-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
"csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="],
"filelist/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"jsonld-context-parser/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
@ -1640,6 +1921,52 @@
"pkg-dir/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
"svelte-i18n/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.19.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA=="],
"svelte-i18n/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.19.12", "", { "os": "android", "cpu": "arm" }, "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w=="],
"svelte-i18n/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.19.12", "", { "os": "android", "cpu": "arm64" }, "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA=="],
"svelte-i18n/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.19.12", "", { "os": "android", "cpu": "x64" }, "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew=="],
"svelte-i18n/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.19.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g=="],
"svelte-i18n/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.19.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A=="],
"svelte-i18n/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.19.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA=="],
"svelte-i18n/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.19.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg=="],
"svelte-i18n/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.19.12", "", { "os": "linux", "cpu": "arm" }, "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w=="],
"svelte-i18n/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.19.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA=="],
"svelte-i18n/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.19.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA=="],
"svelte-i18n/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA=="],
"svelte-i18n/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w=="],
"svelte-i18n/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.19.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg=="],
"svelte-i18n/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg=="],
"svelte-i18n/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.19.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg=="],
"svelte-i18n/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.19.12", "", { "os": "linux", "cpu": "x64" }, "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg=="],
"svelte-i18n/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.19.12", "", { "os": "none", "cpu": "x64" }, "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA=="],
"svelte-i18n/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.19.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw=="],
"svelte-i18n/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.19.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA=="],
"svelte-i18n/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.19.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A=="],
"svelte-i18n/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.19.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ=="],
"svelte-i18n/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.12", "", { "os": "win32", "cpu": "x64" }, "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA=="],
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
"pkg-dir/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],

@ -15,7 +15,7 @@
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"webdev": "cross-env NG_ENV_WEB=1 TAURI_DEBUG=1 NG_PUBLIC_DEV=1 vite",
"webdev": "cross-env NG_ENV_WEB=1 TAURI_DEBUG=1 NG_ENV_NO_REDIRECT=1 NG_PUBLIC_DEV=1 vite",
"webbuild": "cross-env NG_ENV_WEB=1 NG_ENV_ONEFILE=1 vite build && node prepare-web-file.cjs",
"libwasm": "cd ../.. && cargo install cargo-run-script && cargo run-script libwasm"
},
@ -25,26 +25,33 @@
"@ldo/connected-nextgraph": "1.0.0-alpha.15",
"@ldo/ldo": "1.0.0-alpha.14",
"@ldo/react": "1.0.0-alpha.15",
"@react-oauth/google": "^0.12.2",
"@mui/icons-material": "^7.2.0",
"@mui/material": "^7.2.0",
"@rdfjs/data-model": "^1.2.0",
"@rdfjs/types": "^1.0.1",
"qrcode.react": "^4.2.0",
"@react-oauth/google": "^0.12.2",
"@tauri-apps/api": "^2.9.0",
"@tauri-apps/plugin-opener": "^2",
"@tauri-apps/plugin-log": "^2.7.0",
"@tauri-apps/plugin-opener": "^2",
"async-proxy": "^0.4.1",
"dotenv": "^17.1.0",
"flowbite": "^3.1.2",
"flowbite-svelte": "^1.19.0",
"html5-qrcode": "^2.3.8",
"leaflet": "^1.9.4",
"libphonenumber-js": "^1.12.17",
"qrcode.react": "^4.2.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-hook-form": "^7.62.0",
"react-leaflet": "^5.0.0",
"react-router-dom": "^7.6.3",
"react-waypoint": "^10.3.0",
"zustand": "^5.0.6",
"async-proxy": "^0.4.1"
"svelte-heros-v2": "^3.0.0",
"svelte-i18n": "^4.0.1",
"svelte-in-react": "^0.2.0",
"svelte-time": "^1.0.0",
"zustand": "^5.0.6"
},
"devDependencies": {
"@eslint/js": "^9.30.1",
@ -75,6 +82,12 @@
"vite-plugin-top-level-await": "^1.6.0",
"vite-plugin-wasm": "^3.5.0",
"node-gzip": "^1.1.2",
"cross-env": "^10.1.0"
"cross-env": "^10.1.0",
"@hazycora/vite-plugin-svelte-svg": "^2.4.3",
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@tailwindcss/vite": "^4.1.14",
"@tsconfig/svelte": "^5.0.5",
"svelte": "^5.39.13",
"tailwindcss": "^4.1.14"
}
}

@ -18,7 +18,7 @@ crate-type = ["staticlib", "cdylib", "rlib"]
tauri-build = { version = "2.5.0", features = [] }
[dependencies]
tauri = { version = "2.9.0", features = [] }
tauri = { version = "2.9.0", features = ["unstable"] }
tauri-plugin-log = "2"
log = "0.4"
tauri-plugin-opener = "2"

@ -0,0 +1,20 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "remote-tag-capability",
"windows": ["registration"],
"remote": {
"urls": [
"https://account.nextgraph.eu",
"http://account-dev.nextgraph.eu:5173",
"https://account.nextgraph.one",
"https://account-staging.nextgraph.eu",
"https://account.allelo.eco"
]
},
"permissions": [
"core:event:default",
"core:window:default",
"core:window:allow-close",
"core:window:allow-destroy"
]
}

@ -5,6 +5,9 @@
"windows": ["main"],
"permissions": [
"core:default",
"core:window:allow-close",
"core:window:allow-destroy",
"core:window:allow-get-all-windows",
"contacts-importer:allow-import-contacts",
"contacts-importer:allow-check-permissions",
"contacts-importer:allow-request-permissions",

@ -336,24 +336,31 @@ async fn open_window(
label: String,
title: String,
app: tauri::AppHandle,
) -> Result<(), ()> {
) -> Result<bool, ()> {
log_debug!("open window url {:?}", url);
let _already_exists = app.get_webview_window(&label);
let _already_exists = app.get_window(&label);
#[cfg(desktop)]
if _already_exists.is_some() {
let _ = _already_exists.unwrap().close();
std::thread::sleep(std::time::Duration::from_secs(1));
log_info!("already exists");
//let _ = _already_exists.unwrap().close();
//std::thread::sleep(std::time::Duration::from_secs(1));
return Ok(true);
}
let mut config = WindowConfig::default();
config.label = label;
config.url = tauri::WebviewUrl::External(url.parse().unwrap());
config.title = title;
let _register_window = tauri::WebviewWindowBuilder::from_config(&app, &config)
match tauri::WebviewWindowBuilder::from_config(&app, &config)
.unwrap()
.build()
.unwrap();
Ok(())
{
Ok(_) => {}
Err(e) => {
return Ok(true);
}
}
Ok(false)
}
#[tauri::command(rename_all = "snake_case")]

@ -10,11 +10,13 @@
"frontendDist": "../dist"
},
"app": {
"withGlobalTauri": true,
"windows": [
{
"title": "PNM Prototype",
"width": 1280,
"height": 960
"height": 960,
"label": "main"
}
],
"security": {

@ -23,9 +23,9 @@ let api = createAsyncProxy({},{
export default api;
export const NG_EU_BSP = "https://nextgraph.eu";
export const NG_EU_BSP = import.meta.env.NG_ENV_ALT ? "https://"+import.meta.env.NG_ENV_ALT : "https://nextgraph.eu";
export const NG_EU_BSP_REGISTER = import.meta.env.PROD
? "https://account.nextgraph.eu/#/create"
? import.meta.env.NG_ENV_ALT_ACCOUNT ? import.meta.env.NG_ENV_ALT_ACCOUNT : "https://account.nextgraph.eu/#/create"
: "http://account-dev.nextgraph.eu:5173/#/create";
export const NG_ONE_BSP = "https://nextgraph.one";

@ -1,8 +1,9 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import type { FunctionComponent, PropsWithChildren } from "react";
import { NextGraphAuthContext, useNextGraphAuth } from "./NextGraphAuthContext.js";
import * as ng from "./api";
import ng from "./api";
import type { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected";
import type { NextGraphConnectedPlugin, NextGraphConnectedContext } from "@ldo/connected-nextgraph";
@ -15,10 +16,12 @@ import type { NextGraphConnectedPlugin, NextGraphConnectedContext } from "@ldo/c
export function createBrowserNGReactMethods(
dataset: ConnectedLdoDataset<(NextGraphConnectedPlugin | ConnectedPlugin)[]>,
) : {BrowserNGLdoProvider: React.FunctionComponent<{children?: React.ReactNode | undefined}>, useNextGraphAuth: typeof useNextGraphAuth} {
const BrowserNGLdoProvider: FunctionComponent<PropsWithChildren> = ({
children,
}) => {
const navigate = useNavigate();
const location = useLocation();
const [session, setSession] = useState<NextGraphConnectedContext>(
{
ng: undefined,
@ -33,35 +36,41 @@ export function createBrowserNGReactMethods(
//console.log("init called");
setRanInitialAuthCheck(true);
// TODO: export the types for the session object coming from NG.
// await init( (event: { status: string; session: { session_id: unknown; protected_store_id: unknown; private_store_id: unknown; public_store_id: unknown; }; }) => {
// //console.log("called back in react", event)
// // callback
// // once you receive event.status == "loggedin"
// // you can use the full API
// if (event.status == "loggedin") {
// setSession({
// ng,
// sessionId: event.session.session_id as string, //FIXME: sessionId should be a Number.
// protectedStoreId: event.session.protected_store_id as string,
// privateStoreId: event.session.private_store_id as string,
// publicStoreId: event.session.public_store_id as string
// }); // TODO: add event.session.user too
window.login_callback =
(event:
{ status: string;
session: { session_id: unknown;
protected_store_id: unknown;
private_store_id: unknown;
public_store_id: unknown; };
}) => {
console.log("called back in react", event)
// callback
// once you receive event.status == "loggedin"
// you can use the full API
if (event.status == "loggedin") {
setSession({
ng,
sessionId: event.session.session_id as string, //FIXME: sessionId should be a Number.
protectedStoreId: event.session.protected_store_id as string,
privateStoreId: event.session.private_store_id as string,
publicStoreId: event.session.public_store_id as string
}); // TODO: add event.session.user too
// dataset.setContext("nextgraph", {
// ng,
// sessionId: event.session.session_id as string
// });
// }
// else if (event.status == "cancelled" || event.status == "error" || event.status == "loggedout") {
// setSession({ ng: undefined });
// dataset.setContext("nextgraph", {
// ng: undefined,
// });
// }
// }
// , true // singleton: boolean (will your app create many docs in the system, or should it be launched as a unique instance)
// , []); //list of AccessRequests (for now, leave this empty)
dataset.setContext("nextgraph", {
ng,
sessionId: event.session.session_id as string
});
}
else if (event.status == "cancelled" || event.status == "error" || event.status == "loggedout") {
setSession({ ng: undefined });
dataset.setContext("nextgraph", {
ng: undefined,
});
}
};
if (location.pathname != "/wallet/create") navigate("/wallet/login")
}, []);

@ -1,4 +1,5 @@
import { HashRouter as Router, Routes, Route } from 'react-router-dom';
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { OnboardingProvider } from '@/contexts/OnboardingContext';
@ -33,138 +34,67 @@ import { Button } from '@/components/ui';
import { isNextGraphEnabled } from '@/utils/featureFlags';
import CreateContactPage from "@/pages/CreateContactPage";
const theme = createWireframeTheme();
const NextGraphAppContent = () => {
const nextGraphAuth = useNextGraphAuth() as unknown as NextGraphAuth | undefined;
const { session, login, logout } = nextGraphAuth || {};
console.log('NextGraph Auth:', nextGraphAuth);
console.log('Session:', session);
console.log('Keys:', nextGraphAuth ? Object.keys(nextGraphAuth) : 'no auth');
const hasLogin = Boolean(login);
const hasLogout = Boolean(logout);
const isAuthenticated = Boolean(session?.ng);
const isNextGraphReady = hasLogin && hasLogout;
console.log('hasLogin:', hasLogin, 'hasLogout:', hasLogout);
console.log('isAuthenticated:', isAuthenticated, 'isNextGraphReady:', isNextGraphReady);
if (!isNextGraphReady) {
return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '100vh'
}}
>
<Typography variant="h6">Loading NextGraph...</Typography>
</Box>
);
}
if (!isAuthenticated) {
return (
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: '100vh',
gap: 2
}}
>
<Typography variant="h4" component="h2" gutterBottom>
Welcome to NAO
</Typography>
<Typography variant="body1" color="text.secondary" sx={{ mb: 2 }}>
Please log in with your NextGraph wallet to continue.
</Typography>
<Button
variant="contained"
size="large"
onClick={() => login?.()}
>
Login with NextGraph
</Button>
</Box>
);
}
import { useSvelteComponent } from "svelte-in-react";
import WalletCreate from "./svelte/WalletCreate.svelte";
import WalletLogin from "./svelte/WalletLogin.svelte";
return <AppRoutes />;
};
const theme = createWireframeTheme();
const MockAppContent = () => {
return <AppRoutes />;
};
const AppRoutes = () => {
// Convert the Svelte components to React components
const ReactWalletCreate = useSvelteComponent(WalletCreate);
const ReactWalletLogin = useSvelteComponent(WalletLogin);
const AppRoutes = () => (
<OnboardingProvider>
return <OnboardingProvider>
<Router>
<Routes>
<Route path="/onboarding" element={<SocialContractPage />} />
<Route path="/onboarding/social-contract" element={<SocialContractAgreementPage />} />
<Route path="/onboarding/claim-identity" element={<ClaimIdentityPage />} />
<Route path="/onboarding/accept-connection" element={<AcceptConnectionPage />} />
<Route path="/join-group" element={<GroupJoinPage />} />
<Route path="/*" element={
<DashboardLayout>
<Routes>
<Route path="/onboarding/welcome" element={<WelcomeToVaultPage />} />
<Route path="/" element={<HomePage />} />
<Route path="/import" element={<ImportPage />} />
<Route path="/contacts" element={<ContactListPage />} />
<Route path="/contacts/create" element={<CreateContactPage />} />
<Route path="/contacts/:id" element={<ContactViewPage />} />
<Route path="/groups" element={<GroupPage />} />
<Route path="/groups/create" element={<CreateGroupPage />} />
<Route path="/groups/:groupId" element={<GroupDetailPage />} />
<Route path="/groups/:groupId/info" element={<GroupInfoPage />} />
<Route path="/posts" element={<PostsOffersPage />} />
<Route path="/messages" element={<MessagesPage />} />
<Route path="/notifications" element={<NotificationsPage />} />
<Route path="/account" element={<AccountPage />} />
<Route path="/verify-phone/:phone" element={<PhoneVerificationPage />} />
<Route path="/invite" element={<InvitationPage />} />
</Routes>
</DashboardLayout>
} />
<Route path="/signup" element={<PersonalDataVaultPage />} />
<Route path="/register" element={<PersonalDataVaultPage />} />
<Route path="/login" element={<LoginPage />} />
</Routes>
<BrowserNGLdoProvider>
<Routes>
<Route path="/onboarding" element={<SocialContractPage />} />
<Route path="/onboarding/social-contract" element={<SocialContractAgreementPage />} />
<Route path="/onboarding/claim-identity" element={<ClaimIdentityPage />} />
<Route path="/onboarding/accept-connection" element={<AcceptConnectionPage />} />
<Route path="/join-group" element={<GroupJoinPage />} />
<Route path="/wallet/create" element={<ReactWalletCreate />} />
<Route path="/wallet/login" element={<ReactWalletLogin />} />
<Route path="/*" element={
<DashboardLayout>
<Routes>
<Route path="/onboarding/welcome" element={<WelcomeToVaultPage />} />
<Route path="/" element={<HomePage />} />
<Route path="/import" element={<ImportPage />} />
<Route path="/contacts" element={<ContactListPage />} />
<Route path="/contacts/create" element={<CreateContactPage />} />
<Route path="/contacts/:id" element={<ContactViewPage />} />
<Route path="/groups" element={<GroupPage />} />
<Route path="/groups/create" element={<CreateGroupPage />} />
<Route path="/groups/:groupId" element={<GroupDetailPage />} />
<Route path="/groups/:groupId/info" element={<GroupInfoPage />} />
<Route path="/posts" element={<PostsOffersPage />} />
<Route path="/messages" element={<MessagesPage />} />
<Route path="/notifications" element={<NotificationsPage />} />
<Route path="/account" element={<AccountPage />} />
<Route path="/verify-phone/:phone" element={<PhoneVerificationPage />} />
<Route path="/invite" element={<InvitationPage />} />
</Routes>
</DashboardLayout>
} />
<Route path="/signup" element={<PersonalDataVaultPage />} />
<Route path="/register" element={<PersonalDataVaultPage />} />
<Route path="/login" element={<LoginPage />} />
</Routes>
</BrowserNGLdoProvider>
</Router>
</OnboardingProvider>
);
const AppContent = () => {
const useNextGraph = isNextGraphEnabled();
if (useNextGraph) {
return <NextGraphAppContent />;
}
return <MockAppContent />;
</OnboardingProvider>;
};
function App() {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
{isNextGraphEnabled() ? (
<BrowserNGLdoProvider>
<AppContent />
</BrowserNGLdoProvider>
) : (
<AppContent />
)}
<AppRoutes />
</ThemeProvider>
);
}

@ -266,7 +266,7 @@ export const useContacts = ({limit = 10}: {limit?: number}): ContactsReturn => {
}, [filters, limit]);
const loadNextGraphContacts = useCallback(async (page: number): Promise<string[]> => {
if (!session) {
if (!session || !session.ng) {
return [];
}

@ -50,7 +50,7 @@ export function useSaveContacts(): UseSaveContactsReturn {
}, [session, createData, commitData, changeData, isNextGraph]);
const createContact = useCallback(async (contact: Contact): Promise<Contact | undefined> => {
if (!session) {
if (!session || !session.ng) {
const errorMsg = 'No active session available';
setError(errorMsg);
throw new Error(errorMsg);

@ -19,7 +19,7 @@ export function useUpdateProfile(): UseUpdateProfileReturn {
const {commitData, changeData} = useLdo();
const updateProfile = useCallback(async (profile: Partial<SocialContact>) => {
if (!session) {
if (!session || !session.ng) {
const errorMsg = 'No active session available';
setError(errorMsg);
throw new Error(errorMsg);

@ -1,70 +1,218 @@
* { box-sizing: border-box; }
@import "tailwindcss";
/** To format paths, like Settings > Wallet > Generate Wallet QR */
.path {
font-family: monospace;
background-color: rgba(73, 114, 165, 0.1);
}
/* .splash-loaded {
display: none;
} */
.toggle * {
cursor: pointer;
}
.error-popover h3 {
text-align: center;
color: rgb(200 30 30);
}
.error-popover > div:first-child {
background-color: rgb(200 30 30);
}
.error-popover > div:first-child > h3 {
color: white;
}
.logo {
padding: 1.5em;
will-change: filter;
transition: 0.75s;
padding-bottom: 1em;
}
@keyframes pulse-logo-color {
0%,
100% {
fill: rgb(73, 114, 165);
stroke: rgb(73, 114, 165);
}
50% {
/* Mid-transition color */
stroke: #bbb;
fill: #bbb;
}
}
.logo-pulse path {
animation: pulse-logo-color 2s infinite;
animation-timing-function: cubic-bezier(0.65, 0.01, 0.59, 0.83);
}
.logo-gray path {
fill: #bbb;
stroke: #bbb;
}
.logo-blue path {
fill: rgb(73, 114, 165);
stroke: rgb(73, 114, 165);
}
.jse-absolute-popup-content {
left: 0 !important;
}
.container3 {
margin: 0;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.container3 aside {
width: 20rem !important;
}
div[role="alert"] div {
display: block;
}
.spinner-overlay button {
display: none;
}
.choice-button {
min-width: 305px;
}
.clickable {
cursor: pointer;
}
.row {
display: flex;
justify-content: center;
}
.deactivated-menu > svg {
color: rgb(156 163 175) !important;
}
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color-scheme: light;
color: #213547;
background-color: #ffffff;
color: #0f0f0f;
background-color: white;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 305px;
min-height: 100vh;
}
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
#root {
width: 100%;
min-height: 100vh;
}
/* #app {
/*max-width: 1280px;
margin: 0 auto;
padding: 0rem;
text-align: center;
} */
/* .container2 {
padding-top: 10vh;
} */
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
.toast {
left: 50%;
transform: translateX(-50%);
z-index: 49;
cursor: pointer;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
cursor: pointer;
}
button:hover {
border-color: #646cff;
border-color: #396cd8;
}
button:active {
border-color: #396cd8;
background-color: #e8e8e8;
}
/* input,
button {
outline: none;
} */
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
/* @media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
button:active {
background-color: #0f0f0f69;
}
} */
* {
box-sizing: border-box;
}

@ -2,9 +2,11 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from '@/App'
import * as web_api from "../../../sdk/js/lib-wasm/pkg";
import { default as web_api } from "../../../sdk/js/api-web";
import {init_api} from "./.auth-react/api";
import { select_default_lang } from "./svelte/lang";
init_api(web_api);
await select_default_lang();
createRoot(document.getElementById('root')!).render(
<StrictMode>

@ -2,9 +2,11 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from '@/App'
import native_api from "./native-api";
import { default as native_api } from "./native-api";
import {init_api} from "./.auth-react/api";
import { select_default_lang } from "./svelte/lang";
init_api(native_api);
await select_default_lang();
createRoot(document.getElementById('root')!).render(
<StrictMode>

@ -18,6 +18,7 @@ const mapping = {
"wallet_gen_shuffle_for_pazzle_opening": ["pazzle_length"],
"wallet_gen_shuffle_for_pin": [],
"wallet_open_with_pazzle": ["wallet","pazzle","pin"],
"wallet_open_with_password": ["wallet","password"],
"wallet_open_with_mnemonic_words": ["wallet","mnemonic_words","pin"],
"wallet_open_with_mnemonic": ["wallet","mnemonic","pin"],
"wallet_was_opened": ["opened_wallet"],
@ -65,10 +66,12 @@ let lastStreamId = 0;
const tauri_handler = {
async apply(target, path, caller, args) {
//console.log("CALLING", target, path, args)
try {
if (path[0] === "open_window") {
let callback = args[3];
await invoke(path[0],{url:args[0],label:args[1],title:args[2]});
let already_exists = await invoke(path[0],{url:args[0],label:args[1],title:args[2]});
if (already_exists) return;
let unsub_register_accepted;
let unsub_register_error;
@ -86,23 +89,30 @@ const tauri_handler = {
unsub_register_accepted = await listen(
"accepted",
async (event) => {
console.log("got event", event)
unsub_register();
let reg_popup = Window.getByLabel("registration");
await reg_popup.close();
let reg_popup = await Window.getByLabel("registration");
try {
await reg_popup.close();
} catch (e) {
}
await (callback)("accepted",event.payload);
}
);
unsub_register_error = await listen("error", async (event) => {
console.log("got error event", event)
unsub_register();
let reg_popup = Window.getByLabel("registration");
let reg_popup = await Window.getByLabel("registration");
await reg_popup.close();
await (callback)("error",event.payload);
});
await new Promise((resolve) => setTimeout(resolve, 1000));
let reg_popup = Window.getByLabel("registration");
unsub_register_close = await reg_popup.onCloseRequested(async (event) => {
unsub_register_close = await listen("close", async (event) => {
console.log("got close", event)
unsub_register_close = undefined;
unsub_register();
await (callback)("close");
});
return unsub_register;
@ -290,7 +300,7 @@ const tauri_handler = {
} else if (path[0] === "wallet_create") {
let params = args[0];
params.result_with_wallet_file = false;
params.security_img = Array.from(new Uint8Array(params.security_img));
//params.security_img = Array.from(new Uint8Array(params.security_img));
return await invoke(path[0],{params})
} else if (path[0] === "wallet_read_file") {
let file = args[0];

@ -258,7 +258,7 @@ WHERE {
changeData: ChangeDataFunction,
commitData: CommitDataFunction
) {
if (!session) {
if (!session || !session.ng) {
throw new Error('No active session available');
}
@ -328,7 +328,7 @@ WHERE {
resource: NextGraphResource,
subject: SocialContact
) {
if (!session) {
if (!session || !session.ng) {
throw new Error('No active session available');
}
@ -353,7 +353,7 @@ WHERE {
};
async getDuplicatedContacts(session?: NextGraphSession): Promise<string[][]> {
if (!session) return [];
if (!session || !session.ng) return [];
const sparql = this.getDuplicatedContactsSparql();
const data = await session.ng!.sparql_query(session.sessionId, sparql);
@ -434,7 +434,7 @@ WHERE {
commitData: CommitDataFunction,
changeData: ChangeDataFunction,
) {
if (!session) {
if (!session || !session.ng) {
throw new Error('No active session available');
}

@ -0,0 +1,18 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
export let params: { invitation: string } = { invitation: "" };
import { onMount } from "svelte";
onMount(
() => (window.location.href = "/#/wallet/create?i=" + params.invitation)
);
</script>

@ -0,0 +1,502 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
@component
Wallet creation page.
This component manages the whole UX flow, gives infos about wallets,
offers available brokers, handles wallet creation,
and shows the generated pazzle and mnemonic (if applicable).
-->
<script lang="ts">
import { Button, Alert } from "flowbite-svelte";
import { t } from "svelte-i18n";
import CenteredLayout from "./lib/CenteredLayout.svelte";
import PasswordInput from "./lib/components/PasswordInput.svelte";
import { redirect_server, bootstrap_redirect, base64UrlEncode, push } from "./index";
import {
NG_EU_BSP_REGISTER,
NG_ONE_BSP_REGISTER,
APP_WALLET_CREATE_SUFFIX,
default as ng,
} from "../.auth-react/api";
// @ts-ignore
import Logo from "./assets/nextgraph.svg?component";
import { onMount, onDestroy, tick } from "svelte";
import { wallets, display_error } from "./store";
import Spinner from "./lib/components/Spinner.svelte";
console.log("WalletCreate called")
let search = window.location.href.split("?")[1] || "";
const param = new URLSearchParams(search);
for (const [key, value] of param) {
console.log("PARAM",key,value);
}
let tauri_platform = import.meta.env.TAURI_ENV_PLATFORM;
let wait: any = false;
let registration_error;
let registration_success;
let top;
let error;
let ready;
let invitation;
let pre_invitation;
let username = "";
let password = "";
let username_pass_ok = false;
let password_input;
let username_input;
const username_password_ok = async (e) => {
if (!e || e.key == "Enter" || e.keyCode == 13 || e.type == "enter") {
await tick();
if (!password) {
password_input.scrollIntoView();
password_input.focus();
} else if (!username) {
username_input.scrollIntoView();
username_input.focus();
} else {
username_pass_ok = true;
await do_wallet();
}
}
};
function scrollToTop() {
top.scrollIntoView();
}
async function bootstrap() {
//console.log(await ng.client_info());
if (!tauri_platform || tauri_platform == "android") {
if (param.get("re")) {
registration_error = param.get("re");
console.error("registration_error", registration_error);
} else if (
(param.get("rs") || param.get("i")) &&
!tauri_platform &&
!param.get("ab") &&
!import.meta.env.NG_ENV_NO_REDIRECT
) {
//registration_success = param.get("rs");
// doing the bootstrap recording at nextgraph.net
let i = param.get("i");
invitation = await ng.decode_invitation(i);
let bootstrap_iframe_msgs = await ng.bootstrap_to_iframe_msgs(
invitation.V0.bootstrap
);
let local_invitation = await ng.get_local_bootstrap(location.href);
if (local_invitation) {
bootstrap_iframe_msgs.push(
...(await ng.bootstrap_to_iframe_msgs(
local_invitation.V0.bootstrap
))
);
}
let encoded = base64UrlEncode(JSON.stringify(bootstrap_iframe_msgs));
window.location.href =
bootstrap_redirect +
encoded +
"&m=add&ab=" +
encodeURIComponent(window.location.href);
return;
} else if (param.get("rs")) {
registration_success = param.get("rs");
invitation = await ng.decode_invitation(param.get("i"));
//window.location.replace(window.location.href.split("?")[0]);
} else if (param.get("i")) {
invitation = await ng.get_local_bootstrap_with_public(
location.href,
param.get("i"),
false //import.meta.env.PROD
);
console.log("invitation", invitation);
if (invitation && invitation.V0.url) {
pre_invitation = invitation;
invitation = undefined;
} else if (!invitation) {
let redirect = await ng.get_ngnet_url_of_invitation(param.get("i"));
if (redirect) {
console.error("got an invitation for another broker. redirecting");
window.location.href = redirect;
} else {
//let i = await ng.decode_invitation(param.get("i"));
console.error("invalid invitation. ignoring it");
}
} else {
registration_success = window.location.host;
}
} else {
pre_invitation = await ng.get_local_bootstrap_with_public(
location.href,
undefined,
true
);
console.log("pre_invitation", pre_invitation);
}
}
scrollToTop();
if (!invitation) {
if (pre_invitation) {
await select_bsp(pre_invitation.V0.url, pre_invitation.V0.name);
} else if (!registration_error) {
selectEU(false);
}
} else {
//await do_wallet();
}
}
async function do_wallet() {
let local_invitation = await ng.get_local_bootstrap(location.href);
let additional_bootstrap;
if (local_invitation) {
additional_bootstrap = local_invitation.V0.bootstrap;
}
let core_registration;
if (invitation.V0.code) {
core_registration = invitation.V0.code.ChaCha20Key;
}
let params = {
pazzle_length: 0,
security_txt: username,
security_img: undefined,
password: password,
mnemonic: false,
send_bootstrap: false, //options.cloud || options.bootstrap ? : undefined,
send_wallet: false,
local_save: true,
result_with_wallet_file: false, // this will be automatically changed to true for browser app
core_bootstrap: invitation.V0.bootstrap,
core_registration,
additional_bootstrap,
device_name: "",
pdf: false,
};
//console.log("do wallet with params", params);
try {
ready = await ng.wallet_create(params);
wallets.set(await ng.get_wallets());
console.log($wallets);
push("#/wallet/login");
} catch (e) {
console.error(e);
error = e;
}
}
onMount(async () => await bootstrap());
ready = false;
let unsub_register = () => {};
onDestroy(async () => {
if (unsub_register) unsub_register();
unsub_register = undefined;
});
const select_bsp = async (bsp_url, bsp_name) => {
console.log("select bsp")
if (!tauri_platform || tauri_platform == "android") {
let redirect_url;
if (tauri_platform) {
redirect_url = window.location.href;
} else {
let local_url;
if (!import.meta.env.PROD) {
local_url = "http://localhost:1421";
} else {
let from_url = window.location.href;
if (from_url.startsWith("https://")) from_url = `https://${bsp_name}`;
local_url = await ng.get_local_url(from_url);
}
if (local_url) redirect_url = local_url + APP_WALLET_CREATE_SUFFIX;
}
let create = {
V0: {
redirect_url,
},
};
let ca = await ng.encode_create_account(create);
wait = $t("pages.wallet_create.redirecting_to_registration_page");
window.location.href = bsp_url + "?ca=" + ca;
//window.open(), "_self").focus();
} else {
let create = {
V0: {
redirect_url: undefined,
},
};
wait = $t("pages.wallet_create.complete_in_popup");
let ca = await ng.encode_create_account(create);
let unsub_register;
let temp = await ng.open_window(
bsp_url + "?ca=" + ca,
"registration",
"Registration at a Broker",
async (result, payload) => {
if (result == "accepted") {
wait = false;
console.log("got accepted with payload", payload);
registration_success = bsp_name;
invitation = await ng.decode_invitation(payload.invite);
unsub_register = undefined;
} else if (result == "error") {
wait = false;
console.log("got error with payload", payload);
if (payload) registration_error = payload.error;
unsub_register = undefined;
} else if (result == "close") {
console.log("onCloseOfRegistrationWindow");
wait = false;
registration_error = "You cancelled the registration";
unsub_register = undefined;
}
}
);
console.log("temp",temp)
if (temp) unsub_register = temp;
}
};
const selectONE = async (event) => {
await select_bsp(NG_ONE_BSP_REGISTER, "nextgraph.one");
};
const selectEU = async (event) => {
await select_bsp(
NG_EU_BSP_REGISTER,
import.meta.env.NG_ENV_ALT ? import.meta.env.NG_ENV_ALT : "nextgraph.eu"
);
};
</script>
<CenteredLayout>
<div class="max-w-2xl lg:px-8 mx-auto mb-20">
{#if wait}
<div class="lg:px-8 text-primary-700">
{#if wait === true}
{$t("pages.wallet_create.please_wait")}...
{:else}
{wait}
{/if}
<Spinner className="mt-10 h-14 w-14 mx-auto" />
</div>
{:else}
<div class="container3" bind:this={top}>
<div class="row">
<a href="#/">
<Logo class="logo block h-[8em]" alt={$t("common.logo")} />
</a>
</div>
{#if registration_error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<svg
class="animate-bounce mt-10 h-16 w-16 mx-auto"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
{#if registration_error == "AlreadyExists"}
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("pages.user_registered.already_exists")}
</p>
<a href="#/wallet/login">
<button
tabindex="-1"
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{$t("buttons.login")}
</button>
</a>
{:else}
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("errors.error_occurred", {
values: { message: display_error(registration_error) },
})}
</p>
<a href="#/">
<button
tabindex="-1"
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{$t("buttons.back_to_homepage")}
</button>
</a>
{/if}
</div>
{:else if !username_pass_ok}
<div class=" max-w-6xl lg:px-8 mx-auto">
{#if registration_success}
<Alert color="green" class="mb-5">
<span class="font-bold text-xl"
>{$t("pages.wallet_create.registration_success", {
values: { broker: registration_success },
})}</span
>
</Alert>
{/if}
<p class="max-w-xl md:mx-auto lg:max-w-2xl">
<span class="text-xl"
>{$t("pages.wallet_create.choose_username.title")}</span
>
<Alert color="yellow" class="mt-5">
{@html $t("pages.wallet_create.choose_username.warning")}
</Alert>
</p>
<input
bind:this={username_input}
class="mt-10 mr-0 mb-5 text-md bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
id="username-input"
placeholder={$t("pages.wallet_create.type_username_placeholder")}
autocomplete="username"
autofocus
bind:value={username}
on:keypress={username_password_ok}
/>
<PasswordInput
bind:this={password_input}
id="password-input"
placeholder={$t("pages.wallet_create.type_password_placeholder")}
bind:value={password}
className="mb-5 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
auto_complete="password"
on:enter={username_password_ok}
/>
<Button
disabled={!username || !password}
onclick={() => {
username_password_ok(false);
}}
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z"
/>
</svg>
{@html $t("pages.wallet_create.create_wallet_now")}
</Button>
</div>
{:else if !error}
{#if !ready}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-primary-700">
{$t("pages.wallet_create.creating")}
<svg
class="animate-spin mt-10 h-6 w-6 mx-auto"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<circle
class="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
/>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
</div>
{:else}
<div class="text-left mx-4">
<div class="text-green-800 mx-auto flex flex-col items-center">
<div>{$t("pages.wallet_create.ready")}</div>
<svg
class="my-4 h-16 w-16"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 01-1.043 3.296 3.745 3.745 0 01-3.296 1.043A3.745 3.745 0 0112 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 01-3.296-1.043 3.745 3.745 0 01-1.043-3.296A3.745 3.745 0 013 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 011.043-3.296 3.746 3.746 0 013.296-1.043A3.746 3.746 0 0112 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 013.296 1.043 3.746 3.746 0 011.043 3.296A3.745 3.745 0 0121 12z"
/>
</svg>
</div>
</div>
{/if}
{:else}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
{$t("errors.an_error_occurred")}
<svg
fill="none"
class="animate-bounce mt-10 h-10 w-10 mx-auto"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
<Alert color="red" class="mt-5">
{display_error(error)}
</Alert>
<button
class="mt-10 select-none"
on:click={async () => {
window.location.href = window.location.origin;
}}
>
{$t("buttons.start_over")}
</button>
</div>
{/if}
</div>
{/if}
</div>
</CenteredLayout>
<style>
</style>

@ -0,0 +1,592 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
"Select a wallet to login with" page.
This page is usually the first page the user sees when they visit the app.
It allows the user to select a wallet to login with, create, or import a wallet.
-->
<script lang="ts">
import { onMount, onDestroy, tick } from "svelte";
import { t, locale } from "svelte-i18n";
import Login from "./lib/Login.svelte";
import CenteredLayout from "./lib/CenteredLayout.svelte";
import {
default as ng,
} from "../.auth-react/api";
import { Fileupload, Button } from "flowbite-svelte";
import {
redirect_server,
bootstrap_redirect,
base64UrlEncode,
push
} from "./index";
// @ts-ignore
import Logo from "./assets/nextgraph.svg?component";
import {
wallets,
active_wallet,
opened_wallets,
active_session,
set_active_session,
has_wallets,
display_error,
wallet_from_import,
redirect_after_login,
redirect_if_wallet_is,
} from "./store";
import {
CheckBadge,
ExclamationTriangle,
QrCode,
Cloud,
ArrowRightEndOnRectangle,
} from "svelte-heros-v2";
let tauri_platform = import.meta.env.TAURI_ENV_PLATFORM;
let mobile = tauri_platform == "android" || tauri_platform == "ios";
let wallet;
let selected;
let step;
let error;
let importing = false;
let top;
let wallets_unsub;
let opened_wallets_unsub;
let active_wallet_unsub;
export let without_create = false;
function convert_img_to_url(buffer) {
var blob = new Blob([buffer], {
type: "image/jpeg",
});
var imageUrl = URL.createObjectURL(blob);
return imageUrl;
}
console.log("WalletLogin called")
onMount(async () => {
step = "open";
wallets_unsub = wallets.subscribe((value) => {
console.log("wallets.subscribe(", wallet, selected);
wallet = wallet || selected && $wallets[selected]?.wallet;
//console.log("wallet found locally", wallet);
});
opened_wallets_unsub = opened_wallets.subscribe(async (value) => {
if (!$active_wallet && selected && value[selected]) {
//await tick();
active_wallet.set({ wallet: value[selected], id: selected });
}
});
active_wallet_unsub = active_wallet.subscribe(async (value) => {
if (value && value.wallet) {
console.log("active_wallet.subscribe(", value.wallet, wallet, selected);
step = "loggedin";
await tick();
if (!$active_session) {
try {
let session = await ng.session_start(
value.id,
value.wallet.V0.personal_site
);
//console.log(session);
if (session) {
set_active_session(session);
loggedin();
}
} catch (e) {
step = "open";
error = e;
importing = false;
wallet = undefined;
selected = undefined;
active_wallet.set(undefined);
}
} else {
loggedin();
}
}
});
// Coming from the import Wallet with QR / TextCode ...
if ($wallet_from_import) {
wallet = $wallet_from_import;
importing = true;
}
});
async function loggedin() {
step = "loggedin";
if ($redirect_after_login) {
if (
!$redirect_if_wallet_is ||
$redirect_if_wallet_is == $active_wallet?.id
) {
let redir = $redirect_after_login;
$redirect_after_login = undefined;
$redirect_if_wallet_is = undefined;
push("#" + redir);
} else {
$redirect_after_login = undefined;
$redirect_if_wallet_is = undefined;
push("#/");
}
} else {
push("#/");
}
}
function start_login_from_import() {
// Login button was clicked and `wallet` was set in `onMount`.
// Unset variable from store, to show login screen.
wallet_from_import.set(null);
}
onDestroy(() => {
console.log("onDestroy called");
if (wallets_unsub) wallets_unsub();
if (opened_wallets_unsub) opened_wallets_unsub();
if (active_wallet_unsub) active_wallet_unsub();
wallet_from_import.set(null);
});
async function gotError(event) {
//importing = false;
console.error(event.detail);
}
async function gotWallet(event) {
try {
console.log("gotWallet",event)
if (importing) {
step = "loggedin";
$redirect_after_login = undefined;
$redirect_if_wallet_is = undefined;
let in_memory = !event.detail.trusted;
console.log("IMPORTING", in_memory, event.detail.wallet, wallet);
//register bootstrap when importing
if (!in_memory && !tauri_platform) {
let bootstrap_iframe_msgs =
await ng.get_bootstrap_iframe_msgs_for_brokers(
event.detail.wallet.V0.brokers
);
let encoded = base64UrlEncode(JSON.stringify(bootstrap_iframe_msgs));
let register_bootstrap_url =
bootstrap_redirect +
encoded +
"&close=1&m=add&ab=" +
encodeURIComponent(window.location.href);
console.log(register_bootstrap_url);
window.open(register_bootstrap_url, "_blank");
}
let client = await ng.wallet_import(
wallet,
event.detail.wallet,
in_memory
);
event.detail.wallet.V0.client = client;
// refreshing the wallets
wallets.set(await ng.get_wallets());
//console.log($wallets);
let session = await ng.session_start(
event.detail.id,
event.detail.wallet.V0.personal_site
);
//console.log(session);
if (session) {
set_active_session(session);
}
if (in_memory && !tauri_platform) {
// send a message in BroadcastChannel new_in_mem(lws, opened_wallet=event.detail.wallet).
let name = event.detail.id;
let lws = $wallets[name];
if (lws.in_memory) {
let new_in_mem = {
lws,
name,
opened: event.detail.wallet,
cmd: "new_in_mem",
};
window.wallet_channel.postMessage(new_in_mem, location.href);
}
}
} else {
let client = await ng.wallet_was_opened(event.detail.wallet);
event.detail.wallet.V0.client = client;
}
} catch (e) {
if (importing) {
wallet = undefined;
}
importing = false;
error = e;
step = "open";
return;
}
//await tick();
active_wallet.set(event.detail);
// { wallet,
// id }
}
function cancelLogin(event) {
console.log("cancelLogin");
importing = false;
selected = undefined;
wallet = undefined;
}
function select(id) {
selected = id;
if ($opened_wallets[selected]) {
active_wallet.set({ wallet: $opened_wallets[selected], id: selected });
} else {
wallet = $wallets[selected]?.wallet;
}
importing = false;
console.log("select", wallet, selected)
}
function handleWalletUpload(event) {
const files = event.target.files;
if (files.length > 0) {
let reader = new FileReader();
reader.readAsArrayBuffer(files[0]);
reader.onload = async (e) => {
try {
//console.log(e.target.result);
wallet = await ng.wallet_read_file(e.target.result);
importing = true;
} catch (e) {
error = e;
}
};
}
}
function scrollToTop() {
top.scrollIntoView();
}
onMount(() => scrollToTop());
</script>
<div bind:this={top}>
<CenteredLayout displayFooter={!wallet && !selected}>
{#if error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<ExclamationTriangle class="animate-bounce mt-10 h-16 w-16 mx-auto" />
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("errors.error_occurred", {
values: { message: display_error(error) },
})}
</p>
<button
on:click={() => {
importing = false;
error = undefined;
}}
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{$t("buttons.start_over")}
</button>
</div>
{:else if step == "loggedin"}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-green-800">
{@html $t("pages.wallet_login.logged_in")}...
<svg
class="my-10 h-16 w-16 mx-auto"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 01-1.043 3.296 3.745 3.745 0 01-3.296 1.043A3.745 3.745 0 0112 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 01-3.296-1.043 3.745 3.745 0 01-1.043-3.296A3.745 3.745 0 013 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 011.043-3.296 3.746 3.746 0 013.296-1.043A3.746 3.746 0 0112 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 013.296 1.043 3.746 3.746 0 011.043 3.296A3.745 3.745 0 0121 12z"
/>
</svg>
</div>
{:else if $wallet_from_import}
<!-- Imported a wallet -->
<!-- Title -->
<div>
<h2 class="text-xl mb-6">
{$t("pages.wallet_login.from_import.title")}
</h2>
</div>
<span class="text-green-800">
<CheckBadge class="w-full mt-4" size="3em" />
<div class="mt-4">
{@html $t("pages.wallet_login.from_import.description")}
</div>
</span>
<!-- Show wallet security image and phrase. -->
<div
class="wallet-box mt-4 mx-auto"
role="button"
tabindex="0"
on:click={start_login_from_import}
on:keypress={start_login_from_import}
>
{#if $wallet_from_import.V0.content.password}
<div class="pt-5">
<ArrowRightEndOnRectangle
class="w-16 h-16"
style="display:inline;"
/>
<div>
{#if mobile}Tap{:else}Click{/if} here to login with your wallet
</div>
</div>
<div class="p-5">
<button
tabindex="-1"
style="overflow-wrap: anywhere;"
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-1.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{$wallet_from_import.V0.content.security_txt}
</button>
</div>
{:else}
<span class="securitytxt"
>{$wallet_from_import.V0.content.security_txt}
</span>
<img
alt={$wallet_from_import.V0.content.security_txt}
class="securityimg"
src={convert_img_to_url(
$wallet_from_import.V0.content.security_img
)}
/>
{/if}
</div>
<!-- Login to finish import instructions-->
<div class="my-4">
{@html $t("pages.wallet_login.from_import.instruction")}
</div>
<div>
<button
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
on:click={start_login_from_import}
>
{$t("buttons.login")}
</button>
</div>
{:else if wallet}
<Login
{wallet}
bind:for_import={importing}
on:error={gotError}
on:opened={gotWallet}
on:cancel={cancelLogin}
/>
{:else if !$active_wallet && !selected}
<div class="row">
<a href="#/">
<Logo class="logo block h-40" alt="NextGraph Logo" />
</a>
</div>
<h2 class="pb-5 text-xl">{$t("pages.wallet_login.select_wallet")}</h2>
<div class="flex flex-wrap justify-center gap-5 mb-10">
{#each Object.entries($wallets) as wallet_entry}
<div
class="wallet-box"
role="button"
tabindex="0"
on:click={() => {
select(wallet_entry[0]);
}}
on:keypress={() => {
select(wallet_entry[0]);
}}
>
{#if wallet_entry[1].wallet.V0.content.password}
<div class="pt-5">
<ArrowRightEndOnRectangle
class="w-16 h-16"
style="display:inline;"
/>
<div>
{#if mobile}Tap{:else}Click{/if} here to login with your wallet
</div>
</div>
<div class="p-5">
<button
tabindex="-1"
style="overflow-wrap: anywhere;"
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-1.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{wallet_entry[1].wallet.V0.content.security_txt}
</button>
</div>
{:else}
<span class="securitytxt"
>{wallet_entry[1].wallet.V0.content.security_txt}
</span>
<img
alt={wallet_entry[1].wallet.V0.content.security_txt}
class="securityimg"
src={convert_img_to_url(
wallet_entry[1].wallet.V0.content.security_img
)}
/>
{/if}
</div>
{/each}
<div class="wallet-box">
<!-- <a href="#/wallet/username">
<button
style="justify-content: left;"
tabindex="-1"
class:mt-10={without_create}
class:mt-2.5={!without_create}
class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-1.5 text-center inline-flex items-center justify-center dark:focus:ring-primary-100/55 mb-2"
>
<Cloud class="w-8 h-8 mr-2 -ml-1" tabindex="-1" />
{$t("pages.wallet_login.with_username")}
</button>
</a> -->
<Fileupload
style="display:none;"
id="import_wallet_file"
accept="application/octet-stream, .ngw"
on:change={handleWalletUpload}
/>
<button
class="mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-1.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
on:click={() => {
document.getElementById("import_wallet_file").click();
}}
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15M9 12l3 3m0 0l3-3m-3 3V2.25"
/>
</svg>
{$t("pages.wallet_login.import_file")}
</button>
<a href="#/wallet/login-qr">
<button
style="justify-content: left;"
tabindex="-1"
class="mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-1.5 text-center inline-flex items-center justify-center dark:focus:ring-primary-100/55 mb-2"
>
<QrCode class="w-8 h-8 mr-2 -ml-1" tabindex="-1" />
{$t("pages.wallet_login.import_qr")}
</button>
</a>
<a href="#/wallet/login-text-code">
<button
style="justify-content: left;"
tabindex="-1"
class="mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-1.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"
/>
</svg>
{$t("pages.wallet_login.import_link")}
</button>
</a>
{#if !without_create}
<a href="#/wallet/create">
<button
tabindex="-1"
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-1.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z"
/>
</svg>
{$t("pages.wallet_login.new_wallet")}
</button>
</a>
{/if}
</div>
</div>
{/if}
</CenteredLayout>
</div>
<style>
.wallet-box {
width: 300px;
height: 300px;
background-color: #f6f6f6;
position: relative;
cursor: pointer;
}
.wallet-box button {
min-width: 262px;
}
.securitytxt {
z-index: 100;
width: 300px;
position: absolute;
left: 0;
padding: 5px;
background-color: #ffffffd0;
overflow-wrap: break-word;
}
.wallet-box:focus .securitytxt {
background-color: #ffffffff;
}
.securityimg {
position: absolute;
left: 0;
top: 0;
}
</style>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 225 225"
>
<g>
<circle
r="106.98013"
cy="112.90476"
cx="109.88096"
style="fill:#ffffff;stroke:none;stroke-width:0.268375" />
<path
d="M 98.343352,190.26108 C 80.403778,187.53354 65.011938,179.57839 52.608228,166.62327 38.602093,151.99448 31.178059,133.41381 31.178059,112.98841 c 0,-10.21889 1.700058,-19.44396 5.221234,-28.332119 4.28678,-10.820699 10.037295,-19.39063 18.535095,-27.62263 4.72982,-4.58187 6.60687,-6.10643 11.28099,-9.16256 11.89869,-7.779841 24.173884,-11.879991 38.095802,-12.724761 19.80437,-1.2017 39.11165,5.11306 54.60284,17.858751 1.50718,1.24006 2.72951,2.35934 2.71628,2.48729 -0.0132,0.12795 -3.85821,3.63443 -8.54442,7.79217 -4.6862,4.157729 -10.04724,8.96276 -11.91342,10.677819 -1.86617,1.715071 -3.54094,3.11831 -3.7217,3.11831 -0.18075,0 -1.39985,-0.745188 -2.70911,-1.655969 -7.53011,-5.23834 -15.99428,-7.82188 -25.62597,-7.82188 -12.731628,0 -23.249192,4.3379 -32.143882,13.257541 -6.39594,6.413868 -10.70387,14.555268 -12.50018,23.623578 -0.69099,3.48832 -0.68968,13.53072 0.002,17.00893 3.70508,18.62577 18.31886,33.10194 36.642322,36.29729 4.16439,0.72621 11.98099,0.71223 15.98975,-0.0286 14.03187,-2.59311 25.86047,-11.36806 32.26533,-23.93578 0.77379,-1.51834 1.26018,-2.88461 1.08086,-3.03616 -0.17934,-0.15156 -6.87448,-1.1779 -14.87813,-2.28078 -9.7795,-1.34758 -14.92353,-2.21379 -15.68471,-2.64117 -1.52067,-0.85379 -2.83611,-2.88806 -2.83611,-4.3859 0,-1.1732 2.02687,-15.86876 2.49085,-18.05962 0.29676,-1.40127 2.42559,-3.4934 3.84317,-3.77691 0.62227,-0.12445 8.82712,0.85555 18.28065,2.18348 9.43343,1.32511 17.26269,2.29453 17.39833,2.15427 0.13566,-0.14026 1.11808,-6.54833 2.18313,-14.24014 1.10778,-8.000208 2.20407,-14.60184 2.56177,-15.426229 0.34392,-0.792599 1.11019,-1.849131 1.70287,-2.34782 2.06321,-1.736079 3.1433,-1.785011 12.20439,-0.55291 9.63637,1.310309 10.70873,1.56224 12.28077,2.88503 1.64359,1.382979 2.2732,2.810909 2.25906,5.123309 -0.007,1.10173 -0.92172,8.29645 -2.03332,15.98826 -1.11158,7.69182 -1.97159,14.04091 -1.91113,14.1091 0.0605,0.0682 7.16644,1.11143 15.79109,2.31832 11.10566,1.55407 16.00827,2.38757 16.80223,2.85657 1.53015,0.90389 2.48023,2.64785 2.45017,4.49756 -0.0462,2.84349 -2.41252,18.12279 -2.97521,19.21089 -0.66164,1.27949 -2.60244,2.54696 -3.92109,2.56074 -0.51973,0.005 -7.87449,-0.95937 -16.34391,-2.144 -8.46944,-1.18464 -15.47588,-2.077 -15.56986,-1.98301 -0.094,0.094 -1.18792,7.34163 -2.43097,16.10589 -1.44004,10.15311 -2.49792,16.43621 -2.91556,17.31631 -0.72531,1.52848 -2.76261,3.06291 -4.53817,3.41802 -0.95688,0.19138 -10.90014,-0.92798 -13.59859,-1.53084 -0.5471,-0.12223 -1.89146,0.67252 -4.50941,2.66588 -11.2627,8.57562 -24.34195,13.90917 -38.35741,15.64164 -4.40038,0.54395 -15.72658,0.43298 -19.853658,-0.19451 z"
style="fill:#4972a5;fill-opacity:1;stroke:#4972a5;stroke-width:0.377976;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

@ -0,0 +1,59 @@
/*
* Base64URL-ArrayBuffer
* https://github.com/herrjemand/Base64URL-ArrayBuffer
*
* Copyright (c) 2017 Yuriy Ackermann <ackermann.yuriy@gmail.com>
* Copyright (c) 2012 Niklas von Hertzen
* Licensed under the MIT license.
*
*/
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
// Use a lookup table to find the index.
var lookup = new Uint8Array(256);
for (var i = 0; i < chars.length; i++) {
lookup[chars.charCodeAt(i)] = i;
}
export const encode = function(arraybuffer) {
var bytes = new Uint8Array(arraybuffer),
i, len = bytes.length, base64 = "";
for (i = 0; i < len; i+=3) {
base64 += chars[bytes[i] >> 2];
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
base64 += chars[bytes[i + 2] & 63];
}
if ((len % 3) === 2) {
base64 = base64.substring(0, base64.length - 1);
} else if (len % 3 === 1) {
base64 = base64.substring(0, base64.length - 2);
}
return base64;
};
export const decode = function(base64) {
var bufferLength = base64.length * 0.75,
len = base64.length, i, p = 0,
encoded1, encoded2, encoded3, encoded4;
var arraybuffer = new ArrayBuffer(bufferLength),
bytes = new Uint8Array(arraybuffer);
for (i = 0; i < len; i+=4) {
encoded1 = lookup[base64.charCodeAt(i)];
encoded2 = lookup[base64.charCodeAt(i+1)];
encoded3 = lookup[base64.charCodeAt(i+2)];
encoded4 = lookup[base64.charCodeAt(i+3)];
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
}
return arraybuffer;
};

@ -0,0 +1,962 @@
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
// "post:rich", "post:md", "post:text", "post:html", "post:asciidoc", "page", "code", "code:*", "app", "app:z", "class", "schema", "schema:owl|rdfs|shacl|shex", "service", "service:rust", "service:deno", "contract", "app:n:xxx.xx.xx:", "app:o:",
// "query:sparql", "query:graphql", "query:text", "query:web",
// "data:graph", "data:json", "data:array", "data:map", "data:xml", "data:table", "data:collection", "data:board", "data:grid", "data:geomap",
// "e:mail", "e:web", "e:http://[url of class in ontology]", "e:rdf" (read-only cache of RDF fetched from web2.0)
// "mc:text", "mc:link", "mc:card", "mc:pad",
// "diagram","chart", "doc:pdf", "doc:odf", "doc:latex", "doc:ps", "doc:music", "doc:maths", "doc:chemistry", "doc:braille", "doc:ancientscript",
// "media:image", "media:reel", "media:album", "media:video", "media:audio", "media:song", "media:subtitle", "media:overlay",
// "social:channel", "social:stream", "social:contact", "social:event", "social:calendar", "social:scheduler", "social:reaction", "social:chatroom",
// "prod:task", "prod:project", "prod:issue", "prod:form", "prod:filling", "prod:cad", "prod:slides", "prod:question", "prod:answer", "prod:poll", "prod:vote"
// "file", "file:iana:*", "file:gimp", "file:inkscape", "file:kdenlive", "file:blender", "file:openscad", "file:lyx", "file:scribus", "file:libreoffice", "file:audacity", "file:godot", "file:obsstudio", "file:ardor", "file:krita"
// application/vnd.api+json
// application/activity+json
// epub, dejavu,
// animation: snap, lottie, smil editor: https://github.com/HaikuTeam/animator/
export const has_toc = (class_name) => {
return class_name === "post:rich" || class_name === "post:md" || class_name === "post:html" || class_name === "post:asciidoc" || class_name === "app:z" || class_name === "class"
|| class_name.startsWith("schema") || class_name === "doc:pdf" || class_name === "doc:odf" || class_name === "doc:latex" || class_name === "doc:ps" || class_name === "prod:project" || class_name === "prod:slides"
};
export const official_classes = {
"post:rich": {
"ng:crdt": "YXml",
"ng:n": "Post - Rich Text", // editor: y-ProseMirror, viewer: https://www.npmjs.com/package/prosemirror-to-html-js or https://prosemirror.net/docs/ref/version/0.4.0.html#toDOM https://prosemirror.net/docs/ref/version/0.4.0.html#toHTML
"ng:a": "A Post with Rich Text, including images, links, formatted text, and embeds of other content",
"ng:o": "n:g:z:post:rich",
"ng:w": "n:g:z:post_rich_editor",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Article"],
},
"post:md": {
"ng:crdt": "YXml",
"ng:n": "Post - MarkDown", // editor y-MilkDown, viewer: https://github.com/wooorm/markdown-rs
"ng:a": "A Post with MarkDown, including images, links, formatted text, and embeds of other content",
"ng:o": "n:g:z:post:md",
"ng:w": "n:g:z:post_md_editor",
"ng:x": {
"as":true,
},
"ng:compat": ["file:iana:text:markdown", "code:markdown","as:Article"],
},
"post:text": {
"ng:crdt": "YText",
"ng:n": "Post - Plain Text",
"ng:a": "A Post with Plain Text",
"ng:o": "n:g:z:post:text",
"ng:w": "n:g:z:code_editor",
"ng:x": {
"as":true,
},
"ng:compat": ["file:iana:text:plain", "code:plaintext","as:Article"],
},
"post:html": {
"ng:crdt": "YXml",
"ng:n": "Post - TinyMCE",
"ng:x": {
"as":true,
},
"ng:a": "A Post based on TinyMCE, including images, links, formatted text, and embeds of other content",
"ng:compat": ["as:Article"],
},
"post:asciidoc": { // display with https://github.com/asciidoctor/asciidoctor.js/
"ng:crdt": "YText",
"ng:n": "Post - AsciiDoc",
"ng:a": "A Post based on AsciiDoc format",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Article"],
},
"page": {
"ng:crdt": "YXml",
"ng:n": "Page", // based on GrapeJS, VvvebJs, or Astro ?
"ng:a": "A Page and Site builder",
"ng:compat": [],
},
"code": {
"ng:crdt": "YText",
"ng:n": "Source Code", // edited with CodeMirror, displayed with highlight.js
"ng:a": "A Source Code file. many languages supported",
"ng:o": "n:g:z:pre",
"ng:w": "n:g:z:code_editor",
"ng:compat": ["code:*","file:iana:text:javascript","file:iana:text:css","file:iana:text:html","file:iana:text:markdown", "file:iana:application:xml",
"file:iana:application:yaml", "file:iana:text:xml", "file:iana:application:xhtml+xml"],
},
"code:js": {
"ng:crdt": "YText",
"ng:n": "JavaScript", // edited with CodeMirror, displayed with highlight.js
"ng:a": "A JavaScript Source Code file",
"ng:o": "n:g:z:pre",
"ng:w": "n:g:z:code_editor",
"ng:compat": ["file:iana:text:javascript"],
"implemented": true
},
"code:ts": {
"ng:crdt": "YText",
"ng:n": "TypeScript", // edited with CodeMirror, displayed with highlight.js
"ng:a": "A TypeScript Source Code file",
"ng:o": "n:g:z:pre",
"ng:w": "n:g:z:code_editor",
"ng:compat": ["file:iana:text:typescript"],
"implemented": true
},
"code:rust": {
"ng:crdt": "YText",
"ng:n": "Rust", // edited with CodeMirror, displayed with highlight.js
"ng:a": "A Rust Source Code file",
"ng:o": "n:g:z:pre",
"ng:w": "n:g:z:code_editor",
"ng:compat": [],
"implemented": true
},
"code:svelte": {
"ng:crdt": "YText",
"ng:n": "Svelte", // edited with CodeMirror, displayed with highlight.js
"ng:a": "A Svelte Source Code file",
"ng:o": "n:g:z:pre",
"ng:w": "n:g:z:code_editor",
"ng:compat": [],
"implemented": true
},
"code:react": {
"ng:crdt": "YText",
"ng:n": "React", // edited with CodeMirror, displayed with highlight.js
"ng:a": "A React Source Code file",
"ng:o": "n:g:z:pre",
"ng:w": "n:g:z:code_editor",
"ng:compat": [],
"implemented": true
},
"app": {
"ng:n": "Official App",
"ng:a": "App provided by NextGraph platform",
},
"app:z": {
"ng:crdt": "Elmer",
"ng:n": "Application", // Editor: Monaco
"ng:a": "Create an Application based on NextGraph Framework",
"ng:o": "n:g:z:app_store",
"ng:w": "n:g:z:app_editor",
"ng:include": ["schema:*","service:*","code","file"],
"ng:compat": ["code:svelte"],
},
"class": {
"ng:crdt": "Graph",
"ng:n": "Class",
"ng:a": "Define a custom Class for your data",
"ng:x": {
"rdfs":true,
},
"ng:compat": ["rdfs:Class"],
},
"schema": { // display with https://github.com/VisualDataWeb/WebVOWL
"ng:crdt": "Graph",
"ng:n": "Schema - RDFS/OWL",
"ng:a": "Define the Schema, Ontology or Vocabulary for your data and the relations between them, with RDFS and/or OWL",
"ng:o": "n:g:z:ontology_viewer", // default viewer
"ng:w": "n:g:z:ontology_editor", // default editor
"ng:x": {
"rdfs":true,
"owl":true,
},
"ng:include": ["data:graph"],
"ng:compat": ["rdfs:*","class","owl:Ontology"],
},
"schema:shacl": {
"ng:crdt": "Graph",
"ng:n": "Schema - SHACL",
"ng:a": "Define the rules for your data with SHACL",
"ng:o": "n:g:z:ontology_viewer", // default viewer
"ng:w": "n:g:z:ontology_editor", // default editor
"ng:x": {
"sh":true,
},
"ng:include": ["data:graph"],
"ng:compat": ["sh:Shape", "file:iana:text:shaclc" ],
},
"schema:shex": {
"ng:crdt": "Graph",
"ng:n": "Schema - SHEX",
"ng:a": "Define the rules for your data with SHEX",
"ng:o": "n:g:z:ontology_viewer", // default viewer
"ng:w": "n:g:z:ontology_editor", // default editor
"ng:x": {
"shex":true,
},
"ng:include": ["data:graph"],
"ng:compat": ["shex:*", "file:iana:text:shex", "code:shexc" ],
},
"service": {
"ng:n": "Internal Service",
"ng:a": "Service provided by NextGraph framework",
"ng:o": "n:g:z:service_invoke", // default viewer
},
"service:rust": {
"ng:crdt": "YText",
"ng:n": "Service - Rust", // edited with CodeMirror, displayed with highlight.js
"ng:a": "Service written in Rust and compiled to WASM",
"ng:o": "external_service_invoke", // default viewer
"ng:w": "n:g:z:service_editor", // default editor
"ng:compat": ["code:rust", "file:iana:application:wasm"],
},
"service:deno": {
"ng:crdt": "YText",
"ng:n": "Service - Deno/JS", // edited with CodeMirror, displayed with highlight.js
"ng:a": "Service written in JS/TS for Deno or NodeJS",
"ng:o": "external_service_invoke", // default viewer
"ng:w": "n:g:z:service_editor", // default editor
"ng:compat": ["code:javascript", "code:typescript", "file:iana:text:javascript", "file:iana:application:node"],
},
"contract": {
"ng:crdt": "YText",
"ng:n": "Smart Contract", // edited with CodeMirror, displayed with highlight.js
"ng:a": "Smart Contract with Rust or JS code",
"ng:compat": ["code:rust", "file:iana:application:wasm", "code:javascript", "code:typescript", "file:iana:text:javascript", "file:iana:application:node"],
},
"query:sparql": {
"ng:crdt": "YText",// uses ng:default_graph and ng:named_graph predicates
"ng:n": "SPARQL Query", // edited with YASGUI or Sparnatural, displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:a": "Saved SPARQL Query that can be invoked",
"ng:o": "n:g:z:sparql:invoke",
"ng:w": "n:g:z:sparql_query",
"ng:compat": ["code:sparql", "file:iana:application:sparql-query","file:iana:application:x-sparql-query"],
},
"query:sparql_update": {
"ng:crdt": "YText",// uses ng:default_graph and ng:named_graph predicates
"ng:n": "SPARQL Update", // edited with YASGUI, displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:a": "Saved SPARQL Update that can be invoked",
"ng:o": "n:g:z:sparql:invoke",
"ng:w": "n:g:z:sparql_update",
"ng:compat": ["code:sparql", "file:iana:application:sparql-update"],
},
"query:graphql": {
"ng:crdt": "YText", // uses ng:default_graph predicate
"ng:n": "GraphQL Query", // edited with https://github.com/graphql/graphiql or https://github.com/graphql-editor/graphql-editor, displayed with highlight.js
"ng:a": "Saved GraphQL Query that can be invoked",
"ng:o": "n:g:z:graphql:invoke",
"ng:w": "n:g:z:graphql_query",
"ng:compat": ["code:graphql", "file:iana:application:graphql+json"],
},
"query:text": {
"ng:crdt": "Graph",
"ng:n": "Text Search",
"ng:a": "Saved Text Search and its results",
"ng:compat": [],
},
"query:web": {
"ng:crdt": "Graph",
"ng:n": "Web Search",
"ng:a": "Saved Web Search and its results",
"ng:compat": [],
},
"data:graph": {
"ng:crdt": "Graph", // https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:n": "Graph",
"ng:a": "Define the Graph of your data with Semantic Web / Linked Data",
//"ng:o": "n:g:z:json_ld_viewer", // default viewer
//"ng:w": "n:g:z:json_ld_editor", // default editor
"ng:x": {
"rdf":true,
"xsd":true,
},
"ng:compat": [ "rdf:*", "xsd:*", "file:iana:text:n3", "file:iana:text:rdf+n3", "file:iana:text:turtle", "file:iana:application:n-quads", "file:iana:application:trig", "file:iana:application:n-triples",
"file:iana:application:rdf+xml", "file:iana:application:ld+json"],
"implemented": true
},
"data:json": {
"ng:crdt": "Automerge",
"ng:n": "JSON (Automerge)",
"ng:a": "Automerge JSON Data CRDT",
"ng:o": "n:g:z:json_automerge_viewer", // default viewer
"ng:w": "n:g:z:json_automerge_editor", // default editor
"ng:compat": ["file:iana:application:json", "code:json"],
"implemented": true
},
"data:array": {
"ng:crdt": "YArray",
"ng:n": "Array (Yjs)",
"ng:a": "Yjs Array CRDT",
"ng:o": "n:g:z:json_yarray_viewer", // default viewer
"ng:w": "n:g:z:json_yarray_editor", // default editor
"ng:compat": ["file:iana:application:json", "code:json"],
"implemented": true
},
"data:map": {
"ng:crdt": "YMap",
"ng:n": "Object (Yjs)",
"ng:a": "Yjs Map CRDT (JSON Object)",
"ng:o": "n:g:z:json_ymap_viewer", // default viewer
"ng:w": "n:g:z:json_ymap_editor", // default editor
"ng:compat": ["file:iana:application:json", "code:json"],
"implemented": true
},
"data:xml": {
"ng:crdt": "YXml",
"ng:n": "XML (Yjs)",
"ng:a": "Yjs XML CRDT",
"ng:compat": ["file:iana:text:xml","file:iana:application:xml", "code:xml"],
},
"data:table": {
"ng:crdt": "Automerge", // see https://github.com/frappe/datatable
"ng:n": "Table", // see https://specs.frictionlessdata.io/table-schema displayed with pivot table see https://activetable.io/docs/data https://www.npmjs.com/package/pivottable https://socket.dev/npm/package/svelte-pivottable/alerts/0.2.0?tab=dependencies
"ng:a": "Data in a Table (columns and rows)",
"ng:o": "n:g:z:pivot",
"ng:compat": ["file:iana:application:sparql-results+json","file:iana:application:sparql-results+xml","file:iana:text:csv"],
},
"data:collection": {
"ng:crdt": "Graph",
"ng:n": "Collection",
"ng:a": "An ordered list of items",
"ng:o": "n:g:z:container",
"ng:x": {
"as": true,
"rdf": true,
},
"ng:compat": ["as:Collection","rdf:List","rdf:Seq"],
},
"data:container": {
"ng:crdt": "Graph",
"ng:n": "Container",
"ng:a": "An unordered set of items",
"ng:o": "n:g:z:container",
"ng:x": {
"rdf": true,
"rdfs": true,
"ldp": true,
},
"ng:compat": ["rdfs:member","ldp:contains","rdf:Bag","rdf:Alt"],
"implemented": true
},
"data:plato": {
"ng:crdt": "Graph",
"ng:n": "Plato",
"ng:a": "A tree of files and folders",
"ng:o": "n:g:z:tree",
"ng:compat": ["ng:plato","ng:has_plato"],
},
"data:board": {
"ng:crdt": "Graph",
"ng:n": "Board",
"ng:a": "Whiteboard, infinite canvas to arrange your content in 2D",
"ng:o": "n:g:z:board",
"ng:include": [],
"ng:compat": [], //https://jsoncanvas.org/ https://www.canvasprotocol.org/ https://github.com/orgs/ocwg/discussions/25 https://infinitecanvas.tools/gallery/
},
"data:grid": {
"ng:crdt": "Graph",
"ng:n": "Grid",
"ng:a": "Grid representation of a collection or container",
"ng:o": "n:g:z:grid",
"ng:include": ["data:container","data:collection","data:table","media:album"],
"ng:compat": [],
},
"data:geomap": { // https://github.com/leaflet/leaflet
"ng:crdt": "Graph",
"ng:n": "Geo Map",
"ng:a": "Geographical Map",
"ng:x": {
"wgs": true,
"gn": true,
"as": true,
},
"ng:compat": ["as:Place","wgs:*","gn:*", "file:iana:application:geo+json", "file:iana:application:vnd.mapbox-vector-tile"], // see also https://github.com/topojson/topojson
},
"e:mail": {
"ng:crdt": "Graph",
"ng:n": "Email",
"ng:a": "Email content and headers",
"ng:x": {
"email": "http://www.invincea.com/ontologies/icas/1.0/email#" //https://raw.githubusercontent.com/twosixlabs/icas-ontology/master/ontology/email.ttl // https://www.semanticdesktop.org/ontologies/2007/03/22/nmo/
},
"ng:compat": ["file:iana:message:rfc822","file:iana:multipart:related"],
},
"e:link": {
"ng:crdt": "Graph",
"ng:n": "Web Link",
"ng:a": "HTTP link to a page on the Web",
"ng:compat": [],
},
"e:web": {
"ng:crdt": "Graph",
//https://www.npmjs.com/package/warcio https://github.com/N0taN3rd/node-warc
"ng:n": "Web Archive",
"ng:a": "Archive the content of a web page",
"ng:compat": ["file:iana:application:warc","file:iana:multipart:related"],
},
"e:rdf": {
"ng:crdt": "Graph",
"ng:n": "RDF Archive",
"ng:a": "Archive the triples of an RDF resource dereferenced with HTTP",
"ng:include": ["data:graph"],
},
"mc:text": {
"ng:crdt": "Graph",
"ng:n": "Text Selection",
"ng:a": "Text Selection copied into Magic Carpet",
},
"mc:link": {
"ng:crdt": "Graph",
"ng:n": "Link",
"ng:a": "Link to a document. kept in Magic Carpet",
},
"plato:card": {
"ng:crdt": "Graph",
"ng:n": "Card",
"ng:a": "Card representation of a document",
"ng:o": "n:g:z:card",
},
"plato:pad": {
"ng:crdt": "Graph",
"ng:n": "Pad",
"ng:a": "Pad representation of a document",
"ng:o": "n:g:z:pad",
},
"doc:compose" : {
"ng:crdt": "YArray",
"ng:n": "Composition",
"ng:a": "Compose several blocks into a single document",
"ng:o": "n:g:z:compose:viewer",
"ng:w": "n:g:z:compose:editor",
},
"diagram:mermaid" : {
"ng:crdt": "YText",
"ng:n": "Diagram - Mermaid",
"ng:a": "Describe Diagrams with Mermaid",
"ng:compat": ["file:iana:application:vnd.mermaid"]
},
"diagram:drawio" : {
"ng:crdt": "YXml",
"ng:n": "Diagram - DrawIo",
"ng:a": "Draw Diagrams with DrawIo",
"ng:compat": ["file:iana:application:vnd.jgraph.mxfile","file:iana:application:x-drawio"]
},
"diagram:graphviz" : {
"ng:crdt": "YText",
"ng:n": "Diagram - Graphviz",
"ng:a": "Describe Diagrams with Graphviz",
"ng:compat": ["file:iana:text:vnd.graphviz"]
},
"diagram:excalidraw" : {
"ng:crdt": "Automerge",
"ng:n": "Diagram - Excalidraw",
"ng:a": "Collaborate on Diagrams with Excalidraw",
"ng:compat": ["file:iana:application:vnd.excalidraw+json"]
},
"diagram:gantt" : { //https://github.com/frappe/gantt
"ng:crdt": "Automerge",
"ng:n": "Diagram - Gantt",
"ng:a": "Interactive gantt chart",
"ng:compat": []
},
"diagram:flowchart" : { //https://github.com/adrai/flowchart.js
"ng:crdt": "YText",
"ng:n": "Diagram - Flowchart",
"ng:a": "flow chart diagrams",
"ng:compat": []
},
"diagram:sequence" : { //https://github.com/bramp/js-sequence-diagrams
"ng:crdt": "YText",
"ng:n": "Diagram - Sequence",
"ng:a": "sequence diagrams",
"ng:compat": []
},
// checkout https://www.mindmaps.app/ but it is AGPL
"diagram:markmap" : { //https://github.com/markmap/markmap
"ng:crdt": "YText",
"ng:n": "Diagram - Markmap",
"ng:a": "mindmaps with markmap",
"ng:compat": []
},
"diagram:mymind" : { //https://github.com/markmap/markmap
"ng:crdt": "YText", // see MyMind format, MindMup JSON, FreeMind XML and MindMap Architect XML
"ng:n": "Diagram - Mymind",
"ng:a": "mindmaps with mymind",
"ng:compat": [] // https://github.com/ondras/my-mind/wiki/Saving-and-loading#file-formats
},
"diagram:jsmind" : { //https://github.com/hizzgdev/jsmind
"ng:crdt": "Automerge",
"ng:n": "Diagram - jsmind",
"ng:a": "mindmaps with jsmind",
"ng:compat": [] // https://hizzgdev.github.io/jsmind/docs/en/1.usage.html
},
// DC and C3 have Crossfilter https://github.com/dc-js/dc.js http://crossfilter.github.io/crossfilter/ https://github.com/c3js/c3 http://dc-js.github.io/dc.js/
// take inspiration from https://github.com/metabase/metabase
// have a look at https://github.com/observablehq
// another open source dashboard with many data sources https://github.com/getredash/redash
// and another one https://github.com/apache/superset
// https://github.com/Rich-Harris/pancake
// https://github.com/williamngan/pts
// https://visjs.org/
"viz:cytoscape" : {
"ng:crdt": "Automerge",
"ng:n": "Viz - Cytoscape",
"ng:a": "Graph theory (network) visualization",
"ng:compat": [] // https://github.com/cytoscape/cytoscape.js
},
"viz:vega" : {
"ng:crdt": "Automerge",
"ng:n": "Viz - Vega",
"ng:a": "Grammar for interactive graphics",
"ng:compat": [] // https://vega.github.io/vega-lite/docs/ https://github.com/vega/editor
},
"viz:vizzu" : {
"ng:crdt": "Automerge",
"ng:n": "Viz - Vizzu",
"ng:a": "Animated data visualizations and data stories",
"ng:compat": [] // https://github.com/vizzuhq/vizzu-lib
},
"viz:plotly" : { //https://github.com/plotly/plotly.js
"ng:crdt": "Automerge",
"ng:n": "Viz - Plotly",
"ng:a": "Declarative charts",
"ng:compat": []
},
"viz:avail" : {
"ng:crdt": "Automerge",
"ng:n": "Viz - Avail",
"ng:a": "Time Data Availability Visualization",
"ng:compat": [] // https://github.com/flrs/visavail
},
"chart:frappecharts" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - Frappe",
"ng:a": "GitHub-inspired responsive charts",
"ng:compat": [] // https://github.com/frappe/charts
},
"chart:financial" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - Financial",
"ng:a": "Financial charts",
"ng:compat": [] //https://github.com/tradingview/lightweight-charts
},
// have a look at https://github.com/cube-js/cube and https://awesome.cube.dev/ and https://frappe.io/products
"chart:apexcharts" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - ApexCharts",
"ng:a": "Interactive data visualizations",
"ng:compat": [] // https://github.com/apexcharts/apexcharts.js
},
//realtime data with https://github.com/square/cubism
"chart:billboard" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - BillBoard",
"ng:a": "Interactive data visualizations based on D3",
"ng:compat": [] // https://github.com/naver/billboard.js
},
"chart:echarts" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - ECharts",
"ng:a": "Interactive charting and data visualization with Apache ECharts",
"ng:compat": [] // https://github.com/apache/echarts
},
"chart:chartjs" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - Chart.js",
"ng:a": "Simple yet flexible charting for designers & developers with Chart.js",
"ng:compat": [] // https://github.com/chartjs/Chart.js
},
// see if to provide plain D3, and also all the https://github.com/antvis libraries: G2, G6, L7, S2, X6. Have a look at AVA
"doc:pdf": {
"ng:crdt": "Graph",
"ng:n": "PDF",
"ng:a": "upload and display a PDF file",
"ng:compat": ["file:iana:application:pdf"] // https://github.com/mozilla/pdf.js https://viewerjs.org/
},
"doc:odf": { //!!! becareful: AGPL
"ng:crdt": "Graph",
"ng:n": "ODF",
"ng:a": "upload and display an ODF file",
"ng:compat": ["file:iana:application:vnd.oasis.opendocument*"] // https://webodf.org/ https://github.com/webodf/WebODF https://viewerjs.org/
},
// see also https://github.com/Mathpix/mathpix-markdown-it
"doc:latex": {
"ng:crdt": "Graph",
"ng:n": "Latex",
"ng:a": "upload and display a Latex or Tex file",
"ng:compat": ["file:iana:application:x-tex","file:iana:text:x-tex"] // https://github.com/michael-brade/LaTeX.js https://github.com/mathjax/MathJax
},
"doc:ps": { //!!! becareful: AGPL https://github.com/ochachacha/ps-wasm
"ng:crdt": "Graph",
"ng:n": "Postscript",
"ng:a": "upload and display a PostScript file",
"ng:compat": ["file:iana:application:postscript"] // https://www.npmjs.com/package/ghostscript4js
},
"doc:music:abc": { //https://github.com/paulrosen/abcjs
"ng:crdt": "YText",
"ng:n": "Musical Notation",
"ng:a": "sheet music notation",
"ng:compat": []
},
"doc:music:guitar": { //https://github.com/birdca/fretboard
"ng:crdt": "YText",
"ng:n": "Music - Guitar",
"ng:a": "charts for guitar chords and scales",
"ng:compat": []
},
"doc:maths": { //https://github.com/KaTeX/KaTeX
"ng:crdt": "YText",
"ng:n": "Maths",
"ng:a": "TeX math rendering",
"ng:compat": ["file:iana:application:x-tex","file:iana:text:x-tex"]
},
"doc:chemistry": { //GPL!! https://github.com/aeris-data/ChemDoodle/tree/master/ChemDoodleWeb-8.0.0 or https://github.com/aseevia/smiles-3d-vue
"ng:crdt": "YText",
"ng:n": "Molecules (SMILES)",
"ng:a": "simplified molecular-input line-entry system (SMILES)",
"ng:compat": ["file:iana:chemical:x-daylight-smiles"] // https://en.wikipedia.org/wiki/SYBYL_line_notation and http://fileformats.archiveteam.org/wiki/Chemical_data
},
"doc:ancientscript": { //https://dn-works.com/ufas/
"ng:crdt": "YText", // use Unicode and special fonts
"ng:n": "Ancient Script",
"ng:a": "Ancient Script",
"ng:compat": []
},
"doc:braille": { //https://en.wikipedia.org/wiki/Braille_Patterns
"ng:crdt": "YText", // use Unicode and special fonts
"ng:n": "Braille Patterns",
"ng:a": "Braille Patterns",
"ng:compat": []
},
"media:image": {
"ng:crdt": "Graph",
"ng:n": "Image",
"ng:a": "upload and display an image",
"ng:o": "n:g:z:media",
"ng:x": {
"as":true,
},
"ng:compat": ["file:iana:image*","as:Image"]
},
"media:reel": {
"ng:crdt": "Graph",
"ng:n": "Reel",
"ng:a": "upload and display a Reel (video from mobile)",
"ng:o": "n:g:z:media",
"ng:compat": ["file:iana:video*"]
},
"media:video": {
"ng:crdt": "Graph",
"ng:n": "Video",
"ng:a": "upload and display a Video (and film)",
"ng:o": "n:g:z:media",
"ng:x": {
"as":true,
},
"ng:compat": ["file:iana:video*","as:Video"]
},
"media:album": {
"ng:crdt": "Graph",
"ng:n": "Album",
"ng:a": "Assemble several images and/or videos into an ordered Album",
"ng:o": "n:g:z:gallery",
"ng:include": ["data:collection"],
"ng:compat": []
},
"media:audio": {
"ng:crdt": "Graph",
"ng:n": "Audio",
"ng:a": "upload and play an Audio file, Audio note or Voice message",
"ng:o": "n:g:z:media",
"ng:x": {
"as":true,
},
"ng:compat": ["file:iana:audio*","as:Audio"]
},
"media:song": {
"ng:crdt": "Graph",
"ng:n": "Song",
"ng:a": "A song from an artist,album and/or lyrics",
"ng:o": "n:g:z:media",
"ng:x": {
"music": "http://purl.org/ontology/mo/",
},
"ng:compat": ["music:MusicalWork","music:MusicArtist", "music:Lyrics"]
// see also https://polifonia-project.eu/wp-content/uploads/2022/01/Polifonia_D2.1_V1.0.pdf
// Music ontology http://musicontology.com/docs/faq.html with data based on existing databases https://musicbrainz.org/doc/MusicBrainz_Database/Schema https://github.com/megaconfidence/open-song-database https://www.discogs.com/developers
},
"media:subtitle": { //https://captioneasy.com/subtitle-file-formats/
"ng:crdt": "YText",
"ng:n": "Subtitles",
"ng:a": "Subtitles",
"ng:compat": [] // TBD
},
"media:overlay": {
"ng:crdt": "Graph",
"ng:n": "Overlay",
"ng:a": "Composition of an image, reel, text, icon, link, mention or other content into a layered content",
"ng:o": "n:g:z:media",
"ng:compat": []
},
"social:activity": {
"ng:crdt": "Graph",
"ng:n": "Activity",
"ng:a": "Activity sent in a Stream",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Activity"]
},
"social:channel": {
"ng:crdt": "Graph",
"ng:n": "Channel",
"ng:a": "Broadcast channel with subscribers",
"ng:compat": []
},
"social:stream": {
"ng:crdt": "Graph",
"ng:n": "Stream",
"ng:a": "A document or store's stream branch",
"ng:compat": []
},
"social:contact": {
"ng:crdt": "Graph",
"ng:n": "Contact",
"ng:a": "Contact: an Individual, Organization or Group",
"ng:x": {
"vcard":true,
"foaf": true,
},
"ng:include": ["data:graph"],
"ng:compat": ["foaf:Person","foaf:Agent","vcard:Individual", "vcard:Organization", "vcard:Group", "file:iana:text:vcard", "file:iana:application:vcard+json", "file:iana:application:vcard+xml" ],
},
"social:event": {
"ng:crdt": "Graph",
"ng:n": "Event",
"ng:a": "An event occuring in specific location and time",
"ng:x": {
"as":true,
},
"ng:include": ["post:*"],
"ng:compat": ["as:Event"]
},
"social:calendar": {
"ng:crdt": "Graph",
"ng:n": "Calendar",
"ng:a": "A calendar where events are gathered",
"ng:x": {
"as":true,
"time": true,
},
"ng:include": ["data:collection"],
"ng:compat": ["time:TemporalEntity", "file:iana:text:calendar", "file:iana:application:calendar+xml", "file:iana:application:calendar+json"] //https://www.rfc-editor.org/rfc/rfc5545
},
"social:scheduler": {
"ng:crdt": "Graph",
"ng:n": "Scheduler",
"ng:a": "Helps finding a common time slot for several participants to a future event",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Invite","as:Reject","as:Accept","as:TentativeAccept","as:TentativeReject"]
},
"social:reaction": {
"ng:crdt": "Graph",
"ng:n": "Reaction",
"ng:a": "A reaction by user to some content",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Like", "as:Dislike", "as:Listen", "as:Read", "as:View"]
},
"social:chatroom": {
"ng:crdt": "Graph",
"ng:n": "ChatRoom",
"ng:a": "A room for group chat",
},
"social:live": {
"ng:crdt": "Graph",
"ng:n": "Live",
"ng:a": "A live session of video or audio, with optional chat",
},
"prod:task": {
"ng:crdt": "Graph",
"ng:n": "Task",
"ng:a": "A task to be done",
"ng:x": {
"as":true,
"pair": "http://virtual-assembly.org/ontologies/pair#",
},
"ng:include": ["post:*"],
"ng:compat": ["pair:Task"] //see VTODO in iCalendar https://www.cs.utexas.edu/~mfkb/RKF/tree/components/specs/ontologies/Calendar-onto.html
// see todo and todoList of Mobilizon https://framagit.org/framasoft/mobilizon/-/blob/main/lib/federation/activity_stream/converter/todo.ex
// https://framagit.org/framasoft/mobilizon/-/blob/main/lib/federation/activity_stream/converter/todo_list.ex
},
"prod:project": {
"ng:crdt": "Graph",
"ng:n": "Project",
"ng:a": "A project management / KanBan",
"ng:x": {
"as":true,
"pair": "http://virtual-assembly.org/ontologies/pair#",
},
"ng:include": ["post:*"],
"ng:compat": ["pair:Project"]
},
// see SRO https://www.researchgate.net/publication/350158531_From_a_Scrum_Reference_Ontology_to_the_Integration_of_Applications_for_Data-Driven_Software_Development
// https://ceur-ws.org/Vol-1442/paper_4.pdf
// see focalbaord, specially for their import scripts https://github.com/mattermost/focalboard/tree/main/import
// and their data model https://github.com/mattermost/focalboard/tree/main/server/model
// https://github.com/leif81/bzkanban
// https://github.com/HigorLoren/donko (react)
// https://github.com/trobonox/kanri (GPL, Vue)
// https://github.com/waterrmalann/kards (vanilla JS)
// see also https://github.com/wekan/wekan
// see also https://taiga.io/ (for inspiration. as it is AGPL and python)
// see also https://github.com/plankanban/planka (for inspiration. as it is AGPL and React)
// see also https://kolaente.dev/vikunja/vikunja (for inspiration. AGPL. Vue and Go)
// see also https://github.com/laurent22/joplin/ (for inspiration. AGPL)
// see also https://github.com/SrGMC/kanbana
/// svelte: https://github.com/V-Py/svelte-kanban
// https://github.com/supabase-community/svelte-kanban
// https://github.com/therosbif/kanban
"prod:issue": {
"ng:crdt": "Graph",
"ng:n": "Issue",
"ng:a": "An issue to be solved",
"ng:x": {
"as":true,
"pair": "http://virtual-assembly.org/ontologies/pair#",
},
"ng:include": ["prod:task"],
"ng:compat": ["pair:Challenge"]
},
//https://github.com/go-gitea/gitea/issues/20232
// datamodel of gitea issues: https://github.com/go-gitea/gitea/blob/165346c15c6d021028a65121e692a17ffc927e2c/models/issue.go#L35-L79
"prod:form": {
"ng:crdt": "Graph",
"ng:n": "Form",
"ng:a": "A form to be filled-in",
"ng:x": {
"form" : "http://rdf.danielbeeke.nl/form/form-dev.ttl#",
},
"ng:compat": ["form:*","file:iana:application:schema+json"]
},
// https://jsonforms.io/docs/
// https://github.com/jsonform/jsonform
// https://jsonforms.io/docs/integrations/vue
// >>> https://github.com/json-editor/json-editor
// or >>> https://github.com/webgme/svelte-jsonschema-form
// or >>> https://github.com/restspace/svelte-schema-form
// see https://ceur-ws.org/Vol-1515/regular14.pdf
// and https://github.com/protegeproject/facsimile
// https://www.drupal.org/project/webform
// see https://www.semantic-mediawiki.org/wiki/Extension:Page_Forms
// https://www.mediawiki.org/wiki/Extension:Page_Forms
// https://rdf-form.danielbeeke.nl/
// consider using Shapes
"prod:filling": {
"ng:crdt": "Graph",
"ng:n": "Form filling",
"ng:a": "A form that has been filled-in",
"ng:compat": []
},
"prod:cad": { // https://mattferraro.dev/posts/cadmium
"ng:crdt": "Automerge",
"ng:n": "CAD",
"ng:a": "CADmium",
"ng:compat": []
},
"prod:spreadsheet": {
"ng:crdt": "Automerge",
"ng:n": "Spreadsheet",
"ng:a": "Spreadsheet",
"ng:compat": []
},
"prod:slides": { //https://github.com/hakimel/reveal.js
//https://pandoc.org/MANUAL.html#slide-shows
"ng:crdt": "Graph",
"ng:n": "Slides",
"ng:a": "Slides and presentations",
"ng:include": ["post:*"],
"ng:compat": []
},
"prod:question" : {
"ng:crdt": "Graph",
"ng:n": "Question",
"ng:a": "A question that needs answers",
"ng:x": {
"as":true,
},
"ng:include": ["post:*"],
"ng:compat": ["as:Question"]
},
"prod:answer" :{
"ng:crdt": "Graph",
"ng:n": "Answer",
"ng:a": "An answer to a question",
"ng:x": {
"as":true,
},
"ng:include": ["post:*"],
"ng:compat": ["as:Note"]
},
"prod:poll" : {
"ng:crdt": "Graph",
"ng:n": "Poll",
"ng:a": "A poll where people will vote",
"ng:x": {
"as":true,
},
"ng:include": ["post:*"],
"ng:compat": ["as:Question"]
},
"prod:vote" : {
"ng:crdt": "Graph",
"ng:n": "Vote",
"ng:a": "A vote cast for a Poll",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Note"]
},
"file" : {
"ng:crdt": "Graph",
"ng:n": "File",
"ng:a": "Binary file",
"ng:o": "n:g:z:file_viewer",
"ng:compat": []
},
"file:ng:wallet" : {
"ng:n": "NextGraph Wallet File",
"ng:a": "NextGraph Wallet File (.ngw)",
"ng:compat": []
},
"file:ng:doc" : {
"ng:n": "NextGraph Document File",
"ng:a": "NextGraph Document File (.ngd)",
"ng:compat": []
},
"file:ng:html" : {
"ng:n": "NextGraph Document Html",
"ng:a": "NextGraph Document Html standalone file",
"ng:compat": []
},
"file:text" : {
"ng:crdt": "Graph",
"ng:n": "File",
"ng:a": "Text file",
"ng:o": "n:g:z:file_viewer",
"ng:compat": ["file:iana:text:*", "file:iana:image:svg+xml", "file:iana:application:n-quads", "file:iana:application:trig", "file:iana:application:n-triples", "file:iana:application:rdf+xml", "file:iana:application:ld+json",
"file:iana:application:xml", "file:iana:application:yaml", "file:iana:application:xhtml+xml", "file:iana:application:node","file:iana:application:sparql-results+json","file:iana:application:sparql-results+xml",
"file:iana:message:rfc822","file:iana:multipart:related", "file:iana:text:vnd.graphviz", "file:iana:application:vnd.excalidraw+json", "file:iana:application:x-tex","file:iana:text:x-tex",
"file:iana:application:vcard+json", "file:iana:application:vcard+xml", "file:iana:text:calendar", "file:iana:application:calendar+xml", "file:iana:application:calendar+json",
"file:iana:application:schema+json", "file:iana:application:geo+json", "file:iana:application:json" ]
},
};

@ -0,0 +1,21 @@
export const redirect_server = import.meta.env.NG_REDIR_SERVER || "nextgraph.net";
export const bootstrap_redirect = import.meta.env.NG_DEV
? "http://localhost:1421/bootstrap.html#/?b="
: import.meta.env.DEV
? "http://localhost:14403/#/?b="
: import.meta.env.NG_DEV3
? "http://127.0.0.1:3033/bootstrap/#/?b="
: `https://${redirect_server}/bootstrap/#/?b=`;
export function base64UrlEncode(str) {
const base64 = btoa(str); // Standard Base64 encoding
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
export function push(location) {
if (!location || location.length < 1 || (location.charAt(0) != '/' && location.indexOf('#/') !== 0)) {
throw Error('Invalid parameter location')
}
window.location.hash = (location.charAt(0) == '#' ? '' : '#') + location
}

@ -0,0 +1,50 @@
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
import { register, init, locale, format } from "svelte-i18n";
import { default as ng } from "../.auth-react/api";
// Make sure that a file named `locales/<lang>.json` exists when adding it here.
export const available_languages = {
en: "English",
//de: "Deutsch",
//fr: "Français",
//ru: "Русский",
//es: "Español",
//it: "Italiano",
//zh: "中文",
//pt: "Português",
};
export const select_default_lang = async () => {
for (const lang of Object.keys(available_languages)) {
let json = await import(`./locales/${lang}.json`);
register(lang, async ()=>{return json})
}
init({
fallbackLocale: "en",
initialLocale: "en",
});
let locales = await ng.locales();
for (let lo of locales) {
if (available_languages[lo]) {
// exact match (if locales is a 2 chars lang code, or if we support regionalized translations)
locale.set(lo);
return;
}
lo = lo.substr(0, 2);
if (available_languages[lo]) {
locale.set(lo);
return;
}
}
};

@ -0,0 +1,110 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
import * as ng from "../../.auth-react/api";
import { onMount, tick } from "svelte";
import { locale, t } from "svelte-i18n";
import { available_languages } from "../lang";
import { Language } from "svelte-heros-v2";
export let displayFooter = false;
let changingLang = false;
const changeLang = () => {
changingLang = true;
scrollToTop();
};
let top;
function scrollToTop() {
top.scrollIntoView();
}
const selectLang = async (lang) => {
locale.set(lang);
changingLang = false;
await tick();
scrollToTop();
};
let tauri_platform = import.meta.env.TAURI_ENV_PLATFORM;
const displayPopup = async (url, title) => {
if (!tauri_platform || tauri_platform == "android") {
window.open(url, "_blank").focus();
} else {
await ng.open_window(url, "viewer", title);
}
};
const displayNextgraphOrg = async () => {
await displayPopup("https://nextgraph.org", "NextGraph.org");
};
</script>
<div bind:this={top}>
{#if !changingLang}
<div class="centered">
<slot />
</div>
{#if displayFooter}
<div class="centered">
<div class="mb-20 mt-10">
<button
on:click={changeLang}
class="text-primary-700 bg-white bg-none ring-0 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55"
>
<Language
tabindex="-1"
class="w-7 h-7 mr-2 transition duration-75 "
/>Change language <!--note to translator: DO NOT TRANSLATE! it should stay in english always-->
</button>
<br />
<button
on:click={displayNextgraphOrg}
class="text-primary-700 bg-white bg-none ring-0 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
{$t("common.about_nextgraph")}
</button>
</div>
</div>
{/if}
{:else}
<div class="centered">
<ul class="mb-20 mt-10">
{#each Object.entries(available_languages) as lang}
<li
tabindex="0"
role="menuitem"
class="flex items-center p-2 text-lg mb-2 font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700"
on:keypress={() => selectLang(lang[0])}
on:click={() => selectLang(lang[0])}
>
<span class="mx-3">{lang[1]}</span>
</li>
{/each}
</ul>
</div>
{/if}
</div>
<style>
.centered {
/*max-width: 1280px;*/
margin: 0 auto;
padding: 0rem;
text-align: center;
width: fit-content;
}
</style>

File diff suppressed because one or more lines are too long

@ -0,0 +1,379 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
The Login Procedure.
Has multiple states (steps) through the user flow.
-->
<script lang="ts">
import { Alert, Toggle, Button } from "flowbite-svelte";
import { onMount, createEventDispatcher, tick } from "svelte";
import { t } from "svelte-i18n";
import {
default as ng,
} from "../../.auth-react/api";
import {
PuzzlePiece,
XCircle,
Backspace,
ArrowPath,
LockOpen,
CheckCircle,
ArrowLeft,
} from "svelte-heros-v2";
import PasswordInput from "./components/PasswordInput.svelte";
import Spinner from "./components/Spinner.svelte";
import { display_error } from "../store";
//import Worker from "../worker.js?worker&inline";
export let wallet;
export let for_import = false;
let top;
function scrollToTop() {
top.scrollIntoView();
}
let tauri_platform = import.meta.env.TAURI_ENV_PLATFORM;
const dispatch = createEventDispatcher();
function init_simple() {
error = undefined;
step = "password";
scrollToTop();
}
onMount(async () => {
loaded = false;
if (for_import) {
device_name = await ng.get_device_name();
step = "import";
}
//load_svg();
//console.log(wallet);
//await init();
init_simple();
if (!tauri_platform) {
try {
localStorage;
} catch (e) {
trusted = false;
no_local_storage = true;
console.log("no access to localStorage");
}
}
});
let step = "password";
let loaded = false;
let error;
let trusted = true;
let no_local_storage = false;
let password = "";
let unlockWith: "pazzle" | "mnemonic" | "password" | undefined = "password";
let device_name;
async function finish() {
step = "opening";
await tick();
// open the wallet
try {
if (tauri_platform) {
// TODO @niko: Add device_name as param to open_with_* APIs
let opened_wallet =
await ng.wallet_open_with_password(password);
// try {
// let client = await ng.wallet_was_opened(opened_wallet);
// opened_wallet.V0.client = client;
// } catch (e) {
// console.log(e);
// error = e;
// step = "end";
// dispatch("error", { error: e });
// return;
// }
step = "end";
dispatch("opened", {
wallet: opened_wallet,
id: opened_wallet.V0.wallet_id,
trusted,
device_name,
});
} else {
let worker_import = await ng.get_worker();
const myWorker = new worker_import.default();
myWorker.onerror = (e) => {
console.error(e);
error = "WebWorker error";
step = "end";
dispatch("error", { error });
};
myWorker.onmessageerror = (e) => {
console.error(e);
error = e;
step = "end";
dispatch("error", { error: e });
};
myWorker.onmessage = async (msg) => {
//console.log("Message received from worker", msg.data);
if (msg.data.loaded) {
if (unlockWith === "password") {
myWorker.postMessage({ wallet, password, device_name });
}
//console.log("postMessage");
} else if (msg.data.success) {
//console.log(msg.data);
// try {
// let client = await ng.wallet_was_opened(msg.data.success);
// msg.data.success.V0.client = client;
// } catch (e) {
// console.log(e);
// error = e;
// step = "end";
// dispatch("error", { error: e });
// return;
// }
step = "end";
dispatch("opened", {
wallet: msg.data.success,
id: msg.data.success.V0.wallet_id,
trusted,
device_name,
});
} else {
console.error(msg.data.error);
error = msg.data.error;
step = "end";
dispatch("error", { error: msg.data.error });
}
};
}
} catch (e) {
console.error(e);
if (
(e.message && e.message.includes("constructor")) ||
(typeof e === "string" && e.includes("constructor"))
)
e = "BrowserTooOld";
error = e;
step = "end";
dispatch("error", { error: e });
}
// display the result
}
function cancel() {
dispatch("cancel");
}
function go_back() {
if (step === "password") {
init_simple();
}
}
</script>
<div
class="flex-col justify-center md:max-w-2xl py-4 sm:px-8"
bind:this={top}
>
{#if step == "import"}
{#if no_local_storage}
<div class="max-w-xl lg:px-8 mx-auto px-4 mb-2">
<Alert color="orange" class="">
Access to local storage is denied. <br />You won't be able to save
your wallet in this browser.<br />
If you wanted to save it, please allow storing local data<br />
for the websites {location.origin} <br />
and https://nextgraph.net and then reload the page. <br />
</Alert>
</div>
{:else}
<div class="max-w-xl lg:px-8 mx-auto px-4 mb-2">
<span class="text-xl"
>{$t("pages.wallet_create.save_wallet_options.trust")}
</span> <br />
<p class="text-sm">
{$t("pages.wallet_create.save_wallet_options.trust_description")}
{#if !tauri_platform}
{$t("pages.login.trust_device_allow_cookies")}{/if}<br />
</p>
<div class="flex justify-center items-center my-4">
<Toggle class="" bind:checked={trusted}
>{$t("pages.login.trust_device_yes")}</Toggle
>
</div>
</div>
{/if}
<div class="max-w-xl lg:px-8 mx-auto px-4 text-primary-700">
<div class="flex flex-col justify-centerspace-x-12 mt-4 mb-4">
<!-- Device Name, if trusted-->
{#if trusted}
<label for="device-name-input" class="text-sm text-black">
{$t("pages.login.device_name_label")}
</label>
<input
id="device-name-input"
bind:value={device_name}
placeholder={$t("pages.login.device_name_placeholder")}
type="text"
class="w-full mb-10 lg:px-8 mx-auto px-4 bg-gray-50 border border-gray-300 text-xs rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
/>
{/if}
<button
on:click={start_with_password}
on:keypress={start_with_password}
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<LockOpen
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 focus:outline-none group-hover:text-gray-900 dark:group-hover:text-white"
/>
{$t("pages.login.open")}
</button>
<button
on:click={cancel}
class="mt-3 mb-2 text-gray-500 dark:text-gray-400 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
><ArrowLeft
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 focus:outline-none group-hover:text-gray-900 dark:group-hover:text-white"
/>{$t("pages.login.login_cancel")}
</button>
</div>
</div>
{:else if step == "password"}
<label
for="password-input"
class="block mb-2 text-xl text-gray-900 dark:text-white"
>{$t("pages.login.enter_password")}</label
>
<PasswordInput
id="password-input"
bind:value={password}
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
auto_complete="password"
autofocus={true}
on:enter={finish}
/>
<div class="flex">
<button
on:click={cancel}
class="mt-3 mr-2 mb-2 ml-auto bg-red-100 hover:bg-red-100/90 disabled:opacity-65 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
><XCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition focus:outline-none duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>{$t("buttons.cancel")}</button
>
<Button
onclick={finish}
class="mt-3 mb-2 ml-auto text-white bg-primary-700 hover:bg-primary-700/90 disabled:opacity-65 focus:ring-4 focus:ring-blue-500 focus:border-blue-500 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-blue-500 dark:focus:border-blue-500"
disabled={password.trim().length < 2}
><CheckCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>{$t("buttons.confirm")}</Button
>
</div>
<!-- The following steps have navigation buttons and fixed layout -->
{:else if step == "opening"}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-primary-700">
{@html $t("pages.login.opening_wallet")}
<Spinner className="mt-10 h-14 w-14 mx-auto" />
</div>
{:else if step == "end"}
{#if error}
<div class=" max-w-6xl lg:px-8 mx-auto text-red-800">
<div class="mt-auto max-w-6xl lg:px-8">
{$t("errors.an_error_occurred")}
<svg
fill="none"
class="animate-bounce mt-10 h-10 w-10 mx-auto"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
<Alert color="red" class="mt-5">
{display_error(error)}
</Alert>
</div>
<div class="flex justify-between mt-auto gap-4 mr-3 ml-3">
<button
on:click={cancel}
class="mt-10 bg-red-100 hover:bg-red-100/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
><XCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 focus:outline-none group-hover:text-gray-900 dark:group-hover:text-white"
/>{$t("buttons.cancel")}</button
>
<button
class="mt-10 ml-2 select-none text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
on:click={init_simple}
>
<ArrowPath
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 focus:outline-none group-hover:text-gray-900 dark:group-hover:text-white"
/>
{$t("buttons.try_again")}
</button>
</div>
</div>
{:else}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-green-800">
{@html $t("pages.login.wallet_opened")}
<svg
class="my-10 h-16 w-16 mx-auto"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 01-1.043 3.296 3.745 3.745 0 01-3.296 1.043A3.745 3.745 0 0112 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 01-3.296-1.043 3.745 3.745 0 01-1.043-3.296A3.745 3.745 0 013 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 011.043-3.296 3.746 3.746 0 013.296-1.043A3.746 3.746 0 0112 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 013.296 1.043 3.746 3.746 0 011.043 3.296A3.745 3.745 0 0121 12z"
/>
</svg>
</div>
{/if}
{/if}
</div>
<style>
</style>

@ -0,0 +1,95 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
Component to inform the user, that no wallet is registered on this device.
Offers login or create wallet buttons.
-->
<script>
// @ts-ignore
import Logo from "../assets/nextgraph.svg?component";
import { link } from "svelte-spa-router";
import CenteredLayout from "./CenteredLayout.svelte";
import { t } from "svelte-i18n";
export let without_create = false;
</script>
<CenteredLayout displayFooter={true}>
<div class="container3">
<div class="row">
<Logo class="logo block h-40" alt={$t("common.logo")} />
</div>
<h1 class="text-2xl text-center mb-10">{$t("pages.no_wallet.welcome")}</h1>
<p class="max-w-sm">
{@html $t("pages.no_wallet.description")}<br />
{@html $t("pages.no_wallet.instructions_login")}{#if !without_create}{@html $t("pages.no_wallet.instructions_create")}
{:else}
{@html $t("pages.no_wallet.instructions_nocreate")}
{/if}
</p>
{#if !without_create}
<div class="row mt-5">
<a href="/wallet/create" use:link>
<button
tabindex="-1"
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
class="w-8 h-8 -ml-1 mr-2"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z"
/>
</svg>
{$t("pages.no_wallet.create_wallet")}
</button>
</a>
</div>
{/if}
<div class="row mt-5">
<a href="/wallet/login" use:link>
<button
tabindex="-1"
class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="currentColor"
stroke="currentColor"
stroke-width="2"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z"
/>
</svg>
{$t("buttons.login")}
</button>
</a>
</div>
</div>
</CenteredLayout>

@ -0,0 +1,33 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
import ng from "../api";
import {
branch_subscribe,
active_session,
online,
} from "../store";
import { onMount, onDestroy, tick } from "svelte";
import { Button, Progressbar, Spinner } from "flowbite-svelte";
import { t } from "svelte-i18n";
let is_tauri = import.meta.env.TAURI_ENV_PLATFORM;
onMount(async () => {
});
</script>

@ -0,0 +1 @@
export { default as LogoSimple } from "./components/LogoSimple.svelte";

@ -0,0 +1,91 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
export let value: string = "";
export let id: string | undefined = undefined;
export let rows: number = 3;
let has_success: boolean = false;
const tauri_platform = import.meta.env.TAURI_ENV_PLATFORM;
const setClipboard = async (text: string) => {
if (tauri_platform) {
// TODO: this won't work for tauri platform.
// const { writeText } = await import("@tauri-apps/api/clipboard");
// await writeText(text);
} else {
navigator.clipboard.writeText(text);
}
};
const on_click = (e) => {
has_success = true;
setTimeout(() => (has_success = false), 2_000);
setClipboard(value);
};
</script>
<div class="w-full mt-2">
<div class="relative">
<textarea
{id}
{rows}
style="resize: none;"
{value}
class="col-span-6 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500"
class:pr-11={!tauri_platform}
disabled
readonly
/>
{#if !tauri_platform}
<button
on:click={on_click}
class="absolute inset-y-0 right-0 p-3 flex items-center text-sm leading-5 bg-transparent shadow-none"
>
<span id="default-icon" class:hidden={has_success}>
<svg
class="w-3.5 h-3.5"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 18 20"
>
<path
d="M16 1h-3.278A1.992 1.992 0 0 0 11 0H7a1.993 1.993 0 0 0-1.722 1H2a2 2 0 0 0-2 2v15a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2Zm-3 14H5a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2Zm0-4H5a1 1 0 0 1 0-2h8a1 1 0 1 1 0 2Zm0-5H5a1 1 0 0 1 0-2h2V2h4v2h2a1 1 0 1 1 0 2Z"
/>
</svg>
</span>
<span
id="success-icon"
class="inline-flex items-center"
class:hidden={!has_success}
>
<svg
class="w-3.5 h-3.5 text-blue-700 dark:text-blue-500"
aria-hidden={!has_success}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 16 12"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M1 5.917 5.724 10.5 15 1.5"
/>
</svg>
</span>
</button>
{/if}
</div>
</div>

@ -0,0 +1,40 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
@component Logo
The NextGraph Logo svg with color changing between blue and gray,
depending on connection status:
- connected: blue
- connecting: pulse between blue and gray
- disconnected: gray
Provide classes using the `className` prop.
-->
<script lang="ts">
import { connection_status } from "../../store";
// @ts-ignore
import Logo from "../../assets/nextgraph-nofill.svg?component";
export let className: string = "";
let connection_status_class = "logo-blue";
// Color is adjusted to connection status.
$: if ($connection_status === "connecting" || $connection_status === "starting") {
connection_status_class = "logo-pulse";
} else if ($connection_status === "disconnected") {
connection_status_class = "logo-gray";
} else {
connection_status_class = "logo-blue";
}
</script>
<Logo class={`${className} ${connection_status_class}`} />

@ -0,0 +1,23 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
@component LogoSimple
The NextGraph Logo svg
-->
<script lang="ts">
// @ts-ignore
import Logo from "../../assets/nextgraph.svg?component";
import { t } from "svelte-i18n";
</script>
<Logo class="logo block h-[8em]" alt={$t("common.logo")} />

@ -0,0 +1,64 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
import {
Toast,
} from "flowbite-svelte";
import {
remove_toast
} from "../../store";
import { onMount, onDestroy, tick } from "svelte";
const toast_color = {
"error":"red",
"warning":"orange",
"success":"green",
"info":"blue"
};
const toast_icon = {
"error": XCircle,
"warning": ExclamationCircle,
"success": CheckCircle,
"info": InformationCircle,
}
import {
CheckCircle,
XCircle,
ExclamationCircle,
InformationCircle,
Icon,
} from "svelte-heros-v2";
export let toast;
export let i;
onMount(()=>{
toast.i = i;
if (toast.level=="success")
{
toast.timer = setTimeout(()=>{remove_toast(i);}, toast.timeout || 10000);
}
});
</script>
<div class="toast fixed flex w-full max-w-xs" style="top:{16+i*74}px;"
on:click|capture|stopPropagation={()=>{remove_toast(toast.i);}}
on:keypress={()=>{}}
>
<Toast color="{toast_color[toast.level]}" >
<Icon tabindex="-1" slot="icon" class="w-8 h-8 p-1 focus:outline-none" variation="outline" color="currentColor" icon={toast_icon[toast.level]} />
{toast.text}
</Toast>
</div>

@ -0,0 +1,98 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
export let value: string | undefined = undefined;
export let placeholder: string | undefined = undefined;
export let className: string | undefined = undefined;
export let classNameToggle: string | undefined = "right-0";
export let id: string | undefined = undefined;
export let auto_complete: string | undefined = undefined;
import { createEventDispatcher } from "svelte";
export let show: boolean = false;
export let autofocus = false;
export let input = undefined;
let type: "password" | "text" = "password";
$: type = show ? "text" : "password";
function handleInput(event: Event) {
const target = event.target as HTMLInputElement;
value = target.value;
}
const dispatch = createEventDispatcher();
async function toggle() {
let { selectionStart, selectionEnd } = input;
show = !show;
input.focus();
setTimeout(function () {
input.selectionStart = selectionStart;
input.selectionEnd = selectionEnd;
}, 0);
}
const key_pressed = async (e: any) => {
if (e.key == "Enter" || e.keyCode == 13) {
dispatch("enter");
}
};
</script>
<div class="relative">
<!-- svelte-ignore a11y-autofocus -->
<input
bind:this={input}
{value}
{placeholder}
{id}
{type}
{autofocus}
on:input={handleInput}
class={`${className} pr-12 text-md block`}
autocomplete={auto_complete}
on:keypress={key_pressed}
/>
<div
class={`${classNameToggle} clickable absolute inset-y-0 pr-3 flex items-center text-sm leading-5`}
>
<svg
fill="none"
on:click={toggle}
on:keypress={toggle}
class={`${show ? "block" : "hidden"} h-6 text-gray-700`}
xmlns="http://www.w3.org/2000/svg"
viewbox="0 0 576 512"
>
<path
fill="currentColor"
d="M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z"
>
</path>
</svg>
<svg
fill="none"
class={`${!show ? "block" : "hidden"} h-6 text-gray-700`}
on:click={toggle}
on:keypress={toggle}
xmlns="http://www.w3.org/2000/svg"
viewbox="0 0 640 512"
>
<path
fill="currentColor"
d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"
>
</path>
</svg>
</div>
</div>

@ -0,0 +1,38 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
export let className: string = "";
export let color: string = "currentColor";
export let width: number = 24;
</script>
<svg
class={"animate-spin " + className}
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke={color}
viewBox={`0 0 ${width} ${width}`}
>
<circle
class="opacity-25"
cx={width / 2}
cy={width / 2}
r={width / 2.4}
stroke={color}
stroke-width={width / 6}
/>
<path
class="opacity-75"
fill={color}
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>

@ -0,0 +1,3 @@
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''}>
<path d="M4 21.25c-1.519 0-2.75 1.231-2.75 2.75s1.231 2.75 2.75 2.75c1.519 0 2.75-1.231 2.75-2.75v0c-0.002-1.518-1.232-2.748-2.75-2.75h-0zM4 25.25c-0.69 0-1.25-0.56-1.25-1.25s0.56-1.25 1.25-1.25c0.69 0 1.25 0.56 1.25 1.25v0c-0.001 0.69-0.56 1.249-1.25 1.25h-0zM20 21.25c-1.519 0-2.75 1.231-2.75 2.75s1.231 2.75 2.75 2.75c1.519 0 2.75-1.231 2.75-2.75v0c-0.002-1.518-1.232-2.748-2.75-2.75h-0zM20 25.25c-0.69 0-1.25-0.56-1.25-1.25s0.56-1.25 1.25-1.25c0.69 0 1.25 0.56 1.25 1.25v0c-0.001 0.69-0.56 1.249-1.25 1.25h-0zM12 13.25c-1.519 0-2.75 1.231-2.75 2.75s1.231 2.75 2.75 2.75c1.519 0 2.75-1.231 2.75-2.75v0c-0.002-1.518-1.232-2.748-2.75-2.75h-0zM12 17.25c-0.69 0-1.25-0.56-1.25-1.25s0.56-1.25 1.25-1.25c0.69 0 1.25 0.56 1.25 1.25v0c-0.001 0.69-0.56 1.249-1.25 1.25h-0zM20 13.25c-1.519 0-2.75 1.231-2.75 2.75s1.231 2.75 2.75 2.75c1.519 0 2.75-1.231 2.75-2.75v0c-0.002-1.518-1.232-2.748-2.75-2.75h-0zM20 17.25c-0.69 0-1.25-0.56-1.25-1.25s0.56-1.25 1.25-1.25c0.69 0 1.25 0.56 1.25 1.25v0c-0.001 0.69-0.56 1.249-1.25 1.25h-0zM28 5.25c-1.519 0-2.75 1.231-2.75 2.75s1.231 2.75 2.75 2.75c1.519 0 2.75-1.231 2.75-2.75v0c-0.002-1.518-1.232-2.748-2.75-2.75h-0zM28 9.25c-0.69 0-1.25-0.56-1.25-1.25s0.56-1.25 1.25-1.25c0.69 0 1.25 0.56 1.25 1.25v0c-0.001 0.69-0.56 1.249-1.25 1.25h-0zM4 5.25c-1.519 0-2.75 1.231-2.75 2.75s1.231 2.75 2.75 2.75c1.519 0 2.75-1.231 2.75-2.75v0c-0.002-1.518-1.232-2.748-2.75-2.75h-0zM4 9.25c-0.69 0-1.25-0.56-1.25-1.25s0.56-1.25 1.25-1.25c0.69 0 1.25 0.56 1.25 1.25v0c-0.001 0.69-0.56 1.249-1.25 1.25h-0zM20 5.25c-1.519 0-2.75 1.231-2.75 2.75s1.231 2.75 2.75 2.75c1.519 0 2.75-1.231 2.75-2.75v0c-0.002-1.518-1.232-2.748-2.75-2.75h-0zM20 9.25c-0.69 0-1.25-0.56-1.25-1.25s0.56-1.25 1.25-1.25c0.69 0 1.25 0.56 1.25 1.25v0c-0.001 0.69-0.56 1.249-1.25 1.25h-0z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512" fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''}>
<path d="M365.1,74.6c-43.8,0-80.2,36.4-80.2,80.2c0,38.2,27,70.9,64.3,78.3c-0.9,21.4-12.1,33.6-30.8,48.5
c-23.3,17.7-53.2,23.3-74.6,27c-46.6,8.4-71.8,30.8-83,45.7V159.5c16.8-2.8,32.6-12.1,44.8-25.2c13.1-14.9,20.5-33.6,20.5-54.1
C226.2,36.4,189.8,0,146,0S65.7,36.4,65.7,80.2c0,19.6,7.5,38.2,19.6,53.2c11.2,13.1,26.1,21.4,42.9,25.2v195.8
c-16.8,3.7-31.7,13.1-42.9,25.2c-13.1,14.9-19.6,33.6-19.6,52.2c0,43.8,36.4,80.2,80.2,80.2s80.2-36.4,80.2-80.2
c0-27-13.1-51.3-35.4-66.2c10.3-11.2,28-22.4,58.8-28c25.2-4.7,60.6-11.2,88.6-32.6c27-20.5,42-42,43.8-73.7
c37.3-7.5,64.3-40.1,64.3-78.3C445.3,110,408.9,74.6,365.1,74.6L365.1,74.6z M97.5,81.1c0-26.1,21.4-48.5,48.5-48.5
c26.1,0,48.5,21.4,48.5,48.5S173,129.6,146,129.6C118.9,129.6,97.5,107.2,97.5,81.1z M193.5,433.7c0,26.1-21.4,48.5-48.5,48.5
c-26.1,0-48.5-21.4-48.5-48.5s21.4-48.5,48.5-48.5C172.1,386.1,193.5,407.5,193.5,433.7z M365.1,202.4c-26.1,0-48.5-21.4-48.5-48.5
c0-26.1,21.4-48.5,48.5-48.5c26.1,0,48.5,21.4,48.5,48.5C412.7,180.9,391.2,202.4,365.1,202.4z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,8 @@
<svg viewBox="0 0 360.99 360.99" xml:space="preserve" fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} xmlns="http://www.w3.org/2000/svg">
<path d="M360.99,189.609l-9.322-11.75l-43.003,34.118l-56.418-32.573v-64.916l45.639-36.209l-9.322-11.75l-44.455,35.27
l-57.419-33.151V22.754h-15v48.673l-52.578,30.356L74.676,66.529l-9.322,11.75l45.592,36.171v63.564l-65.558,37.851v73.894
L0,325.768l9.322,11.75l44.426-35.246l62.29,35.964l64.355-37.156l64.354,37.156l70.651-40.791v-71.664L360.99,189.609z
M125.945,115.158l55.651-32.13l55.65,32.13v64.246l-55.662,32.137l-55.639-32.123V115.158z M171.689,288.785l-55.651,32.131
l-55.65-32.131v-64.26l55.65-32.131l55.651,32.131V288.785z M300.398,288.785l-55.651,32.131l-55.65-32.131v-64.246l55.663-32.137
l55.639,32.124V288.785z"/>
</svg>

After

Width:  |  Height:  |  Size: 841 B

@ -0,0 +1,191 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
import {
Icon,
BugAnt,
DocumentText,
Window,
CodeBracket,
SquaresPlus,
ViewfinderCircle,
ArrowsPointingOut,
Cube,
ClipboardDocumentCheck,
MagnifyingGlass,
RocketLaunch,
Sun,
TableCells,
ListBullet,
RectangleGroup,
Squares2x2,
MapPin,
CircleStack,
Envelope,
GlobeAlt,
DocumentChartBar,
Document,
ClipboardDocumentList,
Photo,
Film,
RectangleStack,
SpeakerWave,
MusicalNote,
Ticket,
CursorArrowRays,
Megaphone,
User,
Clock,
CalendarDays,
Calendar,
Stop,
Flag,
HandRaised,
Newspaper,
PencilSquare,
CubeTransparent,
PresentationChartBar,
QuestionMarkCircle,
CheckCircle,
ChartPie,
Bars3BottomLeft,
Link,
Square2Stack,
Clipboard,
StopCircle,
Bolt,
Heart,
Cog,
Square3Stack3d,
ChatBubbleLeftRight,
Fire,
ReceiptPercent,
ArrowTrendingUp,
CursorArrowRipple,
VideoCamera,
Variable,
Language,
QueueList,
} from "svelte-heros-v2";
import PdfIcon from "./PdfIcon.svelte";
import BrailleIcon from "./BrailleIcon.svelte";
import ChemistryIcon from "./ChemistryIcon.svelte";
import GuitarIcon from "./GuitarIcon.svelte";
import JsonIcon from "./JsonIcon.svelte";
import JsIcon from "./JsIcon.svelte";
import TsIcon from "./TsIcon.svelte";
import RustIcon from "./RustIcon.svelte";
import SvelteIcon from "./SvelteIcon.svelte";
import ReactIcon from "./ReactIcon.svelte";
import GraphQLIcon from "./GraphQLIcon.svelte";
export let config = {};
export let dataClass: string;
export let color = "currentColor";
const exact_mapping = {
page: Window,
"app": Cog,
"app:z": SquaresPlus,
class: ViewfinderCircle,
contract: ClipboardDocumentCheck,
"query:text": MagnifyingGlass,
"query:web": MagnifyingGlass,
"query:graphql": GraphQLIcon,
"data:graph": Sun,
"data:json": JsonIcon,
"data:map": JsonIcon,
"data:array": JsonIcon,
"data:table": TableCells,
"data:collection": ListBullet,
"data:container": Square3Stack3d,
"data:board": RectangleGroup,
"data:grid": Squares2x2,
"data:geomap": MapPin,
"e:mail": Envelope,
"e:link": Link,
"mc:text": Bars3BottomLeft,
"mc:link": Link,
"plato:card": Clipboard,
"plato:pad": Square2Stack,
"media:image": Photo,
"media:reel": VideoCamera,
"media:video": Film,
"media:album": RectangleStack,
"media:audio": SpeakerWave,
"media:song": MusicalNote,
"media:subtitle": Ticket,
"media:overlay": CursorArrowRays,
"social:channel": Megaphone,
"social:stream": Bolt,
"social:contact": User,
"social:event": Clock,
"social:calendar": CalendarDays,
"social:scheduler": Calendar,
"social:reaction": Heart,
"social:chatroom": ChatBubbleLeftRight,
"social:live": Fire,
"prod:task": Stop,
"prod:project": Flag,
"prod:issue": HandRaised,
"prod:form": Newspaper,
"prod:filling": PencilSquare,
"prod:cad": CubeTransparent,
"prod:slides": PresentationChartBar,
"prod:question": QuestionMarkCircle,
"prod:answer": CheckCircle,
"prod:poll": CursorArrowRipple,
"prod:vote": CheckCircle,
"prod:spreadsheet": ReceiptPercent,
"doc:compose": QueueList,
"doc:maths": Variable,
"doc:music:abc": MusicalNote,
"doc:pdf": PdfIcon,
"doc:braille": BrailleIcon,
"doc:ancientscript": Language,
"doc:chemistry": ChemistryIcon,
"doc:music:guitar": GuitarIcon,
"code:js": JsIcon,
"code:ts": TsIcon,
"code:rust": RustIcon,
"code:svelte": SvelteIcon,
"code:react": ReactIcon,
};
const prefix_mapping = {
"post:": DocumentText,
code: CodeBracket,
schema: ArrowsPointingOut,
service: Cube,
"e:": GlobeAlt,
"app:": StopCircle,
"query:": RocketLaunch,
"data:": CircleStack,
"diagram": DocumentChartBar,
"chart": ChartPie,
"viz": ArrowTrendingUp,
"doc:": ClipboardDocumentList,
file: Document,
};
const find = (t) => {
let e = exact_mapping[t];
if (e) return e;
for (let prefix of Object.entries(prefix_mapping)) {
if (t.startsWith(prefix[0])) return prefix[1];
}
return BugAnt;
};
</script>
<Icon {...config} variation="outline" {color} icon={find(dataClass)} />

@ -0,0 +1,57 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
@component DeviceIcon
Display an icon for a device class provided by the `device` attribute.
Pass `config` for custom attributes.
-->
<script lang="ts">
import {
Icon,
Cube,
GlobeAlt,
QuestionMarkCircle,
DevicePhoneMobile,
ComputerDesktop,
ServerStack,
Key,
CommandLine,
} from "svelte-heros-v2";
export let config = {};
export let device: string;
const mapping = {
Web: GlobeAlt,
NativeIos: DevicePhoneMobile,
NativeAndroid: DevicePhoneMobile,
NativeMacOS: ComputerDesktop,
NativeLinux: ComputerDesktop,
NativeWin: ComputerDesktop,
NativeService: ServerStack,
NodeService: ServerStack,
Verifier: ServerStack,
VerifierLocal: ServerStack,
ClientBroker: ServerStack,
WalletMaster: ServerStack,
Box: Cube,
Stick: Key, // VerifierStick
Cli: CommandLine,
};
const find = (dataClass: string) => {
return mapping[dataClass] || QuestionMarkCircle;
};
</script>
<Icon {...config} variation="outline" color="black" icon={find(device)} />

@ -0,0 +1,3 @@
<svg viewBox="0 0 32 32" fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} xmlns="http://www.w3.org/2000/svg">
<path d="M18.734 3.667l6.578 3.802c1.089-1.146 2.901-1.193 4.047-0.104 0.193 0.188 0.365 0.401 0.5 0.635 0.786 1.37 0.313 3.12-1.063 3.906-0.229 0.13-0.479 0.234-0.745 0.297v7.599c1.531 0.365 2.474 1.896 2.109 3.427-0.063 0.271-0.172 0.531-0.307 0.771-0.792 1.365-2.536 1.833-3.906 1.042-0.26-0.146-0.5-0.344-0.698-0.568l-6.542 3.776c0.495 1.495-0.318 3.109-1.813 3.604-0.292 0.099-0.594 0.146-0.896 0.146-1.573 0-2.854-1.271-2.854-2.849 0-0.271 0.042-0.547 0.12-0.813l-6.583-3.797c-1.089 1.141-2.896 1.188-4.036 0.094-1.135-1.089-1.177-2.891-0.094-4.031 0.38-0.396 0.865-0.677 1.396-0.807v-7.599c-1.531-0.365-2.479-1.906-2.109-3.443 0.063-0.266 0.167-0.521 0.302-0.755 0.786-1.365 2.536-1.833 3.901-1.042 0.234 0.135 0.453 0.302 0.641 0.5l6.583-3.797c-0.448-1.51 0.417-3.099 1.922-3.542 0.26-0.083 0.536-0.12 0.813-0.12 1.573 0 2.854 1.271 2.854 2.844 0 0.281-0.042 0.557-0.12 0.823zM18.047 4.839c-0.026 0.026-0.047 0.052-0.078 0.078l8.615 14.917c0.036-0.010 0.078-0.021 0.109-0.031v-7.609c-1.526-0.375-2.453-1.922-2.073-3.448 0.005-0.031 0.016-0.068 0.021-0.099zM14.026 4.917l-0.078-0.078-6.594 3.802c0.438 1.51-0.438 3.089-1.948 3.526-0.036 0.010-0.068 0.016-0.104 0.026v7.609l0.115 0.031 8.615-14.917zM16.797 5.594c-0.521 0.146-1.073 0.146-1.589 0l-8.615 14.917c0.391 0.375 0.667 0.859 0.802 1.391h17.214c0.13-0.531 0.406-1.016 0.802-1.396zM18.109 27.229l6.552-3.786c-0.021-0.063-0.036-0.125-0.052-0.188h-17.219l-0.031 0.109 6.589 3.802c0.516-0.536 1.245-0.87 2.052-0.87 0.839 0 1.589 0.359 2.109 0.932z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,4 @@
<svg viewBox="0 0 32 32" fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} xmlns="http://www.w3.org/2000/svg">
<path d="M18.448,26.655c0.001,-0.001 0.001,-0.001 0.001,-0.002c2.407,-3.406 6.792,-9.888 8.717,-14.401c0.535,-1.252 0.882,-2.367 0.983,-3.246c0.088,-0.778 -0.016,-1.414 -0.263,-1.881c-0.359,-0.676 -1.158,-1.309 -2.339,-1.783c-2.201,-0.881 -5.872,-1.342 -9.545,-1.342c-3.673,-0 -7.344,0.461 -9.545,1.342c-1.181,0.474 -1.98,1.107 -2.338,1.783c-0.248,0.467 -0.352,1.103 -0.263,1.881c0.1,0.879 0.447,1.994 0.982,3.246c1.925,4.513 6.31,10.995 8.716,14.402c0.001,0 0.001,0.001 0.001,0.002c0.563,0.792 1.475,1.263 2.447,1.263c0.972,-0 1.884,-0.471 2.446,-1.264Zm-1.631,-1.157c-0.188,0.264 -0.491,0.421 -0.815,0.421c-0.324,0 -0.628,-0.157 -0.815,-0.421c-2.346,-3.321 -6.633,-9.632 -8.51,-14.03c-0.375,-0.88 -0.652,-1.675 -0.781,-2.345c-0.086,-0.449 -0.142,-0.813 -0.01,-1.061c0.109,-0.207 0.339,-0.37 0.627,-0.536c0.422,-0.242 0.961,-0.45 1.585,-0.632c2.061,-0.601 4.983,-0.894 7.904,-0.894c2.921,-0 5.843,0.293 7.904,0.894c0.624,0.182 1.163,0.39 1.585,0.632c0.288,0.166 0.518,0.329 0.628,0.536c0.131,0.248 0.075,0.612 -0.011,1.061c-0.129,0.67 -0.406,1.465 -0.781,2.345c-1.877,4.398 -6.164,10.709 -8.51,14.03l-0,-0Z"/>
<path d="M15.993,8.956l0,0.001c-0.001,0.018 -0.001,0.036 -0.001,0.054l-0,4.601c-0.236,-0.066 -0.485,-0.101 -0.742,-0.101c-1.518,-0 -2.75,1.232 -2.75,2.75c0,1.517 1.232,2.75 2.75,2.75c1.518,-0 2.75,-1.233 2.75,-2.75c0,-0.073 -0.008,-4.835 -0.008,-4.835l1.301,1.301c0.39,0.39 1.024,0.39 1.414,-0c0.39,-0.391 0.39,-1.024 0,-1.414l-3.008,-3.009c-0.39,-0.39 -1.024,-0.39 -1.414,0c-0.182,0.181 -0.279,0.415 -0.292,0.652Zm-0.743,6.555c0.414,-0 0.75,0.336 0.75,0.75c0,0.414 -0.336,0.75 -0.75,0.75c-0.414,-0 -0.75,-0.336 -0.75,-0.75c0,-0.414 0.336,-0.75 0.75,-0.75Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -0,0 +1,3 @@
<svg viewBox="0 0 16 16" fill="none" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} xmlns="http://www.w3.org/2000/svg">
<path fill-rule="nonzero" clip-rule="nonzero" d="M0 1.75C0 0.783501 0.783502 0 1.75 0H14.25C15.2165 0 16 0.783502 16 1.75V3.75C16 4.16421 15.6642 4.5 15.25 4.5C14.8358 4.5 14.5 4.16421 14.5 3.75V1.75C14.5 1.61193 14.3881 1.5 14.25 1.5H1.75C1.61193 1.5 1.5 1.61193 1.5 1.75V14.25C1.5 14.3881 1.61193 14.5 1.75 14.5H15.25C15.6642 14.5 16 14.8358 16 15.25C16 15.6642 15.6642 16 15.25 16H1.75C0.783501 16 0 15.2165 0 14.25V1.75ZM8.25 5.75C8.66421 5.75 9 6.08579 9 6.5V10.5C9 11.5048 8.72399 12.2584 8.15514 12.7324C7.61223 13.1848 6.95384 13.25 6.5 13.25C6.08579 13.25 5.75 12.9142 5.75 12.5C5.75 12.0858 6.08579 11.75 6.5 11.75C6.84617 11.75 7.06277 11.6902 7.19486 11.5801C7.301 11.4916 7.5 11.2452 7.5 10.5V6.5C7.5 6.08579 7.83578 5.75 8.25 5.75ZM11.2757 6.58011C11.6944 6.08164 12.3507 5.75 13.25 5.75C14.0849 5.75 14.7148 6.03567 15.1394 6.48481C15.4239 6.78583 15.4105 7.26052 15.1095 7.54505C14.8085 7.82958 14.3338 7.81621 14.0493 7.51519C13.9394 7.39898 13.7204 7.25 13.25 7.25C12.7493 7.25 12.5306 7.41836 12.4243 7.54489C12.2934 7.70065 12.25 7.896 12.25 8C12.25 8.104 12.2934 8.29935 12.4243 8.45511C12.5306 8.58164 12.7493 8.75 13.25 8.75C13.3257 8.75 13.3988 8.76121 13.4676 8.78207C14.1307 8.87646 14.6319 9.17251 14.9743 9.58011C15.3684 10.0493 15.5 10.604 15.5 11C15.5 11.396 15.3684 11.9507 14.9743 12.4199C14.5556 12.9184 13.8993 13.25 13 13.25C12.1651 13.25 11.5352 12.9643 11.1106 12.5152C10.8261 12.2142 10.8395 11.7395 11.1405 11.4549C11.4415 11.1704 11.9162 11.1838 12.2007 11.4848C12.3106 11.601 12.5296 11.75 13 11.75C13.5007 11.75 13.7194 11.5816 13.8257 11.4551C13.9566 11.2993 14 11.104 14 11C14 10.896 13.9566 10.7007 13.8257 10.5449C13.7194 10.4184 13.5007 10.25 13 10.25C12.9243 10.25 12.8512 10.2388 12.7824 10.2179C12.1193 10.1235 11.6181 9.82749 11.2757 9.41989C10.8816 8.95065 10.75 8.396 10.75 8C10.75 7.604 10.8816 7.04935 11.2757 6.58011Z" fill="currentColor" fill-opacity="0.80"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1,4 @@
<svg viewBox="0 0 24 24" fill="none" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} xmlns="http://www.w3.org/2000/svg">
<path d="M14 19H16C17.1046 19 18 18.1046 18 17V14.5616C18 13.6438 18.6246 12.8439 19.5149 12.6213L21.0299 12.2425C21.2823 12.1794 21.2823 11.8206 21.0299 11.7575L19.5149 11.3787C18.6246 11.1561 18 10.3562 18 9.43845V5H14" stroke="currentColor"/>
<path d="M10 5H8C6.89543 5 6 5.89543 6 7V9.43845C6 10.3562 5.37541 11.1561 4.48507 11.3787L2.97014 11.7575C2.71765 11.8206 2.71765 12.1794 2.97014 12.2425L4.48507 12.6213C5.37541 12.8439 6 13.6438 6 14.5616V19H10" stroke="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 665 B

@ -0,0 +1,10 @@
<svg fill="none" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} viewBox="-10 255 1034 734" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor"
d="M278 256q-95 0 -127.5 28t-32.5 113v92q0 57 -20 79t-74 22h-24v55h24q53 0 73.5 22t20.5 80v92q0 84 32.5 112.5t127.5 28.5h25v-55h-27q-54 0 -70 -16.5t-16 -71.5v-95q0 -59 -17.5 -86.5t-59.5 -37.5q42 -10 59.5 -37t17.5 -87v-95q0 -55 16 -71.5t70 -16.5h27v-55
h-25zM697 256v55h27q53 0 69.5 16.5t16.5 71.5v95q0 60 17 87t60 37q-42 10 -59.5 37t-17.5 87v95q0 55 -16.5 71.5t-69.5 16.5h-27v55h24q95 0 127 -28.5t32 -112.5l1 -92q-1 -58 20 -80t75 -22h24v-55h-24q-54 0 -75 -22t-20 -79v-92q-1 -85 -33 -113t-127 -28h-24z
M617 341q-27 0 -51 14t-37 39q-16 31 -11 64l-1 -2v5q-1 6 -5 13q-5 10 -16 21q-13 13 -35 26q-38 24 -68 24q-14 0 -21 -5v0l2 3l-6 -3q-37 -20 -77 -7.5t-60 49.5t-7.5 77t49.5 60q27 14 57.5 11t53.5 -22l-1 2l5 -3q6 -2 15 -2q12 0 27 4q18 5 41 17q33 18 48 39
q10 13 11 26q-1 28 13.5 53.5t40.5 39.5q37 19 77 7t60 -49t7.5 -77.5t-49.5 -59.5q-5 -3 -10 -5h2l-3 -3q-5 -4 -8 -11q-6 -11 -9 -25q-4 -19 -4.5 -44t2.5 -44q3 -15 8 -26q3 -7 8 -12l3 -3h-3q28 -14 43 -43q20 -37 7.5 -77t-49.5 -60q-23 -12 -49 -11zM619 357
q27 0 46 17v0q-10 -9 -31 -7t-41 15q6 6 6 14.5t-5.5 15t-14.5 6.5q-3 0 -6 -1h-1q-9 -3 -15 6q-10 19 -11 37t8 29q-19 -21 -18 -51t22 -53q13 -14 29 -21t32 -7zM550 524q7 0 11 2l10 6q9 4 19 7q21 20 23 81q0 36 -8 59q-6 15 -15 23q-14 6 -25 16q-10 3 -25 1
q-24 -4 -56 -21q-34 -19 -51 -38q-10 -12 -11 -22q1 -13 -2 -26l1 1v-5q1 -5 5 -12q6 -9 17 -19q13 -13 34 -26q42 -26 70 -27h3zM323 548q27 0 46 17h-1q-10 -9 -30.5 -7t-40.5 15q5 6 5.5 14t-5.5 14.5t-15 7.5q-2 0 -5 -1h-2q-8 -3 -15 6q-9 18 -10 36.5t8 28.5
q-20 -20 -19 -50t23 -53q12 -14 28 -21t33 -7zM637 709q27 0 46 17h-1q-10 -9 -30.5 -6.5t-40.5 15.5q5 5 5.5 13.5t-5.5 15t-15 6.5h-5l-2 -1q-8 -2 -15 6q-10 19 -10.5 37t8.5 29q-20 -21 -19 -50.5t23 -53.5q12 -13 28 -20.5t33 -7.5z" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,6 @@
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''}>
<path d="M14 3a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h12zM2 2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H2z"/>
<path fill-rule="evenodd" d="M9.146 8.146a.5.5 0 0 1 .708 0L11.5 9.793l1.646-1.647a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 0-.708z"/>
<path fill-rule="evenodd" d="M11.5 5a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0v-4a.5.5 0 0 1 .5-.5z"/>
<path d="M3.56 11V7.01h.056l1.428 3.239h.774l1.42-3.24h.056V11h1.073V5.001h-1.2l-1.71 3.894h-.039l-1.71-3.894H2.5V11h1.06z"/>
</svg>

After

Width:  |  Height:  |  Size: 725 B

@ -0,0 +1,64 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
@component DeviceIcon
Display an icon for a device class provided by the `device` attribute.
Pass `config` for custom attributes.
-->
<script lang="ts">
import {
Icon,
Bolt,
Megaphone,
QuestionMarkCircle,
ExclamationCircle,
Key,
LockClosed,
GlobeAlt,
UserGroup,
PaperAirplane,
} from "svelte-heros-v2";
import DataClassIcon from "./DataClassIcon.svelte";
export let config = {};
export let img: string;
const mapping = {
stream: Bolt,
channel: Megaphone,
private: Key,
protected: LockClosed,
public: GlobeAlt,
group: UserGroup,
dialog: PaperAirplane,
unknown_doc: ExclamationCircle,
};
const find = (dataClass: string) => {
return mapping[dataClass] || QuestionMarkCircle;
};
</script>
{#if img.startsWith("blob:")}
<img style="aspect-ratio:1;" class="rounded-full" src={img} alt="profile"/>
{:else if img.startsWith("class:")}
<DataClassIcon {config} dataClass={img.slice(6)} />
{:else if img.startsWith("nav:")}
<Icon {...config} variation="outline" color="currentColor" icon={find(img.slice(4))} />
{:else}
<QuestionMarkCircle {...config}/>
{/if}

@ -0,0 +1,3 @@
<svg viewBox="-4 0 40 40" fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} xmlns="http://www.w3.org/2000/svg">
<path d="M25.6686 26.0962C25.1812 26.2401 24.4656 26.2563 23.6984 26.145C22.875 26.0256 22.0351 25.7739 21.2096 25.403C22.6817 25.1888 23.8237 25.2548 24.8005 25.6009C25.0319 25.6829 25.412 25.9021 25.6686 26.0962ZM17.4552 24.7459C17.3953 24.7622 17.3363 24.7776 17.2776 24.7939C16.8815 24.9017 16.4961 25.0069 16.1247 25.1005L15.6239 25.2275C14.6165 25.4824 13.5865 25.7428 12.5692 26.0529C12.9558 25.1206 13.315 24.178 13.6667 23.2564C13.9271 22.5742 14.193 21.8773 14.468 21.1894C14.6075 21.4198 14.7531 21.6503 14.9046 21.8814C15.5948 22.9326 16.4624 23.9045 17.4552 24.7459ZM14.8927 14.2326C14.958 15.383 14.7098 16.4897 14.3457 17.5514C13.8972 16.2386 13.6882 14.7889 14.2489 13.6185C14.3927 13.3185 14.5105 13.1581 14.5869 13.0744C14.7049 13.2566 14.8601 13.6642 14.8927 14.2326ZM9.63347 28.8054C9.38148 29.2562 9.12426 29.6782 8.86063 30.0767C8.22442 31.0355 7.18393 32.0621 6.64941 32.0621C6.59681 32.0621 6.53316 32.0536 6.44015 31.9554C6.38028 31.8926 6.37069 31.8476 6.37359 31.7862C6.39161 31.4337 6.85867 30.8059 7.53527 30.2238C8.14939 29.6957 8.84352 29.2262 9.63347 28.8054ZM27.3706 26.1461C27.2889 24.9719 25.3123 24.2186 25.2928 24.2116C24.5287 23.9407 23.6986 23.8091 22.7552 23.8091C21.7453 23.8091 20.6565 23.9552 19.2582 24.2819C18.014 23.3999 16.9392 22.2957 16.1362 21.0733C15.7816 20.5332 15.4628 19.9941 15.1849 19.4675C15.8633 17.8454 16.4742 16.1013 16.3632 14.1479C16.2737 12.5816 15.5674 11.5295 14.6069 11.5295C13.948 11.5295 13.3807 12.0175 12.9194 12.9813C12.0965 14.6987 12.3128 16.8962 13.562 19.5184C13.1121 20.5751 12.6941 21.6706 12.2895 22.7311C11.7861 24.0498 11.2674 25.4103 10.6828 26.7045C9.04334 27.3532 7.69648 28.1399 6.57402 29.1057C5.8387 29.7373 4.95223 30.7028 4.90163 31.7107C4.87693 32.1854 5.03969 32.6207 5.37044 32.9695C5.72183 33.3398 6.16329 33.5348 6.6487 33.5354C8.25189 33.5354 9.79489 31.3327 10.0876 30.8909C10.6767 30.0029 11.2281 29.0124 11.7684 27.8699C13.1292 27.3781 14.5794 27.011 15.985 26.6562L16.4884 26.5283C16.8668 26.4321 17.2601 26.3257 17.6635 26.2153C18.0904 26.0999 18.5296 25.9802 18.976 25.8665C20.4193 26.7844 21.9714 27.3831 23.4851 27.6028C24.7601 27.7883 25.8924 27.6807 26.6589 27.2811C27.3486 26.9219 27.3866 26.3676 27.3706 26.1461ZM30.4755 36.2428C30.4755 38.3932 28.5802 38.5258 28.1978 38.5301H3.74486C1.60224 38.5301 1.47322 36.6218 1.46913 36.2428L1.46884 3.75642C1.46884 1.6039 3.36763 1.4734 3.74457 1.46908H20.263L20.2718 1.4778V7.92396C20.2718 9.21763 21.0539 11.6669 24.0158 11.6669H30.4203L30.4753 11.7218L30.4755 36.2428ZM28.9572 10.1976H24.0169C21.8749 10.1976 21.7453 8.29969 21.7424 7.92417V2.95307L28.9572 10.1976ZM31.9447 36.2428V11.1157L21.7424 0.871022V0.823357H21.6936L20.8742 0H3.74491C2.44954 0 0 0.785336 0 3.75711V36.2435C0 37.5427 0.782956 40 3.74491 40H28.2001C29.4952 39.9997 31.9447 39.2143 31.9447 36.2428Z" />
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

@ -0,0 +1,9 @@
<svg fill="none" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} viewBox="-10 255 1034 734" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor"
d="M704 227q-40 0 -74.5 20.5t-53.5 56.5q-23 43 -15 92l-2 -2v6q-1 9 -7 19q-7 15 -23 30q-20 19 -50.5 38t-57.5 28q-22 7 -40 7q-14 0 -24 -4l-8 -3l3 3l-8 -4q-35 -19 -73.5 -17.5t-72 22t-52 55.5t-17 74t22 72t55.5 52q40 21 83.5 16.5t76.5 -31.5l-1 2l7 -4
q9 -3 21 -3q17 -1 39 5q27 8 59 25q48 26 70 56q15 19 16 37q-1 42 19.5 78.5t58.5 56.5q35 18 73.5 16.5t72 -22t52 -55.5t17 -74t-22 -72t-55.5 -51q-7 -4 -15 -7l3 -1l-5 -4q-6 -5 -11 -16q-8 -15 -12 -36q-6 -27 -7 -63t3 -63q4 -22 11 -37q5 -11 12 -18l5 -4h-5
q41 -21 62 -62q19 -35 17.5 -73.5t-22 -71.5t-55.5 -52q-33 -18 -70 -17zM706 250q39 0 66 25v0q-15 -13 -44.5 -10t-58.5 22q8 8 8.5 20t-8 21.5t-21.5 9.5h-8l-2 -1q-12 -4 -21 8q-16 29 -16 56.5t15 42.5q-20 -19 -27 -46.5t0.5 -56t28.5 -51.5q18 -19 41 -29.5t47 -10.5
zM605 491q11 0 18 3.5t14 7.5q13 7 27 11q11 11 20 33q11 33 12.5 84t-10.5 84q-9 22 -22 34q-20 9 -36 23q-14 5 -36 1q-34 -6 -81 -31q-49 -26 -73 -54q-14 -17 -17 -32q2 -18 -1 -37v1l1 -6q1 -8 7 -18q8 -13 24 -28q20 -18 50 -37q62 -38 103 -39zM279 525q39 0 66 25
h-1q-14 -13 -44 -10t-58 22q7 8 7.5 20t-8 21.5t-20.5 9.5q-4 1 -8 0l-2 -1q-13 -4 -22 8q-15 29 -15.5 56.5t14.5 42.5q-20 -19 -26.5 -46.5t1 -56t28.5 -51.5q18 -19 41 -29.5t47 -10.5zM731 758q39 0 66 25v0q-14 -13 -44 -10t-59 22q8 8 8.5 20t-8 21.5t-21.5 9.5
q-4 0 -8 -1h-2q-12 -4 -21 8q-16 29 -16 56.5t15 42.5q-20 -19 -27 -46.5t0.5 -56t28.5 -51.5q18 -19 41 -29.5t47 -10.5z" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -0,0 +1,3 @@
<svg fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} viewBox="0 -1.5 27 27" xmlns="http://www.w3.org/2000/svg">
<path d="m15.902 11.974c0 1.331-1.079 2.41-2.41 2.41s-2.41-1.079-2.41-2.41 1.079-2.41 2.41-2.41 2.41 1.079 2.41 2.41z"/><path d="m13.491 17.494c-.201.005-.438.008-.676.008-2.811 0-5.522-.425-8.073-1.214l.193.051c-1.351-.436-2.522-1.079-3.541-1.903l.021.016c-.789-.571-1.32-1.455-1.41-2.467l-.001-.013c0-1.594 1.747-3.154 4.681-4.172 2.512-.827 5.403-1.304 8.405-1.304.139 0 .278.001.417.003h-.021c.116-.002.252-.003.389-.003 2.965 0 5.82.469 8.496 1.337l-.195-.055c1.305.424 2.438 1.036 3.433 1.814l-.024-.018c.775.546 1.298 1.404 1.386 2.387l.001.013c0 1.656-1.954 3.332-5.103 4.374-2.363.729-5.08 1.149-7.895 1.149-.17 0-.339-.002-.508-.005h.025zm0-9.84c-.106-.002-.232-.002-.358-.002-2.881 0-5.656.452-8.259 1.289l.191-.053c-2.698.941-3.908 2.228-3.908 3.087 0 .893 1.301 2.3 4.153 3.274 2.249.697 4.834 1.099 7.513 1.099.235 0 .469-.003.702-.009l-.034.001c.146.003.318.005.49.005 2.684 0 5.274-.4 7.715-1.143l-.187.049c2.96-.984 4.32-2.391 4.32-3.28-.102-.638-.462-1.176-.966-1.515l-.008-.005c-.866-.674-1.876-1.217-2.97-1.574l-.07-.02c-2.368-.766-5.093-1.208-7.92-1.208-.142 0-.283.001-.424.003h.021z"/><path d="m8.023 23.986c-.016 0-.035.001-.053.001-.453 0-.878-.119-1.245-.327l.013.007c-1.378-.8-1.858-3.092-1.28-6.141.697-3.128 1.827-5.894 3.344-8.4l-.069.124c1.499-2.655 3.31-4.926 5.425-6.872l.02-.018c.923-.844 2.003-1.537 3.187-2.028l.073-.027c.407-.196.885-.31 1.39-.31.501 0 .976.113 1.4.314l-.02-.008c1.435.826 1.911 3.36 1.238 6.606-.72 2.967-1.818 5.58-3.262 7.959l.07-.123c-1.452 2.63-3.209 4.882-5.266 6.819l-.014.013c-.958.877-2.083 1.59-3.321 2.082l-.074.026c-.46.181-.992.292-1.549.305h-.006zm1.205-14.447.499.288c-1.381 2.28-2.465 4.926-3.106 7.74l-.034.18c-.533 2.809-.019 4.498.72 4.926.191.102.417.161.657.161.02 0 .041 0 .061-.001h-.003c.955 0 2.458-.605 4.196-2.122 1.976-1.867 3.654-4.023 4.972-6.404l.068-.135c1.318-2.156 2.371-4.653 3.025-7.307l.038-.182c.629-3.058.086-4.93-.686-5.378-.238-.094-.514-.148-.802-.148-.364 0-.708.087-1.012.24l.013-.006c-1.118.465-2.078 1.086-2.907 1.846l.007-.006c-2.041 1.881-3.772 4.057-5.136 6.468l-.069.132z"/><path d="m18.96 24c-1.306 0-2.96-.787-4.69-2.276-2.175-1.983-4.017-4.282-5.464-6.834l-.072-.137c-1.43-2.349-2.551-5.075-3.215-7.975l-.036-.185c-.162-.709-.255-1.522-.255-2.357 0-.527.037-1.044.108-1.551l-.007.058c.085-.998.608-1.858 1.372-2.399l.01-.007c1.43-.83 3.865.024 6.342 2.228 2.022 1.914 3.748 4.113 5.118 6.54l.072.138c1.428 2.297 2.557 4.961 3.242 7.798l.038.186c.163.709.257 1.524.257 2.36 0 .577-.044 1.143-.13 1.696l.008-.062c-.103 1.022-.644 1.901-1.429 2.456l-.011.007c-.348.199-.764.316-1.207.316-.018 0-.036 0-.054-.001h.003zm-9.228-9.823c1.458 2.571 3.217 4.771 5.271 6.656l.02.018c2.166 1.863 3.884 2.266 4.628 1.834.773-.446 1.339-2.276.754-5.233-.702-2.89-1.787-5.434-3.219-7.741l.065.112c-1.379-2.456-3.027-4.562-4.948-6.384l-.012-.011c-2.334-2.074-4.225-2.54-4.998-2.094-.473.385-.784.952-.825 1.593v.007c-.055.39-.086.84-.086 1.298 0 .757.086 1.493.248 2.201l-.013-.066c.673 2.952 1.747 5.559 3.182 7.924l-.066-.117z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -0,0 +1,3 @@
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''}>
<path d="M8 .1c.422 0 .765.342.765.765v.916c.296.035.587.091.87.166l.283-.683a.764.764 0 111.413.585l-.276.665c.287.157.56.335.817.533l.633-.633a.765.765 0 011.081 1.081l-.62.62c.24.298.453.618.637.956l.631-.261a.765.765 0 11.585 1.413l-.654.27c.072.277.126.56.16.849h.81a.765.765 0 010 1.529h-.81a6.334 6.334 0 01-.21 1.027l.664.275a.765.765 0 11-.585 1.413l-.672-.278c-.13.24-.278.471-.44.693l.504.504a.765.765 0 01-1.081 1.081l-.465-.465c-.3.253-.627.48-.978.677l.269.65a.765.765 0 11-1.413.586l-.27-.65a6.332 6.332 0 01-.883.181v.57a.765.765 0 01-1.53 0v-.555a6.386 6.386 0 01-1.087-.218l-.278.672a.765.765 0 11-1.413-.585l.285-.688a6.38 6.38 0 01-.84-.581l-.407.406a.765.765 0 01-1.081-1.081l.428-.428a6.348 6.348 0 01-.459-.703l-.748.31a.765.765 0 01-.585-1.413l.748-.31a6.339 6.339 0 01-.205-1.09H.865a.765.765 0 010-1.53h.762c.044-.298.108-.593.192-.88l-.81-.336a.765.765 0 01.585-1.413l.815.337c.181-.33.39-.643.625-.934l-.62-.62a.765.765 0 011.081-1.081l.633.633c.205-.158.42-.303.645-.435l-.316-.763a.765.765 0 011.413-.585L6.175 2a6.34 6.34 0 011.06-.22V.865C7.235.442 7.578.1 8 .1zm-.765 3.354a4.854 4.854 0 00-3.487 2.36l.61.199a.765.765 0 11-.472 1.454l-.653-.212a4.823 4.823 0 001.294 4.225l.458-.63a.764.764 0 011.237.898l-.47.648A4.818 4.818 0 008 12.948c.812 0 1.577-.2 2.249-.552l-.352-.484a.765.765 0 011.237-.899l.34.467c.349-.36.642-.773.867-1.227a4.843 4.843 0 00.34-2.97l-.567.184a.764.764 0 11-.472-1.454l.5-.163a4.827 4.827 0 00-3.377-2.374v.447a.765.765 0 11-1.53 0v-.469z" fill="currentColor" fill-opacity="0.80"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,3 @@
<svg viewBox="0 0 15 15" fill="none" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.2829 1.94409C14.2083 3.42511 14.046 5.27647 13.0128 6.56576C13.8628 8.37306 13.2462 10.5713 11.5104 11.656L7.27012 14.3056C5.39667 15.4763 2.92892 14.9066 1.75825 13.0331C0.832798 11.5521 0.99519 9.70071 2.02833 8.41145C1.17829 6.60415 1.79488 4.40587 3.53076 3.32117L7.771 0.671576C9.64446 -0.499089 12.1122 0.070635 13.2829 1.94409ZM8.30092 1.51962C9.70601 0.641625 11.5568 1.06892 12.4348 2.47401C13.0645 3.48168 13.023 4.71945 12.4301 5.66263C11.8046 4.92992 10.9523 4.46839 10.0447 4.31762L10.7691 3.86494L10.2392 3.0169L5.15088 6.19641L5.6808 7.04446L7.80091 5.71967C9.206 4.84167 11.0568 5.26899 11.9348 6.67408C12.8128 8.07918 12.3855 9.92999 10.9804 10.808L6.7402 13.4576C5.33511 14.3356 3.4843 13.9083 2.6063 12.5032C1.97665 11.4955 2.01814 10.2578 2.61103 9.31458C3.23653 10.0473 4.08885 10.5088 4.99651 10.6596L4.27222 11.1122L4.80214 11.9602L9.89043 8.78071L9.36051 7.93267L7.24023 9.25756C5.83514 10.1356 3.98429 9.70821 3.10629 8.30312C2.2283 6.89803 2.65559 5.04722 4.06068 4.16922L8.30092 1.51962Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,3 @@
<svg viewBox="0 0 16 16" fill="none" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} xmlns="http://www.w3.org/2000/svg">
<path fill-rule="nonzero" clip-rule="nonzero" d="M0 1.75C0 0.783501 0.783502 0 1.75 0H14.25C15.2165 0 16 0.783502 16 1.75V3.75C16 4.16421 15.6642 4.5 15.25 4.5C14.8358 4.5 14.5 4.16421 14.5 3.75V1.75C14.5 1.61193 14.3881 1.5 14.25 1.5H1.75C1.61193 1.5 1.5 1.61193 1.5 1.75V14.25C1.5 14.3881 1.61193 14.5 1.75 14.5H15.25C15.6642 14.5 16 14.8358 16 15.25C16 15.6642 15.6642 16 15.25 16H1.75C0.783501 16 0 15.2165 0 14.25V1.75ZM4.75 6.5C4.75 6.08579 5.08579 5.75 5.5 5.75H9.25C9.66421 5.75 10 6.08579 10 6.5C10 6.91421 9.66421 7.25 9.25 7.25H8.25V12.5C8.25 12.9142 7.91421 13.25 7.5 13.25C7.08579 13.25 6.75 12.9142 6.75 12.5V7.25H5.5C5.08579 7.25 4.75 6.91421 4.75 6.5ZM11.2757 6.58011C11.6944 6.08164 12.3507 5.75 13.25 5.75C14.0849 5.75 14.7148 6.03567 15.1394 6.48481C15.4239 6.78583 15.4105 7.26052 15.1095 7.54505C14.8085 7.82958 14.3338 7.81621 14.0493 7.51519C13.9394 7.39898 13.7204 7.25 13.25 7.25C12.7493 7.25 12.5306 7.41836 12.4243 7.54489C12.2934 7.70065 12.25 7.896 12.25 8C12.25 8.104 12.2934 8.29935 12.4243 8.45511C12.5306 8.58164 12.7493 8.75 13.25 8.75C13.3257 8.75 13.3988 8.76121 13.4676 8.78207C14.1307 8.87646 14.6319 9.17251 14.9743 9.58011C15.3684 10.0493 15.5 10.604 15.5 11C15.5 11.396 15.3684 11.9507 14.9743 12.4199C14.5556 12.9184 13.8993 13.25 13 13.25C12.1651 13.25 11.5352 12.9643 11.1106 12.5152C10.8261 12.2142 10.8395 11.7395 11.1405 11.4549C11.4415 11.1704 11.9162 11.1838 12.2007 11.4848C12.3106 11.601 12.5296 11.75 13 11.75C13.5007 11.75 13.7194 11.5816 13.8257 11.4551C13.9566 11.2993 14 11.104 14 11C14 10.896 13.9566 10.7007 13.8257 10.5449C13.7194 10.4184 13.5007 10.25 13 10.25C12.9243 10.25 12.8512 10.2388 12.7824 10.2179C12.1193 10.1235 11.6181 9.82749 11.2757 9.41989C10.8816 8.95065 10.75 8.396 10.75 8C10.75 7.604 10.8816 7.04935 11.2757 6.58011Z" fill="currentColor" fill-opacity="0.80"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1,35 @@
<svg fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} viewBox="0 0 493.249 493.249" xmlns="http://www.w3.org/2000/svg">
<path d="M463.007,168.49c0-28.703-33.46-51.188-76.174-51.188c-18.346,0-35.576,4.216-49.249,11.953
c-13.401-9.919-28.469-17.705-44.7-22.856c6.058-13.7,9.44-29.27,9.44-44.106C302.323,19.261,274.349,0,246.625,0
s-55.699,19.261-55.699,62.292c0,14.836,3.383,30.406,9.44,44.106c-16.231,5.152-31.299,12.938-44.7,22.857
c-13.674-7.737-30.904-11.954-49.249-11.954c-42.715,0-76.175,22.484-76.175,51.188c0,13.253,10.782,22.164,32.047,26.485
c12.216,2.482,27.183,3.384,40.87,3.714c-6.298,16.744-9.754,34.868-9.754,53.787c0,24.754,5.938,52.82,16.436,80.015
c-8.104,2.426-16.193,5.903-23.818,10.306c-17.027,9.83-30.687,23.381-38.463,38.157c-8.446,16.049-9.126,31.767-1.913,44.26
c2.842,4.922,7.37,8.331,13.094,9.856c2.395,0.638,4.977,0.941,7.73,0.941c19.806,0,48.526-15.642,80.912-34.457
c0.346-0.201,0.679-0.394,1.021-0.593c26.628,33.774,57.808,53.408,89.722,56.382v27.408c0,4.694,3.806,8.5,8.5,8.5
c4.694,0,8.5-3.806,8.5-8.5v-27.408c31.914-2.974,63.094-22.607,89.721-56.382c0.343,0.199,0.677,0.393,1.023,0.594
c32.387,18.815,61.104,34.456,80.91,34.456c2.752,0,5.336-0.302,7.73-0.94c5.724-1.525,10.252-4.934,13.094-9.856
c14.351-24.858-3.385-61.06-40.376-82.416c-7.626-4.403-15.715-7.88-23.818-10.307c10.497-27.194,16.435-55.26,16.435-80.015
c0-18.919-3.456-37.042-9.754-53.787c13.688-0.331,28.653-1.232,40.87-3.714C452.225,190.654,463.007,181.743,463.007,168.49z
M382.844,252.476c0,3.003-0.11,6.077-0.306,9.2h-63.661l-29.605-51.278l53.91-53.91
C367.681,181.13,382.844,215.064,382.844,252.476z M341.784,376.22l-50.758-50.758l27.012-46.786h62.58
C375.449,310.854,361.534,346.538,341.784,376.22z M112.518,277.981h62.293l27.413,47.479l-50.759,50.759
C131.574,346.325,117.597,310.34,112.518,277.981z M110.405,252.476c0-36.355,14.316-69.428,37.606-93.881l54.442,54.442
l-27.681,47.944h-64.103C110.501,258.098,110.405,255.256,110.405,252.476z M246.625,116.256c31.587,0,60.696,10.81,83.827,28.92
l-57.812,57.813h-56.193l-55.958-55.959C183.976,127.807,213.976,116.256,246.625,116.256z M218.07,318.907l-28.556-49.459
l28.556-49.459h57.11l28.555,49.459l-28.555,49.459H218.07z M207.926,62.292c0-27.938,14.829-45.292,38.699-45.292
s38.698,17.355,38.698,45.292c0,13.275-3.384,27.74-9.191,39.826c-9.552-1.871-19.415-2.862-29.507-2.862
c-10.092,0-19.955,0.991-29.507,2.862C211.31,90.031,207.926,75.567,207.926,62.292z M65.674,178.315
c-11.542-2.345-18.432-6.018-18.432-9.825c0-18.532,27.099-34.188,59.175-34.188c12.666,0,24.903,2.444,35.035,6.858
c-12.375,11.699-22.804,25.432-30.752,40.66C96.007,181.647,78.785,180.979,65.674,178.315z M66.876,419.08
c-1.383,0-2.644-0.141-3.758-0.438c-1.699-0.453-2.325-1.195-2.749-1.929c-4.19-7.256-3.397-17.145,2.234-27.842
c6.301-11.972,17.636-23.105,31.92-31.352c7.061-4.077,14.547-7.218,21.969-9.265c5.949,12.995,12.908,25.592,20.732,37.305
c0.361,0.541,0.729,1.065,1.092,1.6C117.117,399.474,83.236,419.082,66.876,419.08z M246.625,440.753
c-32.18,0-61.76-20.875-85.077-50.575l54.271-54.271h61.611l54.272,54.271C308.385,419.878,278.805,440.753,246.625,440.753z
M398.727,357.519c27.779,16.038,43.419,43.145,34.154,59.194c-0.424,0.734-1.051,1.477-2.749,1.929
c-14.29,3.806-52.207-18.127-75.199-31.483c0.363-0.536,0.731-1.059,1.092-1.6c7.824-11.712,14.783-24.31,20.732-37.305
C384.179,350.3,391.666,353.442,398.727,357.519z M382.549,181.82c-7.948-15.228-18.376-28.962-30.752-40.66
c10.132-4.414,22.37-6.858,35.036-6.858c32.076,0,59.174,15.656,59.174,34.188c0,3.808-6.89,7.48-18.432,9.825
C414.464,180.979,397.242,181.647,382.549,181.82z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

@ -0,0 +1,5 @@
<svg fill="currentColor" width="24" height="24" tabindex="-1" class={$$props.class || ''} style={$$props.style || ''} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<polygon points="21 11 24 11 24 23 26 23 26 11 29 11 29 9 21 9 21 11"/>
<polygon points="20 9 18 9 16 15 14 9 12 9 14.75 16 12 23 14 23 16 17 18 23 20 23 17.25 16 20 9"/>
<polygon points="3 11 6 11 6 23 8 23 8 11 11 11 11 9 3 9 3 11"/>
</svg>

After

Width:  |  Height:  |  Size: 429 B

@ -0,0 +1,130 @@
<!--
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
import {
Icon,
BugAnt,
DocumentText,
Window,
CodeBracket,
SquaresPlus,
ViewfinderCircle,
ArrowsPointingOut,
Cube,
Briefcase,
MagnifyingGlass,
RocketLaunch,
Sun,
TableCells,
ListBullet,
RectangleGroup,
Squares2x2,
MapPin,
CircleStack,
Envelope,
GlobeAlt,
DocumentChartBar,
Document,
ClipboardDocumentList,
Photo,
Film,
RectangleStack,
Microphone,
MusicalNote,
Ticket,
CursorArrowRays,
Megaphone,
User,
Clock,
CalendarDays,
Calendar,
Stop,
Flag,
HandRaised,
Newspaper,
PencilSquare,
CubeTransparent,
PresentationChartBar,
QuestionMarkCircle,
CheckCircle,
ChartPie,
Bars3BottomLeft,
Link,
Square2Stack,
Clipboard,
StopCircle,
Share,
Play,
DocumentArrowDown,
DocumentArrowUp,
CloudArrowUp,
CloudArrowDown,
Beaker,
Eye,
Square3Stack3d,
QueueList,
} from "svelte-heros-v2";
import JsonIcon from "./JsonIcon.svelte";
import JsonLdIcon from "./JsonLdIcon.svelte";
import RdfIcon from "./RdfIcon.svelte";
import TurtleIcon from "./TurtleIcon.svelte";
import GraphQLIcon from "./GraphQLIcon.svelte";
export let config = {};
export let zera: string;
const exact_mapping = {
json_ld_editor: JsonLdIcon,
json_editor: JsonIcon,
triple_editor: RdfIcon,
turtle_viewer: TurtleIcon,
rdf_viewer: CircleStack,
graph_viewer: Sun,
compose: QueueList,
sparql_query: RocketLaunch,
sparnatural: CursorArrowRays,
graphql: GraphQLIcon,
invoke: Play,
ontology_viewer: ArrowsPointingOut,
download: DocumentArrowDown,
edit: PencilSquare,
file: Document,
source: CodeBracket,
post: DocumentText,
pad: Square2Stack,
container: Square3Stack3d,
card: Clipboard,
gallery: RectangleStack,
load_graph: CloudArrowUp,
load: DocumentArrowUp,
dump: CloudArrowDown,
ext: GlobeAlt,
app_store: SquaresPlus,
app_editor: Beaker,
list: ListBullet,
grid: Squares2x2,
view: Eye,
};
const prefix_mapping = {};
const find = (t) => {
let e = exact_mapping[t];
if (e) return e;
for (let prefix of Object.entries(prefix_mapping)) {
if (t.startsWith(prefix[0])) return prefix[1];
}
return BugAnt;
};
</script>
<Icon {...config} variation="outline" color="currentColor" icon={find(zera)} />

@ -0,0 +1,2 @@
export { default as NoWallet} from "./NoWallet.svelte";
export { default as CenteredLayout} from "./CenteredLayout.svelte";

@ -0,0 +1,956 @@
{
"app": {
"sparql_update_editor" : {
"success": "SPARQL Update successful!"
}
},
"doc": {
"doc": "Document",
"protected_store": "Protected Profile",
"public_store": "Public Site",
"private_store": "Private Store",
"group_store": "Group Store",
"dialog_store": "Dialog Store",
"rich": "Post or Article",
"markdown": "Markdown",
"text": "Plain Text",
"social": "Social",
"group": "Group",
"pro": "Pro",
"media": "Media",
"chart": "Chart",
"viz": "Visualization",
"diagram": "Diagram",
"other": "Other formats",
"data": "Data",
"code": "Code",
"apps": "Apps",
"new_app": "Create a new App",
"record_reel": "Record Reel",
"record_voice": "Record Audio",
"take_picture": "Take a picture",
"select_class": "Select a type of document to create",
"destination": {
"mc": "Keep in Magic Carpet",
"stream": "Send in current Stream",
"dialog": "Send in Dialog",
"store": "Save in current Store"
},
"sparql_query": "SPARQL Query",
"run_query": "Run Query",
"run_update": "Run Update",
"query_all_docs": "Query all docs",
"view_as_turtle": "View as Turtle",
"view_graph": "View Graph",
"results": "Results",
"empty": "Empty",
"type_your_text_here": "Type your text here",
"sparql_update": "SPARQL Update",
"no_triples": "No triples in this Graph.",
"start_editing": "Start editing",
"create": "Create a Document",
"creating": "Please wait while your Document is being created",
"not_found" : "Document not found",
"empty_container": "Container is empty.",
"sign_snapshot": "Create a signed Snapshot",
"sign_heads": "Sign current heads",
"take_snapshot": "and take a Snapshot",
"signed_snapshot_is_on_its_way": "Your request for a signed snapshot has been sent to all signers. You will be notified when it is ready",
"signature_is_on_its_way": "Your request for a signature has been sent to all signers. You will be notified when it is ready",
"signature_is_ready": "Your signature is ready.",
"not_found_details_online" : "The document could not be found locally on this device, nor on the broker.",
"not_found_details_offline" : "The document could not be found locally on this device, and it seems like you are offline, so it could not be retrieved from any broker neither.<br/><br/>If you are opening this document for the first time on this device, you have to be online now so the document can be fetched.<br/><br/> We will try connecting and fetching it every 5 seconds.",
"cannot_load_offline": "You are offline and using the web app. There is currently a limitation on local storage within the Web App, and you need to connect to the broker every time you login with the Web App.<br/><br/>For now, the Web App does not keep a local copy of your documents. due to the limit of 5MB in localStorage. We will remove this limitation soon. Stay tuned!<br/><br/>Check your connectivity status in the ",
"header": {
"buttons": {
"edit": "Edit",
"edit_intro": "Edit title & intro",
"edit_profile": "Edit profile",
"bookmarked": "Saved",
"all_docs": "All Docs",
"groups": "Groups",
"channels": "Channels",
"inbox": "Inbox",
"chat": "Chat",
"save": "Save"
},
"doc":{
"title": "Title",
"about": "Introduction"
},
"profile": {
"title": "Name",
"about": "Bio"
}
},
"signature": {
"title": "Signature",
"current_heads": "Current heads",
"or_click_on_head": "or click on one of the signed heads to get its link.",
"here_is_the_link": "Here is its link that you can share.",
"cli_warning": "For now the link is only usable with the CLI, by running the following command",
"signed_snap_at_head": "A signed snapshot is currently at the head."
},
"file": {
"download": "Download",
"upload_progress": "Uploading...",
"upload": "Upload file"
},
"errors": {
"InvalidNuri": "Invalid NURI",
"no_session": "No active session"
},
"errors_details": {
"InvalidNuri": "The provided NextGraph URI is invalid",
"no_session": "Please refresh the page or close and reopen the app"
},
"graph" : "Graph",
"discrete" : "Document",
"menu" : {
"edit_with": "Edit with",
"view_as": "View as",
"install_app_to_edit": "Install App to edit",
"live_editing": "Live editing (real-time)",
"live_editing_description": "Collaborate in real-time with other users. If deactivated, you will have to save manually your edits",
"items": {
"new_block": {
"label": "New Block",
"desc": "Create a new block that can be embedded/included in this doc or other docs"
},
"editor_chat": {
"label": "Editors' Chat",
"desc": "Chat with other Editors about the Document you are editing"
},
"folders": {
"label": "Folders",
"desc": "Organize your documents in folders and platos"
},
"toc": {
"label": "Table of Content",
"desc": "Table of Content for Graph and Document"
},
"files": {
"label": "Attachments and Files",
"desc": "List all attached files and resources files, and download them if needed"
},
"share": {
"label": "Share",
"desc": "Share with others, or react"
},
"comments": {
"label": "Comments",
"desc": "See comments or annotations, replies, and write your own."
},
"branches": {
"label": "Branches",
"desc": "View, edit or fork branches and blocks"
},
"history": {
"label": "History",
"desc": "Open history of modifications, and travel back in time, to previous revisions"
},
"find": {
"label": "Find",
"desc": "Information about the document, statistics, and keywords"
},
"bookmark": {
"label": "Save",
"desc": "Keep a bookmark of this Document in your private store."
},
"annotate": {
"label": "Annotate",
"desc": "Write private annotations on this Document. Only you can see those annotations. You will also have an option to share them with others."
},
"info": {
"label": "Information",
"desc": "Information about the document, statistics, and keywords"
},
"repost": {
"label": "Post in my Stream",
"desc": "Post in your Stream (publish, repost, reply, boost)"
},
"dm": {
"label": "Send in Direct Message",
"desc": "Send as Direct Message to a contact or in a group chat"
},
"react": {
"label": "Like and React",
"desc": "Like, react, rate"
},
"author": {
"label": "Reply to Author(s)",
"desc": "Sends a private message to the author(s) in reply to this Document"
},
"quote": {
"label": "Quote/Mention in new Post",
"desc": "Write a Post that quotes/cites this Document"
},
"forward": {
"label": "Share via other apps",
"desc": "Share this document to users with other platforms and apps"
},
"link": {
"label": "Links",
"desc": "Get the links to access this Document on the web"
},
"qr": {
"label": "QR-Code",
"desc": "Display or download a QR-Code that links to this Document"
},
"download": {
"label": "Export and Download",
"desc": "Export to several formats and Download the file, or create a self-contained HTML file of this Document that works offline"
},
"notifs": {
"label": "Notifications",
"desc": "Change your notification settings for this Document"
},
"permissions": {
"label": "Permissions",
"desc": "See and change permissions and members for this Document"
},
"settings": {
"label": "Settings",
"desc": "Change settings for this Document"
},
"copy": {
"label": "Copy or Move",
"desc": "Copy, Move, Duplicate, Fork"
},
"embed": {
"label": "Embed",
"desc": "Embed this Document or Block into another Document, or insert a Block into this Document"
},
"schema": {
"label": "Schema",
"desc": "See and manage the Schema of this Document (Model, Ontology, Vocabulary)"
},
"signature": {
"label": "Signature",
"desc": "Obtain and verify the Signature of the Document to prove its authenticity. Or request a signature if there isn't any."
},
"translations": {
"label": "Translations",
"desc": "Manage the translations of your document in order to offer it in multiple languages"
},
"services": {
"label": "Services",
"desc": "See and invoke services available for this Document. Services can be read-only, or read-write"
},
"print": {
"label": "Print",
"desc": "Print or save to PDF"
},
"console": {
"label": "Console",
"desc": "Open a console and run interactive commands"
},
"source": {
"label": "Source",
"desc": "View and Download the source code of this Document"
},
"dev": {
"label": "Developer",
"desc": "Open the developer toolbox"
},
"tools": {
"label": "Tools",
"desc": "Select a tool"
},
"mc": {
"label": "Magic Carpet",
"desc": "Opens the Magic Carpet (like a clipboard, but better)"
},
"archive": {
"label": "Archive",
"desc": "Archive documents that you don't need anymore"
}
}
}
},
"pages": {
"not_found": {
"title": "Page Not Found",
"message": "The page you are looking for does not exist.<br/>It has probably not been implemented yet"
},
"user_panel": {
"title": "User Panel",
"personal": "Personal"
},
"user_registered": {
"success": "You have been successfully registered.",
"success_with_invitation": "You have been successfully registered to {invitation_name}."
},
"wallet_info": {
"title": "Wallet",
"download": "Download Wallet File",
"download_failed": "Download Failed:<br/>{error}",
"download_in_progress": "Download in progress...",
"download_successful": "You will find the file named \"{wallet_file}\" in your Downloads folder",
"download_file_button": "Click here to download the wallet file",
"remove_wallet": "Remove wallet from Device",
"remove_wallet_modal.title": "Remove wallet?",
"remove_wallet_modal.confirm": "Are you sure you want to remove this wallet from your device?",
"create_text_code": "Export by generating a TextCode",
"scan_qr.title": "Export by scanning a QR-Code",
"scan_qr.no_camera": "If to the contrary, the other device does not have a camera, ",
"scan_qr.other_has_camera": "If the other device where you want to import the Wallet, has a camera, then you can just click on the Back button and select <span class=\"path\">Export by generating a QR-Code</span>",
"scan_qr.notes": "You will now scan the QR-Code that appears on the screen of the other device (the one you want to transfer your wallet to). You will be asked to allow the app to use your camera.",
"scan_qr.scanner.title": "Scan your QR-Code",
"scan_qr.scanner.loading": "Loading scanner",
"scan_qr.syncing": "Synchronizing wallet",
"scan_qr.scan_successful": "Success!<br />Your wallet has been transferred to the other device.",
"gen_qr.title": "Export by generating a QR-Code",
"gen_qr.notes": "In order to transfer your wallet to another device, you will now display a QR-Code here on this device, and you will then scan it with the other device where you want to transfer your wallet to.",
"gen_qr.no_camera": "If the device where you want to import the Wallet, does not have a camera, then you will have to choose another method.",
"gen_qr.img_title": "Your Export QR-Code to Scan",
"gen_qr.img_alt": "Your Export QR-Code to Scan",
"gen_qr.gen_button": "Display QR-Code",
"gen_text_code.title": "Export with TextCode",
"gen_text_code.gen_btn": "Generate TextCode",
"gen_text_code.label": "Your TextCode:"
},
"settings": {
"title": "Settings"
},
"admin": {
"title": "Admin"
},
"accounts": {
"title": "Accounts"
},
"full_layout": {
"home": "Home",
"stream": "Stream",
"search": "Search",
"create": "Create",
"shared": "Shared",
"site": "Site",
"messages": "Messages",
"notifications": "Notifications"
},
"install": {
"app_availability": "<b>NextGraph App</b> is available for download as a native app for your mobile, tablet, laptop and desktop.<br /> The app supports iOS, Android, Linux, macOS, Windows, or any other platform with a modern browser.",
"has_wallet_warning": "A wallet is saved in this browser. <br />If it is yours, once the installation of the app will be finished,<br /> choose the option \"Login\" on the app.<br /> (do not create another wallet from the app).",
"android_play_store": "Android Play Store",
"download_apk": "Download APK",
"ios_app_store": "iOS App Store",
"download_mac_os": "Download for MacOS",
"download_linux": "Download Linux Package",
"download_windows": "Download for Windows",
"other_platforms": "Other platforms"
},
"no_wallet": {
"welcome": "Welcome to NextGraph",
"description": "We could not find a wallet on this device.",
"instructions_login": "If you already have a wallet, select \"Login\"",
"instructions_create": ", otherwise, select \"Create Wallet\" here below.",
"instructions_nocreate": ". Creation of a Wallet is not possible while<br/> logging-in to a third-party app.",
"create_wallet": "Create Wallet"
},
"login": {
"heading": "How to open your wallet? You have 2 options:",
"with_pazzle": "With your Pazzle",
"pazzle_steps": {
"1": "For each one of the 9 categories of images, you will be presented with the 15 possible image choices. The categories are shuffled at every login. They will not always appear in the same order.",
"2": "At each category, only one of the 15 displayed choices is the correct image that belongs to your pazzle. Find it and tap or click on that one. The 15 images are shuffled too, they will not appear at the same position at each login. On a computer, you can also use the tab key on your keyboard to move to the desired item on the screen, then press the space bar to select each one.",
"3": "Once you completed the last category, you will be presented with all the images you have previously selected. Their order is displayed as it was when you picked them. But this is not the correct order of the images in your pazzle. You now have to order them correctly.",
"4": "You must remember which image should be the first one in your pazzle. Find it on the screen and click or tap on it. It will be greyed out and the number 1 will appear on top of it.",
"5": "Move on to the second image of your pazzle (that you memorized). Find it on the screen and tap on it. Repeat this step until you reached the last image.",
"6": "Finally, you are asked for your PIN code. Enter it by clicking or tapping on the digits."
},
"with_mnemonic": "With your 12 words Mnemonic (passphrase)",
"mnemonic_steps": {
"1": "Enter your twelve words mnemonic in the input field. The words must be separated by spaces.",
"2": "Enter the PIN code that you chose when you created your wallet."
},
"trust_device_allow_cookies": "By selecting this option, you agree to saving some cookies on your browser.",
"trust_device_yes": "Yes, save my wallet on this device",
"device_name_label": "Name of this device. You can edit it now",
"device_name_placeholder": "Enter name of this device",
"loading_pazzle": "Loading Pazzle",
"open_with_pazzle": "Open With Pazzle instead",
"login_cancel": "Cancel Login",
"open_with_mnemonic": "Open with Mnemonic",
"open": "Open my wallet",
"enter_mnemonic": "Enter your 12 words mnemonic",
"mnemonic_placeholder": "12 words separated by spaces",
"enter_password": "Enter your password",
"select_emoji": "Select your image for category:<br />{category}",
"order_emojis": "Select each image in the correct order",
"enter_pin": "Enter your PIN code",
"opening_wallet": "Opening your wallet...<br /> Please wait",
"wallet_opened": "Your wallet is opened! <br />Please wait while the app is loading...",
"redirecting": "Redirecting to",
"qr_code": "Wallet QRCode",
"qr_modal_title": "My Wallet QRCode",
"qr_modal_description": "Use this QRCode to log in with your wallet on new devices.",
"keep_wallet": "Save to Device for Future Logins"
},
"account_info": {
"title": "Accounts Info",
"site": "{name} account",
"devices": "Devices",
"brokers": "Brokers",
"no_brokers_connected": "No brokers connected"
},
"wallet_create": {
"redirecting_to_registration_page": "Redirecting to the Broker Service Provider registration page",
"complete_in_popup": "Complete the registration in the popup window",
"own_your_ngbox": "Own your NG-Box",
"self-host_broker": "Self-host a broker",
"tos_ng_net": "Terms of Service NextGraph.net",
"wallet_description": "A <b>NextGraph Wallet</b> is unique to each person. It stores your credentials and authorizations to access documents. You need one in order to start using NextGraph.<br /><br />If you already have a wallet, you should not create a new one. Instead, <a href=\"#/wallet/login\" >login here with your existing wallet.</a > If you never created a NextGraph Wallet before, please follow the instructions below in order to create your unique personal wallet.",
"has_wallet": "Some wallets are saved on this device,<br /> to log in with one of them, <a href=\"#/wallet/login\" use:link>click here.</a>",
"please_read": "Please read",
"wallet_about": {
"title": "What is a wallet?",
"1": "Your wallet is a secure and encrypted small file that contains some important information that only you should have access to.",
"2": "In your wallet, we store all the permissions to access documents you have been granted with, or that you have created yourself.<br/><b>There are 3 ways to unlock your wallet:</b>",
"password": "With a regular <b>username and password</b>. This is the default option and the easiest way. It is probably also the less secure one as you will probably choose a weak password. Also, it implies that we store your wallet on the Broker, in an encrypted form.",
"mnemonic": "With a <b>mnemonic</b> (like a passphrase) composed of 12 english words, which will be randomly generated for you. This is more secure but not easy to remember.",
"pazzle": "With a <b>pazzle</b> (contraction of puzzle and password) which is a new method that is both secure and easy to remember. It is composed of 9 images that will be generated for you in a specific order. Unlocking your wallet is then like solving a small puzzle.",
"3": "You will choose which option you prefer in the following screens. You can change option later on, after your wallet has been created. In any case, you will also have to choose a <b>PIN code</b> of 4 digits.",
"4": "Don't worry, it is easier to remember 9 images than a password like \"69$g&ms%C*%\", and it has the same strength as a complex password. The entropy of your pazzle is <b >66bits</b >, which is considered very high by all standards.",
"5": "You should only create <b>one unique wallet for yourself</b >. All your accounts, identities and permissions will be added into this unique wallet. Do not create another wallet if you already have one. Instead, you will <b>import</b> your existing wallet in all the devices you want to use.",
"6": "Your wallet can be transferred from one device to another with the help of a small file that you download, or with a QRcode, or with a TextCode that you copy/paste. In any case, you should never share this file or code with anybody else.",
"7": "We at NextGraph will never see the content of your wallet. It is encrypted and we do not know your credentials, so we cannot see what is inside.",
"8": "We offer a Wallet Recovery mechanism, that you can use in the event of lost or compromised devices or credentials. It is optional and implies storing an encrypted recovery kit on your broker.",
"9": "Please note that we will never ask for your email address. We cannot contact you by email, and even the recovery mechanism doesn't rely on emails. If you receive an email from us, delete it immediately as it must be spam (unless you subscribed to our newsletter, of course). "
},
"create_wallet_now": "I create my wallet now!",
"select_server": "NextGraph is based on an efficient decentralized P2P network, and in order to join this network and start using the app, you need to first select a <b>broker&nbsp;server</b>.",
"broker_about": {
"title": "What is a broker?",
"1": "The broker helps you keep all your data in <b>sync</b>, as it is connected to the internet 24/7 and keeps a copy of the updates for you. This way, even if the devices of the other participants are offline, you can still see what they shared with you.",
"2": "All your data is secure and <b>end-to-end encrypted</b>, and the broker cannot see the content of the documents as it does not have the keys to decrypt them.",
"3": "The broker helps you enforce your <b>privacy</b> as it hides your internet address (IP) from other users you share documents with.",
"4": "It will be possible in the future to use NextGraph without any broker and to have direct connections between peers, but this will imply a less smooth experience.",
"5": "At anytime you can decide to switch to another broker service provider or host it yourself. Your data is totally <b >portable</b > and can freely move to another broker.",
"6": "Soon we will offer you the opportunity to host your own broker at <b>home</b> or <b>office</b>. Instead of using a \"broker service provider\", you will own a small device that you connect behind your internet router. It is called <b>NG Box</b> and will be available soon.",
"7": "Organizations and companies have the opportunity to host a broker <b>on-premise</b> or in the <b>cloud</b>, as the software is open source. Individuals can also <b>self-host</b> a broker on any VPS server or at home, on their dedicated hardware.",
"8": "You can also start by installing the Native App and create the wallet from there, and then select the broker from the app. <br/>At any time you will be able to transfer your Wallet from one device to another (including from the web-app and the native apps)."
},
"choose_broker": "Please choose one broker among the list",
"register_with_broker": "Register with {broker}",
"for_eu_citizens": "European Union Server",
"for_rest": "International Server",
"this_broker": "this Broker",
"enter_invite_link": "Enter an invitation link",
"scan_invite_qr": "Scan an invitation QR-code",
"self_hosted_broker": "Self-hosted broker",
"ng_box": "NG Box (owned or invited)",
"install_app": "Install the app",
"registration_success": "You are creating an account at {broker}",
"choose_username": {
"title": "Now choose your username and password",
"warning": "Please note that we do not offer password recovery mechanism for now.<br/> We won't be able to help you if you forget your password."
},
"type_username_placeholder": "Type in your username",
"type_password_placeholder": "Type in your password",
"choose_pin": {
"title": "Let's start creating your wallet by choosing a PIN code",
"description": "We recommend you to choose a PIN code that you already know very well. <br />We at NextGraph will never see your PIN.",
"rules": "Here are the rules for the PIN:",
"1": "It cannot be a series like 1234 or 8765.",
"2": "The same digit cannot repeat more than once. By example 4484 is invalid.",
"3": "Try to avoid birth dates, last digits of phone numbers, or zip codes"
},
"chosen_pin": "You have chosen:",
"confirm_pin": "Please confirm your PIN code.",
"confirm_pin_description": "Enter the same PIN again.",
"pin_confirmed_as": "You PIN is confirmed as: ",
"security_phrase_invalid": "The security phrase your entered is invalid.",
"choose_security_phrase_and_image": {
"title": "Now let's enter a security phrase and a security image",
"description": "As a verification step, this phrase and image will be presented to you every time you are about to unlock your wallet.<br /> This security measure will prevent you from entering your credentials on malicious sites and apps.",
"warning": "Every time you will unlock your wallet, if you do not see and recognize your own security phrase and image before entering your credentials, please stop and DO NOT enter your credentials, as you would otherwise be the victim of a phishing attempt.",
"rules_title": "Here are the rules for the security phrase and image:",
"1": "The phrase should be at least (minimum) 10 characters long and maximum 100.",
"2": "It should be something you will remember, but not something too personal.",
"3": "Do not enter your full name, nor address, nor phone number.",
"4": "Instead, you can enter a quote, a small sentence that you like, or something meaningless to others, but unique to you.",
"5": "The image should be minimum 150x150px. There is no need to provide more than 400x400px as it will be scaled down anyway.",
"6": "We accept several formats like JPEG, PNG, GIF, WEBP and more.",
"7": "The image should be unique to you. But it should not be too personal neither.",
"8": "Do not upload your face picture, this is not a profile pic.",
"9": "The best would be a landscape you like or any other picture that you will recognize as unique.",
"10": "Please be aware that other people who are sharing this device with you, will be able to see this image and phrase."
},
"type_security_phrase_placeholder": "Type a security phrase...",
"save_security_phrase_and_image": "Save security phrase & image",
"tap_to_upload": "Tap to upload an image",
"click_to_upload": "Click to select an image",
"or_drag_drop": "or drag and drop",
"pins_no_match": "You didn't enter the same PIN twice",
"pin_invalid": "The pin your entered is invalid.",
"almost_done": "We are almost done!",
"save_wallet_options": {
"description": "There are 2 options to choose before we can create your wallet.",
"trust": "Do you trust this device?",
"trust_description": "If you do, if this device is yours, or it is used by a few trusted persons of your family or workplace, and you would like to login again from this device in the future, then you can save your wallet on this device. To the contrary, if this device is public and shared by strangers, do not save your wallet here.",
"trust_toggle": "Yes, save my wallet on this device",
"device_name_description": "To identify which device you are connected with, every device should have a name (e.g. Bob's laptop). Please enter it here.",
"cloud": "Keep a copy in the cloud?",
"cloud_description": "Are you afraid that you will loose the file containing your wallet? If this would happen, your wallet would be lost forever, together with all your documents. We can keep an encrypted copy of your wallet in our cloud. Only you will be able to download it with a special link. You would have to keep this link safely though. By selecting this option, you agree to the",
"cloud_toggle": "Save my wallet in the cloud?",
"cloud_tos": "Terms of Service of our cloud",
"pdf": "Should we create a PDF file of your wallet?",
"pdf_description": "We can prepare for you a PDF file containing all the information of your wallet, unencrypted. In the next screen, once your wallet is ready, you will be able to download such PDF file. You should print this file and then delete the PDF (and empty the trash). Keep this printed document in a safe place. It contains all the information to regenerate your wallet in case you lost access to it.",
"pdf_toggle": "Yes, create a PDF of my wallet",
"link": "Create a link to access your wallet easily?",
"link_description": "When you want to use your wallet on the web or from other devices, we can help you find your wallet by creating a simple link accessible from anywhere. Only you will have access to this link. In order to do so, we will keep your wallet ID and some information about your broker on our cloud servers. If you prefer to opt out, just uncheck this option. By selecting this option, you agree to the",
"link_toggle": "Create a link to my wallet?"
},
"lets_create": "Let's create this wallet",
"creating": "Your wallet is being created",
"ready": "Your wallet is ready!",
"download_wallet_description": "Please download your wallet and keep it in a safe location",
"download_wallet": "Download my wallet",
"download_wallet_done": "Your wallet file has been downloaded into your \"Downloads\" folder, with the name<br /><span class=\"text-black\"> {download_name}</span ><br /> <span class=\"font-bold\" >Please move it to a safe and durable place.</span ><br />",
"download_pdf_description": "Please download your Recovery PDF, print it, and delete it.",
"download_pdf": "Download my PDF",
"download_pdf_done": "Your Recovery PDF file has been downloaded into your \"Downloads\" folder,<br /> with the name <span class=\"text-black\"> {pdf_name}</span ><br /><br /> <span class=\"font-bold\" >Please print it and then delete it.</span ><br /><br />",
"your_pazzle": "Here below is your Pazzle. <br /> The <span class=\"font-bold\">order</span> of each image is <span class=\"font-bold\">important</span>!",
"your_mnemonic": "And here is your mnemonic (your alternative passphrase):",
"unlock_tips_1": "You can use both the pazzle or the mnemonic to unlock your wallet. The pazzle is easier to remember. The mnemonic is useful in some special cases. We recommend that you use the pazzle. <span class=\"font-bold text-xl\" >Copy both on a piece of paper.</span > You should try to memorize the pazzle. Once you did, you won't need the paper anymore.",
"unlock_tips_2": "Now click on \"Continue to Login\" and select your new wallet.",
"unlock_tips_3": "It is important that you <span class=\"font-bold\">login</span> with this wallet <span class=\"font-bold\">at least once</span> from this {platform, select, browser {browser tab} other {device}}, while connected to the internet, so your personal site can be created on your broker.",
"continue_to_login": "Continue to Login",
"continue_confirm": "Did you write down your login credentials?",
"continue_confirm_description": "The pazzle and the mnemonic <span class=\"font-bold\"> will not be shown to you again</span >. Please make sure, you have written them down.",
"continue_confirm_go_back": "Take me back",
"continue_confirm_yes": "Yes, I did"
},
"wallet_login": {
"select_wallet": "Select a wallet to login with",
"from_import.title": "Your wallet has been transferred",
"from_import.description": "Your wallet has been received from the other device!",
"from_import.instruction": "To finish the import, please log in.",
"with_username": "Import via Username",
"import_file": "Import a Wallet File",
"import_qr": "Import with QR-Code",
"import_link": "Import with TextCode",
"new_wallet": "Create a new Wallet",
"logged_in": "You are logged in.<br /> please wait while the app is loading",
"offline_advice": "If you do not have internet on this device, you can use the \"Import a Wallet file\" method instead."
},
"wallet_login_username": {
"title": "Import Wallet with your Username",
"description": "If you have created a username and password for your Wallet, then you can enter the details here below in order to import your wallet from your broker. You only have to do that once on this device.",
"username": "Username",
"username_placeholder_domain": "with the @domain part",
"username_placeholder_without_domain": "without @{domain}",
"username_placeholder_without_at": "without the @domain part",
"password": "Password",
"password_placeholder": "Enter your password here",
"next": "Next",
"connect": "Connect",
"redirect": "Redirect me",
"retrieve_button": "Connect & Retrieve Wallet",
"success_btn": "Continue to Login",
"error.username": "The username you entered is invalid. Only alphanumerical characters are allowed (together with hyphen and underscore)",
"error.nodomainplease": "Please enter your username without a trailing @domain",
"warning.nodomainplease": "You shouldn't enter any @domain part for your username",
"warning.nospecificdomainplease": "You don't need to enter the @{domain} part of your username",
"error.invalid_domain": "the @domain part is invalid",
"error.mandatory_domain": "You must enter the @domain part of your username.",
"error.need_redirect": "This user is from another broker. Do you want to be redirected to that broker?"
},
"wallet_login_qr": {
"title": "Import Wallet with QR-Code",
"scan.description": "To import your wallet from another device, generate an export QR-Code there. In order to do so, on the other device, go to<br /><span class=\"path\">User Panel > Wallet > Export by generating a QR-Code</span>.",
"scan.modal.title": "Scan Wallet QR-Code",
"gen.button": "Generate QR-Code",
"gen.description": "To import your wallet from another device, you have to generate a QR-Code here on this device, and then scan it with your other device (the one where your wallet is located for now).<br/>If your other device does not have a camera, then you have to use another method for importing your wallet here.",
"gen.letsgo": "Ready? On your other device, you first have to be logged-in (wallet is opened) and then you go to<br /><span class=\"path\">User Panel > Wallet > Export by scanning a QR-code</span>.<br />Then on this present device, click below on the<br/><span class=\"path\">Generate QR-Code</span> button.",
"gen.generated": "Scan this QR-Code from the other device.<br/>You have 5 minutes to do so.",
"success_btn": "Continue to Login"
},
"wallet_login_textcode": {
"title": "Import Wallet from TextCode",
"description": "To generate a TextCode, open a logged in device and go to<br /><span class=\"path\">User Panel > Wallet > Export by generating a TextCode</span>.",
"import_btn": "Import with TextCode",
"enter_here": "Enter your TextCode here below and click on Import button"
},
"scan_qr": {
"scanning": "Scanning the QR-Code"
}
},
"buttons": {
"ok": "Ok",
"go_back": "Go back",
"back": "Back",
"confirm": "Confirm",
"cancel": "Cancel",
"remove": "Remove",
"correct": "Correct",
"try_again": "Try again",
"back_to_homepage": "Go back to Homepage",
"logout": "Logout",
"login": "Login",
"start_over": "Start over",
"scan_qr": "Scan QR-Code"
},
"errors": {
"an_error_occurred": "An error occurred",
"error_occurred": "An error occurred:<br />{message}",
"AlreadyExists": "The user is already registered with the selected broker.<br />Try logging in instead.",
"InvalidSignature": "The signature is invalid.",
"IncompleteSignature": "The signature is incomplete.",
"SerializationError": "The data could not be serialized.",
"EncryptionError": "Your wallet could not be opened. You probably did a mistake when entering your credentials.",
"DecryptionError": "Error with decryption.",
"InvalidValue": "The value is invalid.",
"ConnectionNotFound": "The connection was not found.",
"InvalidSecurityImage": "The security image you chose is not valid.",
"InvalidSecurityText": "The security text you chose is too short. It must be at least 10 characters long.",
"InvalidKey": "The key is invalid.",
"InvalidInvitation": "The invitation is invalid.",
"InvalidCreateAccount": "An error occurred creating the account.",
"InvalidFileFormat": "The file format is invalid.",
"InvalidArgument": "The parameter is invalid.",
"PermissionDenied": "Permission denied.",
"InvalidPazzle": "The pazzle is not correct.",
"InvalidMnemonic": "The mnemonic is not correct.",
"CommitLoadError": "Error loading commit.",
"ObjectParseError": "Error parsing object.",
"StorageError": "Storage error.",
"NotFound": "Not Found",
"JsStorageKeyNotFound": "Could not find JavaScript storage key.",
"IoError": "Input/Output error.",
"CommitVerifyError": "Verifying commit failed.",
"LocalBrokerNotInitialized": "The local broker is not initialized.",
"JsStorageReadError": "Could not read from JavaScript Storage.",
"JsStorageWriteError": "Could not write to JavaScript Storage.",
"CannotSaveWhenInMemoryConfig": "Saving while configured for In-Memory is not possible.",
"WalletNotFound": "The wallet was not found.",
"WalletAlreadyAdded": "The wallet is already added.",
"WalletAlreadyOpened": "The wallet is already open.",
"WalletError": "Error with wallet.",
"BrokerError": "Error with broker.",
"SessionNotFound": "The session cannot be found.",
"SessionAlreadyStarted": "The session is already started.",
"RepoNotFound": "The repository cannot be found.",
"BranchNotFound": "The branch cannot be found.",
"StoreNotFound": "The store cannot be found.",
"UserNotFound": "The user cannot be found.",
"TopicNotFound": "The topic cannot be found.",
"NotConnected": "You are not connected.",
"ActorError": "Actor error.",
"ProtocolError": "Protocol error.",
"ServerError": "Server error.",
"InvalidResponse": "Received an invalid response.",
"BootstrapError": "Error while bootstrapping",
"NotAServerError": "Not a server.",
"VerifierError": "Error during verification.",
"SiteNotFoundOnBroker": "The site cannot be found on the broker",
"BrokerConfigErrorStr": "{error}",
"BrokerConfigError": "Error in the broker configuration.",
"MalformedEvent": "The event has an invalid format.",
"InvalidPayload": "The payload is invalid.",
"WrongUploadId": "The upload ID is incorrect.",
"FileError": "Error with file.",
"InternalError": "Internal Error",
"OxiGraphError": "Error in OxiGraph database.",
"ConfigError": "Error in configuration.",
"LocalBrokerIsHeadless": "The local broker is headless.",
"LocalBrokerIsNotHeadless": "The local broker is not headless.",
"InvalidNuri": "Invalid NextGraph URI.",
"InvalidTarget": "Cannot resolve target.",
"ExportWalletTimeOut": "The wallet-export session has expired. Try again.",
"ConnectionError": "Could not connect to the server.",
"IncompatibleQrCode": "You scanned a NextGraph QR-Code that is of the wrong type.",
"NotARendezVous": "You scanned an invalid QR-Code.",
"camera_unavailable": "Camera is unavailable.",
"ServerAlreadyRunningInOtherProcess": "App is already running on this device. Check it and close it.",
"WsError": "WebSocket error",
"cannot_load_this_file": "Cannot load this file",
"graph_not_found": "Graph not found",
"SocialQueryAlreadyStarted": "Social Query already started",
"ContactAlreadyExists": "Contact already added to your account",
"ContactNotFound": "You don't have any contact. We cannot start the Social Query",
"InvalidProfile": "Your profile is incomplete. You should add a name before you can share your profile with others",
"no_wasm_on_old_safari": "Your Safari browser is too old (version before 14.1). As a result we cannot load Automerge, needed for this document. Please upgrade your macOS or iOS system",
"BrowserTooOld": "Your browser is too old. Please upgrade it, use another browser, or install our native app. If you are using jshelter or another javascript protection mechanism, please deactivate it as we need access to the WebWorker facility of your browser.",
"NoLocalStorage": "You have disabled local storage in your browser. Please allow the current website (and also https://nextgraph.net website) to store data in this browser as otherwise we cannot proceed with Wallet creation. After allowing storage, please refresh the current page."
},
"auth":{
"select_broker":"<b>{origin}</b><br/>wants to access your wallet<br/><br/>Please select your broker in the list below:",
"unexpected_error":"An error occurred during the auth process"
},
"connectivity": {
"stopped": "Stopped",
"personal": "Personal",
"connecting": "Connecting",
"connected": "Connected",
"loading": "Loading",
"connection_error_short": "{error}",
"online": "Online",
"offline": "Offline"
},
"common": {
"version": "Version: {version}",
"logo": "NextGraph Logo",
"support_nextgraph": "Support NextGraph",
"about_nextgraph": "About NextGraph",
"donate_nextgraph": "Donate to NextGraph"
},
"wallet_sync": {
"offline_warning": "You cannot transfer your wallet when offline.<br />Please make sure you are connected to the internet first.",
"textcode.usage_warning": "You have to exchange this TextCode with the other device by any means available to you (email, other messenger apps, etc...). It is highly recommended to use a tool that is end-to-end encrypted. If you can, you should use the \"Import with QR-Code\" option instead, as it is safer and simpler. If your devices are not connected to the internet, then you can use the \"Import a Wallet File\" option. In this case, you will transfer the wallet file with a USB key, from one device to the other, or for mobile, by connecting your mobile with the USB cable, to the computer, and then transferring the file with the File Transfer utility on Android, or AirDrop/Finder/iTunes on an iPhone/mac/PC. We do not recommend uploading your wallet file to any cloud service.",
"server_transfer_notice": "Both devices need to be online.<br />During this wallet transfer, your wallet will be temporarily and securely stored on our servers for up to 5 minutes, using two levels of encryption.<br/> We at NextGraph will never be able to read your wallet, your PIN, your pazzle nor your mnemonic.",
"importing": "Importing wallet",
"expiry": "The TextCode will be valid for 5 minutes.",
"error": "An error occurred while synchronizing your wallet:<br />{error}",
"no_camera": "Unfortunately, your device does not have a camera.<br /> You cannot scan any QR-Code.<br /> In order to export your wallet to another device, you will have to use another method.",
"no_camera_alternatives": "You have 2 other options: \"Import a Wallet file\" (transfer it using a USB key by example, useful if you are offline) or \"Import a TextCode\" (which is a text you will have to transfer with another messaging app)."
},
"emojis": {
"category": {
"face": "Face",
"face_unwell": "Bad Face",
"face_costume": "Costumed",
"emotion": "Emotion",
"body": "Body",
"sport": "Sport",
"bigger_animal": "Big Animal",
"smaller_animal": "Small Animal",
"plants": "Plants and Insects",
"fruits": "Fruits and Veggies",
"food": "Food and Drinks",
"travel": "Travel",
"sky": "Sky and Weather",
"play": "Leisure",
"house": "Household"
},
"codes": {
"COMMENT": "YOU CAN FIND I18N UNICODE DESCRIPTIONS AT https://github.com/unicode-org/cldr-json",
"happy": "happy face",
"happy_tears": "face with tears of joy",
"halo": "smiling face with halo ring",
"three_hearts": "face with 3 hearts",
"with_two_hearts": "face with 2 heart-eyes",
"one_heart": "face blowing one heart kiss",
"with_tongue": "face with tongue",
"with_two_hands": "face with two hands",
"one_hand": "face with hand over mouth",
"silenced": "silenced zipper-mouth face",
"celebrating": "partying face",
"sunglasses": "face with sunglasses",
"eyes_up": "face with rolling eyes up",
"monocle": "face with monocle",
"sleeping": "sleeping face",
"mask": "face with medical mask",
"fever": "fever face with thermometer",
"bandage": "face with head-bandage",
"vomit": "face vomiting",
"tissue": "tissue sneezing face",
"hot": "red face with sweat",
"cold": "cold face",
"crossed_eyes": "face with crossed-out eyes",
"exploding": "exploding head",
"sad": "frowning sad face",
"long_nose": "long nose lying face",
"many_tears": "loudly crying face",
"fear": "face screaming in fear",
"tired": "tired yawning face",
"annoyed": "annoyed face with steam from nose",
"clown": "clown face",
"ghost": "ghost",
"dog": "dog face",
"happy_cat": "happy cat with smiling eyes",
"scared_cat": "weary scared cat",
"sad_cat": "crying cat",
"monkey_no_see": "see-no-evil monkey",
"monkey_no_hear": "hear-no-evil monkey",
"monkey_no_talk": "speak-no-evil monkey",
"builder": "construction worker",
"princess": "princess",
"firefighter": "firefighter",
"mage": "mage",
"mermaid": "mermaid",
"fairy": "fairy",
"letter_heart": "love letter",
"red_heart": "red heart",
"two_hearts": "two hearts",
"kiss": "kiss mark",
"hundred": "hundred points",
"explosion": "explosion",
"drops": "sweat droplets",
"handshake": "handshake",
"hand_five_fingers": "hand with 5 fingers splayed",
"hand_two_fingers": "victory hand with 2 fingers",
"thumbs_up": "thumbs up",
"fist": "raised fist",
"two_hands": "two open hands",
"writing": "writing hand",
"praying": "praying folded hands",
"arm": "flexed arm",
"leg": "leg",
"foot": "foot",
"ear": "ear",
"nose": "nose",
"brain": "brain",
"tooth": "tooth",
"bone": "bone",
"eye": "eye",
"tongue": "tongue",
"mouth": "mouth",
"shirt": "t-shirt",
"pants": "pants",
"dress": "dress",
"shoe": "running shoe",
"fencing": "fencing",
"horse_riding": "horse riding",
"ski": "skier",
"rowing_boat": "rowing boat",
"swim": "swimming",
"surf": "surfing",
"gym": "lifting weights",
"wrestling": "two people wrestling",
"bike": "biking",
"parachute": "parachute",
"football": "football",
"basketball": "basketball",
"tennis": "tennis",
"ping_pong": "ping pong",
"martial": "judo uniform kimono",
"lion": "lion",
"leopard": "leopard",
"horse": "horse face",
"zebra": "zebra",
"pig": "pig",
"goat": "goat",
"sheep": "sheep",
"camel": "camel",
"giraffe": "giraffe",
"elephant": "elephant",
"rhinoceros": "rhinoceros",
"flamingo": "flamingo",
"whale": "whale",
"dolphin": "dolphin",
"bear": "bear",
"rooster": "rooster",
"chick": "hatching chick",
"eagle": "eagle",
"duck": "duck",
"owl": "owl",
"rabbit": "rabbit",
"penguin": "penguin",
"lizard": "lizard",
"turtle": "turtle",
"snake": "snake",
"hedgehog": "hedgehog",
"bat": "bat",
"fish": "fish",
"shell": "shell",
"octopus": "octopus",
"snail": "snail",
"butterfly": "butterfly",
"ant": "ant",
"bee": "honeybee",
"beetle": "beetle",
"rose": "rose",
"sunflower": "sunflower",
"fir": "evergreen fir tree",
"palm_tree": "palm tree",
"cactus": "cactus",
"clover": "four leaf clover",
"potted_plant": "potted plant",
"bouquet": "bouquet",
"three_leaves": "three fallen leaf",
"mushroom": "mushroom",
"grapes": "grapes",
"watermelon": "watermelon",
"lemon": "lemon",
"banana": "banana",
"pineapple": "pineapple",
"apple": "red apple",
"cherries": "cherries",
"strawberry": "strawberry",
"three_blueberries": "three blueberries",
"kiwi": "kiwi",
"avocado": "avocado",
"eggplant": "eggplant",
"carrot": "carrot",
"corn": "corn",
"pepper": "red hot pepper",
"croissant": "croissant",
"bread": "baguette bread",
"pretzel": "pretzel",
"cheese": "cheese",
"pizza": "slice of pizza",
"egg": "fried egg",
"ice_cream": "ice cream",
"cookie": "cookie",
"cake": "piece of cake",
"chocolate": "chocolate",
"sweet": "candy",
"coffee": "coffee",
"champagne_bottle": "champagne bottle",
"glass_wine": "wine glass",
"two_glasses": "two glasses of cava",
"mountain": "mountain",
"camping": "camping",
"beach": "beach",
"compass": "compass",
"museum": "museum",
"house": "house",
"fountain": "fountain",
"circus": "circus",
"train": "train",
"taxi": "taxi",
"motorcycle": "motorcycle",
"sailboat": "sailboat",
"airplane": "airplane",
"helicopter": "helicopter",
"rocket": "rocket",
"sun": "sun",
"moon": "moon",
"planet": "planet",
"star": "star",
"night_sky": "night sky",
"cloud": "cloud with rain",
"umbrella": "umbrella with rain drops",
"lightning": "lightning",
"snowflake": "snowflake",
"snowman": "snowman",
"thermometer": "thermometer",
"fire": "fire",
"balloon": "balloon",
"kite": "kite",
"rainbow": "rainbow",
"guitar": "guitar",
"saxophone": "saxophone",
"music": "musical note",
"painting": "painting",
"chess": "chess",
"gift": "gift",
"die": "game die",
"puzzle": "puzzle",
"teddy_bear": "teddy bear",
"firecracker": "firecracker",
"bullseye": "bullseye",
"roller_skate": "roller skate",
"kick_scooter": "kick scooter",
"anchor": "anchor",
"scuba_diving": "scuba diving",
"broom": "broom",
"magnifying_glass": "magnifying glass",
"bulb": "light bulb",
"three_books": "three books",
"package": "package",
"pencil": "pencil",
"pin": "pin",
"paperclip": "paperclip",
"scissors": "scissors",
"key": "key",
"lock": "lock",
"chair": "chair",
"bathtub": "bathtub",
"sponge": "sponge",
"shopping_cart": "shopping cart"
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,667 @@
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
import {
writable,
readable,
readonly,
derived,
get,
type Writable,
} from "svelte/store";
import { official_classes } from "./classes";
import { official_apps, official_services } from "./zeras";
import { format } from "svelte-i18n";
let loaded_external_apps = {};
export const load_app = async (appName: string) => {
let app = await get_app(appName);
return await import(`./apps/${app["ng:b"]}.svelte`);
};
export const load_official_app = async (app) => {
//console.log(app);
//console.log(app["ng:b"]);
let component = await import(`./apps/${app["ng:b"]}.svelte`);
//console.log(component.default);
return component.default;
};
export const get_app = (appName: string) => {
if (appName.startsWith("n:g:z")) {
let app = official_apps[appName];
if (!app) throw new Error("Unknown official app");
return app;
} else {
//TODO: load external app from its repo
// TODO: keep it in cache in loaded_external_apps
}
};
export const invoke_service = async (serviceName: string, nuri: string, args: object) => {
if (serviceName.startsWith("n:g:z")) {
let service = official_services[serviceName];
if (!service) throw new Error("Unknown official service");
// TODO: do this in WebWorker
// TODO: if on native app or CLI: use deno
//return await ng.app_invoke(serviceName[6..], nuri, args);
} else {
// TODO: if on webapp: only allow those invocations from IFrame of external app or from n:g:z:external_service_invoke (which runs in an IFrame) and run it from webworker
// TODO: if on native app or CLI: use deno
// TODO: load external service from its repo
}
};
export const get_class = (class_name) => {
if (class_name.startsWith("app:") && class_name !== "app:z") {
//TODO: load external app from its repo
// cache it in loaded_external_apps
// return the class
} else {
return official_classes[class_name];
}
};
const find_viewers_for_class = (class_name: string) => {
let found = [];
for (const zera of Object.entries(official_apps)) {
if (zera[0].includes("dump") || zera[0].includes("source")) continue;
let viewers = zera[1]["ng:o"];
if (viewers && viewers.includes(class_name)) {
found.push(zera[0]);
}
}
return found;
}
const find_editors_for_class = (class_name: string) => {
let found = [];
for (const zera of Object.entries(official_apps)) {
let viewers = zera[1]["ng:w"];
if (viewers && viewers.includes(class_name)) {
found.push(zera[0]);
}
}
return found;
}
const find_source_viewer_for_class = (class_def, class_name) => {
switch (class_def["ng:crdt"]) {
case 'Graph':
return "n:g:z:crdt_source_viewer:rdf";
case 'YMap':
return "n:g:z:crdt_source_viewer:ymap";
case 'YArray':
return "n:g:z:crdt_source_viewer:yarray";
case 'Automerge':
case 'Elmer':
return "n:g:z:crdt_source_viewer:json";
case 'YXml':
return "n:g:z:crdt_source_viewer:xml";
case 'YText':
if (class_name === "post:text" || class_name.startsWith("code")) return false;
return "n:g:z:crdt_source_viewer:text";
}
}
const class_to_viewers_editors = (class_name: string) => {
let class_def = get_class(class_name);
let has_discrete = class_def["ng:crdt"] !== "Graph";
let discrete_viewer = has_discrete ? class_def["ng:o"] : undefined;
let discrete_editor = has_discrete ? class_def["ng:w"] : undefined;
let graph_viewers = [];
let graph_editors = [];
if (!has_discrete) {
if (class_def["ng:o"]) graph_viewers.push(class_def["ng:o"]);
if (class_def["ng:w"]) graph_editors.push(class_def["ng:w"]);
}
for (const additional_g_v of find_viewers_for_class("data:graph")){
if (!graph_viewers.includes(additional_g_v)) graph_viewers.push(additional_g_v);
}
for (const additional_g_e of find_editors_for_class("data:graph")){
if (!graph_editors.includes(additional_g_e)) graph_editors.push(additional_g_e);
}
let graph_viewer = graph_viewers[0];
let graph_editor = graph_editors[0];
let discrete_viewers = [];
let discrete_editors = [];
if (has_discrete) {
if (discrete_viewer) discrete_viewers.push(discrete_viewer);
if (discrete_editor) discrete_editors.push(discrete_editor);
for (const v of find_viewers_for_class(class_name)) {
if (v!==discrete_viewer) discrete_viewers.push(v);
}
for (const e of find_editors_for_class(class_name)) {
if (e!==discrete_editor) discrete_editors.push(e);
}
let source_viewer = find_source_viewer_for_class(class_def, class_name);
if (source_viewer) discrete_viewers.push(source_viewer);
if (!discrete_viewer) discrete_viewer = discrete_viewers[0];
}
return {
graph_viewers,
graph_editors,
discrete_viewers,
discrete_editors,
graph_viewer,
graph_editor,
discrete_viewer,
discrete_editor
}
}
export const open_branch = (nuri: string, in_tab: boolean) => {
if (!get(all_tabs)[nuri]) {
all_tabs.update((old) => {
if (!old[nuri]) {
//console.log("creating tab for ",nuri)
old[nuri] = JSON.parse(JSON.stringify(old[""]));
old[nuri].branch.nuri = nuri.substring(0,nuri.length-47); // we remove the ":v:[char;44]" part
old[nuri].store.overlay = nuri.substring(nuri.length-47); // and put it in store.overlay
}
return old;
});
}
if (in_tab) {
cur_branch.set(nuri);
let store_type = get(all_tabs)[nuri].store.store_type;
if (store_type) change_nav_bar(`nav:${store_type}`,get(format)(`doc.${store_type}_store`), undefined);
}
}
export const update_class = (cur_tab, class_name) => {
cur_tab.branch.class = class_name;
cur_tab.graph_or_discrete = get_class(class_name)["ng:crdt"] === "Graph";
cur_tab.branch.has_discrete = !cur_tab.graph_or_discrete;
return {...cur_tab, ...class_to_viewers_editors(class_name)};
}
export const update_branch_display = (cur_tab) => {
if (cur_tab.doc.nuri == cur_tab.branch.nuri) {
cur_tab.branch.type = "main";
cur_tab.branch.display = "main";
}
}
export const show_modal_menu = writable(false);
export const show_spinner = writable(false);
export const show_doc_popup = writable(false);
export const cur_doc_popup = writable("");
export const show_modal_create = writable(false);
export const in_memory_graph = writable("");
export const in_memory_discrete = writable("");
//TODO: call it also when switching branches inside same repo
export const reset_in_memory = () => {
//console.log("reset_in_memory");
in_memory_graph.update((d)=> {return "";});
in_memory_discrete.update((d)=> {return "";});
//console.log(get(in_memory_graph));
//console.log(get(in_memory_discrete));
};
export const all_tabs = writable({
"":{
store: {
repo: false, // a StoreRepo serialization
overlay: "", // "v:"
has_outer: "", // "l:"
store_type: "", //"public" "protected", "private", "group", "dialog",
readcap: "", // "r:" readcap of main
is_member: "", // "r:" readcap of store root branch
can_edit: true,
inner: "", // "w:l:"
stream: { // only if not a Dialog
notif: 0,
last: "",
nuri: "",
},
// comes from main branch of store
title: "",
icon: "",
description: "",
},
plato: {
nuri: "",
can_edit: false,
},
branch: {
nuri: "", // :o or :o:b
readcap: "", // "r:"
comment_branch: "", // nuri
class: "",
has_discrete: false,
id: "", //"b:xxx" branch id (can be null if not of type "branch")
c: "", //"c:xxx" commit(s) id
type: "", // "main", "stream", "detached", "branch", "in_memory" (does not save)
display: "", // or main or stream or a:xx or branch:X or c:X (only 7 chars)
attachments: 0,
files: 0,
comments: 0,
title: "",
icon: "",
description: "",
app: "", // current app being used
},
view_or_edit: true, // true=> view, false=> edit
graph_viewer: "", // selected viewer
graph_editor: "", // selected editor
discrete_viewer: "", // selected viewer
discrete_editor: "", // selected editor
graph_viewers: [], // list of available viewers
graph_editors: [], // list of available editors
discrete_viewers: [], // list of available viewers
discrete_editors: [], // list of available editors
find: "",//or string to find
graph_or_discrete: false, // set to branch.crdt === "data/graph"
doc: {
nuri: "",// :o
is_store: false,
is_member: "", // ":r" readcap of root branch
authors: [],
inbox: "",
can_edit: false,
live_edit: false,
title: "",
icon: "",
description: "",
live_editors: {
},
branches : {},
},
folders_pane: false,
toc_pane: false,
messenger_pane: false,
right_pane: "", // "branches", "files", "history", "comments", "info", "chat", "mc"
action: false, // "repost", "dm", "react", "author", "copy", "forward", "link", "qr", "download", "embed", "new_block", "notifs", "schema", "signature", "permissions", "settings", "print", "console", "source", "services", "dev",
show_menu: false,
persistent_error: false,
header_in_view: true,
}
});
export let in_memory_save = [];
let in_memory_save_callback = async (updates) => {};
export const cur_tab_register_on_save = (f:(updates) => Promise<void>) => {
in_memory_save_callback = f;
in_memory_save = [];
}
export const cur_tab_deregister_on_save = async () => {
await save();
in_memory_save_callback = async (updates) => {};
}
export const save = async () => {
// saving the doc
// TODO fetch updates from local storage
nav_bar.update((o) => { if (o.save === true) o.save = false; return o; });
if (in_memory_save.length > 0) {
let temp = in_memory_save;
in_memory_save = [];
await in_memory_save_callback(temp);
}
}
export const set_header_in_view = function(val) {
cur_tab_update((old) => { old.header_in_view = val; return old;});
}
export const cur_branch = writable("");
export const cur_tab = derived([cur_branch, all_tabs], ([cb, all]) => {return all[cb];});
export const can_have_header = derived(cur_tab, ($cur_tab) => {
return !($cur_tab.doc.is_store); // && ( $cur_tab.store.store_type === "private" || $cur_tab.store.store_type === "dialog"));
});
export const cur_tab_branch_nuri = derived(cur_tab, ($cur_tab) => {
return $cur_tab.branch.nuri;
});
export const cur_tab_doc_can_edit = derived(cur_tab, ($cur_tab) => {
return $cur_tab.doc.can_edit;
});
export const cur_tab_doc_is_store = derived(cur_tab, ($cur_tab) => {
return $cur_tab.doc.is_store;
});
export const cur_tab_doc_is_member = derived(cur_tab, ($cur_tab) => {
return $cur_tab.doc.is_member;
});
export const cur_tab_store_type = derived(cur_tab, ($cur_tab) => {
return $cur_tab.store.store_type;
});
export const cur_tab_persistent_error = derived(cur_tab, ($cur_tab) => {
return $cur_tab.persistent_error;
});
export const cur_tab_header_in_view = derived(cur_tab, ($cur_tab) => {
return $cur_tab.header_in_view;
});
export const cur_tab_right_pane = derived(cur_tab, ($cur_tab) => {
return $cur_tab.right_pane;
});
export const cur_tab_folders_pane = derived(cur_tab, ($cur_tab) => {
return $cur_tab.folders_pane;
});
export const cur_tab_toc_pane = derived(cur_tab, ($cur_tab) => {
return $cur_tab.toc_pane;
});
export const cur_tab_show_menu = derived(cur_tab, ($cur_tab) => {
return $cur_tab.show_menu;
});
export const cur_tab_branch_class = derived(cur_tab, ($cur_tab) => {
return $cur_tab.branch.class;
});
export const cur_tab_branch_has_discrete = derived(cur_tab, ($cur_tab) => {
return $cur_tab.branch.has_discrete;
});
export const cur_tab_graph_or_discrete = derived(cur_tab, ($cur_tab) => {
return $cur_tab.graph_or_discrete;
});
export const cur_tab_view_or_edit = derived(cur_tab, ($cur_tab) => {
return $cur_tab.view_or_edit;
});
export const edit_header_button = derived(cur_tab, ($cur_tab) => {
return ($cur_tab.doc.is_store && ( $cur_tab.store.store_type === "public" || $cur_tab.store.store_type === "protected"))? "doc.header.buttons.edit_profile" : "doc.header.buttons.edit_intro";
});
export const in_private_store = derived(cur_tab, ($cur_tab) => {
return $cur_tab.store.store_type === "private";
});
export const header_title = derived(cur_tab, ($cur_tab) => {
if ($cur_tab.doc.is_store) {
if ($cur_tab.store.store_type !== "private" && $cur_tab.store.store_type !== "dialog") {
return $cur_tab.store.title;
}
} else {
let title = $cur_tab.branch.title || $cur_tab.doc.title;
if (title) return title;
let app = get_app($cur_tab.branch.class);
if (app) return app["ng:n"];
}
return false;
});
/* to be used with <NavIcon img={$cur_tab_store_icon_override || $nav_bar.icon} config={{
tabindex:"-1",
class:"w-8 h-8 focus:outline-none"
}}/>
*/
export const header_icon = derived(cur_tab, ($cur_tab) => {
if ($cur_tab.doc.is_store) {
if ($cur_tab.store.store_type !== "private") {
return $cur_tab.store.icon;// TODO: fetch image and return blob:
}
} else {
let icon = $cur_tab.branch.icon || $cur_tab.doc.icon;
if (icon) return icon;// TODO: fetch image and return blob:
let class_type = get_class($cur_tab.branch.class);
if (class_type) return "class:" + $cur_tab.branch.class;
}
return false;
});
export const header_description = derived(cur_tab, ($cur_tab) => {
if ($cur_tab.doc.is_store) {
if ($cur_tab.store.store_type !== "private") {
return $cur_tab.store.description;
}
} else {
let description = $cur_tab.branch.description || $cur_tab.doc.description;
if (description) return description;
}
return false;
});
export const cur_tab_store_name_override = derived(cur_tab, ($cur_tab) => { if ($cur_tab.doc.is_store && $cur_tab.store.store_type !== "private" && $cur_tab.store.title && !$cur_tab.header_in_view) return $cur_tab.store.title; else return false; });
export const cur_tab_store_icon_override = derived(cur_tab, ($cur_tab) => { if ($cur_tab.doc.is_store && $cur_tab.store.store_type !== "private" && $cur_tab.store.icon && !$cur_tab.header_in_view) return $cur_tab.store.icon; else return false; });
export const tab_update = function( tab, fn ) {
all_tabs.update((all) => {
all[tab] = fn(all[tab]);
return all;
});
};
export const cur_tab_update = function( fn ) {
all_tabs.update((all) => {
all[get(cur_branch)] = fn(all[get(cur_branch)]);
return all;
});
};
export const live_editing = writable(false);
export const showMenu = async () => {
await save();
show_modal_menu.set(true);
cur_tab_update(ct => {
ct.show_menu = true;
return ct;
});
}
export const hideMenu = () => {
show_modal_menu.set(false);
cur_tab_update(ct => {
ct.show_menu = false;
return ct;
});
}
export const nav_bar = writable({
//icon: "class:post:rich",
icon: "",
//icon: "blob:http://localhost:1421/be6f968f-ff51-4e8f-bd32-36c60b7af49a",
title: "",
back: false,
newest: 0,
save: undefined,
});
live_editing.subscribe((val) => {
cur_tab_update((old)=> {
old.doc.live_edit = val;
nav_bar.update((o) => {
o.save = old.doc.live_edit ? undefined : ( in_memory_save.length > 0 ? true : false )
return o;
});
return old;
});
});
export const nav_bar_newest = derived(nav_bar, ($nav_bar) => {
return $nav_bar.newest;
});
export const nav_bar_save = derived(nav_bar, ($nav_bar) => {
return $nav_bar.save;
});
export const nav_bar_back = derived(nav_bar, ($nav_bar) => {
return $nav_bar.back;
});
export const nav_bar_title = derived(nav_bar, ($nav_bar) => {
return $nav_bar.title;
});
export const nav_bar_icon = derived(nav_bar, ($nav_bar) => {
return $nav_bar.icon;
});
export const nav_bar_reset_newest = () => {
nav_bar.update((old) => {
old.newest = 0;
return old;
});
}
export const change_nav_bar = (icon, title, back) => {
nav_bar.update((old) => {
if (icon !== undefined) {
old.icon = icon;
}
if (title !== undefined) {
old.title = title;
}
if (back !== undefined) {
old.back = back;
}
return old;
});
live_editing.set(get(cur_tab).doc.live_edit);
};
export const persistent_error = (nuri, pe) => {
tab_update(nuri, tab => {
tab.persistent_error = pe;
return tab;
});
}
export const all_files_count = derived(cur_tab, ($cur_tab) => {
let total = $cur_tab.branch.files;
return total ? `(${total})` : "";
});
export const all_comments_count = derived(cur_tab, ($cur_tab) => {
let total = $cur_tab.branch.comments;
return total ? `(${total})` : "";
});
export const has_editor_chat = derived(cur_tab, ($cur_tab) => {
return $cur_tab.doc.can_edit && $cur_tab.store.store_type !== "private" && $cur_tab.store.store_type !== "dialog";
});
export const toggle_live_edit = async () => {
let is_live;
cur_tab_update(ct => {
ct.doc.live_edit = !ct.doc.live_edit;
is_live = ct.doc.live_edit;
live_editing.set(ct.doc.live_edit);
return ct;
});
if (is_live) {
//send all the updates with live_discrete_update
await save();
}
}
export const set_viewer = (app_name: string) => {
if (get(cur_tab).graph_or_discrete) {
cur_tab_update(ct => {ct.graph_viewer = app_name; ct.branch.app = app_name; return ct;});
} else {
cur_tab_update(ct => {ct.discrete_viewer = app_name; ct.branch.app = app_name; return ct;});
}
}
export const set_editor = (app_name: string) => {
if (get(cur_tab).graph_or_discrete) {
cur_tab_update(ct => {ct.graph_editor = app_name; ct.branch.app = app_name; return ct;});
} else {
cur_tab_update(ct => {ct.discrete_editor = app_name; ct.branch.app = app_name; return ct;});
}
}
export const toggle_graph_discrete = () => {
cur_tab_update(ct => {
ct.graph_or_discrete = !ct.graph_or_discrete;
return ct;
});
}
export const set_graph_discrete = (val:boolean) => {
cur_tab_update(ct => {
ct.graph_or_discrete = val;
return ct;
});
}
export const set_view_or_edit = (val:boolean) => {
cur_tab_update(ct => {
ct.view_or_edit = val;
return ct;
});
}
export const open_viewer = () => {
set_view_or_edit(true);
}
export const cur_viewer = derived(cur_tab, ($cur_tab) => {
let app_name = $cur_tab.graph_or_discrete ? $cur_tab.graph_viewer : $cur_tab.discrete_viewer;
if (app_name) {
let app = get_app(app_name);
return app;
}
});
export const cur_editor = derived(cur_tab, ($cur_tab) => {
let app_name = $cur_tab.graph_or_discrete ? $cur_tab.graph_editor : $cur_tab.discrete_editor;
if (app_name) {
let app = get_app(app_name);
return app;
}
});
export const cur_app = derived(cur_tab, ($cur_tab) => {
let app_name = $cur_tab.view_or_edit ? $cur_tab.graph_or_discrete ? $cur_tab.graph_viewer : $cur_tab.discrete_viewer : $cur_tab.graph_or_discrete ? $cur_tab.graph_editor : $cur_tab.discrete_editor;
if (app_name) {
let app = get_app(app_name);
return app;
}
});
export const available_viewers = derived(cur_tab, ($cur_tab) => {
let list = $cur_tab.graph_or_discrete ? $cur_tab.graph_viewers : $cur_tab.discrete_viewers;
return list.map((viewer) => {
let app = { ...get_app(viewer) };
if (!app["ng:u"]) app["ng:u"] = "view";
return app
});
});
export const available_editors = derived(cur_tab, ($cur_tab) => {
let list = $cur_tab.graph_or_discrete ? $cur_tab.graph_editors : $cur_tab.discrete_editors;
return list.map((editor) => {
let app = { ...get_app(editor) };
if (!app["ng:u"]) app["ng:u"] = "edit";
return app
});
});

@ -0,0 +1,776 @@
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
// "n:g:z:hide" >> hides when in viewer mode
// "n:g:z:compose" >> a viewer made of a list of viewers (useful when different views on the same branch needs to be aggregated, or when the discrete is not composable - i.e it is not a Post)
//"n:g:z:json_ld_editor", "n:g:z:json_editor", "n:g:z:triple_editor", "n:g:z:rdf_viewer:turtle", "n:g:z:rdf_viewer:n3", "n:g:z:rdf_viewer:json_ld", "n:g:z:rdf_viewer:graph",
//"n:g:z:sparql_query:yasgui", "n:g:z:sparql_query:sparnatural", "n:g:z:graphql_query", "n:g:z:sparql_update:yasgui", "n:g:z:ontology_editor", "n:g:z:owl_viewer", "n:g:z:sparql:invoke", "n:g:z:graphql:invoke", "n:g:z:dump_download",
// "n:g:z:post_rich_editor", "n:g:z:post_md_editor", "n:g:z:code_editor", "n:g:z:file_viewer", "n:g:z:file_source", "n:g:z:crdt_source_viewer:xml", "n:g:z:crdt_source_viewer:md", "n:g:z:crdt_source_viewer:json", "n:g:z:crdt_source_viewer:text", "n:g:z:crdt_source_viewer:rdf"
//"n:g:z:post:rich", "n:g:z:post:md", "n:g:z:text", "n:g:z:pre", "n:g:z:pad", "n:g:z:card", "n:g:z:gallery", "n:g:z:columns", "n:g:z:tree", "n:g:z:summary", "n:g:z:list", "n:g:z:grid", "n:g:z:list_n_post", "n:g:z:grid_n_post", "n:g:z:board",
//"n:g:z:map", "n:g:z:chart", "n:g:z:pivot", "n:g:z:timeline", "n:g:z:email", "n:g:z:web_archive", "n:g:z:diagram_editor", "n:g:z:pdf", "n:g:z:latex", "n:g:z:media", "n:g:z:media_editor",
//"n:g:z:service_editor", "n:g:z:service_invoke", "n:g:z:external_service_invoke", "n:g:z:contract", "n:g:z:text_query", "n:g:z:web_query", "n:g:z:scan_qrcode", "n:g:z:upload_file",
//"n:g:z:messenger", "n:g:z:group", "n:g:z:contact", "n:g:z:event", "n:g:z:calendar", "n:g:z:scheduler",
//"n:g:z:task", "n:g:z:project", "n:g:z:issue", "n:g:z:form_editor", "n:g:z:form_filler", "n:g:z:cad", "n:g:z:slides", "n:g:z:question", "n:g:z:poll",
//"n:g:z:app_store", "n:g:z:app_editor", "n:xxx.xx.xx:yy", "o:xx:yy:zz"
export const official_apps = {
"n:g:z:sparql_update": {
"ng:n": "SPARQL Update",
"ng:a": "View, edit and invoke a Graph SPARQL Update",
"ng:c": "app",
"ng:u": "sparql_query",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_update",
"ng:b": "SparqlUpdateEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui
"ng:o": [],
"ng:w": ["query:sparql_update","data:graph"],
implemented: true,
},
"n:g:z:json_ld_editor": {
"ng:n": "JSON-LD Editor",
"ng:a": "Edit the RDF Graph as JSON-LD",
"ng:c": "app",
"ng:u": "json_ld_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_ld_editor",
"ng:b": "JsonLdEditor",
"ng:w": ["data:graph"],
},
"n:g:z:json_yarray_editor": {
"ng:n": "JSON Editor",
"ng:a": "Edit the JSON data",
"ng:c": "app",
"ng:u": "json_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_yarray_editor",
"ng:b": "YArrayEditor",
"ng:w": ["data:array"],
implemented: true,
},
"n:g:z:json_automerge_editor": {
"ng:n": "JSON Editor",
"ng:a": "Edit the JSON data",
"ng:c": "app",
"ng:u": "json_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_automerge_editor",
"ng:b": "AutomergeEditor",
"ng:w": ["data:json"],
"full_width": true,
implemented: true,
},
"n:g:z:json_ymap_editor": {
"ng:n": "JSON Editor",
"ng:a": "Edit the JSON data",
"ng:c": "app",
"ng:u": "json_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_ymap_editor",
"ng:b": "YMapEditor",
"ng:w": ["data:map"],
implemented: true,
},
"n:g:z:triple_editor": {
"ng:n": "Graph Triples Editor",
"ng:a": "Edit the RDF Graph as triples",
"ng:c": "app",
"ng:u": "triple_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:triple_editor",
"ng:b": "TripleEditor",
"ng:w": ["data:graph"],
},
"n:g:z:rdf_viewer:turtle": { // https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:n": "Turtle",
"ng:a": "View the RDF Graph in Turtle format",
"ng:c": "app",
"ng:u": "turtle_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:rdf_viewer:turtle",
"ng:b": "TurtleViewer",
"ng:o": ["data:graph"],
"ng:w": [],
implemented: true,
},
"n:g:z:sparql_query": {
"ng:n": "SPARQL Query",
"ng:a": "View, edit and invoke a Graph SPARQL query",
"ng:c": "app",
"ng:u": "sparql_query",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_query",
"ng:b": "SparqlQueryEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui
"ng:o": ["data:graph"],
"ng:w": ["query:sparql"],
implemented: true,
},
"n:g:z:json_ld_viewer": {
"ng:n": "JSON-LD",
"ng:a": "View the RDF Graph as JSON-LD",
"ng:c": "app",
"ng:u": "json_ld_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_ld_viewer",
"ng:b": "JsonLdViewer",
"ng:o": ["data:graph"],
},
"n:g:z:rdf_viewer:graph": {
"ng:n": "Graph Explorer",
"ng:a": "View the RDF Graph as interactive visualization",
"ng:c": "app",
"ng:u": "graph_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:rdf_viewer:graph",
"ng:b": "GraphViewer", // GraphExplorer https://github.com/zazuko/graph-explorer !! AGPL
"ng:o": ["data:graph"],
"ng:w": [],
},
"n:g:z:json_ymap_viewer": {
"ng:n": "JSON",
"ng:a": "View the JSON data",
"ng:c": "app",
"ng:u": "json_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_ymap_viewer",
"ng:b": "YMapViewer",
"ng:o": ["data:map"],
implemented: true,
},
"n:g:z:json_yarray_viewer": {
"ng:n": "JSON",
"ng:a": "View the JSON data",
"ng:c": "app",
"ng:u": "json_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_yarray_viewer",
"ng:b": "YArrayViewer",
"ng:o": ["data:array"],
implemented: true,
},
"n:g:z:json_automerge_viewer": {
"ng:n": "JSON",
"ng:a": "View the JSON data",
"ng:c": "app",
"ng:u": "json_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_automerge_viewer",
"ng:b": "AutomergeViewer",
"ng:o": ["data:json"],
"full_width": true,
implemented: true,
},
"n:g:z:triple_viewer": {
"ng:n": "Graph Triples",
"ng:a": "View the RDF Graph as triples",
"ng:c": "app",
"ng:u": "triple_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:triple_viewer",
"ng:b": "TripleViewer",
"ng:o": ["data:graph"],
},
"n:g:z:sparql_query:sparnatural": {
"ng:n": "SPARNatural Query",
"ng:a": "View, edit and invoke a Graph SPARQL query with SPARnatural tool",
"ng:c": "app",
"ng:u": "sparnatural",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_query:sparnatural",
"ng:b": "SparNaturalEditor",
"ng:o": ["data:graph"],
"ng:w": ["query:sparql"],
},
"n:g:z:graphql_query": {
"ng:n": "GraphQL Query",
"ng:a": "View, edit and invoke a GraphQL query",
"ng:c": "app",
"ng:u": "graphql",//favicon. can be a did:ng:j
"ng:g": "n:g:z:graphql_query",
"ng:b": "GraphqlEditor",
"ng:o": ["data:graph"],
"ng:w": ["query:graphql"],
},
"n:g:z:rdf_viewer:n3": { // ?
"ng:n": "N3",
"ng:a": "View the RDF Graph in N3 format",
"ng:c": "app",
"ng:u": "rdf_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:rdf_viewer:n3",
"ng:b": "N3Viewer",
"ng:o": ["data:graph"],
"ng:w": [],
},
"n:g:z:rdf_viewer:json_ld": { // highlight.js JSON
"ng:n": "JSON-LD Source",
"ng:a": "View the RDF Graph in JSON-LD format",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:rdf_viewer:json_ld",
"ng:b": "JsonLdSourceViewer",
"ng:o": ["data:graph"],
"ng:w": [],
},
"n:g:z:ontology_editor": {
"ng:n": "Ontology Editor",
"ng:a": "Edit the Ontology",
"ng:c": "app",
"ng:u": "json_ld_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:ontology_editor",
"ng:b": "OntologyEditor",
"ng:o": [],
"ng:w": ["schema*"],
},
"n:g:z:ontology_viewer": {
"ng:n": "Ontology",
"ng:a": "View the OWL Ontology",
"ng:c": "app",
"ng:u": "ontology_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:ontology_viewer",
"ng:b": "OntologyViewer", // display with https://github.com/VisualDataWeb/WebVOWL
"ng:o": ["schema*"],
"ng:w": [],
},
"n:g:z:sparql:invoke": { // displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:n": "SPARQL Invoke",
"ng:a": "View and invoke the saved SPARQL query",
"ng:c": "app",
"ng:u": "invoke",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql:invoke",
"ng:b": "SparqlInvoker",
"ng:o": ["query:sparql","query:sparql_update"],
"ng:w": [],
},
"n:g:z:graphql:invoke": {
"ng:n": "GraphQL Invoke",
"ng:a": "View and invoke the saved GraphQL query",
"ng:c": "app",
"ng:u": "invoke",//favicon. can be a did:ng:j
"ng:g": "n:g:z:graphql:invoke",
"ng:b": "GraphqlInvoker",
"ng:o": ["query:graphql"],
"ng:w": [],
},
"n:g:z:dump_download": {
"ng:n": "Download",
"ng:a": "Download a file containing a document exported data",
"ng:c": "app",
"ng:u": "download",//favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_download",
"ng:b": "Downloader",
"ng:o": ["data:graph","file*","data:*"],
"ng:w": [],
},
"n:g:z:post_rich_editor": {
"ng:n": "Post Editor",
"ng:a": "Edit the post with ProseMirror",
"ng:c": "app",
"ng:u": "edit",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post_rich_editor",
"ng:b": "ProseMirrorEditor",
"ng:o": [],
"ng:w": ["post:rich"],
implemented: true,
},
"n:g:z:post_md_editor": {
"ng:n": "Post MD Editor",
"ng:a": "Edit the post with MilkDown",
"ng:c": "app",
"ng:u": "edit",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post_md_editor",
"ng:b": "MilkDownEditor",
"ng:o": [],
"ng:w": ["post:md"],
"full_width": true,
implemented: true,
},
"n:g:z:code_editor": {
"ng:n": "Text Editor",
"ng:a": "Edit the code/text with CodeMirror",
"ng:c": "app",
"ng:u": "edit",//favicon. can be a did:ng:j
"ng:g": "n:g:z:code_editor",
"ng:b": "CodeMirrorEditor",
"ng:o": [],
"ng:w": ["code*","post:text"],
implemented: true,
},
"n:g:z:file_viewer": {
"ng:n": "File details",
"ng:a": "See details about this file",
"ng:c": "app",
"ng:u": "file",//favicon. can be a did:ng:j
"ng:g": "n:g:z:file_viewer",
"ng:b": "FileDetails",
"ng:o": ["file*"],
"ng:w": ["file*"], // in editor mode: can change the name, and delete the file
},
"n:g:z:file_source": { // only works for files containing text source (SVG, HTML, JS, CSS, etc...)
"ng:n": "File source",
"ng:a": "See the source code of this file",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:file_source",
"ng:b": "FileSource",
"ng:o": ["file:text"],
"ng:w": [],
},
"n:g:z:crdt_source_viewer:xml": {
"ng:n": "XML source",
"ng:a": "See the source code of this document, in XML",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:xml",
"ng:b": "XmlSource", // displayed with highlight.js , with option to download
"ng:o": ["post:rich","post:md","post:html","page","data:xml", "diagram:drawio"],
"ng:w": [],
implemented: true,
},
"n:g:z:viewer:md": {
"ng:n": "MarkDown source",
"ng:a": "See the MarkDown source of this document",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:viewer:md",
"ng:b": "MdSource", // displayed with highlight.js , with option to download
"ng:o": ["post:md"],
"ng:w": [],
implemented: true,
},
"n:g:z:crdt_source_viewer:json": {
"ng:n": "JSON Source",
"ng:a": "See the source code of this document, in JSON",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:json",
"ng:b": "AutomergeJsonSource", // displayed with highlight.js , with option to download
"ng:o": ["data:json", "data:table", "diagram:jsmind", "diagram:gantt", "diagram:excalidraw", "viz:*", "chart:*", "prod:cad"],
"ng:w": [],
"full_width": true,
implemented: true,
},
"n:g:z:crdt_source_viewer:ymap": {
"ng:n": "JSON Source",
"ng:a": "See the source code of this document, in JSON",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:ymap",
"ng:b": "YMapSource", // displayed with highlight.js , with option to download
"ng:o": ["data:map"],
"ng:w": [],
implemented: true,
},
"n:g:z:crdt_source_viewer:yarray": {
"ng:n": "JSON Source",
"ng:a": "See the source code of this document, in JSON",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:yarray",
"ng:b": "YArraySource", // displayed with highlight.js , with option to download
"ng:o": ["data:array"],
"ng:w": [],
implemented: true,
},
"n:g:z:crdt_source_viewer:text": {
"ng:n": "Text source",
"ng:a": "See the source code of this document, in plain-text",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:text",
"ng:b": "TextViewer", // displayed with highlight.js , with option to download and copy paste
"ng:o": ["post:asciidoc", "service*", "contract", "query:sparql*","query:graphql","diagram:mermaid","diagram:graphviz","diagram:flowchart",
"diagram:sequence","diagram:markmap","diagram:mymind","doc:music*", "doc:maths", "doc:chemistry", "doc:ancientscript", "doc:braille", "media:subtitle"],
"ng:w": [],
implemented: true,
},
// "n:g:z:crdt_source_viewer:rdf": {
// "ng:n": "RDF source",
// "ng:a": "See the source graph of this document, in RDF (turtle)",
// "ng:c": "app",
// "ng:u": "source",//favicon. can be a did:ng:j
// "ng:g": "n:g:z:crdt_source_viewer:rdf",
// "ng:b": "TurtleViewer", //, with option to download
// "ng:o": ["data:graph"],
// "ng:w": [],
// implemented: true,
// },
"n:g:z:post:rich": {
"ng:n": "Post",
"ng:a": "View a Rich Post",
"ng:c": "app",
"ng:u": "post",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post:rich",
"ng:b": "ProseMirrorViewer", // https://www.npmjs.com/package/prosemirror-to-html-js or https://prosemirror.net/docs/ref/version/0.4.0.html#toDOM https://prosemirror.net/docs/ref/version/0.4.0.html#toHTML
"ng:o": ["post:rich"],
"ng:w": [],
implemented: true,
},
"n:g:z:post:md": {
"ng:n": "Post",
"ng:a": "View a Markdown Post",
"ng:c": "app",
"ng:u": "post",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post:md",
"ng:b": "PostMdViewer", // https://github.com/wooorm/markdown-rs
"ng:o": ["post:md"],
"ng:w": [],
implemented: true,
},
"n:g:z:compose:editor": {
"ng:n": "Composition Editor",
"ng:a": "Compose several blocks into a single document",
"ng:c": "app",
"ng:u": "compose",//favicon. can be a did:ng:j
"ng:g": "n:g:z:compose:editor",
"ng:b": "ComposeEditor",
"ng:w": ["doc:compose"],
},
"n:g:z:compose:viewer": {
"ng:n": "Composition",
"ng:a": "Composition of several blocks",
"ng:c": "app",
"ng:u": "compose",//favicon. can be a did:ng:j
"ng:g": "n:g:z:compose:viewer",
"ng:b": "ComposeViewer",
"ng:o": ["doc:compose"],
},
"n:g:z:post:text": {
"ng:n": "Text",
"ng:a": "View a Text Post",
"ng:c": "app",
"ng:u": "post",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post:text",
"ng:b": "TextViewer",
"ng:o": ["post:text"],
"ng:w": [],
implemented: true,
},
"n:g:z:pre": {
"ng:n": "Source Code",
"ng:a": "View a Source Code",
"ng:c": "app",
"ng:u": "post",//favicon. can be a did:ng:j
"ng:g": "n:g:z:pre",
"ng:b": "TextViewer", // displayed with highlight.js
"ng:o": ["code*"],
"ng:w": [],
implemented: true,
},
"n:g:z:pad": {
"ng:n": "Pad",
"ng:a": "Pad view of a document",
"ng:c": "app",
"ng:u": "pad",//favicon. can be a did:ng:j
"ng:g": "n:g:z:pad",
"ng:b": "Pad",
"ng:o": ["plato:pad"],
"ng:w": [],
},
"n:g:z:card": {
"ng:n": "Card",
"ng:a": "Card view of a document",
"ng:c": "app",
"ng:u": "card",//favicon. can be a did:ng:j
"ng:g": "n:g:z:card",
"ng:b": "Card",
"ng:o": ["plato:card"],
"ng:w": [],
},
"n:g:z:gallery": {
"ng:n": "Gallery",
"ng:a": "Gallery view of an album or collection",
"ng:c": "app",
"ng:u": "gallery",//favicon. can be a did:ng:j
"ng:g": "n:g:z:gallery",
"ng:b": "Gallery",
"ng:o": ["media:album","data:collection"],
"ng:w": [],
},
"n:g:z:app_store": {
"ng:n": "App Store",
"ng:a": "Install or remove Apps of NextGraph ecosystem",
"ng:c": "app",
"ng:u": "app_store",//favicon. can be a did:ng:j
"ng:g": "n:g:z:app_store",
"ng:b": "AppStore",
"ng:o": ["app:z"],
"ng:w": [],
},
"n:g:z:app_editor": {
"ng:n": "App editor",
"ng:a": "Create and modify Apps with NextGraph IDE",
"ng:c": "app",
"ng:u": "app_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:app_editor",
"ng:b": "AppEditor",
"ng:o": ["app:z"],
"ng:w": ["app:z"],
},
"n:g:z:container": {
"ng:n": "Container",
"ng:a": "See the content of document as a Container",
"ng:c": "app",
"ng:u": "container",//favicon. can be a did:ng:j
"ng:g": "n:g:z:container",
"ng:b": "ContainerView",
implemented: true,
"ng:o": ["data:collection","data:container"],
"ng:w": ["data:collection","data:container"],
},
"n:g:z:grid": {
"ng:n": "Grid",
"ng:a": "See the content of document as a grid",
"ng:c": "app",
"ng:u": "grid",//favicon. can be a did:ng:j
"ng:g": "n:g:z:grid",
"ng:b": "GridView",
"ng:o": ["data:grid"],
"ng:w": ["data:grid"],
},
"n:g:z:media": {
"ng:n": "Media",
"ng:a": "View media",
"ng:c": "app",
"ng:u": "view",//favicon. can be a did:ng:j
"ng:g": "n:g:z:media",
"ng:b": "MediaView",
"ng:o": ["media:*"],
"ng:w": [],
},
"n:g:z:service_editor": {
"ng:n": "Service Editor",
"ng:a": "Write and define a Service in Rust or JS/Deno",
"ng:c": "app",
"ng:u": "edit",//favicon. can be a did:ng:j
"ng:g": "n:g:z:service_editor",
"ng:b": "CodeMirrorEditor",
"ng:o": [],
"ng:w": ["service:*"],
},
"n:g:z:service_invoke": {
"ng:n": "Service Invoker",
"ng:a": "Invoke internal Service, with optional arguments",
"ng:c": "app",
"ng:u": "invoke",//favicon. can be a did:ng:j
"ng:g": "n:g:z:service_invoke",
"ng:b": "ServiceInvoker",
"ng:o": ["service"],
"ng:w": [],
},
"n:g:z:external_service_invoke": {
"ng:n": "Service Invoker",
"ng:a": "Invoke the Service, with optional arguments",
"ng:c": "app",
"ng:u": "invoke",//favicon. can be a did:ng:j
"ng:g": "n:g:z:external_service_invoke",
"ng:b": "ExternalServiceInvoker",
"ng:o": ["service:*"],
"ng:w": [],
},
"n:g:z:upload_file": {
"ng:n": "Upload binary file",
"ng:a": "Upload a binary file into the Document",
"ng:c": "app",
"ng:u": "load",//favicon. can be a did:ng:j
"ng:g": "n:g:z:upload_file",
"ng:b": "UploadFile",
"ng:o": [],
"ng:w": [],
},
"n:g:z:import_file": {
"ng:n": "Import from external file",
"ng:a": "Import an external file with compatible format",
"ng:c": "app",
"ng:u": "load_graph",//favicon. can be a did:ng:j
"ng:g": "n:g:z:import_file",
"ng:b": "UploadFile",
"ng:o": [],
"ng:w": ["data:graph"],
},
// TODO: "n:g:z:columns", "n:g:z:tree", "n:g:z:summary", "n:g:z:list_n_post", "n:g:z:grid_n_post", "n:g:z:board",
// TODO: "n:g:z:map", "n:g:z:chart", "n:g:z:pivot", "n:g:z:timeline", "n:g:z:email", "n:g:z:web_archive", "n:g:z:diagram_editor", "n:g:z:pdf", "n:g:z:latex", "n:g:z:media_editor",
// TODO: "n:g:z:contract", "n:g:z:text_query", "n:g:z:web_query", "n:g:z:scan_qrcode",
// TODO: "n:g:z:messenger", "n:g:z:group", "n:g:z:contact", "n:g:z:event", "n:g:z:calendar", "n:g:z:scheduler",
// TODO: "n:g:z:task", "n:g:z:project", "n:g:z:issue", "n:g:z:form_editor", "n:g:z:form_filler", "n:g:z:cad", "n:g:z:slides", "n:g:z:question", "n:g:z:poll",
};
// OFFICIAL SERVICES
//"n:g:z:dump_rdf:turtle", "n:g:z:dump_rdf:n3", "n:g:z:dump_rdf:json_ld", "n:g:z:load_rdf:turtle", "n:g:z:load_rdf:n3", "n:g:z:load_rdf:json_ld", "n:g:z:load_file", "n:g:z:dump_file",
//"n:g:z:dump_json", "n:g:z:dump_xml", "n:g:z:dump_text", "n:g:z:load_json", "n:g:z:load_xml", "n:g:z:load_text", "n:g:z:load_md", "n:g:z:sparql_query", "n:g:z:sparql_update", "n:g:z:dump_crdt_source", "n:g:z:dump_ng_html_file", "n:g:z:dump_ng_file"
export const official_services = {
"n:g:z:dump_rdf:turtle": {
"ng:n": "Turtle export",
"ng:a": "Export quads of RDF Graphs in Turtle format",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_rdf:turtle",
"ng:o": ["data:graph"],
"ng:w": [],
"ng:result": ["file:iana:text:turtle"],
},
"n:g:z:dump_rdf:n3": {
"ng:n": "N3 export",
"ng:a": "Export quads of RDF Graphs in N3 format",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_rdf:n3",
"ng:o": ["data:graph"],
"ng:w": [],
"ng:result": ["file:iana:text:n3"],
},
"n:g:z:dump_rdf:json_ld": {
"ng:n": "JSON-LD export",
"ng:a": "Export quads of RDF Graphs in JSON-LD format",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_rdf:json_ld",
"ng:o": ["data:graph"],
"ng:w": [],
"ng:result": ["file:iana:application:ld+json"],
},
"n:g:z:load_rdf:turtle": {
"ng:n": "Import Turtle triples",
"ng:a": "Import Turtle triples into the document",
"ng:c": "service",
"ng:u": "load_graph",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_rdf:turtle",
"ng:o": [],
"ng:w": ["data:graph"],
},
"n:g:z:load_rdf:n3": {
"ng:n": "Import N3 triples",
"ng:a": "Import N3 triples into the document",
"ng:c": "service",
"ng:u": "load_graph",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_rdf:n3",
"ng:o": [],
"ng:w": ["data:graph"],
},
"n:g:z:load_rdf:json_ld": {
"ng:n": "Import JSON-LD triples",
"ng:a": "Import JSON-LD triples into the document",
"ng:c": "service",
"ng:u": "load_graph",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_rdf:json_ld",
"ng:o": [],
"ng:w": ["data:graph"],
},
"n:g:z:load_file": {
"ng:n": "Add file",
"ng:a": "Add a binary file in the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_file",
"ng:o": [],
"ng:w": ["data:graph"],
},
"n:g:z:dump_file": {
"ng:n": "Export File",
"ng:a": "Get the binary content of a file",
"ng:c": "service",
"ng:u": "dump",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_file",
"ng:o": ["file*"],
"ng:result": ["file:iana:*"],
},
"n:g:z:dump_json": {
"ng:n": "Export JSON",
"ng:a": "Export JSON content of document",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_json",
"ng:o": ["data:json", "data:map", "data:array", "data:table", "diagram:jsmind", "diagram:gantt", "diagram:excalidraw", "viz:*", "chart:*", "prod:cad"],
"ng:w": [],
"ng:result": ["file:iana:application:json"],
},
"n:g:z:dump_xml": {
"ng:n": "Export XML",
"ng:a": "Export XML content of document",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_xml",
"ng:o": ["post:rich","post:md","post:html","page","data:xml", "diagram:drawio"],
"ng:w": [],
"ng:result": ["file:iana:text:xml"],
},
"n:g:z:dump_text": {
"ng:n": "Export Text",
"ng:a": "Export plain-text content of document",
"ng:c": "service",
"ng:u": "dump",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_text",
"ng:o": ["post:text", "post:asciidoc", "code*", "service*", "contract", "query:sparql*","query:graphql","diagram:mermaid","diagram:graphviz","diagram:flowchart",
"diagram:sequence","diagram:markmap","diagram:mymind","doc:music*", "doc:maths", "doc:chemistry", "doc:ancientscript", "doc:braille", "media:subtitle"],
"ng:w": [],
"ng:result": ["file:iana:text:plain"],
},
"n:g:z:dump_ng_html_file": {
"ng:n": "NextGraph Standalone file",
"ng:a": "Get a standalone HTML file of this Document",
"ng:c": "service",
"ng:u": "ext",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_ng_html_file",
"ng:o": ["data:graph"],
"ng:w": [],
"ng:result": ["file:iana:text:html"],
},
"n:g:z:load_json": {
"ng:n": "Import JSON",
"ng:a": "Import some JSON into the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_json",
"ng:o": [],
"ng:w": ["data:json","data:map", "data:array"],
},
"n:g:z:load_xml": {
"ng:n": "Import XML",
"ng:a": "Import some XML into the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_xml",
"ng:o": [],
"ng:w": ["data:xml"],
},
"n:g:z:load_text": {
"ng:n": "Import Text",
"ng:a": "Import plain text into the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_text",
"ng:o": [],
"ng:w": ["post:text","post:rich","post:md","code*"],
},
"n:g:z:load_md": {
"ng:n": "Import Markdown",
"ng:a": "Import some Markdown into the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_md",
"ng:o": [],
"ng:w": ["post:md"],
},
"n:g:z:sparql_query": {
"ng:n": "SPARQL query",
"ng:a": "Invoke a SPARQL Query",
"ng:c": "service",
"ng:u": "sparql_query",// favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_query",
"ng:o": ["data:graph"],
"ng:w": [],
"ng:result": ["file:iana:application:sparql-results+json","file:iana:application:json"]
},
"n:g:z:sparql_update": {
"ng:n": "SPARQL update",
"ng:a": "Invoke a SPARQL Update",
"ng:c": "service",
"ng:u": "sparql_query",// favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_update",
"ng:o": [],
"ng:w": ["data:graph"],
},
"n:g:z:dump_crdt_source": { // uses dump_rdf, dump_text, dump_json or dump_xml depending on the CRDT type
"ng:n": "Export source",
"ng:a": "Export source of document as text file",
"ng:c": "service",
"ng:u": "source",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_crdt_source",
"ng:o": ["data:graph"],
"ng:w": [],
"ng:result": ["file:iana:*"]
},
};

@ -0,0 +1,11 @@
// svelte.config.js
export default {
compilerOptions: {
experimental: {
async: true
}
},
vitePlugin: {
//inspector: true
}
};

@ -0,0 +1,5 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html","./src/**/*.{js,ts,jsx,svelte,tsx,html}"],
plugins: [],
};

@ -1,6 +1,8 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "ES2020",
"verbatimModuleSyntax": false,
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",

@ -1,5 +1,8 @@
import { defineConfig, UserConfig, PluginOption } from "vite";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import svelteSVG from "@hazycora/vite-plugin-svelte-svg";
import { resolve } from "node:path";
import { viteSingleFile } from "vite-plugin-singlefile"
import wasm from "vite-plugin-wasm";
@ -13,9 +16,28 @@ export default defineConfig((): UserConfig => {
const config = {
worker: {
format: 'es' as "es" | "iife",
},
plugins: [react()],
plugins: [tailwindcss(),react(),svelte(),
svelteSVG({
svgoConfig: {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
// disable plugins
removeViewBox: false,
},
},
},
{
name: 'prefixIds',
}
],
}, // See https://github.com/svg/svgo#configuration
requireSuffix: true, // Set false to accept '.svg' without the '?component'
})
],
base: "/",
resolve: {
alias: {

@ -99,30 +99,12 @@ importers:
app/ui-common:
dependencies:
'@sindresorhus/is':
specifier: 4.6.0
version: 4.6.0
'@tailwindcss/typography':
specifier: ^0.5.13
version: 0.5.19(tailwindcss@3.4.18)
async-proxy:
specifier: ^0.4.1
version: 0.4.1
char-regex:
specifier: 1.0.2
version: 1.0.2
classnames:
specifier: ^2.3.2
version: 2.5.1
debug:
specifier: ^4.3.6
version: 4.4.3
emojilib:
specifier: 2.4.0
version: 2.4.0
extend:
specifier: 3.0.2
version: 3.0.2
flowbite:
specifier: ^1.6.5
version: 1.8.1
@ -132,76 +114,34 @@ importers:
html5-qrcode:
specifier: ^2.3.8
version: 2.3.8
immutable-json-patch:
specifier: ^6.0.1
version: 6.0.2
lodash.debounce:
specifier: 4.0.8
version: 4.0.8
skin-tone:
specifier: 2.0.0
version: 2.0.0
style-mod:
specifier: ^4.1.2
version: 4.1.2
svelte-i18n:
specifier: ^4.0.0
version: 4.0.1(svelte@3.59.2)
svelte-inview:
specifier: ^4.0.2
version: 4.0.4(svelte@3.59.2)
svelte-spa-router:
specifier: ^3.3.0
version: 3.3.0
vite-plugin-top-level-await:
specifier: 1.3.1
version: 1.3.1(@swc/helpers@0.5.17)(rollup@4.50.2)(vite@4.2.1(@types/node@18.19.124))
xml-beautifier:
specifier: ^0.5.0
version: 0.5.0
version: 1.3.1(@swc/helpers@0.5.17)(rollup@4.50.2)(vite@4.2.1(@types/node@24.3.0))
devDependencies:
'@sveltejs/vite-plugin-svelte':
specifier: 2.0.0
version: 2.0.0(svelte@3.59.2)(vite@4.2.1(@types/node@18.19.124))
'@swc/core':
specifier: ~1.6.0
version: 1.6.13(@swc/helpers@0.5.17)
version: 2.0.0(svelte@3.59.2)(vite@4.2.1(@types/node@24.3.0))
'@tsconfig/svelte':
specifier: ^3.0.0
version: 3.0.0
'@types/node':
specifier: ^18.7.10
version: 18.19.124
autoprefixer:
specifier: ^10.4.14
version: 10.4.21(postcss@8.5.6)
dayjs:
specifier: ^1.11.10
version: 1.11.18
internal-ip:
specifier: ^7.0.0
version: 7.0.0
postcss:
specifier: ^8.4.23
version: 8.5.6
postcss-load-config:
specifier: ^4.0.1
version: 4.0.2(postcss@8.5.6)
prettier:
specifier: ^3.3.2
version: 3.6.2
prettier-plugin-svelte:
specifier: ^3.2.5
version: 3.4.0(prettier@3.6.2)(svelte@3.59.2)
shx:
specifier: ^0.3.4
version: 0.3.4
svelte:
specifier: ^3.54.0
version: 3.59.2
svelte-check:
specifier: ^3.0.0
version: 3.8.6(@babel/core@7.28.4)(postcss-load-config@4.0.2(postcss@8.5.6))(postcss@8.5.6)(svelte@3.59.2)
svelte-heros-v2:
specifier: ^1.3.0
version: 1.3.0(svelte@3.59.2)
@ -214,21 +154,18 @@ importers:
tailwindcss:
specifier: ^3.3.1
version: 3.4.18
tslib:
specifier: ^2.4.1
version: 2.8.1
typescript:
specifier: ^4.9.5
version: 4.9.5
vite:
specifier: 4.2.1
version: 4.2.1(@types/node@18.19.124)
version: 4.2.1(@types/node@24.3.0)
vite-plugin-svelte-svg:
specifier: 2.2.1
version: 2.2.1(svelte@3.59.2)(vite@4.2.1(@types/node@18.19.124))
version: 2.2.1(svelte@3.59.2)(vite@4.2.1(@types/node@24.3.0))
vite-plugin-wasm:
specifier: 3.2.2
version: 3.2.2(vite@4.2.1(@types/node@18.19.124))
version: 3.2.2(vite@4.2.1(@types/node@24.3.0))
engine/broker/auth:
dependencies:
@ -858,10 +795,10 @@ importers:
version: 4.3.0(@types/node@24.3.0)(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(jiti@2.6.1)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(yaml@2.8.1)
'@astrojs/svelte':
specifier: 7.1.0
version: 7.1.0(@types/node@24.3.0)(astro@5.13.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1))(jiti@2.6.1)(lightningcss@1.30.1)(svelte@5.39.12)(typescript@5.9.2)(yaml@2.8.1)
version: 7.1.0(@types/node@24.3.0)(astro@5.13.2(@types/node@24.3.0)(encoding@0.1.13)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1))(jiti@2.6.1)(lightningcss@1.30.1)(svelte@5.39.12)(typescript@5.9.2)(yaml@2.8.1)
'@astrojs/vue':
specifier: ^5.1.0
version: 5.1.1(@types/node@24.3.0)(astro@5.13.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1))(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(vue@3.5.19(typescript@5.9.2))(yaml@2.8.1)
version: 5.1.1(@types/node@24.3.0)(astro@5.13.2(@types/node@24.3.0)(encoding@0.1.13)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1))(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(vue@3.5.19(typescript@5.9.2))(yaml@2.8.1)
'@gn8/alien-signals-react':
specifier: ^0.1.1
version: 0.1.1(alien-signals@2.0.7)(react@19.1.1)
@ -894,7 +831,7 @@ importers:
version: 2.0.7
astro:
specifier: 5.13.2
version: 5.13.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1)
version: 5.13.2(@types/node@24.3.0)(encoding@0.1.13)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1)
install:
specifier: ^0.13.0
version: 0.13.0
@ -2674,10 +2611,6 @@ packages:
'@sinclair/typebox@0.27.8':
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
'@sindresorhus/is@4.6.0':
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
engines: {node: '>=10'}
'@sindresorhus/merge-streams@4.0.0':
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'}
@ -3966,10 +3899,6 @@ packages:
resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
char-regex@1.0.2:
resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
engines: {node: '>=10'}
character-entities-html4@2.1.0:
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
@ -4228,10 +4157,6 @@ packages:
resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==}
engines: {node: '>=18'}
default-gateway@6.0.3:
resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==}
engines: {node: '>= 10'}
define-lazy-prop@3.0.0:
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
engines: {node: '>=12'}
@ -4337,9 +4262,6 @@ packages:
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
emojilib@2.4.0:
resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==}
encoding@0.1.13:
resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
@ -4530,10 +4452,6 @@ packages:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
execa@9.6.0:
resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==}
engines: {node: ^18.19.0 || >=20.5.0}
@ -4697,10 +4615,6 @@ packages:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
get-stream@6.0.1:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
engines: {node: '>=10'}
get-stream@9.0.1:
resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==}
engines: {node: '>=18'}
@ -4870,10 +4784,6 @@ packages:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
human-signals@2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
human-signals@8.0.1:
resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==}
engines: {node: '>=18.18.0'}
@ -4893,9 +4803,6 @@ packages:
resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
engines: {node: '>= 4'}
immutable-json-patch@6.0.2:
resolution: {integrity: sha512-KwCA5DXJiyldda8SPha1zB+6+vbEi5/jRRcYii/6yFXlyu9ZjiSH/wPq8Ri2Hk8iGjjTMcHW3Z21S4MOpl7sOw==}
immutable@4.3.7:
resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
@ -4929,10 +4836,6 @@ packages:
resolution: {integrity: sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==}
engines: {node: '>= 0.10'}
internal-ip@7.0.0:
resolution: {integrity: sha512-qE4TeD4brqC45Vq/+VASeMiS1KRyfBkR6HT2sh9pZVVCzSjPkaCEfKFU+dL0PRv7NHJtvoKN2r82G6wTfzorkw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
interpret@1.4.0:
resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
engines: {node: '>= 0.10'}
@ -4940,10 +4843,6 @@ packages:
intl-messageformat@10.7.18:
resolution: {integrity: sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==}
ip-regex@4.3.0:
resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==}
engines: {node: '>=8'}
ip-regex@5.0.0:
resolution: {integrity: sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -4988,10 +4887,6 @@ packages:
engines: {node: '>=14.16'}
hasBin: true
is-ip@3.1.0:
resolution: {integrity: sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==}
engines: {node: '>=8'}
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
@ -5256,9 +5151,6 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
@ -5373,9 +5265,6 @@ packages:
resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==}
engines: {node: '>=0.12'}
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@ -5479,10 +5368,6 @@ packages:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
min-indent@1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
@ -5635,10 +5520,6 @@ packages:
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
engines: {node: '>=0.10.0'}
npm-run-path@4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
npm-run-path@6.0.0:
resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==}
engines: {node: '>=18'}
@ -5750,10 +5631,6 @@ packages:
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
onetime@5.1.2:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
engines: {node: '>=6'}
oniguruma-parser@0.12.1:
resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==}
@ -5768,14 +5645,6 @@ packages:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
p-event@4.2.0:
resolution: {integrity: sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==}
engines: {node: '>=8'}
p-finally@1.0.0:
resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==}
engines: {node: '>=4'}
p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
@ -5792,10 +5661,6 @@ packages:
resolution: {integrity: sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==}
engines: {node: '>=18'}
p-timeout@3.2.0:
resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==}
engines: {node: '>=8'}
p-timeout@6.1.4:
resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==}
engines: {node: '>=14.16'}
@ -6197,10 +6062,6 @@ packages:
remark-stringify@11.0.0:
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
repeat-string@1.6.1:
resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==}
engines: {node: '>=0.10'}
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
@ -6371,9 +6232,6 @@ packages:
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
@ -6388,10 +6246,6 @@ packages:
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
skin-tone@2.0.0:
resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==}
engines: {node: '>=8'}
slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
@ -6485,10 +6339,6 @@ packages:
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
engines: {node: '>=12'}
strip-final-newline@2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
strip-final-newline@4.0.0:
resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==}
engines: {node: '>=18'}
@ -6504,9 +6354,6 @@ packages:
strip-literal@3.0.0:
resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==}
style-mod@4.1.2:
resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
sucrase@3.35.0:
resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
engines: {node: '>=16 || 14 >=14.17'}
@ -6532,12 +6379,6 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
svelte-check@3.8.6:
resolution: {integrity: sha512-ij0u4Lw/sOTREP13BdWZjiXD/BlHE6/e2e34XzmVmsp5IN4kVa3PWP65NM32JAgwjZlwBg/+JtiNV1MM8khu0Q==}
hasBin: true
peerDependencies:
svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0
svelte-check@4.3.3:
resolution: {integrity: sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==}
engines: {node: '>= 18.0.0'}
@ -6564,11 +6405,6 @@ packages:
peerDependencies:
svelte: ^3 || ^4 || ^5
svelte-inview@4.0.4:
resolution: {integrity: sha512-PlXNSHHijvQ6MhmSYUj6cMyS+39NttoTffk7W5WYF8T2tsyLgJnKhyuAF+/hSujbY0vpsmqXaMd2nolEKvR8Kw==}
peerDependencies:
svelte: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^5.0.0-next
svelte-preprocess@5.1.4:
resolution: {integrity: sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==}
engines: {node: '>= 16.0.0'}
@ -6885,10 +6721,6 @@ packages:
undici-types@7.10.0:
resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==}
unicode-emoji-modifier-base@1.0.0:
resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==}
engines: {node: '>=4'}
unicode-properties@1.4.1:
resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==}
@ -7450,9 +7282,6 @@ packages:
resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==}
engines: {node: '>=18'}
xml-beautifier@0.5.0:
resolution: {integrity: sha512-QG/qiHeolHUd1tAtM+5zHxTzDprb8qvhmIYUYV1E9QK/jTFlrAa1Mz7QQqJPeqc3uuFAGzTOhjvbdx2hOP6bHw==}
xml-name-validator@5.0.0:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}
@ -7691,10 +7520,10 @@ snapshots:
- tsx
- yaml
'@astrojs/svelte@7.1.0(@types/node@24.3.0)(astro@5.13.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1))(jiti@2.6.1)(lightningcss@1.30.1)(svelte@5.39.12)(typescript@5.9.2)(yaml@2.8.1)':
'@astrojs/svelte@7.1.0(@types/node@24.3.0)(astro@5.13.2(@types/node@24.3.0)(encoding@0.1.13)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1))(jiti@2.6.1)(lightningcss@1.30.1)(svelte@5.39.12)(typescript@5.9.2)(yaml@2.8.1)':
dependencies:
'@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.39.12)(vite@6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))
astro: 5.13.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1)
astro: 5.13.2(@types/node@24.3.0)(encoding@0.1.13)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1)
svelte: 5.39.12
svelte2tsx: 0.7.43(svelte@5.39.12)(typescript@5.9.2)
typescript: 5.9.2
@ -7747,12 +7576,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@astrojs/vue@5.1.1(@types/node@24.3.0)(astro@5.13.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1))(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(vue@3.5.19(typescript@5.9.2))(yaml@2.8.1)':
'@astrojs/vue@5.1.1(@types/node@24.3.0)(astro@5.13.2(@types/node@24.3.0)(encoding@0.1.13)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1))(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(vue@3.5.19(typescript@5.9.2))(yaml@2.8.1)':
dependencies:
'@vitejs/plugin-vue': 5.2.1(vite@6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.19(typescript@5.9.2))
'@vitejs/plugin-vue-jsx': 4.2.0(vite@6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.19(typescript@5.9.2))
'@vue/compiler-sfc': 3.5.21
astro: 5.13.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1)
astro: 5.13.2(@types/node@24.3.0)(encoding@0.1.13)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1)
vite: 6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite-plugin-vue-devtools: 7.7.7(rollup@4.50.2)(vite@6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.19(typescript@5.9.2))
vue: 3.5.19(typescript@5.9.2)
@ -8004,7 +7833,7 @@ snapshots:
dependencies:
buffer: 6.0.3
'@capsizecss/unpack@2.4.0':
'@capsizecss/unpack@2.4.0(encoding@0.1.13)':
dependencies:
blob-to-buffer: 1.2.9
cross-fetch: 3.2.0(encoding@0.1.13)
@ -9497,8 +9326,6 @@ snapshots:
'@sinclair/typebox@0.27.8': {}
'@sindresorhus/is@4.6.0': {}
'@sindresorhus/merge-streams@4.0.0': {}
'@solid-notifications/discovery@0.1.2(encoding@0.1.13)':
@ -9547,7 +9374,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@sveltejs/vite-plugin-svelte@2.0.0(svelte@3.59.2)(vite@4.2.1(@types/node@18.19.124))':
'@sveltejs/vite-plugin-svelte@2.0.0(svelte@3.59.2)(vite@4.2.1(@types/node@24.3.0))':
dependencies:
debug: 4.4.3
deepmerge: 4.3.1
@ -9555,8 +9382,8 @@ snapshots:
magic-string: 0.27.0
svelte: 3.59.2
svelte-hmr: 0.15.3(svelte@3.59.2)
vite: 4.2.1(@types/node@18.19.124)
vitefu: 0.2.5(vite@4.2.1(@types/node@18.19.124))
vite: 4.2.1(@types/node@24.3.0)
vitefu: 0.2.5(vite@4.2.1(@types/node@24.3.0))
transitivePeerDependencies:
- supports-color
@ -10213,21 +10040,21 @@ snapshots:
chai: 5.3.3
tinyrainbow: 2.0.0
'@vitest/mocker@3.2.4(vite@7.1.10(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))':
'@vitest/mocker@3.2.4(vite@6.3.6(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
magic-string: 0.30.19
optionalDependencies:
vite: 7.1.10(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite: 6.3.6(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
'@vitest/mocker@3.2.4(vite@7.1.10(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))':
'@vitest/mocker@3.2.4(vite@6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
magic-string: 0.30.19
optionalDependencies:
vite: 7.1.10(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite: 6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
'@vitest/pretty-format@3.2.4':
dependencies:
@ -11036,13 +10863,13 @@ snapshots:
estree-walker: 3.0.3
js-tokens: 9.0.1
astro@5.13.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1):
astro@5.13.2(@types/node@24.3.0)(encoding@0.1.13)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.50.2)(typescript@5.9.2)(yaml@2.8.1):
dependencies:
'@astrojs/compiler': 2.13.0
'@astrojs/internal-helpers': 0.7.2
'@astrojs/markdown-remark': 6.3.6
'@astrojs/telemetry': 3.3.0
'@capsizecss/unpack': 2.4.0
'@capsizecss/unpack': 2.4.0(encoding@0.1.13)
'@oslojs/encoding': 1.1.0
'@rollup/pluginutils': 5.3.0(rollup@4.50.2)
acorn: 8.15.0
@ -11415,8 +11242,6 @@ snapshots:
chalk@5.6.2: {}
char-regex@1.0.2: {}
character-entities-html4@2.1.0: {}
character-entities-legacy@3.0.0: {}
@ -11653,10 +11478,6 @@ snapshots:
bundle-name: 4.1.0
default-browser-id: 5.0.0
default-gateway@6.0.3:
dependencies:
execa: 5.1.1
define-lazy-prop@3.0.0: {}
defu@6.1.4: {}
@ -11741,8 +11562,6 @@ snapshots:
emoji-regex@9.2.2: {}
emojilib@2.4.0: {}
encoding@0.1.13:
dependencies:
iconv-lite: 0.6.3
@ -12079,18 +11898,6 @@ snapshots:
events@3.3.0: {}
execa@5.1.1:
dependencies:
cross-spawn: 7.0.6
get-stream: 6.0.1
human-signals: 2.1.0
is-stream: 2.0.1
merge-stream: 2.0.0
npm-run-path: 4.0.1
onetime: 5.1.2
signal-exit: 3.0.7
strip-final-newline: 2.0.0
execa@9.6.0:
dependencies:
'@sindresorhus/merge-streams': 4.0.0
@ -12286,8 +12093,6 @@ snapshots:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
get-stream@6.0.1: {}
get-stream@9.0.1:
dependencies:
'@sec-ant/readable-stream': 0.4.1
@ -12542,8 +12347,6 @@ snapshots:
- supports-color
optional: true
human-signals@2.1.0: {}
human-signals@8.0.1: {}
iconv-lite@0.6.3:
@ -12557,8 +12360,6 @@ snapshots:
ignore@7.0.5: {}
immutable-json-patch@6.0.2: {}
immutable@4.3.7: {}
import-fresh@3.3.1:
@ -12583,13 +12384,6 @@ snapshots:
install@0.13.0: {}
internal-ip@7.0.0:
dependencies:
default-gateway: 6.0.3
ipaddr.js: 2.2.0
is-ip: 3.1.0
p-event: 4.2.0
interpret@1.4.0: {}
intl-messageformat@10.7.18:
@ -12599,8 +12393,6 @@ snapshots:
'@formatjs/icu-messageformat-parser': 2.11.4
tslib: 2.8.1
ip-regex@4.3.0: {}
ip-regex@5.0.0: {}
ipaddr.js@2.2.0: {}
@ -12632,10 +12424,6 @@ snapshots:
dependencies:
is-docker: 3.0.0
is-ip@3.1.0:
dependencies:
ip-regex: 4.3.0
is-number@7.0.0: {}
is-path-inside@3.0.3: {}
@ -12911,8 +12699,6 @@ snapshots:
dependencies:
p-locate: 5.0.0
lodash.debounce@4.0.8: {}
lodash.merge@4.6.2: {}
lodash.sortby@4.7.0: {}
@ -13112,8 +12898,6 @@ snapshots:
next-tick: 1.1.0
timers-ext: 0.1.8
merge-stream@2.0.0: {}
merge2@1.4.1: {}
microdata-rdf-streaming-parser@2.0.1:
@ -13326,8 +13110,6 @@ snapshots:
dependencies:
mime-db: 1.52.0
mimic-fn@2.1.0: {}
min-indent@1.0.1: {}
mini-svg-data-uri@1.4.4: {}
@ -13448,10 +13230,6 @@ snapshots:
normalize-range@0.1.2: {}
npm-run-path@4.0.1:
dependencies:
path-key: 3.1.1
npm-run-path@6.0.0:
dependencies:
path-key: 4.0.0
@ -13495,10 +13273,6 @@ snapshots:
dependencies:
wrappy: 1.0.2
onetime@5.1.2:
dependencies:
mimic-fn: 2.1.0
oniguruma-parser@0.12.1: {}
oniguruma-to-es@4.3.3:
@ -13523,12 +13297,6 @@ snapshots:
type-check: 0.4.0
word-wrap: 1.2.5
p-event@4.2.0:
dependencies:
p-timeout: 3.2.0
p-finally@1.0.0: {}
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
@ -13546,10 +13314,6 @@ snapshots:
eventemitter3: 5.0.1
p-timeout: 6.1.4
p-timeout@3.2.0:
dependencies:
p-finally: 1.0.0
p-timeout@6.1.4: {}
package-json-from-dist@1.0.1: {}
@ -13717,11 +13481,6 @@ snapshots:
- supports-color
- typescript
prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@3.59.2):
dependencies:
prettier: 3.6.2
svelte: 3.59.2
prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.39.12):
dependencies:
prettier: 3.6.2
@ -14058,8 +13817,6 @@ snapshots:
mdast-util-to-markdown: 2.1.2
unified: 11.0.5
repeat-string@1.6.1: {}
require-from-string@2.0.2: {}
require-relative@0.8.7: {}
@ -14312,8 +14069,6 @@ snapshots:
siginfo@2.0.0: {}
signal-exit@3.0.7: {}
signal-exit@4.1.0: {}
simple-swizzle@0.2.4:
@ -14329,10 +14084,6 @@ snapshots:
sisteransi@1.0.5: {}
skin-tone@2.0.0:
dependencies:
unicode-emoji-modifier-base: 1.0.0
slash@3.0.0: {}
smol-toml@1.4.2: {}
@ -14433,8 +14184,6 @@ snapshots:
dependencies:
ansi-regex: 6.2.2
strip-final-newline@2.0.0: {}
strip-final-newline@4.0.0: {}
strip-indent@3.0.0:
@ -14447,8 +14196,6 @@ snapshots:
dependencies:
js-tokens: 9.0.1
style-mod@4.1.2: {}
sucrase@3.35.0:
dependencies:
'@jridgewell/gen-mapping': 0.3.13
@ -14475,26 +14222,6 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
svelte-check@3.8.6(@babel/core@7.28.4)(postcss-load-config@4.0.2(postcss@8.5.6))(postcss@8.5.6)(svelte@3.59.2):
dependencies:
'@jridgewell/trace-mapping': 0.3.31
chokidar: 3.6.0
picocolors: 1.1.1
sade: 1.8.1
svelte: 3.59.2
svelte-preprocess: 5.1.4(@babel/core@7.28.4)(postcss-load-config@4.0.2(postcss@8.5.6))(postcss@8.5.6)(svelte@3.59.2)(typescript@5.9.2)
typescript: 5.9.2
transitivePeerDependencies:
- '@babel/core'
- coffeescript
- less
- postcss
- postcss-load-config
- pug
- sass
- stylus
- sugarss
svelte-check@4.3.3(picomatch@4.0.3)(svelte@5.39.13)(typescript@5.6.3):
dependencies:
'@jridgewell/trace-mapping': 0.3.31
@ -14526,10 +14253,6 @@ snapshots:
svelte: 3.59.2
tiny-glob: 0.2.9
svelte-inview@4.0.4(svelte@3.59.2):
dependencies:
svelte: 3.59.2
svelte-preprocess@5.1.4(@babel/core@7.28.4)(postcss-load-config@4.0.2(postcss@8.5.6))(postcss@8.5.6)(svelte@3.59.2)(typescript@4.9.5):
dependencies:
'@types/pug': 2.0.10
@ -14877,8 +14600,6 @@ snapshots:
undici-types@7.10.0: {}
unicode-emoji-modifier-base@1.0.0: {}
unicode-properties@1.4.1:
dependencies:
base64-js: 1.5.1
@ -15100,11 +14821,11 @@ snapshots:
rollup: 4.50.2
vite: 7.1.10(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite-plugin-svelte-svg@2.2.1(svelte@3.59.2)(vite@4.2.1(@types/node@18.19.124)):
vite-plugin-svelte-svg@2.2.1(svelte@3.59.2)(vite@4.2.1(@types/node@24.3.0)):
dependencies:
svelte: 3.59.2
svgo: 3.3.2
vite: 4.2.1(@types/node@18.19.124)
vite: 4.2.1(@types/node@24.3.0)
vite-plugin-svelte-svg@2.2.1(svelte@3.59.2)(vite@4.5.14(@types/node@24.3.0)(lightningcss@1.30.1)):
dependencies:
@ -15112,12 +14833,12 @@ snapshots:
svgo: 3.3.2
vite: 4.5.14(@types/node@24.3.0)(lightningcss@1.30.1)
vite-plugin-top-level-await@1.3.1(@swc/helpers@0.5.17)(rollup@4.50.2)(vite@4.2.1(@types/node@18.19.124)):
vite-plugin-top-level-await@1.3.1(@swc/helpers@0.5.17)(rollup@4.50.2)(vite@4.2.1(@types/node@24.3.0)):
dependencies:
'@rollup/plugin-virtual': 3.0.2(rollup@4.50.2)
'@swc/core': 1.6.13(@swc/helpers@0.5.17)
uuid: 9.0.1
vite: 4.2.1(@types/node@18.19.124)
vite: 4.2.1(@types/node@24.3.0)
transitivePeerDependencies:
- '@swc/helpers'
- rollup
@ -15185,9 +14906,9 @@ snapshots:
transitivePeerDependencies:
- supports-color
vite-plugin-wasm@3.2.2(vite@4.2.1(@types/node@18.19.124)):
vite-plugin-wasm@3.2.2(vite@4.2.1(@types/node@24.3.0)):
dependencies:
vite: 4.2.1(@types/node@18.19.124)
vite: 4.2.1(@types/node@24.3.0)
vite-plugin-wasm@3.2.2(vite@4.5.14(@types/node@24.3.0)(lightningcss@1.30.1)):
dependencies:
@ -15201,14 +14922,14 @@ snapshots:
dependencies:
vite: 7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite@4.2.1(@types/node@18.19.124):
vite@4.2.1(@types/node@24.3.0):
dependencies:
esbuild: 0.17.19
postcss: 8.5.6
resolve: 1.22.10
rollup: 3.29.5
optionalDependencies:
'@types/node': 18.19.124
'@types/node': 24.3.0
fsevents: 2.3.3
vite@4.5.14(@types/node@24.3.0)(lightningcss@1.30.1):
@ -15266,21 +14987,6 @@ snapshots:
lightningcss: 1.30.1
yaml: 2.8.1
vite@7.1.10(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1):
dependencies:
esbuild: 0.25.9
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.50.2
tinyglobby: 0.2.15
optionalDependencies:
'@types/node': 22.18.3
fsevents: 2.3.3
jiti: 2.6.1
lightningcss: 1.30.1
yaml: 2.8.1
vite@7.1.10(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1):
dependencies:
esbuild: 0.25.9
@ -15311,9 +15017,9 @@ snapshots:
lightningcss: 1.30.1
yaml: 2.8.1
vitefu@0.2.5(vite@4.2.1(@types/node@18.19.124)):
vitefu@0.2.5(vite@4.2.1(@types/node@24.3.0)):
optionalDependencies:
vite: 4.2.1(@types/node@18.19.124)
vite: 4.2.1(@types/node@24.3.0)
vitefu@0.2.5(vite@4.5.14(@types/node@24.3.0)(lightningcss@1.30.1)):
optionalDependencies:
@ -15335,7 +15041,7 @@ snapshots:
dependencies:
'@types/chai': 5.2.2
'@vitest/expect': 3.2.4
'@vitest/mocker': 3.2.4(vite@7.1.10(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))
'@vitest/mocker': 3.2.4(vite@6.3.6(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))
'@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4
@ -15353,7 +15059,7 @@ snapshots:
tinyglobby: 0.2.15
tinypool: 1.1.1
tinyrainbow: 2.0.0
vite: 7.1.10(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite: 6.3.6(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite-node: 3.2.4(@types/node@22.18.3)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
why-is-node-running: 2.3.0
optionalDependencies:
@ -15378,7 +15084,7 @@ snapshots:
dependencies:
'@types/chai': 5.2.2
'@vitest/expect': 3.2.4
'@vitest/mocker': 3.2.4(vite@7.1.10(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))
'@vitest/mocker': 3.2.4(vite@6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))
'@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4
@ -15396,7 +15102,7 @@ snapshots:
tinyglobby: 0.2.15
tinypool: 1.1.1
tinyrainbow: 2.0.0
vite: 7.1.10(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite: 6.3.6(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
vite-node: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)
why-is-node-running: 2.3.0
optionalDependencies:
@ -15528,10 +15234,6 @@ snapshots:
dependencies:
is-wsl: 3.1.0
xml-beautifier@0.5.0:
dependencies:
repeat-string: 1.6.1
xml-name-validator@5.0.0:
optional: true

@ -9,6 +9,7 @@
import {createAsyncProxy} from "async-proxy";
import {version} from './package.json';
import * as sdk from "@ng-org/lib-wasm";
//import * as sdk from "../lib-wasm/pkg";
import { Bowser } from "../lib-wasm/jsland/bowser.js";
const web_handler = {

@ -4,6 +4,11 @@
"version": "0.1.2",
"type": "module",
"main": "main.ts",
"exports": {
".": {
"default": "./main.ts"
}
},
"dependencies": {
"async-proxy": "^0.4.1",
"@ng-org/lib-wasm": "workspace:*"

@ -6,7 +6,7 @@
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
//import * as ng from "../lib-wasm/pkg";
import * as ng from "@ng-org/lib-wasm";
//import { default as ng } from "./api";
//import ng from "./main";

@ -175,6 +175,7 @@ pub fn privkey_to_string(privkey: JsValue) -> Result<String, JsValue> {
Ok(format!("{p}"))
}
#[wasm_bindgen]
pub fn wallet_open_with_password(wallet: JsValue, password: String) -> Result<JsValue, JsValue> {
let encrypted_wallet = serde_wasm_bindgen::from_value::<Wallet>(wallet)
.map_err(|_| "Deserialization error of wallet")?;

Loading…
Cancel
Save