"file-saver": "2.0.5",
"flux": "4.0.3",
"focus-trap-react": "10.0.2",
- "folds": "2.0.0",
+ "folds": "2.1.0",
"formik": "2.4.6",
"html-dom-parser": "4.0.0",
"html-react-parser": "4.2.0",
"jotai": "2.6.0",
"linkify-react": "4.1.3",
"linkifyjs": "4.1.3",
- "matrix-js-sdk": "34.11.1",
+ "matrix-js-sdk": "35.0.0",
"millify": "6.1.0",
"pdfjs-dist": "4.2.67",
"prismjs": "1.29.0",
"vite": "5.0.13",
"vite-plugin-pwa": "0.20.5",
"vite-plugin-static-copy": "1.0.4",
- "vite-plugin-top-level-await": "1.4.1"
+ "vite-plugin-top-level-await": "1.4.4"
},
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/@ampproject/remapping": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
- "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.1.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
"resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
"integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"json-schema": "^0.4.0",
"jsonpointer": "^5.0.0",
}
},
"node_modules/@babel/code-frame": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
- "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
- "license": "MIT",
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
"dependencies": {
- "@babel/highlight": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
}
},
"node_modules/@babel/compat-data": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
- "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
- "license": "MIT",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz",
+ "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
- "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
- "license": "MIT",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz",
+ "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.0",
- "@babel/helper-compilation-targets": "^7.25.2",
- "@babel/helper-module-transforms": "^7.25.2",
- "@babel/helpers": "^7.25.0",
- "@babel/parser": "^7.25.0",
- "@babel/template": "^7.25.0",
- "@babel/traverse": "^7.25.2",
- "@babel/types": "^7.25.2",
+ "@babel/code-frame": "^7.26.0",
+ "@babel/generator": "^7.26.0",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.0",
+ "@babel/parser": "^7.26.0",
+ "@babel/template": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.26.0",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"url": "https://opencollective.com/babel"
}
},
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/generator": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
- "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
- "license": "MIT",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
+ "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
"dependencies": {
- "@babel/types": "^7.25.6",
+ "@babel/parser": "^7.26.5",
+ "@babel/types": "^7.26.5",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^2.5.1"
+ "jsesc": "^3.0.2"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
- "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
- "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz",
- "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
- "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.25.2",
- "@babel/helper-validator-option": "^7.24.8",
- "browserslist": "^4.23.1",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
+ "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
+ "dependencies": {
+ "@babel/compat-data": "^7.26.5",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
}
},
- "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "license": "ISC"
- },
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz",
- "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-member-expression-to-functions": "^7.24.8",
- "@babel/helper-optimise-call-expression": "^7.24.7",
- "@babel/helper-replace-supers": "^7.25.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
- "@babel/traverse": "^7.25.4",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz",
+ "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
"semver": "^6.3.1"
},
"engines": {
"@babel/core": "^7.0.0"
}
},
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz",
- "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz",
+ "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "regexpu-core": "^5.3.1",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "regexpu-core": "^6.2.0",
"semver": "^6.3.1"
},
"engines": {
"@babel/core": "^7.0.0"
}
},
+ "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz",
- "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
+ "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@babel/helper-compilation-targets": "^7.22.6",
"@babel/helper-plugin-utils": "^7.22.5",
}
},
"node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
- "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
+ "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.24.8",
- "@babel/types": "^7.24.8"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
- "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
- "license": "MIT",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
- "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
- "license": "MIT",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
"dependencies": {
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-simple-access": "^7.24.7",
- "@babel/helper-validator-identifier": "^7.24.7",
- "@babel/traverse": "^7.25.2"
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz",
- "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
+ "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.7"
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
- "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
- "license": "MIT",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
+ "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-remap-async-to-generator": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz",
- "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-wrap-function": "^7.25.0",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-wrap-function": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-replace-supers": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz",
- "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz",
+ "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-member-expression-to-functions": "^7.24.8",
- "@babel/helper-optimise-call-expression": "^7.24.7",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/traverse": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
"@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/helper-simple-access": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
- "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz",
- "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
+ "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
- "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
- "license": "MIT",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
- "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
- "license": "MIT",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
- "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
- "license": "MIT",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-wrap-function": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz",
- "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
+ "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/template": "^7.25.0",
- "@babel/traverse": "^7.25.0",
- "@babel/types": "^7.25.0"
+ "@babel/template": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz",
- "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==",
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
- "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
- "license": "MIT",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
+ "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.24.7",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.26.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
- "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
- "license": "MIT",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz",
+ "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==",
"dependencies": {
- "@babel/types": "^7.25.6"
+ "@babel/types": "^7.26.5"
},
"bin": {
"parser": "bin/babel-parser.js"
}
},
"node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
- "version": "7.25.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz",
- "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
+ "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/traverse": "^7.25.3"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz",
- "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
+ "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz",
- "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
+ "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz",
- "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
- "@babel/plugin-transform-optional-chaining": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz",
- "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
+ "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-async-generators": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
- "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-class-properties": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
- "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.12.13"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-class-static-block": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
- "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
"engines": {
"node": ">=6.9.0"
},
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-dynamic-import": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-export-namespace-from": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
- "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.3"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz",
- "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
+ "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-syntax-import-attributes": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz",
- "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-json-strings": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
- "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
- "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
- "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-object-rest-spread": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
- "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-catch-binding": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
- "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-chaining": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-private-property-in-object": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
- "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-top-level-await": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
- "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+ "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-syntax-typescript": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz",
- "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz",
+ "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.19.0"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
"integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
"@babel/helper-plugin-utils": "^7.18.6"
}
},
"node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz",
- "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
+ "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz",
- "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz",
+ "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-remap-async-to-generator": "^7.25.0",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/traverse": "^7.25.4"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-remap-async-to-generator": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz",
- "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-remap-async-to-generator": "^7.24.7"
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-remap-async-to-generator": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz",
- "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz",
+ "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz",
- "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz",
+ "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz",
- "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
+ "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.25.4",
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz",
- "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
+ "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-classes": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz",
- "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
+ "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-compilation-targets": "^7.25.2",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-replace-supers": "^7.25.0",
- "@babel/traverse": "^7.25.4",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
"globals": "^11.1.0"
},
"engines": {
}
},
"node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz",
- "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
+ "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/template": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/template": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz",
- "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
+ "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-dotall-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz",
- "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
+ "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-duplicate-keys": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz",
- "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
+ "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz",
- "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.0",
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-dynamic-import": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz",
- "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
+ "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz",
- "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
+ "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz",
- "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
+ "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-for-of": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz",
- "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz",
+ "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-function-name": {
- "version": "7.25.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz",
- "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
+ "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.24.8",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/traverse": "^7.25.1"
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-json-strings": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz",
- "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
+ "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-json-strings": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-literals": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz",
- "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
+ "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz",
- "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
+ "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz",
- "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
+ "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-modules-amd": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz",
- "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
+ "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz",
- "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
+ "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.24.8",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-simple-access": "^7.24.7"
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz",
- "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
+ "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.25.0",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-modules-umd": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz",
- "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
+ "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz",
- "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-new-target": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz",
- "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
+ "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz",
- "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==",
+ "version": "7.26.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz",
+ "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-numeric-separator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz",
- "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
+ "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz",
- "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
+ "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.24.7"
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-object-super": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz",
- "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
+ "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-replace-supers": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz",
- "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
+ "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz",
- "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-parameters": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz",
- "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
+ "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz",
- "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz",
+ "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.25.4",
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz",
- "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
+ "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-create-class-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz",
- "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
+ "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz",
- "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
+ "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz",
- "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
+ "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz",
- "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
+ "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.25.9",
"regenerator-transform": "^0.15.2"
},
"engines": {
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
+ "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
"node_modules/@babel/plugin-transform-reserved-words": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz",
- "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
+ "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz",
- "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
+ "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-spread": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz",
- "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
+ "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz",
- "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
+ "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz",
- "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz",
+ "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-typeof-symbol": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz",
- "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz",
+ "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-unicode-escapes": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz",
- "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
+ "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-unicode-property-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz",
- "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
+ "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz",
- "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
+ "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz",
- "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
+ "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.2",
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/preset-env": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz",
- "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.25.4",
- "@babel/helper-compilation-targets": "^7.25.2",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-validator-option": "^7.24.8",
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3",
- "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7",
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz",
+ "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.26.0",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-option": "^7.25.9",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
"@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
- "@babel/plugin-syntax-import-assertions": "^7.24.7",
- "@babel/plugin-syntax-import-attributes": "^7.24.7",
- "@babel/plugin-syntax-import-meta": "^7.10.4",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-syntax-import-assertions": "^7.26.0",
+ "@babel/plugin-syntax-import-attributes": "^7.26.0",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
- "@babel/plugin-transform-arrow-functions": "^7.24.7",
- "@babel/plugin-transform-async-generator-functions": "^7.25.4",
- "@babel/plugin-transform-async-to-generator": "^7.24.7",
- "@babel/plugin-transform-block-scoped-functions": "^7.24.7",
- "@babel/plugin-transform-block-scoping": "^7.25.0",
- "@babel/plugin-transform-class-properties": "^7.25.4",
- "@babel/plugin-transform-class-static-block": "^7.24.7",
- "@babel/plugin-transform-classes": "^7.25.4",
- "@babel/plugin-transform-computed-properties": "^7.24.7",
- "@babel/plugin-transform-destructuring": "^7.24.8",
- "@babel/plugin-transform-dotall-regex": "^7.24.7",
- "@babel/plugin-transform-duplicate-keys": "^7.24.7",
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0",
- "@babel/plugin-transform-dynamic-import": "^7.24.7",
- "@babel/plugin-transform-exponentiation-operator": "^7.24.7",
- "@babel/plugin-transform-export-namespace-from": "^7.24.7",
- "@babel/plugin-transform-for-of": "^7.24.7",
- "@babel/plugin-transform-function-name": "^7.25.1",
- "@babel/plugin-transform-json-strings": "^7.24.7",
- "@babel/plugin-transform-literals": "^7.25.2",
- "@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
- "@babel/plugin-transform-member-expression-literals": "^7.24.7",
- "@babel/plugin-transform-modules-amd": "^7.24.7",
- "@babel/plugin-transform-modules-commonjs": "^7.24.8",
- "@babel/plugin-transform-modules-systemjs": "^7.25.0",
- "@babel/plugin-transform-modules-umd": "^7.24.7",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
- "@babel/plugin-transform-new-target": "^7.24.7",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
- "@babel/plugin-transform-numeric-separator": "^7.24.7",
- "@babel/plugin-transform-object-rest-spread": "^7.24.7",
- "@babel/plugin-transform-object-super": "^7.24.7",
- "@babel/plugin-transform-optional-catch-binding": "^7.24.7",
- "@babel/plugin-transform-optional-chaining": "^7.24.8",
- "@babel/plugin-transform-parameters": "^7.24.7",
- "@babel/plugin-transform-private-methods": "^7.25.4",
- "@babel/plugin-transform-private-property-in-object": "^7.24.7",
- "@babel/plugin-transform-property-literals": "^7.24.7",
- "@babel/plugin-transform-regenerator": "^7.24.7",
- "@babel/plugin-transform-reserved-words": "^7.24.7",
- "@babel/plugin-transform-shorthand-properties": "^7.24.7",
- "@babel/plugin-transform-spread": "^7.24.7",
- "@babel/plugin-transform-sticky-regex": "^7.24.7",
- "@babel/plugin-transform-template-literals": "^7.24.7",
- "@babel/plugin-transform-typeof-symbol": "^7.24.8",
- "@babel/plugin-transform-unicode-escapes": "^7.24.7",
- "@babel/plugin-transform-unicode-property-regex": "^7.24.7",
- "@babel/plugin-transform-unicode-regex": "^7.24.7",
- "@babel/plugin-transform-unicode-sets-regex": "^7.25.4",
+ "@babel/plugin-transform-arrow-functions": "^7.25.9",
+ "@babel/plugin-transform-async-generator-functions": "^7.25.9",
+ "@babel/plugin-transform-async-to-generator": "^7.25.9",
+ "@babel/plugin-transform-block-scoped-functions": "^7.25.9",
+ "@babel/plugin-transform-block-scoping": "^7.25.9",
+ "@babel/plugin-transform-class-properties": "^7.25.9",
+ "@babel/plugin-transform-class-static-block": "^7.26.0",
+ "@babel/plugin-transform-classes": "^7.25.9",
+ "@babel/plugin-transform-computed-properties": "^7.25.9",
+ "@babel/plugin-transform-destructuring": "^7.25.9",
+ "@babel/plugin-transform-dotall-regex": "^7.25.9",
+ "@babel/plugin-transform-duplicate-keys": "^7.25.9",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-dynamic-import": "^7.25.9",
+ "@babel/plugin-transform-exponentiation-operator": "^7.25.9",
+ "@babel/plugin-transform-export-namespace-from": "^7.25.9",
+ "@babel/plugin-transform-for-of": "^7.25.9",
+ "@babel/plugin-transform-function-name": "^7.25.9",
+ "@babel/plugin-transform-json-strings": "^7.25.9",
+ "@babel/plugin-transform-literals": "^7.25.9",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
+ "@babel/plugin-transform-member-expression-literals": "^7.25.9",
+ "@babel/plugin-transform-modules-amd": "^7.25.9",
+ "@babel/plugin-transform-modules-commonjs": "^7.25.9",
+ "@babel/plugin-transform-modules-systemjs": "^7.25.9",
+ "@babel/plugin-transform-modules-umd": "^7.25.9",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-new-target": "^7.25.9",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9",
+ "@babel/plugin-transform-numeric-separator": "^7.25.9",
+ "@babel/plugin-transform-object-rest-spread": "^7.25.9",
+ "@babel/plugin-transform-object-super": "^7.25.9",
+ "@babel/plugin-transform-optional-catch-binding": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9",
+ "@babel/plugin-transform-private-methods": "^7.25.9",
+ "@babel/plugin-transform-private-property-in-object": "^7.25.9",
+ "@babel/plugin-transform-property-literals": "^7.25.9",
+ "@babel/plugin-transform-regenerator": "^7.25.9",
+ "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
+ "@babel/plugin-transform-reserved-words": "^7.25.9",
+ "@babel/plugin-transform-shorthand-properties": "^7.25.9",
+ "@babel/plugin-transform-spread": "^7.25.9",
+ "@babel/plugin-transform-sticky-regex": "^7.25.9",
+ "@babel/plugin-transform-template-literals": "^7.25.9",
+ "@babel/plugin-transform-typeof-symbol": "^7.25.9",
+ "@babel/plugin-transform-unicode-escapes": "^7.25.9",
+ "@babel/plugin-transform-unicode-property-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
"@babel/preset-modules": "0.1.6-no-external-plugins",
"babel-plugin-polyfill-corejs2": "^0.4.10",
"babel-plugin-polyfill-corejs3": "^0.10.6",
"babel-plugin-polyfill-regenerator": "^0.6.1",
- "core-js-compat": "^3.37.1",
+ "core-js-compat": "^3.38.1",
"semver": "^6.3.1"
},
"engines": {
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/preset-env/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/preset-modules": {
"version": "0.1.6-no-external-plugins",
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
"integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/types": "^7.4.4",
"@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@babel/regjsgen": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
- "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@babel/runtime": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz",
- "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==",
- "license": "MIT",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
+ "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
}
},
"node_modules/@babel/runtime-corejs3": {
- "version": "7.20.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz",
- "integrity": "sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz",
+ "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==",
"dev": true,
"dependencies": {
- "core-js-pure": "^3.25.1",
- "regenerator-runtime": "^0.13.11"
+ "core-js-pure": "^3.30.2",
+ "regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/runtime-corejs3/node_modules/regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
- "dev": true
- },
"node_modules/@babel/template": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
- "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
- "license": "MIT",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
+ "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
"dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/parser": "^7.25.0",
- "@babel/types": "^7.25.0"
+ "@babel/code-frame": "^7.25.9",
+ "@babel/parser": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
- "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.6",
- "@babel/parser": "^7.25.6",
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.5.tgz",
+ "integrity": "sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.5",
+ "@babel/parser": "^7.26.5",
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.26.5",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
}
},
"node_modules/@babel/types": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
- "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
- "license": "MIT",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz",
+ "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==",
"dependencies": {
- "@babel/helper-string-parser": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
- "to-fast-properties": "^2.0.0"
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@emotion/hash": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
- "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g=="
},
"node_modules/@esbuild-plugins/node-globals-polyfill": {
"version": "0.2.3",
"cpu": [
"ppc64"
],
- "dev": true,
"optional": true,
"os": [
"aix"
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.9.tgz",
- "integrity": "sha512-kW5ccqWHVOOTGUkkJbtfoImtqu3kA1PFkivM+9QPFSHphPfPBlBalX9eDRqPK+wHCqKhU48/78T791qPgC9e9A==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
+ "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
"cpu": [
"arm"
],
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.9.tgz",
- "integrity": "sha512-ndIAZJUeLx4O+4AJbFQCurQW4VRUXjDsUvt1L+nP8bVELOWdmdCEOtlIweCUE6P+hU0uxYbEK2AEP0n5IVQvhg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
+ "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.9.tgz",
- "integrity": "sha512-UbMcJB4EHrAVOnknQklREPgclNU2CPet2h+sCBCXmF2mfoYWopBn/CfTfeyOkb/JglOcdEADqAljFndMKnFtOw==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
+ "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.9.tgz",
- "integrity": "sha512-d7D7/nrt4CxPul98lx4PXhyNZwTYtbdaHhOSdXlZuu5zZIznjqtMqLac8Bv+IuT6SVHiHUwrkL6ywD7mOgLW+A==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
+ "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.9.tgz",
- "integrity": "sha512-LZc+Wlz06AkJYtwWsBM3x2rSqTG8lntDuftsUNQ3fCx9ZttYtvlDcVtgb+NQ6t9s6K5No5zutN3pcjZEC2a4iQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
+ "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.9.tgz",
- "integrity": "sha512-gIj0UQZlQo93CHYouHKkpzP7AuruSaMIm1etcWIxccFEVqCN1xDr6BWlN9bM+ol/f0W9w3hx3HDuEwcJVtGneQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
+ "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.9.tgz",
- "integrity": "sha512-GNors4vaMJ7lzGOuhzNc7jvgsQZqErGA8rsW+nck8N1nYu86CvsJW2seigVrQQWOV4QzEP8Zf3gm+QCjA2hnBQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
+ "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.9.tgz",
- "integrity": "sha512-cNx1EF99c2t1Ztn0lk9N+MuwBijGF8mH6nx9GFsB3e0lpUpPkCE/yt5d+7NP9EwJf5uzqdjutgVYoH1SNqzudA==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
+ "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
"cpu": [
"arm"
],
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.9.tgz",
- "integrity": "sha512-YPxQunReYp8RQ1FvexFrOEqqf+nLbS3bKVZF5FRT2uKM7Wio7BeATqAwO02AyrdSEntt3I5fhFsujUChIa8CZg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
+ "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.9.tgz",
- "integrity": "sha512-zb12ixDIKNwFpIqR00J88FFitVwOEwO78EiUi8wi8FXlmSc3GtUuKV/BSO+730Kglt0B47+ZrJN1BhhOxZaVrw==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
+ "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
"cpu": [
"ia32"
],
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.9.tgz",
- "integrity": "sha512-X8te4NLxtHiNT6H+4Pfm5RklzItA1Qy4nfyttihGGX+Koc53Ar20ViC+myY70QJ8PDEOehinXZj/F7QK3A+MKQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
+ "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
"cpu": [
"loong64"
],
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.9.tgz",
- "integrity": "sha512-ZqyMDLt02c5smoS3enlF54ndK5zK4IpClLTxF0hHfzHJlfm4y8IAkIF8LUW0W7zxcKy7oAwI7BRDqeVvC120SA==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
+ "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
"cpu": [
"mips64el"
],
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.9.tgz",
- "integrity": "sha512-k+ca5W5LDBEF3lfDwMV6YNXwm4wEpw9krMnNvvlNz3MrKSD2Eb2c861O0MaKrZkG/buTQAP4vkavbLwgIe6xjg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
+ "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
"cpu": [
"ppc64"
],
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.9.tgz",
- "integrity": "sha512-GuInVdogjmg9DhgkEmNipHkC+3tzkanPJzgzTC2ihsvrruLyFoR1YrTGixblNSMPudQLpiqkcwGwwe0oqfrvfA==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
+ "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
"cpu": [
"riscv64"
],
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.9.tgz",
- "integrity": "sha512-49wQ0aYkvwXonGsxc7LuuLNICMX8XtO92Iqmug5Qau0kpnV6SP34jk+jIeu4suHwAbSbRhVFtDv75yRmyfQcHw==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
+ "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
"cpu": [
"s390x"
],
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.9.tgz",
- "integrity": "sha512-Nx4oKEAJ6EcQlt4dK7qJyuZUoXZG7CAeY22R7rqZijFzwFfMOD+gLP56uV7RrV86jGf8PeRY8TBsRmOcZoG42w==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
+ "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.9.tgz",
- "integrity": "sha512-d0WnpgJ+FTiMZXEQ1NOv9+0gvEhttbgKEvVqWWAtl1u9AvlspKXbodKHzQ5MLP6YV1y52Xp+p8FMYqj8ykTahg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.9.tgz",
- "integrity": "sha512-jccK11278dvEscHFfMk5EIPjF4wv1qGD0vps7mBV1a6TspdR36O28fgPem/SA/0pcsCPHjww5ouCLwP+JNAFlw==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.9.tgz",
- "integrity": "sha512-OetwTSsv6mIDLqN7I7I2oX9MmHGwG+AP+wKIHvq+6sIHwcPPJqRx+DJB55jy9JG13CWcdcQno/7V5MTJ5a0xfQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
+ "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.9.tgz",
- "integrity": "sha512-tKSSSK6unhxbGbHg+Cc+JhRzemkcsX0tPBvG0m5qsWbkShDK9c+/LSb13L18LWVdOQZwuA55Vbakxmt6OjBDOQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
+ "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.9.tgz",
- "integrity": "sha512-ZTQ5vhNS5gli0KK8I6/s6+LwXmNEfq1ftjnSVyyNm33dBw8zDpstqhGXYUbZSWWLvkqiRRjgxgmoncmi6Yy7Ng==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
+ "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
"cpu": [
"ia32"
],
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.9.tgz",
- "integrity": "sha512-C4ZX+YFIp6+lPrru3tpH6Gaapy8IBRHw/e7l63fzGDhn/EaiGpQgbIlT5paByyy+oMvRFQoxxyvC4LE0AjJMqQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
+ "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
"cpu": [
"x64"
],
}
},
"node_modules/@eslint/eslintrc": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz",
- "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==",
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
+ "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
"espree": "^9.4.0",
- "globals": "^13.15.0",
+ "globals": "^13.19.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
}
},
"node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "13.19.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
- "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@eslint/eslintrc/node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@fontsource/inter": {
"version": "4.5.14",
"resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.5.14.tgz",
"integrity": "sha512-JDC9AocdPLuGsASkvWw9hS5gtHE7K9dOwL98XLrk5yjYqxy4uVnScG58NUvFMJDVJRl/7c8Wnap6PEs+7Zvj1Q=="
},
"node_modules/@formatjs/ecma402-abstract": {
- "version": "1.17.2",
- "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.2.tgz",
- "integrity": "sha512-k2mTh0m+IV1HRdU0xXM617tSQTi53tVR2muvYOsBeYcUgEAyxV1FOC7Qj279th3fBVQ+Dj6muvNJZcHSPNdbKg==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.2.tgz",
+ "integrity": "sha512-6sE5nyvDloULiyOMbOTJEEgWL32w+VHkZQs8S02Lnn8Y/O5aQhjOEXwWzvR7SsBE/exxlSpY2EsWZgqHbtLatg==",
"dependencies": {
- "@formatjs/intl-localematcher": "0.4.2",
- "tslib": "^2.4.0"
+ "@formatjs/fast-memoize": "2.2.6",
+ "@formatjs/intl-localematcher": "0.5.10",
+ "decimal.js": "10",
+ "tslib": "2"
}
},
- "node_modules/@formatjs/ecma402-abstract/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
"node_modules/@formatjs/fast-memoize": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz",
- "integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.6.tgz",
+ "integrity": "sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw==",
"dependencies": {
- "tslib": "^2.4.0"
+ "tslib": "2"
}
},
- "node_modules/@formatjs/fast-memoize/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
"node_modules/@formatjs/icu-messageformat-parser": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.0.tgz",
- "integrity": "sha512-7uqC4C2RqOaBQtcjqXsSpGRYVn+ckjhNga5T/otFh6MgxRrCJQqvjfbrGLpX1Lcbxdm5WH3Z2WZqt1+Tm/cn/Q==",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.10.0.tgz",
+ "integrity": "sha512-PDeky6nDAyHYEtmSi2X1PG9YpqE+2BRTJT7JvPix8K8JX1wBWQNao6KcPtmZpttQHUHmzMcd/rne7lFesSzUKQ==",
"dependencies": {
- "@formatjs/ecma402-abstract": "1.17.2",
- "@formatjs/icu-skeleton-parser": "1.6.2",
- "tslib": "^2.4.0"
+ "@formatjs/ecma402-abstract": "2.3.2",
+ "@formatjs/icu-skeleton-parser": "1.8.12",
+ "tslib": "2"
}
},
- "node_modules/@formatjs/icu-messageformat-parser/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
"node_modules/@formatjs/icu-skeleton-parser": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.2.tgz",
- "integrity": "sha512-VtB9Slo4ZL6QgtDFJ8Injvscf0xiDd4bIV93SOJTBjUF4xe2nAWOoSjLEtqIG+hlIs1sNrVKAaFo3nuTI4r5ZA==",
+ "version": "1.8.12",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.12.tgz",
+ "integrity": "sha512-QRAY2jC1BomFQHYDMcZtClqHR55EEnB96V7Xbk/UiBodsuFc5kujybzt87+qj1KqmJozFhk6n4KiT1HKwAkcfg==",
"dependencies": {
- "@formatjs/ecma402-abstract": "1.17.2",
- "tslib": "^2.4.0"
+ "@formatjs/ecma402-abstract": "2.3.2",
+ "tslib": "2"
}
},
- "node_modules/@formatjs/icu-skeleton-parser/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
"node_modules/@formatjs/intl-localematcher": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.4.2.tgz",
- "integrity": "sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA==",
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.10.tgz",
+ "integrity": "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==",
"dependencies": {
- "tslib": "^2.4.0"
+ "tslib": "2"
}
},
- "node_modules/@formatjs/intl-localematcher/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.7",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
- "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==",
+ "version": "0.11.14",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+ "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
+ "deprecated": "Use @eslint/config-array instead",
"dev": true,
"dependencies": {
- "@humanwhocodes/object-schema": "^1.2.1",
- "debug": "^4.1.1",
+ "@humanwhocodes/object-schema": "^2.0.2",
+ "debug": "^4.3.1",
"minimatch": "^3.0.5"
},
"engines": {
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
"dev": true
},
"node_modules/@internationalized/date": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.0.tgz",
- "integrity": "sha512-nw0Q+oRkizBWMioseI8+2TeUPEyopJVz5YxoYVzR0W1v+2YytiYah7s/ot35F149q/xAg4F1gT/6eTd+tsUpFQ==",
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.7.0.tgz",
+ "integrity": "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@internationalized/message": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.1.tgz",
- "integrity": "sha512-ZgHxf5HAPIaR0th+w0RUD62yF6vxitjlprSxmLJ1tam7FOekqRSDELMg4Cr/DdszG5YLsp5BG3FgHgqquQZbqw==",
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.6.tgz",
+ "integrity": "sha512-JxbK3iAcTIeNr1p0WIFg/wQJjIzJt9l/2KNY/48vXV7GRGZSv3zMxJsce008fZclk2cDC8y0Ig3odceHO7EfNQ==",
"dependencies": {
"@swc/helpers": "^0.5.0",
"intl-messageformat": "^10.1.0"
}
},
"node_modules/@internationalized/number": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.3.0.tgz",
- "integrity": "sha512-PuxgnKE5NJMOGKUcX1QROo8jq7sW7UWLrL5B6Rfe8BdWgU/be04cVvLyCeALD46vvbAv3d1mUvyHav/Q9a237g==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.0.tgz",
+ "integrity": "sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@internationalized/string": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.1.1.tgz",
- "integrity": "sha512-fvSr6YRoVPgONiVIUhgCmIAlifMVCeej/snPZVzbzRPxGpHl3o1GRe+d/qh92D8KhgOciruDUH8I5mjdfdjzfA==",
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.5.tgz",
+ "integrity": "sha512-rKs71Zvl2OKOHM+mzAFMIyqR5hI1d1O6BBkMK2/lkfg3fkmVh9Eeg0awcA8W2WqYqDOv6a86DIOlFpggwLtbuw==",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
- "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
"dependencies": {
- "@jridgewell/set-array": "^1.0.0",
- "@jridgewell/sourcemap-codec": "^1.4.10"
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
- "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"engines": {
"node": ">=6.0.0"
}
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
- "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
- "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
- "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
- "license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
"node-pre-gyp": "bin/node-pre-gyp"
}
},
- "node_modules/@mapbox/node-pre-gyp/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "optional": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@matrix-org/matrix-sdk-crypto-wasm": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-9.1.0.tgz",
- "integrity": "sha512-CtPoNcoRW6ehwxpRQAksG3tR+NJ7k4DV02nMFYTDwQtie1V4R8OTY77BjEIs97NOblhtS26jU8m1lWsOBEz0Og==",
- "license": "Apache-2.0",
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-11.1.0.tgz",
+ "integrity": "sha512-JPuO9RCVDklDjbFzMvZfQb7PuiFkLY72bniRSu81lRzkkrcbZtmKqBFMm9H4f2FSz+tHVkDnmsvn12I4sdJJ5A==",
"engines": {
"node": ">= 10"
}
"node_modules/@matrix-org/olm": {
"version": "3.2.15",
"resolved": "https://registry.npmjs.org/@matrix-org/olm/-/olm-3.2.15.tgz",
- "integrity": "sha512-S7lOrndAK9/8qOtaTq/WhttJC/o4GAzdfK0MUPpo8ApzsJEC0QjtwrkC3KBXdFP1cD1MXi/mlKR7aaoVMKgs6Q==",
- "license": "Apache-2.0"
+ "integrity": "sha512-S7lOrndAK9/8qOtaTq/WhttJC/o4GAzdfK0MUPpo8ApzsJEC0QjtwrkC3KBXdFP1cD1MXi/mlKR7aaoVMKgs6Q=="
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
}
},
"node_modules/@popperjs/core": {
- "version": "2.11.6",
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
- "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@react-aria/breadcrumbs": {
- "version": "3.5.7",
- "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.7.tgz",
- "integrity": "sha512-z+L1gNyWrjZ4Fs0Vo4AkwJicPpEGIestww6r8CiTlt07eo0vCReNmB3oofI6nMJOSu51yef+qqBtFyr0tqBgiw==",
- "dependencies": {
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/link": "^3.6.1",
- "@react-aria/utils": "^3.21.1",
- "@react-types/breadcrumbs": "^3.7.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.5.20",
+ "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.20.tgz",
+ "integrity": "sha512-xqVSSDPpQuUFpJyIXMQv8L7zumk5CeGX7qTzo4XRvqm5T9qnNAX4XpYEMdktnLrQRY/OemCBScbx7SEwr0B3Kg==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/link": "^3.7.8",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/breadcrumbs": "^3.7.10",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/button": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.8.4.tgz",
- "integrity": "sha512-rTGZk5zu+lQNjfij2fwnw2PAgBgzNLi3zbMw1FL5/XwVx+lEH2toeqKLoqULtd7nSxskYuQz56VhmjUok6Qkmg==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/toggle": "^3.6.3",
- "@react-types/button": "^3.9.0",
- "@react-types/shared": "^3.21.0",
+ "version": "3.11.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.11.1.tgz",
+ "integrity": "sha512-NSs2HxHSSPSuYy5bN+PMJzsCNDVsbm1fZ/nrWM2WWWHTBrx9OqyrEXZVV9ebzQCN9q0nzhwpf6D42zHIivWtJA==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/toolbar": "3.0.0-beta.12",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/toggle": "^3.8.1",
+ "@react-types/button": "^3.10.2",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/calendar": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.2.tgz",
- "integrity": "sha512-HiyUiY0C2aoHa2252Es/Rj1fh5/tewLf6/3gUr42zKl7lq4IqG9cyW7LVRwA47ow1VGLPZSSqTcVakB7jgr7Zw==",
- "dependencies": {
- "@internationalized/date": "^3.5.0",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/live-announcer": "^3.3.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/calendar": "^3.4.1",
- "@react-types/button": "^3.9.0",
- "@react-types/calendar": "^3.4.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.7.0.tgz",
+ "integrity": "sha512-9YUbgcox7cQgvZfQtL2BLLRsIuX4mJeclk9HkFoOsAu3RGO5HNsteah8FV54W8BMjm/bNRXIPUxtjTTP+1L6jg==",
+ "dependencies": {
+ "@internationalized/date": "^3.7.0",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/calendar": "^3.7.0",
+ "@react-types/button": "^3.10.2",
+ "@react-types/calendar": "^3.6.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/checkbox": {
- "version": "3.11.2",
- "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.11.2.tgz",
- "integrity": "sha512-8cgXxpc7IMJ9buw+Rbhr1xc66zNp2ePuFpjw3uWyH7S3IJEd2f5kXUDNWLXQRADJso95UlajRlJQiG4QIObEnA==",
- "dependencies": {
- "@react-aria/label": "^3.7.2",
- "@react-aria/toggle": "^3.8.2",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/checkbox": "^3.5.1",
- "@react-stately/toggle": "^3.6.3",
- "@react-types/checkbox": "^3.5.2",
- "@react-types/shared": "^3.21.0",
+ "version": "3.15.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.15.1.tgz",
+ "integrity": "sha512-ETgsMDZ0IZzRXy/OVlGkazm8T+PcMHoTvsxp0c+U82c8iqdITA+VJ615eBPOQh6OkkYIIn4cRn/e+69RmGzXng==",
+ "dependencies": {
+ "@react-aria/form": "^3.0.12",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/toggle": "^3.10.11",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/checkbox": "^3.6.11",
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/toggle": "^3.8.1",
+ "@react-types/checkbox": "^3.9.1",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/combobox": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.7.1.tgz",
- "integrity": "sha512-37no1b3sRI9mDh3MpMPWNt0Q8QdoRipnx12Vx5Uvtb0PA23hwOWDquICzs157SoJpXP49/+eH6LiA0uTsqwVuQ==",
- "dependencies": {
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/listbox": "^3.11.1",
- "@react-aria/live-announcer": "^3.3.1",
- "@react-aria/menu": "^3.11.1",
- "@react-aria/overlays": "^3.18.1",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/textfield": "^3.12.2",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/collections": "^3.10.2",
- "@react-stately/combobox": "^3.7.1",
- "@react-stately/layout": "^3.13.3",
- "@react-types/button": "^3.9.0",
- "@react-types/combobox": "^3.8.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.11.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.11.1.tgz",
+ "integrity": "sha512-TTNbGhUuqxzPcJzd6hufOxuHzX0UARkw+0bl+TuCwNPQnqrcPf20EoOZvd3MHZwGq6GCP4QV+qo0uGx83RpUvA==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/listbox": "^3.14.0",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/menu": "^3.17.0",
+ "@react-aria/overlays": "^3.25.0",
+ "@react-aria/selection": "^3.22.0",
+ "@react-aria/textfield": "^3.16.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/combobox": "^3.10.2",
+ "@react-stately/form": "^3.1.1",
+ "@react-types/button": "^3.10.2",
+ "@react-types/combobox": "^3.13.2",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/datepicker": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.8.1.tgz",
- "integrity": "sha512-q2Z5DYDkic3RWzvg3oysrA2VEebuxtEfqj8PSlNFndZh/pNrA+Tvkaatdk/BoxlsZsfeLof+/tBq6yWeqTDguQ==",
- "dependencies": {
- "@internationalized/date": "^3.5.0",
- "@internationalized/number": "^3.3.0",
- "@internationalized/string": "^3.1.1",
- "@react-aria/focus": "^3.14.3",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/label": "^3.7.2",
- "@react-aria/spinbutton": "^3.5.4",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/datepicker": "^3.8.0",
- "@react-types/button": "^3.9.0",
- "@react-types/calendar": "^3.4.1",
- "@react-types/datepicker": "^3.6.1",
- "@react-types/dialog": "^3.5.6",
- "@react-types/shared": "^3.21.0",
+ "version": "3.13.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.13.0.tgz",
+ "integrity": "sha512-TmJan65P3Vk7VDBNW5rH9Z25cAn0vk8TEtaP3boCs8wJFE+HbEuB8EqLxBFu47khtuKTEqDP3dTlUh2Vt/f7Xw==",
+ "dependencies": {
+ "@internationalized/date": "^3.7.0",
+ "@internationalized/number": "^3.6.0",
+ "@internationalized/string": "^3.2.5",
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/form": "^3.0.12",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/spinbutton": "^3.6.11",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/datepicker": "^3.12.0",
+ "@react-stately/form": "^3.1.1",
+ "@react-types/button": "^3.10.2",
+ "@react-types/calendar": "^3.6.0",
+ "@react-types/datepicker": "^3.10.0",
+ "@react-types/dialog": "^3.5.15",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/dialog": {
- "version": "3.5.7",
- "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.7.tgz",
- "integrity": "sha512-IKeBaIQBl+WYkhytyE0eISW4ApOEvCJZuw9Xq7gjlKFBlF4X6ffo8souv12KpaznK6/fp1vtEXMmy1AfejiT8Q==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/overlays": "^3.18.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/overlays": "^3.6.3",
- "@react-types/dialog": "^3.5.6",
- "@react-types/shared": "^3.21.0",
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.21.tgz",
+ "integrity": "sha512-tBsn9swBhcptJ9QIm0+ur0PVR799N6qmGguva3rUdd+gfitknFScyT08d7AoMr9AbXYdJ+2R9XNSZ3H3uIWQMw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/overlays": "^3.25.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/dialog": "^3.5.15",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/dnd": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.4.3.tgz",
- "integrity": "sha512-9yiYTQvfT5EUmSsGY3vZlK1xs+xHOFDw5I+c+HyvwqiSu0AIZ4yXqpJVwbarKeZlTOQGCWtb/SOHEdMXfaXKgA==",
- "dependencies": {
- "@internationalized/string": "^3.1.1",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/live-announcer": "^3.3.1",
- "@react-aria/overlays": "^3.18.1",
- "@react-aria/utils": "^3.21.1",
- "@react-aria/visually-hidden": "^3.8.6",
- "@react-stately/dnd": "^3.2.5",
- "@react-types/button": "^3.9.0",
- "@react-types/shared": "^3.21.0",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.8.1.tgz",
+ "integrity": "sha512-FoXYQ4z33E9YBzIGRJM1B1oZep6CvEWgXvjCZGURatjr3qG7vf95mOqA5kVd9bjLL7QK4w0ujJWEBfog3WmufA==",
+ "dependencies": {
+ "@internationalized/string": "^3.2.5",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/overlays": "^3.25.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/dnd": "^3.5.1",
+ "@react-types/button": "^3.10.2",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/focus": {
- "version": "3.14.3",
- "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.14.3.tgz",
- "integrity": "sha512-gvO/frZ7SxyfyHJYC+kRsUXnXct8hGHKlG1TwbkzCCXim9XIPKDgRzfNGuFfj0i8ZpR9xmsjOBUkHZny0uekFA==",
+ "version": "3.19.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.19.1.tgz",
+ "integrity": "sha512-bix9Bu1Ue7RPcYmjwcjhB14BMu2qzfJ3tMQLqDc9pweJA66nOw8DThy3IfVr8Z7j2PHktOLf9kcbiZpydKHqzg==",
"dependencies": {
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/utils": "^3.21.1",
- "@react-types/shared": "^3.21.0",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0",
- "clsx": "^1.1.1"
+ "clsx": "^2.0.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
- "node_modules/@react-aria/grid": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.8.4.tgz",
- "integrity": "sha512-UxEz98Z6yxVAOq7QSZ9OmSsvMwxJDVl7dVRwUHeqWxNprk9o5GGCLjhMv948XBUEnOvLV2qgtI7UoGzSdliUJA==",
+ "node_modules/@react-aria/form": {
+ "version": "3.0.12",
+ "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.12.tgz",
+ "integrity": "sha512-8uvPYEd3GDyGt5NRJIzdWW1Ry5HLZq37vzRZKUW8alZ2upFMH3KJJG55L9GP59KiF6zBrYBebvI/YK1Ye1PE1g==",
"dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/live-announcer": "^3.3.1",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/collections": "^3.10.2",
- "@react-stately/grid": "^3.8.2",
- "@react-stately/selection": "^3.14.0",
- "@react-stately/virtualizer": "^3.6.4",
- "@react-types/checkbox": "^3.5.2",
- "@react-types/grid": "^3.2.2",
- "@react-types/shared": "^3.21.0",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/form": "^3.1.1",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/grid": {
+ "version": "3.11.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.11.1.tgz",
+ "integrity": "sha512-Wg8m68RtNWfkhP3Qjrrsl1q1et8QCjXPMRsYgKBahYRS0kq2MDcQ+UBdG1fiCQn/MfNImhTUGVeQX276dy1lww==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/selection": "^3.22.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/grid": "^3.10.1",
+ "@react-stately/selection": "^3.19.0",
+ "@react-types/checkbox": "^3.9.1",
+ "@react-types/grid": "^3.2.11",
+ "@react-types/shared": "^3.27.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/gridlist": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.7.1.tgz",
- "integrity": "sha512-XnU8mTc/KrwHsGayQm0u5aoaDzdZ8DftKSSfyBEqLiCaibKFqMADb987SOY5+IVGEtYkxDRn1Reo52U0Fs4mxg==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/grid": "^3.8.4",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/list": "^3.10.0",
- "@react-types/checkbox": "^3.5.2",
- "@react-types/shared": "^3.21.0",
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.10.1.tgz",
+ "integrity": "sha512-11FlupBg5C9ehs7R6OjqMPWEOLK/4IuSrq7D1xU+Hnm7ZYI/KKcCXvNMjMmnOz/gGzOmfgVwz5PIKaY9aZarEg==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/grid": "^3.11.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/selection": "^3.22.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/list": "^3.11.2",
+ "@react-stately/tree": "^3.8.7",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/i18n": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.8.4.tgz",
- "integrity": "sha512-YlTJn7YJlUxds/T5dNtme551qc118NoDQhK+IgGpzcmPQ3xSnwBAQP4Zwc7wCpAU+xEwnNcsGw+L1wJd49He/A==",
- "dependencies": {
- "@internationalized/date": "^3.5.0",
- "@internationalized/message": "^3.1.1",
- "@internationalized/number": "^3.3.0",
- "@internationalized/string": "^3.1.1",
- "@react-aria/ssr": "^3.8.0",
- "@react-aria/utils": "^3.21.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.12.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.5.tgz",
+ "integrity": "sha512-ooeop2pTG94PuaHoN2OTk2hpkqVuoqgEYxRvnc1t7DVAtsskfhS/gVOTqyWGsxvwAvRi7m/CnDu6FYdeQ/bK5w==",
+ "dependencies": {
+ "@internationalized/date": "^3.7.0",
+ "@internationalized/message": "^3.1.6",
+ "@internationalized/number": "^3.6.0",
+ "@internationalized/string": "^3.2.5",
+ "@react-aria/ssr": "^3.9.7",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/interactions": {
- "version": "3.19.1",
- "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.19.1.tgz",
- "integrity": "sha512-2QFOvq/rJfMGEezmtYcGcJmfaD16kHKcSTLFrZ8aeBK6hYFddGVZJZk+dXf+G7iNaffa8rMt6uwzVe/malJPBA==",
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.23.0.tgz",
+ "integrity": "sha512-0qR1atBIWrb7FzQ+Tmr3s8uH5mQdyRH78n0krYaG8tng9+u1JlSi8DGRSaC9ezKyNB84m7vHT207xnHXGeJ3Fg==",
"dependencies": {
- "@react-aria/ssr": "^3.8.0",
- "@react-aria/utils": "^3.21.1",
- "@react-types/shared": "^3.21.0",
+ "@react-aria/ssr": "^3.9.7",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/label": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.2.tgz",
- "integrity": "sha512-rS0xQy+4RH1+JLESzLZd9H285McjNNf2kKwBhzU0CW3akjlu7gqaMKEJhX9MlpPDIVOUc2oEObGdU3UMmqa8ew==",
+ "version": "3.7.14",
+ "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.14.tgz",
+ "integrity": "sha512-EN1Md2YvcC4sMqBoggsGYUEGlTNqUfJZWzduSt29fbQp1rKU2KlybTe+TWxKq/r2fFd+4JsRXxMeJiwB3w2AQA==",
"dependencies": {
- "@react-aria/utils": "^3.21.1",
- "@react-types/label": "^3.8.1",
- "@react-types/shared": "^3.21.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/link": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.6.1.tgz",
- "integrity": "sha512-uVkuNHabxE11Eqeo0d1RA86EckOlfJ2Ld8uN8HnTxiLetXLZYUMBwlZfBJvT3RdwPtTG7jC3OK3BvwiyIJrtZw==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/utils": "^3.21.1",
- "@react-types/link": "^3.5.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.7.8",
+ "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.8.tgz",
+ "integrity": "sha512-oiXUPQLZmf9Q9Xehb/sG1QRxfo28NFKdh9w+unD12sHI6NdLMETl5MA4CYyTgI0dfMtTjtfrF68GCnWfc7JvXQ==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/link": "^3.5.10",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/listbox": {
- "version": "3.11.1",
- "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.11.1.tgz",
- "integrity": "sha512-AkguQaIkqpP5oe++EZqYHowD7FfeQs+yY0QZVSsVPpNExcBug8/GcXvhSclcOxdh6ekZg4Wwcq7K0zhuTSOPzg==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/label": "^3.7.2",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/collections": "^3.10.2",
- "@react-stately/list": "^3.10.0",
- "@react-types/listbox": "^3.4.5",
- "@react-types/shared": "^3.21.0",
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.14.0.tgz",
+ "integrity": "sha512-pyVbKavh8N8iyiwOx6I3JIcICvAzFXkKSFni1yarfgngJsJV3KSyOkzLomOfN9UhbjcV4sX61/fccwJuvlurlA==",
+ "dependencies": {
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/selection": "^3.22.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/list": "^3.11.2",
+ "@react-types/listbox": "^3.5.4",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/live-announcer": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.3.1.tgz",
- "integrity": "sha512-hsc77U7S16trM86d+peqJCOCQ7/smO1cybgdpOuzXyiwcHQw8RQ4GrXrS37P4Ux/44E9nMZkOwATQRT2aK8+Ew==",
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.4.1.tgz",
+ "integrity": "sha512-4X2mcxgqLvvkqxv2l1n00jTzUxxe0kkLiapBGH1LHX/CxA1oQcHDqv8etJ2ZOwmS/MSBBiWnv3DwYHDOF6ubig==",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@react-aria/menu": {
- "version": "3.11.1",
- "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.11.1.tgz",
- "integrity": "sha512-1eVVDrGnSExaL7e8IiaM9ndWTjT23rsnQGUK3p66R1Ojs8Q5rPBuJpP74rsmIpYiKOCr8WyZunjm5Fjv5KfA5Q==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/overlays": "^3.18.1",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/collections": "^3.10.2",
- "@react-stately/menu": "^3.5.6",
- "@react-stately/tree": "^3.7.3",
- "@react-types/button": "^3.9.0",
- "@react-types/menu": "^3.9.5",
- "@react-types/shared": "^3.21.0",
+ "version": "3.17.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.17.0.tgz",
+ "integrity": "sha512-aiFvSv3G1YvPC0klJQ/9quB05xIDZzJ5Lt6/CykP0UwGK5i8GCqm6/cyFLwEXsS5ooUPxS3bqmdOsgdADSSgqg==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/overlays": "^3.25.0",
+ "@react-aria/selection": "^3.22.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/menu": "^3.9.1",
+ "@react-stately/selection": "^3.19.0",
+ "@react-stately/tree": "^3.8.7",
+ "@react-types/button": "^3.10.2",
+ "@react-types/menu": "^3.9.14",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/meter": {
- "version": "3.4.7",
- "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.7.tgz",
- "integrity": "sha512-Cp4d6Pd5K6iphXMS/VZ81YxlboUi0I4WPQ+EYb4fxFBJMXVwMK6N5dnn8kwG0vpIx9m0pkFVxSZhlbrwnvW9KA==",
+ "version": "3.4.19",
+ "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.19.tgz",
+ "integrity": "sha512-IIA+gTHrNVbMuBgcqdGLEKd/ZiKM2hOUqS6uztbT15dwPJTmtfJiTWA2872PiY52p+gqPSanZuTc2TXYJa+rew==",
"dependencies": {
- "@react-aria/progress": "^3.4.7",
- "@react-types/meter": "^3.3.5",
- "@react-types/shared": "^3.21.0",
+ "@react-aria/progress": "^3.4.19",
+ "@react-types/meter": "^3.4.6",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/numberfield": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.9.1.tgz",
- "integrity": "sha512-s9LM5YUzZpbOn5KldUS2JmkDNOA9obVmm8TofICH+z6RnReznp72NLPn0IwblRnocmMOIvGINT55Tz50BmbfNA==",
- "dependencies": {
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/live-announcer": "^3.3.1",
- "@react-aria/spinbutton": "^3.5.4",
- "@react-aria/textfield": "^3.12.2",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/numberfield": "^3.6.2",
- "@react-types/button": "^3.9.0",
- "@react-types/numberfield": "^3.6.1",
- "@react-types/shared": "^3.21.0",
- "@react-types/textfield": "^3.8.1",
+ "version": "3.11.10",
+ "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.10.tgz",
+ "integrity": "sha512-bYbTfO9NbAKMFOfEGGs+lvlxk0I9L0lU3WD2PFQZWdaoBz9TCkL+vK0fJk1zsuKaVjeGsmHP9VesBPRmaP0MiA==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/spinbutton": "^3.6.11",
+ "@react-aria/textfield": "^3.16.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/numberfield": "^3.9.9",
+ "@react-types/button": "^3.10.2",
+ "@react-types/numberfield": "^3.8.8",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/overlays": {
- "version": "3.18.1",
- "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.18.1.tgz",
- "integrity": "sha512-C74eZbTp3OA/gXy9/+4iPrZiz7g27Zy6Q1+plbg5QTLpsFLBt2Ypy9jTTANNRZfW7a5NW/Bnw9WIRjCdtTBRXw==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/ssr": "^3.8.0",
- "@react-aria/utils": "^3.21.1",
- "@react-aria/visually-hidden": "^3.8.6",
- "@react-stately/overlays": "^3.6.3",
- "@react-types/button": "^3.9.0",
- "@react-types/overlays": "^3.8.3",
- "@react-types/shared": "^3.21.0",
+ "version": "3.25.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.25.0.tgz",
+ "integrity": "sha512-UEqJJ4duowrD1JvwXpPZreBuK79pbyNjNxFUVpFSskpGEJe3oCWwsSDKz7P1O7xbx5OYp+rDiY8fk/sE5rkaKw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/ssr": "^3.9.7",
+ "@react-aria/utils": "^3.27.0",
+ "@react-aria/visually-hidden": "^3.8.19",
+ "@react-stately/overlays": "^3.6.13",
+ "@react-types/button": "^3.10.2",
+ "@react-types/overlays": "^3.8.12",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/progress": {
- "version": "3.4.7",
- "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.7.tgz",
- "integrity": "sha512-wQ+xnzt5bBdbyQ2Qx80HxaFrPZRFKge57tmJWg4qelo7tzmgb3a22tf0Ug4C3gEz/uAv0JQWOtqLKTxjsiVP7g==",
- "dependencies": {
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/label": "^3.7.2",
- "@react-aria/utils": "^3.21.1",
- "@react-types/progress": "^3.5.0",
- "@react-types/shared": "^3.21.0",
+ "version": "3.4.19",
+ "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.19.tgz",
+ "integrity": "sha512-5HHnBJHqEUuY+dYsjIZDYsENeKr49VCuxeaDZ0OSahbOlloIOB1baCo/6jLBv1O1rwrAzZ2gCCPcVGed/cjrcw==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/progress": "^3.5.9",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/radio": {
- "version": "3.8.2",
- "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.8.2.tgz",
- "integrity": "sha512-j8yyGjboTgoBEQWlnJbQVvegKiUeQEUvU/kZ7ZAdj+eAL3BqfO6FO7yt6WzK7ZIBzjGS9YbesaUa3hwIjDi3LA==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/label": "^3.7.2",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/radio": "^3.9.1",
- "@react-types/radio": "^3.5.2",
- "@react-types/shared": "^3.21.0",
+ "version": "3.10.11",
+ "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.11.tgz",
+ "integrity": "sha512-R150HsBFPr1jLMShI4aBM8heCa1k6h0KEvnFRfTAOBu+B9hMSZOPB+d6GQOwGPysNlbset90Kej8G15FGHjqiA==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/form": "^3.0.12",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/radio": "^3.10.10",
+ "@react-types/radio": "^3.8.6",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/searchfield": {
- "version": "3.5.7",
- "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.5.7.tgz",
- "integrity": "sha512-HYjB/QH3AR2E39N6eu+P/DmJMjGweg6LrO1QUbBbKJS+LDorHTN9YNKA4N89gnDDz2IPyycjxtr71hEv0I092A==",
- "dependencies": {
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/textfield": "^3.12.2",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/searchfield": "^3.4.6",
- "@react-types/button": "^3.9.0",
- "@react-types/searchfield": "^3.5.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.8.0.tgz",
+ "integrity": "sha512-AaZuH9YIWlMyE1m7cSjHCfOuQmlWN+w8HVW32TxeGGGL1kJsYAlSYWYHUyYFIKh245kq/m5zUxAxmw5Ygmnx5w==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/textfield": "^3.16.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/searchfield": "^3.5.9",
+ "@react-types/button": "^3.10.2",
+ "@react-types/searchfield": "^3.5.11",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/select": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.13.1.tgz",
- "integrity": "sha512-tWWOnMnrV1nlZzdO04Ntvf5GCJ6MPkg8Gwv6y0klDDjt12Qyc7J8INluW5A4eMUdtxCkWdaiEsXjyYBHT14ILQ==",
- "dependencies": {
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/label": "^3.7.2",
- "@react-aria/listbox": "^3.11.1",
- "@react-aria/menu": "^3.11.1",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/utils": "^3.21.1",
- "@react-aria/visually-hidden": "^3.8.6",
- "@react-stately/select": "^3.5.5",
- "@react-types/button": "^3.9.0",
- "@react-types/select": "^3.8.4",
- "@react-types/shared": "^3.21.0",
+ "version": "3.15.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.15.1.tgz",
+ "integrity": "sha512-FOtY1tuHt0YTHwOEy/sf7LEIL+Nnkho3wJmfpWQuTxsvMCF7UJdQPYPd6/jGCcCdiqW7H4iqyjUkSp6nk/XRWQ==",
+ "dependencies": {
+ "@react-aria/form": "^3.0.12",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/listbox": "^3.14.0",
+ "@react-aria/menu": "^3.17.0",
+ "@react-aria/selection": "^3.22.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-aria/visually-hidden": "^3.8.19",
+ "@react-stately/select": "^3.6.10",
+ "@react-types/button": "^3.10.2",
+ "@react-types/select": "^3.9.9",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/selection": {
- "version": "3.17.1",
- "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.17.1.tgz",
- "integrity": "sha512-g5gkSc/M+zJiVgWbUpKN095ea0D4fxdluH9ZcXxN4AAvcrVfEJyAnMmWOIKRebN8xR0KPfNRnKB7E6jld2tbuQ==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/collections": "^3.10.2",
- "@react-stately/selection": "^3.14.0",
- "@react-types/shared": "^3.21.0",
+ "version": "3.22.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.22.0.tgz",
+ "integrity": "sha512-XFOrK525HX2eeWeLZcZscUAs5qsuC1ZxsInDXMjvLeAaUPtQNEhUKHj3psDAl6XDU4VV1IJo0qCmFTVqTTMZSg==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/selection": "^3.19.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/separator": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.3.7.tgz",
- "integrity": "sha512-5XjDhvGVmGHxxOrXLFCQhOs75v579nPTaSlrKhG/5BjTN3JrByAtuNAw8XZf3HbtiCRZnnL2bKdVbHBjmbuvDw==",
+ "version": "3.4.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.5.tgz",
+ "integrity": "sha512-RQA9sKZdAEjP1Yrv0GpDdXgmXd56kXDE8atPDHEC0/A4lpYh/YFLfXcv1JW0Hlg4kBocdX2pB2INyDGhiD+yfw==",
"dependencies": {
- "@react-aria/utils": "^3.21.1",
- "@react-types/shared": "^3.21.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/slider": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.2.tgz",
- "integrity": "sha512-io7yJm2jS0gK1ILE9kjClh9zylKsOLbRy748CyD66LDV0ZIjj2D/uZF6BtfKq7Zhc2OsMvDB9+e2IkrszKe8uw==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/label": "^3.7.2",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/radio": "^3.9.1",
- "@react-stately/slider": "^3.4.4",
- "@react-types/radio": "^3.5.2",
- "@react-types/shared": "^3.21.0",
- "@react-types/slider": "^3.6.2",
+ "version": "3.7.15",
+ "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.15.tgz",
+ "integrity": "sha512-v9tujsuvJYRX0vE/vMYBzTT9FXbzrLsjkOrouNq+UdBIr7wRjIWTHHM0j+khb2swyCWNTbdv6Ce316Zqx2qWFg==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/slider": "^3.6.1",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/slider": "^3.7.8",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/spinbutton": {
- "version": "3.5.4",
- "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.5.4.tgz",
- "integrity": "sha512-W5dhUOjyBIgd8d4z526fW/HXQ+BdFceeGyvNAXoYBi/1gt3KqN/6CZgskG7OQEufxCOWc9e4A2eWNwvkQVJvWg==",
- "dependencies": {
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/live-announcer": "^3.3.1",
- "@react-aria/utils": "^3.21.1",
- "@react-types/button": "^3.9.0",
- "@react-types/shared": "^3.21.0",
+ "version": "3.6.11",
+ "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.11.tgz",
+ "integrity": "sha512-RM+gYS9tf9Wb+GegV18n4ArK3NBKgcsak7Nx1CkEgX9BjJ0yayWUHdfEjRRvxGXl+1z1n84cJVkZ6FUlWOWEZA==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/button": "^3.10.2",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/ssr": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.8.0.tgz",
- "integrity": "sha512-Y54xs483rglN5DxbwfCPHxnkvZ+gZ0LbSYmR72LyWPGft8hN/lrl1VRS1EW2SMjnkEWlj+Km2mwvA3kEHDUA0A==",
+ "version": "3.9.7",
+ "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.7.tgz",
+ "integrity": "sha512-GQygZaGlmYjmYM+tiNBA5C6acmiDWF52Nqd40bBp0Znk4M4hP+LTmI0lpI1BuKMw45T8RIhrAsICIfKwZvi2Gg==",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"node": ">= 12"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/switch": {
- "version": "3.5.6",
- "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.5.6.tgz",
- "integrity": "sha512-W6H/0TFa72MJY02AatUERt5HKgaDTF8lOaTjNNmS6U6U20+//uvrVCqcBof8OMe4M60mQpkp7Bd6756CJAMX1w==",
- "dependencies": {
- "@react-aria/toggle": "^3.8.2",
- "@react-stately/toggle": "^3.6.3",
- "@react-types/switch": "^3.4.2",
+ "version": "3.6.11",
+ "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.11.tgz",
+ "integrity": "sha512-paYCpH+oeL+8rgQK+cBJ+IaZ1sXSh3+50WPlg2LvLBta0QVfQhPR4juPvfXRpfHHhCjFBgF4/RGbV8q5zpl3vA==",
+ "dependencies": {
+ "@react-aria/toggle": "^3.10.11",
+ "@react-stately/toggle": "^3.8.1",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/switch": "^3.5.8",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/table": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.13.1.tgz",
- "integrity": "sha512-TBtCmJsKl3rJW/dCzA0ZxPGb8mN7ndbryLh3u+iV/+GVAVsytvAenOGrq9sLHHWXwQo5RJoO1bkUudvrZrJ5/g==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/grid": "^3.8.4",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/live-announcer": "^3.3.1",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/utils": "^3.21.1",
- "@react-aria/visually-hidden": "^3.8.6",
- "@react-stately/collections": "^3.10.2",
- "@react-stately/flags": "^3.0.0",
- "@react-stately/table": "^3.11.2",
- "@react-stately/virtualizer": "^3.6.4",
- "@react-types/checkbox": "^3.5.2",
- "@react-types/grid": "^3.2.2",
- "@react-types/shared": "^3.21.0",
- "@react-types/table": "^3.9.0",
+ "version": "3.16.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.16.1.tgz",
+ "integrity": "sha512-T28TIGnKnPBunyErDBmm5jUX7AyzT7NVWBo9pDSt9wUuEnz0rVNd7p9sjmP2+u7I645feGG9klcdpCvFeqrk8A==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/grid": "^3.11.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/utils": "^3.27.0",
+ "@react-aria/visually-hidden": "^3.8.19",
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/flags": "^3.0.5",
+ "@react-stately/table": "^3.13.1",
+ "@react-types/checkbox": "^3.9.1",
+ "@react-types/grid": "^3.2.11",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/table": "^3.10.4",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/tabs": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.8.1.tgz",
- "integrity": "sha512-3kRd5rYKclmW9lllcANq0oun2d1pZq7Onma95laYfrWtPBZ3YDVKOkujGSqdfSQAFVshWBjl2Q03yyvcRiwzbQ==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/list": "^3.10.0",
- "@react-stately/tabs": "^3.6.1",
- "@react-types/shared": "^3.21.0",
- "@react-types/tabs": "^3.3.3",
+ "version": "3.9.9",
+ "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.9.tgz",
+ "integrity": "sha512-oXPtANs16xu6MdMGLHjGV/2Zupvyp9CJEt7ORPLv5xAzSY5hSjuQHJLZ0te3Lh/KSG5/0o3RW/W5yEqo7pBQQQ==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/selection": "^3.22.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/tabs": "^3.7.1",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/tabs": "^3.3.12",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/tag": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.2.1.tgz",
- "integrity": "sha512-i7Mj3IhB91sGp3NS6iNBVh25W+LR2XXpTmtn3OS4R62q3Oalw/1PKqPWqFc73Lb5IWF5rj3eh2yTf+rerWf3dw==",
- "dependencies": {
- "@react-aria/gridlist": "^3.7.1",
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/label": "^3.7.2",
- "@react-aria/selection": "^3.17.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/list": "^3.10.0",
- "@react-types/button": "^3.9.0",
- "@react-types/shared": "^3.21.0",
+ "version": "3.4.9",
+ "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.9.tgz",
+ "integrity": "sha512-Vnps+zk8vYyjevv2Bc6vc9kSp9HFLKrKUDmrWMc0DfseypwJMc3Ya6F965ZVTjF9nuWrojNmvgusNu7qyXFShQ==",
+ "dependencies": {
+ "@react-aria/gridlist": "^3.10.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/selection": "^3.22.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/list": "^3.11.2",
+ "@react-types/button": "^3.10.2",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/textfield": {
- "version": "3.12.2",
- "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.12.2.tgz",
- "integrity": "sha512-wRg8LJjZV6o4S/LRFqxs5waGDTiuIa/CRN+/X37Fu7GeZFeK0IBvWjKPlXLe7gMswaFqRmTKnQCU42mzUdDK1g==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/label": "^3.7.2",
- "@react-aria/utils": "^3.21.1",
- "@react-types/shared": "^3.21.0",
- "@react-types/textfield": "^3.8.1",
+ "version": "3.16.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.16.0.tgz",
+ "integrity": "sha512-53RVpMeMDN/QoabqnYZ1lxTh1xTQ3IBYQARuayq5EGGMafyxoFHzttxUdSqkZGK/+zdSF2GfmjOYJVm2nDKuDQ==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/form": "^3.0.12",
+ "@react-aria/label": "^3.7.14",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/textfield": "^3.11.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/toggle": {
- "version": "3.8.2",
- "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.8.2.tgz",
- "integrity": "sha512-0+RmlOQtyRmU+Dd9qM9od4DPpITC7jqA+n3aZn732XtCsosz5gPGbhFuLbSdWRZ42FQgqo7pZQWaDRZpJPkipA==",
+ "version": "3.10.11",
+ "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.11.tgz",
+ "integrity": "sha512-J3jO3KJiUbaYVDEpeXSBwqcyKxpi9OreiHRGiaxb6VwB+FWCj7Gb2WKajByXNyfs8jc6kX9VUFaXa7jze60oEQ==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/toggle": "^3.8.1",
+ "@react-types/checkbox": "^3.9.1",
+ "@react-types/shared": "^3.27.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/toolbar": {
+ "version": "3.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.12.tgz",
+ "integrity": "sha512-a+Be27BtM2lzEdTzm19FikPbitfW65g/JZln3kyAvgpswhU6Ljl8lztaVw4ixjG4H0nqnKvVggMy4AlWwDUaVQ==",
"dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/toggle": "^3.6.3",
- "@react-types/checkbox": "^3.5.2",
- "@react-types/shared": "^3.21.0",
- "@react-types/switch": "^3.4.2",
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/i18n": "^3.12.5",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/tooltip": {
- "version": "3.6.4",
- "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.6.4.tgz",
- "integrity": "sha512-5WCOiRSugzbfEOH+Bjpuf6EsNyynqq5S1uDh/P6J8qiYDjc0xLRJ5dyLdytX7c8MK9Y0pIHi6xb0xR9jDqJXTw==",
- "dependencies": {
- "@react-aria/focus": "^3.14.3",
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/tooltip": "^3.4.5",
- "@react-types/shared": "^3.21.0",
- "@react-types/tooltip": "^3.4.5",
+ "version": "3.7.11",
+ "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.11.tgz",
+ "integrity": "sha512-mhZgAWUj7bUWipDeJXaVPZdqnzoBCd/uaEbdafnvgETmov1udVqPTh9w4ZKX2Oh1wa2+OdLFrBOk+8vC6QbWag==",
+ "dependencies": {
+ "@react-aria/focus": "^3.19.1",
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-stately/tooltip": "^3.5.1",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/tooltip": "^3.4.14",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/utils": {
- "version": "3.21.1",
- "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.21.1.tgz",
- "integrity": "sha512-tySfyWHXOhd/b6JSrSOl7krngEXN3N6pi1hCAXObRu3+MZlaZOMDf/j18aoteaIF2Jpv8HMWUJUJtQKGmBJGRA==",
+ "version": "3.27.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.27.0.tgz",
+ "integrity": "sha512-p681OtApnKOdbeN8ITfnnYqfdHS0z7GE+4l8EXlfLnr70Rp/9xicBO6d2rU+V/B3JujDw2gPWxYKEnEeh0CGCw==",
"dependencies": {
- "@react-aria/ssr": "^3.8.0",
- "@react-stately/utils": "^3.8.0",
- "@react-types/shared": "^3.21.0",
+ "@react-aria/ssr": "^3.9.7",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0",
- "clsx": "^1.1.1"
+ "clsx": "^2.0.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/visually-hidden": {
- "version": "3.8.6",
- "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.6.tgz",
- "integrity": "sha512-6DmS/JLbK9KgU/ClK1WjwOyvpn8HtwYn+uisMLdP7HlCm692peYOkXDR1jqYbHL4GlyLCD0JLI+/xGdVh5aR/w==",
+ "version": "3.8.19",
+ "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.19.tgz",
+ "integrity": "sha512-MZgCCyQ3sdG94J5iJz7I7Ai3IxoN0U5d/+EaUnA1mfK7jf2fSYQBqi6Eyp8sWUYzBTLw4giXB5h0RGAnWzk9hA==",
"dependencies": {
- "@react-aria/interactions": "^3.19.1",
- "@react-aria/utils": "^3.21.1",
- "@react-types/shared": "^3.21.0",
- "@swc/helpers": "^0.5.0",
- "clsx": "^1.1.1"
+ "@react-aria/interactions": "^3.23.0",
+ "@react-aria/utils": "^3.27.0",
+ "@react-types/shared": "^3.27.0",
+ "@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/calendar": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.4.1.tgz",
- "integrity": "sha512-XKCdrXNA7/ukZ842EeDZfLqYUQDv/x5RoAVkzTbp++3U/MLM1XZXsqj+5xVlQfJiWpQzM9L6ySjxzzgepJDeuw==",
- "dependencies": {
- "@internationalized/date": "^3.5.0",
- "@react-stately/utils": "^3.8.0",
- "@react-types/calendar": "^3.4.1",
- "@react-types/datepicker": "^3.6.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.7.0.tgz",
+ "integrity": "sha512-N15zKubP2S7eWfPSJjKVlmJA7YpWzrIGx52BFhwLSQAZcV+OPcMgvOs71WtB7PLwl6DUYQGsgc0B3tcHzzvdvQ==",
+ "dependencies": {
+ "@internationalized/date": "^3.7.0",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/calendar": "^3.6.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/checkbox": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.5.1.tgz",
- "integrity": "sha512-j+EbHpZgS8J2LbysbVDK3vQAJc7YZHOjHRX20auEzVmulAFKwkRpevo/R5gEL4EpOz4bRyu+BH/jbssHXG+Ezw==",
- "dependencies": {
- "@react-stately/toggle": "^3.6.3",
- "@react-stately/utils": "^3.8.0",
- "@react-types/checkbox": "^3.5.2",
- "@react-types/shared": "^3.21.0",
+ "version": "3.6.11",
+ "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.11.tgz",
+ "integrity": "sha512-jApdBis+Q1sXLivg+f7krcVaP/AMMMiQcVqcz5gwxlweQN+dRZ/NpL0BYaDOuGc26Mp0lcuVaET3jIZeHwtyxA==",
+ "dependencies": {
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/checkbox": "^3.9.1",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/collections": {
- "version": "3.10.2",
- "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.2.tgz",
- "integrity": "sha512-h+LzCa1gWhVRWVH8uR+ZxsKmFSx7kW3RIlcjWjhfyc59BzXCuojsOJKTTAyPVFP/3kOdJeltw8g/reV1Cw/x6Q==",
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.12.1.tgz",
+ "integrity": "sha512-8QmFBL7f+P64dEP4o35pYH61/lP0T/ziSdZAvNMrCqaM+fXcMfUp2yu1E63kADVX7WRDsFJWE3CVMeqirPH6Xg==",
"dependencies": {
- "@react-types/shared": "^3.21.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/combobox": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.7.1.tgz",
- "integrity": "sha512-JMKsbhCgP8HpwRjHLBmJILzyU9WzWykjXyP4QF/ifmkzGRjC/s46+Ieq+WonjVaLNGCoi6XqhYn2x2RyACSbsQ==",
- "dependencies": {
- "@react-stately/collections": "^3.10.2",
- "@react-stately/list": "^3.10.0",
- "@react-stately/menu": "^3.5.6",
- "@react-stately/select": "^3.5.5",
- "@react-stately/utils": "^3.8.0",
- "@react-types/combobox": "^3.8.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.10.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.10.2.tgz",
+ "integrity": "sha512-uT642Dool4tQBh+8UQjlJnTisrJVtg3LqmiP/HqLQ4O3pW0O+ImbG+2r6c9dUzlAnH4kEfmEwCp9dxkBkmFWsg==",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/list": "^3.11.2",
+ "@react-stately/overlays": "^3.6.13",
+ "@react-stately/select": "^3.6.10",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/combobox": "^3.13.2",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/datepicker": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.8.0.tgz",
- "integrity": "sha512-6YDSmkrRafYCWhRHks8Z2tZavM1rqSOy8GY8VYjYMCVTFpRuhPK9TQaFv2BdzZL/vJ6OGThxqoglcEwywZVq2g==",
- "dependencies": {
- "@internationalized/date": "^3.5.0",
- "@internationalized/string": "^3.1.1",
- "@react-stately/overlays": "^3.6.3",
- "@react-stately/utils": "^3.8.0",
- "@react-types/datepicker": "^3.6.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.12.0.tgz",
+ "integrity": "sha512-AfJEP36d+QgQ30GfacXtYdGsJvqY2yuCJ+JrjHct+m1nYuTkMvMMnhwNBFasgDJPLCDyHzyANlWkl2kQGfsBFw==",
+ "dependencies": {
+ "@internationalized/date": "^3.7.0",
+ "@internationalized/string": "^3.2.5",
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/overlays": "^3.6.13",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/datepicker": "^3.10.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/dnd": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.2.5.tgz",
- "integrity": "sha512-f9S+ycjAMEaz9HqGxkx4jsqo/ZS8kh0o97rxSKpGFKPZ02UMFWCr9lJI1p3hVGukiMahrmsNtoQXAvMcFAZyQQ==",
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.5.1.tgz",
+ "integrity": "sha512-N18wt6fka9ngJJqxfAzmdtyrk9whAnqWUxZn22CatjNQsqukI4a6KRYwZTXM9x/wm7KamhVOp+GBl85zM8GLdA==",
"dependencies": {
- "@react-stately/selection": "^3.14.0",
- "@react-types/shared": "^3.21.0",
+ "@react-stately/selection": "^3.19.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/flags": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.0.0.tgz",
- "integrity": "sha512-e3i2ItHbIa0eEwmSXAnPdD7K8syW76JjGe8ENxwFJPW/H1Pu9RJfjkCb/Mq0WSPN/TpxBb54+I9TgrGhbCoZ9w==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.0.5.tgz",
+ "integrity": "sha512-6wks4csxUwPCp23LgJSnkBRhrWpd9jGd64DjcCTNB2AHIFu7Ab1W59pJpUL6TW7uAxVxdNKjgn6D1hlBy8qWsA==",
"dependencies": {
- "@swc/helpers": "^0.4.14"
+ "@swc/helpers": "^0.5.0"
}
},
- "node_modules/@react-stately/flags/node_modules/@swc/helpers": {
- "version": "0.4.36",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz",
- "integrity": "sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q==",
+ "node_modules/@react-stately/form": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.1.1.tgz",
+ "integrity": "sha512-qavrz5X5Mdf/Q1v/QJRxc0F8UTNEyRCNSM1we/nnF7GV64+aYSDLOtaRGmzq+09RSwo1c8ZYnIkK5CnwsPhTsQ==",
"dependencies": {
- "legacy-swc-helpers": "npm:@swc/helpers@=0.4.14",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@react-stately/flags/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
- "node_modules/@react-stately/grid": {
- "version": "3.8.2",
- "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.8.2.tgz",
- "integrity": "sha512-CB5QpYjXFatuXZodj3r0vIiqTysUe6DURZdJu6RKG2Elx19n2k49fKyx7P7CTKD2sPBOMSSX4edWuTzpL8Tl+A==",
- "dependencies": {
- "@react-stately/collections": "^3.10.2",
- "@react-stately/selection": "^3.14.0",
- "@react-types/grid": "^3.2.2",
- "@react-types/shared": "^3.21.0",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
- "node_modules/@react-stately/layout": {
- "version": "3.13.3",
- "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-3.13.3.tgz",
- "integrity": "sha512-AZ2Sm7iSRcRsNATXg7bjbPpZIjV3z7bHAJtICWA1wHieVVSV1FFoyDyiXdDTIOxyuGeytNPaxtGfPpFZia9Wsg==",
- "dependencies": {
- "@react-stately/collections": "^3.10.2",
- "@react-stately/table": "^3.11.2",
- "@react-stately/virtualizer": "^3.6.4",
- "@react-types/grid": "^3.2.2",
- "@react-types/shared": "^3.21.0",
- "@react-types/table": "^3.9.0",
+ "node_modules/@react-stately/grid": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.10.1.tgz",
+ "integrity": "sha512-MOIy//AdxZxIXIzvWSKpvMvaPEMZGQNj+/cOsElHepv/Veh0psNURZMh2TP6Mr0+MnDTZbX+5XIeinGkWYO3JQ==",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/selection": "^3.19.0",
+ "@react-types/grid": "^3.2.11",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/list": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.0.tgz",
- "integrity": "sha512-Yspumiln2fvzoO8AND8jNAIfBu1XPaYioeeDmsB5Vrya2EvOkzEGsauQSNBJ6Vhee1fQqpnmzH1HB0jfIKUfzg==",
+ "version": "3.11.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.11.2.tgz",
+ "integrity": "sha512-eU2tY3aWj0SEeC7lH9AQoeAB4LL9mwS54FvTgHHoOgc1ZIwRJUaZoiuETyWQe98AL8KMgR1nrnDJ1I+CcT1Y7g==",
"dependencies": {
- "@react-stately/collections": "^3.10.2",
- "@react-stately/selection": "^3.14.0",
- "@react-stately/utils": "^3.8.0",
- "@react-types/shared": "^3.21.0",
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/selection": "^3.19.0",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/menu": {
- "version": "3.5.6",
- "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.5.6.tgz",
- "integrity": "sha512-Cm82SVda1qP71Fcz8ohIn3JYKmKCuSUIFr1WsEo/YwDPkX0x9+ev6rmphHTsxDdkCLcYHSTQL6e2KL0wAg50zA==",
- "dependencies": {
- "@react-stately/overlays": "^3.6.3",
- "@react-stately/utils": "^3.8.0",
- "@react-types/menu": "^3.9.5",
- "@react-types/shared": "^3.21.0",
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.9.1.tgz",
+ "integrity": "sha512-WRjGGImhQlQaer/hhahGytwd1BDq3fjpTkY/04wv3cQJPJR6lkVI5nSvGFMHfCaErsA1bNyB8/T9Y5F5u4u9ng==",
+ "dependencies": {
+ "@react-stately/overlays": "^3.6.13",
+ "@react-types/menu": "^3.9.14",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/numberfield": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.6.2.tgz",
- "integrity": "sha512-li/SO3BU3RGySRNlXhPRKr161GJyNbQe6kjnj+0BFTS/ST9nxCgxFK4llHf+S+I/shNI6+0U2nAjE85QOv4emQ==",
- "dependencies": {
- "@internationalized/number": "^3.3.0",
- "@react-stately/utils": "^3.8.0",
- "@react-types/numberfield": "^3.6.1",
- "@react-types/shared": "^3.21.0",
+ "version": "3.9.9",
+ "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.9.tgz",
+ "integrity": "sha512-hZsLiGGHTHmffjFymbH1qVmA633rU2GNjMFQTuSsN4lqqaP8fgxngd5pPCoTCUFEkUgWjdHenw+ZFByw8lIE+g==",
+ "dependencies": {
+ "@internationalized/number": "^3.6.0",
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/numberfield": "^3.8.8",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/overlays": {
- "version": "3.6.3",
- "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.3.tgz",
- "integrity": "sha512-K3eIiYAdAGTepYqNf2pVb+lPqLoVudXwmxPhyOSZXzjgpynD6tR3E9QfWQtkMazBuU73PnNX7zkH4l87r2AmTg==",
+ "version": "3.6.13",
+ "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.13.tgz",
+ "integrity": "sha512-WsU85Gf/b+HbWsnnYw7P/Ila3wD+C37Uk/WbU4/fHgJ26IEOWsPE6wlul8j54NZ1PnLNhV9Fn+Kffi+PaJMQXQ==",
"dependencies": {
- "@react-stately/utils": "^3.8.0",
- "@react-types/overlays": "^3.8.3",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/overlays": "^3.8.12",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/radio": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.9.1.tgz",
- "integrity": "sha512-DrQPHiP9pz1uQbBP/NDFdO8uOZigPbvuAWPUNK7Gq6kye5lW+RsS97IUnYJePNTSMvhiAVz/aleBt05Gr/PZmg==",
- "dependencies": {
- "@react-stately/utils": "^3.8.0",
- "@react-types/radio": "^3.5.2",
- "@react-types/shared": "^3.21.0",
+ "version": "3.10.10",
+ "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.10.tgz",
+ "integrity": "sha512-9x3bpq87uV8iYA4NaioTTWjriQSlSdp+Huqlxll0T3W3okpyraTTejE91PbIoRTUmL5qByIh2WzxYmr4QdBgAA==",
+ "dependencies": {
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/radio": "^3.8.6",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/searchfield": {
- "version": "3.4.6",
- "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.4.6.tgz",
- "integrity": "sha512-DeVacER0MD35gzQjrYpX/e3k8rjKF82W0OooTkRjeQ2U48femZkQpmp3O+j10foQx2LLaxqt9PSW7QS0Ww1bCA==",
+ "version": "3.5.9",
+ "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.9.tgz",
+ "integrity": "sha512-7/aO/oLJ4czKEji0taI/lbHKqPJRag9p3YmRaZ4yqjIMpKxzmJCWQcov5lzWeFhG/1hINKndYlxFnVIKV/urpg==",
"dependencies": {
- "@react-stately/utils": "^3.8.0",
- "@react-types/searchfield": "^3.5.1",
- "@react-types/shared": "^3.21.0",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/searchfield": "^3.5.11",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/select": {
- "version": "3.5.5",
- "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.5.5.tgz",
- "integrity": "sha512-nDkvFeAZbN7dK/Ty+mk1h4LZYYaoPpkwrG49wa67DTHkCc8Zk2+UEjhKPwOK20th4vfJKHzKjVa0Dtq4DIj0rw==",
- "dependencies": {
- "@react-stately/collections": "^3.10.2",
- "@react-stately/list": "^3.10.0",
- "@react-stately/menu": "^3.5.6",
- "@react-stately/selection": "^3.14.0",
- "@react-stately/utils": "^3.8.0",
- "@react-types/select": "^3.8.4",
- "@react-types/shared": "^3.21.0",
+ "version": "3.6.10",
+ "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.10.tgz",
+ "integrity": "sha512-V7V0FCL9T+GzLjyfnJB6PUaKldFyT/8Rj6M+R9ura1A0O+s/FEOesy0pdMXFoL1l5zeUpGlCnhJrsI5HFWHfDw==",
+ "dependencies": {
+ "@react-stately/form": "^3.1.1",
+ "@react-stately/list": "^3.11.2",
+ "@react-stately/overlays": "^3.6.13",
+ "@react-types/select": "^3.9.9",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/selection": {
- "version": "3.14.0",
- "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.14.0.tgz",
- "integrity": "sha512-E5rNH+gVGDJQDSnPO30ynu6jZ0Z0++VPUbM5Bu3P/bZ3+TgoTtDDvlONba3fspgSBDfdnHpsuG9eqYnDtEAyYA==",
+ "version": "3.19.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.19.0.tgz",
+ "integrity": "sha512-AvbUqnWjqVQC48RD39S9BpMKMLl55Zo5l/yx5JQFPl55cFwe9Tpku1KY0wzt3fXXiXWaqjDn/7Gkg1VJYy8esQ==",
"dependencies": {
- "@react-stately/collections": "^3.10.2",
- "@react-stately/utils": "^3.8.0",
- "@react-types/shared": "^3.21.0",
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/slider": {
- "version": "3.4.4",
- "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.4.4.tgz",
- "integrity": "sha512-tFexbtN50zSo6e1Gi8K9MBfqgOo1eemF/VvFbde3PP9nG+ODcxEIajaYDPlMUuFw5cemJuoKo3+G5NBBn2/AjQ==",
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.6.1.tgz",
+ "integrity": "sha512-8kij5O82Xe233vZZ6qNGqPXidnlNQiSnyF1q613c7ktFmzAyGjkIWVUapHi23T1fqm7H2Rs3RWlmwE9bo2KecA==",
"dependencies": {
- "@react-aria/i18n": "^3.8.4",
- "@react-aria/utils": "^3.21.1",
- "@react-stately/utils": "^3.8.0",
- "@react-types/shared": "^3.21.0",
- "@react-types/slider": "^3.6.2",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/slider": "^3.7.8",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/table": {
- "version": "3.11.2",
- "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.11.2.tgz",
- "integrity": "sha512-EVgksPAsnEoqeT+5ej4aGJdu9kAu3LCDqQfnmif2P/R1BP5eDU1Kv0N/mV/90Xp546g7kuZ1wS2if/hWDXEA5g==",
- "dependencies": {
- "@react-stately/collections": "^3.10.2",
- "@react-stately/flags": "^3.0.0",
- "@react-stately/grid": "^3.8.2",
- "@react-stately/selection": "^3.14.0",
- "@react-stately/utils": "^3.8.0",
- "@react-types/grid": "^3.2.2",
- "@react-types/shared": "^3.21.0",
- "@react-types/table": "^3.9.0",
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.13.1.tgz",
+ "integrity": "sha512-Im8W+F8o9EhglY5kqRa3xcMGXl8zBi6W5phGpAjXb+UGDL1tBIlAcYj733bw8g/ITCnaSz9ubsmON0HekPd6Jg==",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/flags": "^3.0.5",
+ "@react-stately/grid": "^3.10.1",
+ "@react-stately/selection": "^3.19.0",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/grid": "^3.2.11",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/table": "^3.10.4",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/tabs": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.1.tgz",
- "integrity": "sha512-akGmejEaXg2RMZuWbRZ0W1MLr515e0uV0iVZefKBlcHtD/mK9K9Bo2XxBScf0TIhaPJ6Qa2w2k2+V7RmT7r8Ag==",
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.7.1.tgz",
+ "integrity": "sha512-gr9ACyuWrYuc727h7WaHdmNw8yxVlUyQlguziR94MdeRtFGQnf3V6fNQG3kxyB77Ljko69tgDF7Nf6kfPUPAQQ==",
"dependencies": {
- "@react-stately/list": "^3.10.0",
- "@react-stately/utils": "^3.8.0",
- "@react-types/shared": "^3.21.0",
- "@react-types/tabs": "^3.3.3",
+ "@react-stately/list": "^3.11.2",
+ "@react-types/shared": "^3.27.0",
+ "@react-types/tabs": "^3.3.12",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/toggle": {
- "version": "3.6.3",
- "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.6.3.tgz",
- "integrity": "sha512-4kIMTjRjtaapFk4NVmBoFDUYfkmyqDaYAmHpRyEIHTDpBYn0xpxZL/MHv9WuLYa4MjJLRp0MeicuWiZ4ai7f6Q==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.8.1.tgz",
+ "integrity": "sha512-MVpe79ghVQiwLmVzIPhF/O/UJAUc9B+ZSylVTyJiEPi0cwhbkKGQv9thOF0ebkkRkace5lojASqUAYtSTZHQJA==",
"dependencies": {
- "@react-stately/utils": "^3.8.0",
- "@react-types/checkbox": "^3.5.2",
- "@react-types/shared": "^3.21.0",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/checkbox": "^3.9.1",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/tooltip": {
- "version": "3.4.5",
- "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.5.tgz",
- "integrity": "sha512-VrwQcjnrNddSulh+Zql8P8cORRnWqSPkHPqQwD/Ly91Rva3gUIy+VwnYeThbGDxRzlUv1wfN+UQraEcrgwSZ/Q==",
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.5.1.tgz",
+ "integrity": "sha512-0aI3U5kB7Cop9OCW9/Bag04zkivFSdUcQgy/TWL4JtpXidVWmOha8txI1WySawFSjZhH83KIyPc+wKm1msfLMQ==",
"dependencies": {
- "@react-stately/overlays": "^3.6.3",
- "@react-stately/utils": "^3.8.0",
- "@react-types/tooltip": "^3.4.5",
+ "@react-stately/overlays": "^3.6.13",
+ "@react-types/tooltip": "^3.4.14",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/tree": {
- "version": "3.7.3",
- "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.7.3.tgz",
- "integrity": "sha512-wB/68qetgCYTe7OMqbTFmtWRrEqVdIH2VlACPCsMlECr3lW9TrrbrOwlHIJfLhkxWvY3kSCoKcOJ5KTiJC9LGA==",
- "dependencies": {
- "@react-stately/collections": "^3.10.2",
- "@react-stately/selection": "^3.14.0",
- "@react-stately/utils": "^3.8.0",
- "@react-types/shared": "^3.21.0",
+ "version": "3.8.7",
+ "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.7.tgz",
+ "integrity": "sha512-hpc3pyuXWeQV5ufQ02AeNQg/MYhnzZ4NOznlY5OOUoPzpLYiI3ZJubiY3Dot4jw5N/LR7CqvDLHmrHaJPmZlHg==",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.1",
+ "@react-stately/selection": "^3.19.0",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/shared": "^3.27.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/utils": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.8.0.tgz",
- "integrity": "sha512-wCIoFDbt/uwNkWIBF+xV+21k8Z8Sj5qGO3uptTcVmjYcZngOaGGyB4NkiuZhmhG70Pkv+yVrRwoC1+4oav9cCg==",
+ "version": "3.10.5",
+ "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.5.tgz",
+ "integrity": "sha512-iMQSGcpaecghDIh3mZEpZfoFH3ExBwTtuBEcvZ2XnGzCgQjeYXcMdIUwAfVQLXFTdHUHGF6Gu6/dFrYsCzySBQ==",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
- }
- },
- "node_modules/@react-stately/virtualizer": {
- "version": "3.6.4",
- "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-3.6.4.tgz",
- "integrity": "sha512-lf3+FDRnyLyY1IhLfwA6GuE/9F3nIEc5p245NkUSN1ngKlXI5PvLHNatiVbONC3wt90abkpMK+WMhu2S/B+4lA==",
- "dependencies": {
- "@react-aria/utils": "^3.21.1",
- "@react-types/shared": "^3.21.0",
- "@swc/helpers": "^0.5.0"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/breadcrumbs": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.1.tgz",
- "integrity": "sha512-WWC5pQdWkAzJ2hkx4w7f+waDLLvuD9vowKey+bdLoEmKvdaHNLLVUQPEyFm6SQ5+E3pNBWkNx9a+0S9iW6wa+Q==",
+ "version": "3.7.10",
+ "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.10.tgz",
+ "integrity": "sha512-5HhRxkKHfAQBoyOYzyf4HT+24HgPE/C/QerxJLNNId303LXO03yeYrbvRqhYZSlD1ACLJW9OmpPpREcw5iSqgw==",
"dependencies": {
- "@react-types/link": "^3.5.1",
- "@react-types/shared": "^3.21.0"
+ "@react-types/link": "^3.5.10",
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/button": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.0.tgz",
- "integrity": "sha512-YhbchUDB7yL88ZFA0Zqod6qOMdzCLD5yVRmhWymk0yNLvB7EB1XX4c5sRANalfZSFP0RpCTlkjB05Hzp4+xOYg==",
+ "version": "3.10.2",
+ "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.10.2.tgz",
+ "integrity": "sha512-h8SB/BLoCgoBulCpyzaoZ+miKXrolK9XC48+n1dKJXT8g4gImrficurDW6+PRTQWaRai0Q0A6bu8UibZOU4syg==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/calendar": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.1.tgz",
- "integrity": "sha512-tiCkHi6IQtYcVoAESG79eUBWDXoo8NImo+Mj8WAWpo1lOA3SV1W2PpeXkoRNqtloilQ0aYcmsaJJUhciQG4ndg==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.6.0.tgz",
+ "integrity": "sha512-BtFh4BFwvsYlsaSqUOVxlqXZSlJ6u4aozgO3PwHykhpemwidlzNwm9qDZhcMWPioNF/w2cU/6EqhvEKUHDnFZg==",
"dependencies": {
- "@internationalized/date": "^3.5.0",
- "@react-types/shared": "^3.21.0"
+ "@internationalized/date": "^3.7.0",
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/checkbox": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.5.2.tgz",
- "integrity": "sha512-iRQrbY8vRRya3bt3i7sHAifhP/ozfkly1/TItkRK5MNPRNPRDKns55D8ZFkRMj4NSyKQpjVt1zzlBXrnSOxWdQ==",
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.9.1.tgz",
+ "integrity": "sha512-0x/KQcipfNM9Nvy6UMwYG25roRLvsiqf0J3woTYylNNWzF+72XT0iI5FdJkE3w2wfa0obmSoeq4WcbFREQrH/A==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/combobox": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.8.1.tgz",
- "integrity": "sha512-F910tk8K5qE0TksJ9LRGcJIpaPzpsCnFxT6E9oJH3ssK4N8qZL8QfT9tIKo2XWhK9Uxb/tIZOGQwA8Cn7TyZrA==",
+ "version": "3.13.2",
+ "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.13.2.tgz",
+ "integrity": "sha512-yl2yMcM5/v3lJiNZWjpAhQ9vRW6dD55CD4rYmO2K7XvzYJaFVT4WYI/AymPYD8RqomMp7coBmBHfHW0oupk8gg==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/datepicker": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.6.1.tgz",
- "integrity": "sha512-/M+0e9hL9w98f5k4EoxeH2UfPsUPoS6fvmFsmwUZJcDiw7wP510XngnDLy9GOHj9xgqagZ20S79cxcEuTq7U6g==",
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.10.0.tgz",
+ "integrity": "sha512-Att7y4NedNH1CogMDIX9URXgMLxGbZgnFCZ8oxgFAVndWzbh3TBcc4s7uoJDPvgRMAalq+z+SrlFFeoBeJmvvg==",
"dependencies": {
- "@internationalized/date": "^3.5.0",
- "@react-types/calendar": "^3.4.1",
- "@react-types/overlays": "^3.8.3",
- "@react-types/shared": "^3.21.0"
+ "@internationalized/date": "^3.7.0",
+ "@react-types/calendar": "^3.6.0",
+ "@react-types/overlays": "^3.8.12",
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/dialog": {
- "version": "3.5.6",
- "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.6.tgz",
- "integrity": "sha512-lwwaAgoi4xe4eEJxBns+cBIRstIPTKWWddMkp51r7Teeh2uKs1Wki7N+Acb9CfT6JQTQDqtVJm6K76rcqNBVwg==",
+ "version": "3.5.15",
+ "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.15.tgz",
+ "integrity": "sha512-BX1+mV35Oa0aIlhu98OzJaSB7uiCWDPQbr0AkpFBajSSlESUoAjntN+4N+QJmj24z2v6UE9zxGQ85/U/0Le+bw==",
"dependencies": {
- "@react-types/overlays": "^3.8.3",
- "@react-types/shared": "^3.21.0"
+ "@react-types/overlays": "^3.8.12",
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/grid": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.2.tgz",
- "integrity": "sha512-R4USOpn1xfsWVGwZsakRlIdsBA10XNCnAUcRXQTn2JmzLjDCtcln6uYo9IFob080lQuvjkSw3j4zkw7Yo4Qepg==",
- "dependencies": {
- "@react-types/shared": "^3.21.0"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
- }
- },
- "node_modules/@react-types/label": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-types/label/-/label-3.8.1.tgz",
- "integrity": "sha512-fA6zMTF2TmfU7H8JBJi0pNd8t5Ak4gO+ZA3cZBysf8r3EmdAsgr3LLqFaGTnZzPH1Fux6c7ARI3qjVpyNiejZQ==",
+ "version": "3.2.11",
+ "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.11.tgz",
+ "integrity": "sha512-Mww9nrasppvPbsBi+uUqFnf7ya8fXN0cTVzDNG+SveD8mhW+sbtuy+gPtEpnFD2Oyi8qLuObefzt4gdekJX2Yw==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/link": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.1.tgz",
- "integrity": "sha512-hX2KpjB7wSuJw5Pia63+WEgEql53VfVG1Vu2cTUJDxfrgUtawwHtxB8B0K3cs3jBanq69amgAInEx0FfqYY0uQ==",
+ "version": "3.5.10",
+ "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.10.tgz",
+ "integrity": "sha512-IM2mbSpB0qP44Jh1Iqpevo7bQdZAr0iDyDi13OhsiUYJeWgPMHzGEnQqdBMkrfQeOTXLtZtUyOYLXE2v39bhzQ==",
"dependencies": {
- "@react-aria/interactions": "^3.19.1",
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/listbox": {
- "version": "3.4.5",
- "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.4.5.tgz",
- "integrity": "sha512-nuRY3l8h/rBYQWTXWdZz5YJdl6QDDmXpHrnPuX7PxTwbXcwjhoMK+ZkJ0arA8Uv3MPs1OUcT6K6CInsPnG2ARQ==",
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.5.4.tgz",
+ "integrity": "sha512-5otTes0zOwRZwNtqysPD/aW4qFJSxd5znjwoWTLnzDXXOBHXPyR83IJf8ITgvIE5C0y+EFadsWR/BBO3k9Pj7g==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/menu": {
- "version": "3.9.5",
- "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.5.tgz",
- "integrity": "sha512-KB5lJM0p9PxwpVlHV9sRdpjh+sqINeHrJgGizy/cQI9bj26nupiEgamSD14dULNI6BFT9DkgKCsobBtE04DDKQ==",
+ "version": "3.9.14",
+ "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.14.tgz",
+ "integrity": "sha512-RJW/S8IPwbRuohJ/A9HJ7W8QaAY816tm7Nv6+H/TLXG76zu2AS5vEgq+0TcCAWvJJwUdLDpJWJMlo0iIoIBtcg==",
"dependencies": {
- "@react-types/overlays": "^3.8.3",
- "@react-types/shared": "^3.21.0"
+ "@react-types/overlays": "^3.8.12",
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/meter": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.3.5.tgz",
- "integrity": "sha512-7kSP/bqkt6ANHUJLJ4OsHOPNwg9ETvWHAKXDYoCqkLYzdhFh0H/8EAW9z4Bh/io0GvR7ePds9s+32iislfSwDg==",
+ "version": "3.4.6",
+ "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.6.tgz",
+ "integrity": "sha512-YczAht1VXy3s4fR6Dq0ibGsjulGHzS/A/K4tOruSNTL6EkYH9ktHX62Xk/OhCiKHxV315EbZ136WJaCeO4BgHw==",
"dependencies": {
- "@react-types/progress": "^3.5.0",
- "@react-types/shared": "^3.21.0"
+ "@react-types/progress": "^3.5.9"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/numberfield": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.6.1.tgz",
- "integrity": "sha512-jdMCN0mQ7eZkPrCKYkkG+jSjcG2VQ5P7mR9tTaCQeQK1wo+tF/8LWD+6n6dU7hH/qlU9sxVEg3U3kJ9sgNK+Hw==",
+ "version": "3.8.8",
+ "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.8.tgz",
+ "integrity": "sha512-825JPppxDaWh0Zxb0Q+wSslgRQYOtQPCAuhszPuWEy6d2F/M+hLR+qQqvQm9+LfMbdwiTg6QK5wxdWFCp2t7jw==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/overlays": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.3.tgz",
- "integrity": "sha512-TrCG2I2+V+TD0PGi3CqfnyU5jEzcelSGgYJQvVxsl5Vv3ri7naBLIsOjF9x66tPxhINLCPUtOze/WYRAexp8aw==",
+ "version": "3.8.12",
+ "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.12.tgz",
+ "integrity": "sha512-ZvR1t0YV7/6j+6OD8VozKYjvsXT92+C/2LOIKozy7YUNS5KI4MkXbRZzJvkuRECVZOmx8JXKTUzhghWJM/3QuQ==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/progress": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.0.tgz",
- "integrity": "sha512-c1KLQCfYjdUdkTcPy0ZW31dc2+D86ZiZRHPNOaSYFGJjk9ItbWWi8BQTwlrw6D2l/+0d/YDdUFGaZhHMrY9mBQ==",
+ "version": "3.5.9",
+ "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.9.tgz",
+ "integrity": "sha512-zFxOzx3G8XUmHgpm037Hcayls5bqzXVa182E3iM7YWTmrjxJPKZ58XL0WWBgpTd+mJD7fTpnFdAZqSmFbtDOdA==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/radio": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.5.2.tgz",
- "integrity": "sha512-crYQ+97abd5v0Iw9X+Tt+E7KWdm5ckr4g0+Iy8byV1g6MyiBOsNtq9QT99TOzyWJPqqD8T9qZfAOk49wK7KEDg==",
+ "version": "3.8.6",
+ "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.6.tgz",
+ "integrity": "sha512-woTQYdRFjPzuml4qcIf+2zmycRuM5w3fDS5vk6CQmComVUjOFPtD28zX3Z9kc9lSNzaBQz9ONZfFqkZ1gqfICA==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/searchfield": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.1.tgz",
- "integrity": "sha512-+v9fo50JrZOfFzbdgJsW39hyTFv1gVH458nx82aidYJzQocFJniiAEl0ZhhRzbE8RijyjLleKIAY+klPeFmEaQ==",
+ "version": "3.5.11",
+ "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.11.tgz",
+ "integrity": "sha512-MX8d9pgvxZxmgDwI0tiDaf6ijOY8XcRj0HM8Ocfttlk7PEFJK44p51WsUC+fPX1GmZni2JpFkx/haPOSLUECdw==",
"dependencies": {
- "@react-types/shared": "^3.21.0",
- "@react-types/textfield": "^3.8.1"
+ "@react-types/shared": "^3.27.0",
+ "@react-types/textfield": "^3.11.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/select": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.8.4.tgz",
- "integrity": "sha512-jHBaLiAHTcYPz52kuJpypBbR0WAA+YCZHy2HH+W8711HuTqePZCEp6QAWHK9Fw0qwSZQ052jYaWvOsgEZZ6ojQ==",
+ "version": "3.9.9",
+ "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.9.tgz",
+ "integrity": "sha512-/hCd0o+ztn29FKCmVec+v7t4JpOzz56o+KrG7NDq2pcRWqUR9kNwCjrPhSbJIIEDm4ubtrfPu41ysIuDvRd2Bg==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/shared": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.21.0.tgz",
- "integrity": "sha512-wJA2cUF8dP4LkuNUt9Vh2kkfiQb2NLnV2pPXxVnKJZ7d4x2/7VPccN+LYPnH8m0X3+rt50cxWuPKQmjxSsCFOg==",
+ "version": "3.27.0",
+ "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.27.0.tgz",
+ "integrity": "sha512-gvznmLhi6JPEf0bsq7SwRYTHAKKq/wcmKqFez9sRdbED+SPMUmK5omfZ6w3EwUFQHbYUa4zPBYedQ7Knv70RMw==",
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/slider": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.6.2.tgz",
- "integrity": "sha512-LSvna1gpOvBxOBI5I/CYEtkAshWYwPlxE9F/jCaxCa9Q7E9xZp1hFFGY87iQ1A3vQM5SCa5PFStwOvXO7rA55w==",
+ "version": "3.7.8",
+ "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.8.tgz",
+ "integrity": "sha512-utW1o9KT70hqFwu1zqMtyEWmP0kSATk4yx+Fm/peSR4iZa+BasRqH83yzir5GKc8OfqfE1kmEsSlO98/k986+w==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/switch": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.4.2.tgz",
- "integrity": "sha512-OQWpawikWhF+ET1/kE0/JeJVr6gHjkR72p/idTsT7RUJySBcehhAscbIA8iWzVWJvdFCVF2hG7uzBAJTeDMr9A==",
+ "version": "3.5.8",
+ "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.8.tgz",
+ "integrity": "sha512-sL7jmh8llF8BxzY4HXkSU4bwU8YU6gx45P85D0AdYXgRHxU9Cp7BQPOMF4pJoQ8TTej05MymY5q7xvJVmxUTAQ==",
"dependencies": {
- "@react-types/checkbox": "^3.5.2",
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/table": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.9.0.tgz",
- "integrity": "sha512-WOLxZ3tzLA4gxRxvnsZhnnQDbh4Qe/johpHNk4coSOFOP5W8PbunPacXnbvdPkSx6rqrOIzCnYcZCtgk4gDQmg==",
+ "version": "3.10.4",
+ "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.10.4.tgz",
+ "integrity": "sha512-d0tLz/whxVteqr1rophtuuxqyknHHfTKeXrCgDjt8pAyd9U8GPDbfcFSfYPUhWdELRt7aLVyQw6VblZHioVEgQ==",
"dependencies": {
- "@react-types/grid": "^3.2.2",
- "@react-types/shared": "^3.21.0"
+ "@react-types/grid": "^3.2.11",
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/tabs": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.3.tgz",
- "integrity": "sha512-Zc4g5TIwJpKS5fiT9m4dypbCr1xqtauL4wqM76fGERCAZy0FwXTH/yjzHJDYKyWFJrQNWtJ0KAhJR/ZqKDVnIw==",
+ "version": "3.3.12",
+ "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.12.tgz",
+ "integrity": "sha512-E9O9G+wf9kaQ8UbDEDliW/oxYlJnh7oDCW1zaMOySwnG4yeCh7Wu02EOCvlQW4xvgn/i+lbEWgirf7L+yj5nRg==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/textfield": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.8.1.tgz",
- "integrity": "sha512-p8Xmew9kzJd+tCM7h9LyebZHpv7SH1IE1Nu13hLCOV5cZ/tVVVCwjNGLMv4MtUpSn++H42YLJgAW9Uif+a+RHg==",
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.11.0.tgz",
+ "integrity": "sha512-YORBgr6wlu2xfvr4MqjKFHGpj+z8LBzk14FbWDbYnnhGnv0I10pj+m2KeOHgDNFHrfkDdDOQmMIKn1UCqeUuEg==",
"dependencies": {
- "@react-types/shared": "^3.21.0"
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/tooltip": {
- "version": "3.4.5",
- "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.5.tgz",
- "integrity": "sha512-pv87Vlu+Pn1Titw199y5aiSuXF/GHX+fBCihi9BeePqtwYm505e/Si01BNh5ejCeXXOS4JIMuXwmGGzGVdGk6Q==",
+ "version": "3.4.14",
+ "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.14.tgz",
+ "integrity": "sha512-J7CeYL2yPeKIasx1rPaEefyCHGEx2DOCx+7bM3XcKGmCxvNdVQLjimNJOt8IHlUA0nFJQOjmSW/mz9P0f2/kUw==",
"dependencies": {
- "@react-types/overlays": "^3.8.3",
- "@react-types/shared": "^3.21.0"
+ "@react-types/overlays": "^3.8.12",
+ "@react-types/shared": "^3.27.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@remix-run/router": {
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
"integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.10.4",
"@rollup/pluginutils": "^3.1.0"
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
"integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@types/estree": "0.0.39",
"estree-walker": "^1.0.1",
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+ "dev": true
+ },
+ "node_modules/@rollup/plugin-babel/node_modules/estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
+ "dev": true
+ },
+ "node_modules/@rollup/plugin-babel/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
- "license": "MIT"
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
},
"node_modules/@rollup/plugin-inject": {
"version": "5.0.3",
}
}
},
- "node_modules/@rollup/plugin-inject/node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "dev": true
- },
"node_modules/@rollup/plugin-node-resolve": {
- "version": "15.2.3",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz",
- "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==",
+ "version": "15.3.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
+ "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"@types/resolve": "1.20.2",
"deepmerge": "^4.2.2",
- "is-builtin-module": "^3.2.1",
"is-module": "^1.0.0",
"resolve": "^1.22.1"
},
}
}
},
- "node_modules/@rollup/plugin-node-resolve/node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/@rollup/plugin-replace": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz",
"integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^3.1.0",
"magic-string": "^0.25.7"
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
"integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@types/estree": "0.0.39",
"estree-walker": "^1.0.1",
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
- "dev": true,
- "license": "MIT"
+ "dev": true
+ },
+ "node_modules/@rollup/plugin-replace/node_modules/estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
+ "dev": true
},
"node_modules/@rollup/plugin-replace/node_modules/magic-string": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
"integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"sourcemap-codec": "^1.4.8"
}
},
+ "node_modules/@rollup/plugin-replace/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/@rollup/plugin-terser": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
"integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
"dev": true,
- "license": "MIT",
"dependencies": {
"serialize-javascript": "^6.0.1",
"smob": "^1.0.0",
}
},
"node_modules/@rollup/pluginutils": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
- "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
+ "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
"dev": true,
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
- "picomatch": "^2.3.1"
+ "picomatch": "^4.0.2"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
- "rollup": "^1.20.0||^2.0.0||^3.0.0"
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
}
}
},
- "node_modules/@rollup/pluginutils/node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "dev": true
- },
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.8.0.tgz",
- "integrity": "sha512-zdTObFRoNENrdPpnTNnhOljYIcOX7aI7+7wyrSpPFFIOf/nRdedE6IYsjaBE7tjukphh1tMTojgJ7p3lKY8x6Q==",
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz",
+ "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==",
"cpu": [
"arm"
],
- "dev": true,
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.8.0.tgz",
- "integrity": "sha512-aiItwP48BiGpMFS9Znjo/xCNQVwTQVcRKkFKsO81m8exrGjHkCBDvm9PHay2kpa8RPnZzzKcD1iQ9KaLY4fPQQ==",
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz",
+ "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==",
"cpu": [
"arm64"
],
- "dev": true,
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.8.0.tgz",
- "integrity": "sha512-zhNIS+L4ZYkYQUjIQUR6Zl0RXhbbA0huvNIWjmPc2SL0cB1h5Djkcy+RZ3/Bwszfb6vgwUvcVJYD6e6Zkpsi8g==",
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz",
+ "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==",
"cpu": [
"arm64"
],
- "dev": true,
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.8.0.tgz",
- "integrity": "sha512-A/FAHFRNQYrELrb/JHncRWzTTXB2ticiRFztP4ggIUAfa9Up1qfW8aG2w/mN9jNiZ+HB0t0u0jpJgFXG6BfRTA==",
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz",
+ "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"darwin"
]
},
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.8.0.tgz",
- "integrity": "sha512-JsidBnh3p2IJJA4/2xOF2puAYqbaczB3elZDT0qHxn362EIoIkq7hrR43Xa8RisgI6/WPfvb2umbGsuvf7E37A==",
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz",
+ "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==",
"cpu": [
- "arm"
+ "arm64"
],
- "dev": true,
"optional": true,
"os": [
- "linux"
+ "freebsd"
]
},
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.8.0.tgz",
- "integrity": "sha512-hBNCnqw3EVCkaPB0Oqd24bv8SklETptQWcJz06kb9OtiShn9jK1VuTgi7o4zPSt6rNGWQOTDEAccbk0OqJmS+g==",
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz",
+ "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==",
"cpu": [
- "arm64"
+ "x64"
],
- "dev": true,
"optional": true,
"os": [
- "linux"
+ "freebsd"
]
},
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.8.0.tgz",
- "integrity": "sha512-Fw9ChYfJPdltvi9ALJ9wzdCdxGw4wtq4t1qY028b2O7GwB5qLNSGtqMsAel1lfWTZvf4b6/+4HKp0GlSYg0ahA==",
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz",
+ "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==",
"cpu": [
- "arm64"
+ "arm"
],
- "dev": true,
"optional": true,
"os": [
"linux"
]
},
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.8.0.tgz",
- "integrity": "sha512-BH5xIh7tOzS9yBi8dFrCTG8Z6iNIGWGltd3IpTSKp6+pNWWO6qy8eKoRxOtwFbMrid5NZaidLYN6rHh9aB8bEw==",
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz",
+ "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==",
"cpu": [
- "riscv64"
+ "arm"
],
- "dev": true,
"optional": true,
"os": [
"linux"
]
},
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.8.0.tgz",
- "integrity": "sha512-PmvAj8k6EuWiyLbkNpd6BLv5XeYFpqWuRvRNRl80xVfpGXK/z6KYXmAgbI4ogz7uFiJxCnYcqyvZVD0dgFog7Q==",
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz",
+ "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==",
"cpu": [
- "x64"
+ "arm64"
],
- "dev": true,
"optional": true,
"os": [
"linux"
]
},
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.8.0.tgz",
- "integrity": "sha512-mdxnlW2QUzXwY+95TuxZ+CurrhgrPAMveDWI97EQlA9bfhR8tw3Pt7SUlc/eSlCNxlWktpmT//EAA8UfCHOyXg==",
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz",
+ "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==",
"cpu": [
- "x64"
+ "arm64"
],
- "dev": true,
"optional": true,
"os": [
"linux"
]
},
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.8.0.tgz",
- "integrity": "sha512-ge7saUz38aesM4MA7Cad8CHo0Fyd1+qTaqoIo+Jtk+ipBi4ATSrHWov9/S4u5pbEQmLjgUjB7BJt+MiKG2kzmA==",
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz",
+ "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz",
+ "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz",
+ "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz",
+ "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz",
+ "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz",
+ "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz",
+ "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==",
"cpu": [
"arm64"
],
- "dev": true,
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.8.0.tgz",
- "integrity": "sha512-p9E3PZlzurhlsN5h9g7zIP1DnqKXJe8ZUkFwAazqSvHuWfihlIISPxG9hCHCoA+dOOspL/c7ty1eeEVFTE0UTw==",
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz",
+ "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==",
"cpu": [
"ia32"
],
- "dev": true,
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.8.0.tgz",
- "integrity": "sha512-kb4/auKXkYKqlUYTE8s40FcJIj5soOyRLHKd4ugR0dCq0G2EfcF54eYcfQiGkHzjidZ40daB4ulsFdtqNKZtBg==",
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz",
+ "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"win32"
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
"integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
"dev": true,
- "license": "Apache-2.0",
"dependencies": {
"ejs": "^3.1.6",
"json5": "^2.2.0",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
"integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"sourcemap-codec": "^1.4.8"
}
},
"node_modules/@swc/core": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.5.tgz",
- "integrity": "sha512-M8O22EEgdSONLd+7KRrXj8pn+RdAZZ7ISnPjE9KCQQlI0kkFNEquWR+uFdlFxQfwlyCe/Zb6uGXGDvtcov4IMg==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.7.tgz",
+ "integrity": "sha512-py91kjI1jV5D5W/Q+PurBdGsdU5TFbrzamP7zSCqLdMcHkKi3rQEM5jkQcZr0MXXSJTaayLxS3MWYTBIkzPDrg==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
- "@swc/counter": "^0.1.2",
- "@swc/types": "^0.1.5"
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.17"
},
"engines": {
"node": ">=10"
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
- "@swc/core-darwin-arm64": "1.5.5",
- "@swc/core-darwin-x64": "1.5.5",
- "@swc/core-linux-arm-gnueabihf": "1.5.5",
- "@swc/core-linux-arm64-gnu": "1.5.5",
- "@swc/core-linux-arm64-musl": "1.5.5",
- "@swc/core-linux-x64-gnu": "1.5.5",
- "@swc/core-linux-x64-musl": "1.5.5",
- "@swc/core-win32-arm64-msvc": "1.5.5",
- "@swc/core-win32-ia32-msvc": "1.5.5",
- "@swc/core-win32-x64-msvc": "1.5.5"
+ "@swc/core-darwin-arm64": "1.10.7",
+ "@swc/core-darwin-x64": "1.10.7",
+ "@swc/core-linux-arm-gnueabihf": "1.10.7",
+ "@swc/core-linux-arm64-gnu": "1.10.7",
+ "@swc/core-linux-arm64-musl": "1.10.7",
+ "@swc/core-linux-x64-gnu": "1.10.7",
+ "@swc/core-linux-x64-musl": "1.10.7",
+ "@swc/core-win32-arm64-msvc": "1.10.7",
+ "@swc/core-win32-ia32-msvc": "1.10.7",
+ "@swc/core-win32-x64-msvc": "1.10.7"
},
"peerDependencies": {
- "@swc/helpers": "^0.5.0"
+ "@swc/helpers": "*"
},
"peerDependenciesMeta": {
"@swc/helpers": {
}
},
"node_modules/@swc/core-darwin-arm64": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.5.tgz",
- "integrity": "sha512-Ol5ZwZYdTOZsv2NwjcT/qVVALKzVFeh+IJ4GNarr3P99+38Dkwi81OqCI1o/WaDXQYKAQC/V+CzMbkEuJJfq9Q==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.7.tgz",
+ "integrity": "sha512-SI0OFg987P6hcyT0Dbng3YRISPS9uhLX1dzW4qRrfqQdb0i75lPJ2YWe9CN47HBazrIA5COuTzrD2Dc0TcVsSQ==",
"cpu": [
"arm64"
],
}
},
"node_modules/@swc/core-darwin-x64": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.5.tgz",
- "integrity": "sha512-XHWpKBIPKYLgh5/lV2PYjO84lkzf5JR51kjiloyz2Pa9HIV8tHoAP8bYdJwm4nUp2I7KcEh3pPH0AVu5LpxMKw==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.7.tgz",
+ "integrity": "sha512-RFIAmWVicD/l3RzxgHW0R/G1ya/6nyMspE2cAeDcTbjHi0I5qgdhBWd6ieXOaqwEwiCd0Mot1g2VZrLGoBLsjQ==",
"cpu": [
"x64"
],
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.5.tgz",
- "integrity": "sha512-vtoWNCWAe+CNSqtqIwFnIH48qgPPlUZKoQ4EVFeMM+7/kDi6SeNxoh5TierJs5bKAWxD49VkPvRoWFCk6V62mA==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.7.tgz",
+ "integrity": "sha512-QP8vz7yELWfop5mM5foN6KkLylVO7ZUgWSF2cA0owwIaziactB2hCPZY5QU690coJouk9KmdFsPWDnaCFUP8tg==",
"cpu": [
"arm"
],
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.5.tgz",
- "integrity": "sha512-L4l7M78U6h/rCAxId+y5Vu+1KfDRF6dJZtitFcaT293guiUQFwJv8gLxI4Jh5wFtZ0fYd0QaCuvh2Ip79CzGMg==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.7.tgz",
+ "integrity": "sha512-NgUDBGQcOeLNR+EOpmUvSDIP/F7i/OVOKxst4wOvT5FTxhnkWrW+StJGKj+DcUVSK5eWOYboSXr1y+Hlywwokw==",
"cpu": [
"arm64"
],
}
},
"node_modules/@swc/core-linux-arm64-musl": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.5.tgz",
- "integrity": "sha512-DkzJc13ukXa7oJpyn24BjIgsiOybYrc+IxjsQyfNlDrrs1QXP4elStcpkD02SsIuSyHjZV8Hw2HFBMQB3OHPrA==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.7.tgz",
+ "integrity": "sha512-gp5Un3EbeSThBIh6oac5ZArV/CsSmTKj5jNuuUAuEsML3VF9vqPO+25VuxCvsRf/z3py+xOWRaN2HY/rjMeZog==",
"cpu": [
"arm64"
],
}
},
"node_modules/@swc/core-linux-x64-gnu": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.5.tgz",
- "integrity": "sha512-kj4ZwWJGeBEUzHrRQP2VudN+kkkYH7OI1dPVDc6kWQx5X4329JeKOas4qY0l7gDVjBbRwN9IbbPI6TIn2KfAug==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.7.tgz",
+ "integrity": "sha512-k/OxLLMl/edYqbZyUNg6/bqEHTXJT15l9WGqsl/2QaIGwWGvles8YjruQYQ9d4h/thSXLT9gd8bExU2D0N+bUA==",
"cpu": [
"x64"
],
}
},
"node_modules/@swc/core-linux-x64-musl": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.5.tgz",
- "integrity": "sha512-6pTorCs4mYhPhYtC4jNOnhGgjNd3DZcRoZ9P0tzXXP69aCbYjvlgNH/NRvAROp9AaVFeZ7a7PmCWb6+Rbe7NKg==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.7.tgz",
+ "integrity": "sha512-XeDoURdWt/ybYmXLCEE8aSiTOzEn0o3Dx5l9hgt0IZEmTts7HgHHVeRgzGXbR4yDo0MfRuX5nE1dYpTmCz0uyA==",
"cpu": [
"x64"
],
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.5.tgz",
- "integrity": "sha512-o0/9pstmEjwZyrY/bA+mymF0zH7E+GT/XCVqdKeWW9Wn3gTTyWa5MZnrFgI2THQ+AXwdglMB/Zo76ARQPaz/+A==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.7.tgz",
+ "integrity": "sha512-nYAbi/uLS+CU0wFtBx8TquJw2uIMKBnl04LBmiVoFrsIhqSl+0MklaA9FVMGA35NcxSJfcm92Prl2W2LfSnTqQ==",
"cpu": [
"arm64"
],
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.5.tgz",
- "integrity": "sha512-B+nypUwsmCuaH6RtKWgiPCb+ENjxstJPPJeMJvBqlJqyCaIkZzN4M07Ozi3xVv1VG21SRkd6G3xIqRoalrNc0Q==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.7.tgz",
+ "integrity": "sha512-+aGAbsDsIxeLxw0IzyQLtvtAcI1ctlXVvVcXZMNXIXtTURM876yNrufRo4ngoXB3jnb1MLjIIjgXfFs/eZTUSw==",
"cpu": [
"ia32"
],
}
},
"node_modules/@swc/core-win32-x64-msvc": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.5.tgz",
- "integrity": "sha512-ry83ki9ZX0Q+GWGnqc2J618Z+FvKE8Ajn42F8EYi8Wj0q6Jz3mj+pJzgzakk2INm2ldEZ+FaRPipn4ozsZDcBg==",
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.7.tgz",
+ "integrity": "sha512-TBf4clpDBjF/UUnkKrT0/th76/zwvudk5wwobiTFqDywMApHip5O0VpBgZ+4raY2TM8k5+ujoy7bfHb22zu17Q==",
"cpu": [
"x64"
],
"dev": true
},
"node_modules/@swc/helpers": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
- "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==",
+ "version": "0.5.15",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+ "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
"dependencies": {
- "tslib": "^2.4.0"
+ "tslib": "^2.8.0"
}
},
- "node_modules/@swc/helpers/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
"node_modules/@swc/types": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.6.tgz",
- "integrity": "sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==",
+ "version": "0.1.17",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz",
+ "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==",
"dev": true,
"dependencies": {
"@swc/counter": "^0.1.3"
}
},
"node_modules/@types/babel__generator": {
- "version": "7.6.7",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz",
- "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==",
+ "version": "7.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
"dev": true,
"dependencies": {
"@babel/types": "^7.0.0"
}
},
"node_modules/@types/babel__traverse": {
- "version": "7.20.4",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz",
- "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==",
+ "version": "7.20.6",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+ "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
"dev": true,
"dependencies": {
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/estree": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
- "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
- "dev": true
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
},
"node_modules/@types/events": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.3.tgz",
- "integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==",
- "license": "MIT"
+ "integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g=="
},
"node_modules/@types/file-saver": {
"version": "2.0.5",
"dev": true
},
"node_modules/@types/hoist-non-react-statics": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
- "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz",
+ "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/is-hotkey": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.7.tgz",
- "integrity": "sha512-yB5C7zcOM7idwYZZ1wKQ3pTfjA9BbvFqRWvKB46GFddxnJtHwi/b9y84ykQtxQPg5qhdpg4Q/kWU3EGoCTmLzQ=="
+ "version": "0.1.10",
+ "resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.10.tgz",
+ "integrity": "sha512-RvC8KMw5BCac1NvRRyaHgMMEtBaZ6wh0pyPTBu7izn4Sj/AX9Y4aXU5c7rX8PnM/knsuUpC1IeoBkANtxBypsQ=="
},
"node_modules/@types/json-schema": {
- "version": "7.0.11",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
- "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
"node_modules/@types/json5": {
"dev": true
},
"node_modules/@types/lodash": {
- "version": "4.14.191",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
- "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
+ "version": "4.17.14",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.14.tgz",
+ "integrity": "sha512-jsxagdikDiDBeIRaPYtArcT8my4tN1og7MtMRquFT3XNA6axxyHDRUemqDz/taRDdOUn0GnGHRCuff4q48sW9A=="
},
"node_modules/@types/node": {
"version": "18.11.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
- "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
- "dev": true
+ "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA=="
},
"node_modules/@types/prismjs": {
"version": "1.26.0",
"dev": true
},
"node_modules/@types/prop-types": {
- "version": "15.7.5",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
- "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
+ "version": "15.7.14",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
+ "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ=="
},
"node_modules/@types/react": {
"version": "18.2.39",
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/@types/retry": {
"version": "0.12.0",
}
},
"node_modules/@types/scheduler": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
- "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw=="
},
"node_modules/@types/semver": {
- "version": "7.3.13",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
- "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
+ "version": "7.5.8",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+ "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
"dev": true
},
"node_modules/@types/trusted-types": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/@types/ua-parser-js": {
"version": "0.7.36",
}
}
},
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/parser": {
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.1.tgz",
}
}
},
- "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/utils": {
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz",
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
- "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
- "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "dev": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^4.1.1"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/@typescript-eslint/utils/node_modules/estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "dev": true,
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/@typescript-eslint/utils/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz",
}
},
"node_modules/@vanilla-extract/babel-plugin-debug-ids": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@vanilla-extract/babel-plugin-debug-ids/-/babel-plugin-debug-ids-1.0.1.tgz",
- "integrity": "sha512-ynyKqsJiMzM1/yiIJ6QdqpWKlK4IMJJWREpPtaemZrE1xG1B4E/Nfa6YazuDWjDkCJC1tRIpEGnVs+pMIjUxyw==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/babel-plugin-debug-ids/-/babel-plugin-debug-ids-1.2.0.tgz",
+ "integrity": "sha512-z5nx2QBnOhvmlmBKeRX5sPVLz437wV30u+GJL+Hzj1rGiJYVNvgIIlzUpRNjVQ0MgAgiQIqIUbqPnmMc6HmDlQ==",
"dependencies": {
- "@babel/core": "^7.20.7"
+ "@babel/core": "^7.23.9"
}
},
"node_modules/@vanilla-extract/css": {
"outdent": "^0.8.0"
}
},
- "node_modules/@vanilla-extract/css/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vanilla-extract/css/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "node_modules/@vanilla-extract/integration": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/integration/-/integration-6.5.0.tgz",
+ "integrity": "sha512-E2YcfO8vA+vs+ua+gpvy1HRqvgWbI+MTlUpxA8FvatOvybuNcWAY0CKwQ/Gpj7rswYKtC6C7+xw33emM6/ImdQ==",
"dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
+ "@babel/core": "^7.20.7",
+ "@babel/plugin-syntax-typescript": "^7.20.0",
+ "@vanilla-extract/babel-plugin-debug-ids": "^1.0.4",
+ "@vanilla-extract/css": "^1.14.0",
+ "esbuild": "npm:esbuild@~0.17.6 || ~0.18.0 || ~0.19.0",
+ "eval": "0.1.8",
+ "find-up": "^5.0.0",
+ "javascript-stringify": "^2.0.1",
+ "lodash": "^4.17.21",
+ "mlly": "^1.4.2",
+ "outdent": "^0.8.0",
+ "vite": "^5.0.11",
+ "vite-node": "^1.2.0"
}
},
- "node_modules/@vanilla-extract/css/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "node_modules/@vanilla-extract/integration/node_modules/@vanilla-extract/css": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.17.0.tgz",
+ "integrity": "sha512-W6FqVFDD+C71ZlKsuj0MxOXSvHb1tvQ9h/+79aYfi097wLsALrnnBzd0by8C///iurrpQ3S+SH74lXd7Lr9MvA==",
"dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@vanilla-extract/css/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "node_modules/@vanilla-extract/css/node_modules/deepmerge": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
- "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
- "engines": {
- "node": ">=0.10.0"
+ "@emotion/hash": "^0.9.0",
+ "@vanilla-extract/private": "^1.0.6",
+ "css-what": "^6.1.0",
+ "cssesc": "^3.0.0",
+ "csstype": "^3.0.7",
+ "dedent": "^1.5.3",
+ "deep-object-diff": "^1.1.9",
+ "deepmerge": "^4.2.2",
+ "lru-cache": "^10.4.3",
+ "media-query-parser": "^2.0.2",
+ "modern-ahocorasick": "^1.0.0",
+ "picocolors": "^1.0.0"
}
},
- "node_modules/@vanilla-extract/css/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "node_modules/@vanilla-extract/integration/node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/@vanilla-extract/css/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dependencies": {
- "has-flag": "^4.0.0"
+ "node": ">= 6"
},
- "engines": {
- "node": ">=8"
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
}
},
- "node_modules/@vanilla-extract/integration": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/@vanilla-extract/integration/-/integration-6.0.2.tgz",
- "integrity": "sha512-LwfXlh0THeNvVXdA3iWFYvJs1mvEP1PkfQD/7S6Purry7L8iDizDV/87FgWBJ79FnTmYIvMrc7BOQsUajNj9VQ==",
- "dependencies": {
- "@babel/core": "^7.20.7",
- "@babel/plugin-syntax-typescript": "^7.20.0",
- "@vanilla-extract/babel-plugin-debug-ids": "^1.0.1",
- "@vanilla-extract/css": "^1.9.3",
- "esbuild": "^0.16.3",
- "eval": "0.1.6",
- "find-up": "^5.0.0",
- "javascript-stringify": "^2.0.1",
- "lodash": "^4.17.21",
- "outdent": "^0.8.0"
- }
+ "node_modules/@vanilla-extract/integration/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
},
"node_modules/@vanilla-extract/private": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@vanilla-extract/private/-/private-1.0.3.tgz",
- "integrity": "sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ=="
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/private/-/private-1.0.6.tgz",
+ "integrity": "sha512-ytsG/JLweEjw7DBuZ/0JCN4WAQgM9erfSTdS1NQY778hFQSZ6cfCDEZZ0sgVm4k54uNz6ImKB33AYvSR//fjxw=="
},
"node_modules/@vanilla-extract/recipes": {
"version": "0.3.0",
"optional": true
},
"node_modules/acorn": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
- "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
- "dev": true,
- "license": "MIT",
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"bin": {
"acorn": "bin/acorn"
},
}
},
"node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "license": "MIT",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
- "color-convert": "^1.9.0"
+ "color-convert": "^2.0.1"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/anymatch": {
"node": ">= 8"
}
},
+ "node_modules/anymatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
+ "deprecated": "This package is no longer supported.",
"optional": true,
"dependencies": {
"delegates": "^1.0.0",
}
},
"node_modules/array-buffer-byte-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
- "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.5",
- "is-array-buffer": "^3.0.4"
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/array.prototype.flat": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
- "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "es-shim-unscopables": "^1.0.0"
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/array.prototype.flatmap": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
- "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+ "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "es-shim-unscopables": "^1.0.0"
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/array.prototype.tosorted": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz",
- "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "es-shim-unscopables": "^1.0.0",
- "get-intrinsic": "^1.1.3"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
"node_modules/arraybuffer.prototype.slice": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
- "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
"dev": true,
"dependencies": {
"array-buffer-byte-length": "^1.0.1",
- "call-bind": "^1.0.5",
+ "call-bind": "^1.0.8",
"define-properties": "^1.2.1",
- "es-abstract": "^1.22.3",
- "es-errors": "^1.2.1",
- "get-intrinsic": "^1.2.3",
- "is-array-buffer": "^3.0.4",
- "is-shared-array-buffer": "^1.0.2"
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
},
"engines": {
"node": ">= 0.4"
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
"dev": true,
- "license": "ISC",
"engines": {
"node": ">= 4.0.0"
}
}
},
"node_modules/axe-core": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.0.tgz",
- "integrity": "sha512-L3ZNbXPTxMrl0+qTXAzn9FBRvk5XdO56K8CvcCKtlxv44Aw2w2NCclGuvCWxHPw1Riiq3ncP/sxFYj2nUqdoTw==",
+ "version": "4.10.2",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz",
+ "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==",
"dev": true,
"engines": {
"node": ">=4"
"dev": true
},
"node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.11",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz",
- "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==",
+ "version": "0.4.12",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
+ "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.22.6",
- "@babel/helper-define-polyfill-provider": "^0.6.2",
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
"semver": "^6.3.1"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.10.6",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
- "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
+ "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.10.6",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
+ "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
+ "dev": true,
+ "dependencies": {
"@babel/helper-define-polyfill-provider": "^0.6.2",
"core-js-compat": "^3.38.0"
},
}
},
"node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz",
- "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
+ "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.2"
+ "@babel/helper-define-polyfill-provider": "^0.6.3"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
"node_modules/base-x": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.0.tgz",
- "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==",
- "license": "MIT"
+ "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ=="
},
"node_modules/base64-js": {
"version": "1.5.1",
]
},
"node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"dev": true,
"engines": {
"node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/bind-event-listener": {
}
},
"node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
- "fill-range": "^7.0.1"
+ "fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
"integrity": "sha512-L7siI766UCH6+arP9yT5wpA5AFxnmGbKiGSsxEVACl1tE0pvDJeQvMmbY2UmJiuffrr0ZJ2+U6Om46wQBqh1Lw=="
},
"node_modules/browserslist": {
- "version": "4.23.3",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
- "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
+ "version": "4.24.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
"funding": [
{
"type": "opencollective",
"url": "https://github.com/sponsors/ai"
}
],
- "license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001646",
- "electron-to-chromium": "^1.5.4",
- "node-releases": "^2.0.18",
- "update-browserslist-db": "^1.1.0"
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
},
"bin": {
"browserslist": "cli.js"
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz",
"integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==",
- "license": "MIT",
"dependencies": {
"base-x": "^5.0.0"
}
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
- "node_modules/builtin-modules": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
- "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"dev": true,
- "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
"engines": {
- "node": ">=6"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/call-bind": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
- "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
+ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"dev": true,
"dependencies": {
- "es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.4",
- "set-function-length": "^1.2.1"
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
+ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001658",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001658.tgz",
- "integrity": "sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==",
+ "version": "1.0.30001692",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz",
+ "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==",
"funding": [
{
"type": "opencollective",
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ],
- "license": "CC-BY-4.0"
+ ]
},
"node_modules/canvas": {
"version": "2.11.2",
}
},
"node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "license": "MIT",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
- }
- ],
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"engines": {
"node": ">= 8.10.0"
},
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
"optionalDependencies": {
"fsevents": "~2.3.2"
}
}
},
"node_modules/clsx": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
- "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"engines": {
"node": ">=6"
}
},
"node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "license": "MIT",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
- "color-name": "1.1.3"
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
}
},
"node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "license": "MIT"
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/color-support": {
"version": "1.1.3",
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/common-tags": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
"integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=4.0.0"
}
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"devOptional": true
},
+ "node_modules/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="
+ },
"node_modules/confusing-browser-globals": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
"optional": true
},
"node_modules/content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"engines": {
"node": ">= 0.6"
}
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
},
"node_modules/core-js-compat": {
- "version": "3.38.1",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
- "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==",
+ "version": "3.40.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz",
+ "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "browserslist": "^4.23.3"
+ "browserslist": "^4.24.3"
},
"funding": {
"type": "opencollective",
}
},
"node_modules/core-js-pure": {
- "version": "3.26.1",
- "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz",
- "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==",
+ "version": "3.40.0",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.40.0.tgz",
+ "integrity": "sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A==",
"dev": true,
"hasInstallScript": true,
"funding": {
}
},
"node_modules/cross-fetch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
- "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
+ "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
"dependencies": {
- "node-fetch": "2.6.7"
+ "node-fetch": "^2.7.0"
}
},
"node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"dependencies": {
"path-key": "^3.1.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=8"
}
}
},
"node_modules/csstype": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
- "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/damerau-levenshtein": {
"version": "1.0.8",
"dev": true
},
"node_modules/data-view-buffer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
- "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bound": "^1.0.3",
"es-errors": "^1.3.0",
- "is-data-view": "^1.0.1"
+ "is-data-view": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/data-view-byte-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
- "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bound": "^1.0.3",
"es-errors": "^1.3.0",
- "is-data-view": "^1.0.1"
+ "is-data-view": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/inspect-js"
}
},
"node_modules/data-view-byte-offset": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
- "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"is-data-view": "^1.0.1"
},
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
},
"node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "license": "MIT",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dependencies": {
"ms": "^2.1.3"
},
}
}
},
+ "node_modules/decimal.js": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
+ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
+ },
"node_modules/decompress-response": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
"node": ">=8"
}
},
+ "node_modules/dedent": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
+ "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
+ "peerDependencies": {
+ "babel-plugin-macros": "^3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA=="
},
"node_modules/deepmerge": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
- "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
"optional": true
},
"node_modules/detect-libc": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
- "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"optional": true,
"engines": {
"node": ">=8"
}
},
"node_modules/domutils": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
- "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/ejs": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
"dev": true,
- "license": "Apache-2.0",
"dependencies": {
"jake": "^10.8.5"
},
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.16",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.16.tgz",
- "integrity": "sha512-2gQpi2WYobXmz2q23FrOBYTLcI1O/P4heW3eqX+ldmPVDQELRqhiebV380EhlGG12NtnX1qbK/FHpN0ba+7bLA==",
- "license": "ISC"
+ "version": "1.5.83",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.83.tgz",
+ "integrity": "sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ=="
},
"node_modules/emoji-regex": {
"version": "9.2.2",
}
},
"node_modules/es-abstract": {
- "version": "1.23.3",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
- "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
+ "version": "1.23.9",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz",
+ "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==",
"dev": true,
"dependencies": {
- "array-buffer-byte-length": "^1.0.1",
- "arraybuffer.prototype.slice": "^1.0.3",
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
"available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.7",
- "data-view-buffer": "^1.0.1",
- "data-view-byte-length": "^1.0.1",
- "data-view-byte-offset": "^1.0.0",
- "es-define-property": "^1.0.0",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
- "es-set-tostringtag": "^2.0.3",
- "es-to-primitive": "^1.2.1",
- "function.prototype.name": "^1.1.6",
- "get-intrinsic": "^1.2.4",
- "get-symbol-description": "^1.0.2",
- "globalthis": "^1.0.3",
- "gopd": "^1.0.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.0",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
"has-property-descriptors": "^1.0.2",
- "has-proto": "^1.0.3",
- "has-symbols": "^1.0.3",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
"hasown": "^2.0.2",
- "internal-slot": "^1.0.7",
- "is-array-buffer": "^3.0.4",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
"is-callable": "^1.2.7",
- "is-data-view": "^1.0.1",
- "is-negative-zero": "^2.0.3",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.3",
- "is-string": "^1.0.7",
- "is-typed-array": "^1.1.13",
- "is-weakref": "^1.0.2",
- "object-inspect": "^1.13.1",
+ "is-data-view": "^1.0.2",
+ "is-regex": "^1.2.1",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.0",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.3",
"object-keys": "^1.1.1",
- "object.assign": "^4.1.5",
- "regexp.prototype.flags": "^1.5.2",
- "safe-array-concat": "^1.1.2",
- "safe-regex-test": "^1.0.3",
- "string.prototype.trim": "^1.2.9",
- "string.prototype.trimend": "^1.0.8",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.3",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
"string.prototype.trimstart": "^1.0.8",
- "typed-array-buffer": "^1.0.2",
- "typed-array-byte-length": "^1.0.1",
- "typed-array-byte-offset": "^1.0.2",
- "typed-array-length": "^1.0.6",
- "unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.15"
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.18"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
- "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
- "dependencies": {
- "get-intrinsic": "^1.2.4"
- },
"engines": {
"node": ">= 0.4"
}
}
},
"node_modules/es-object-atoms": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
- "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0"
}
},
"node_modules/es-set-tostringtag": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
- "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.2.4",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
- "hasown": "^2.0.1"
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
"dev": true,
"dependencies": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/esbuild": {
- "version": "0.16.9",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.9.tgz",
- "integrity": "sha512-gkH83yHyijMSZcZFs1IWew342eMdFuWXmQo3zkDPTre25LIPBJsXryg02M3u8OpTwCJdBkdaQwqKkDLnAsAeLQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
+ "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/android-arm": "0.16.9",
- "@esbuild/android-arm64": "0.16.9",
- "@esbuild/android-x64": "0.16.9",
- "@esbuild/darwin-arm64": "0.16.9",
- "@esbuild/darwin-x64": "0.16.9",
- "@esbuild/freebsd-arm64": "0.16.9",
- "@esbuild/freebsd-x64": "0.16.9",
- "@esbuild/linux-arm": "0.16.9",
- "@esbuild/linux-arm64": "0.16.9",
- "@esbuild/linux-ia32": "0.16.9",
- "@esbuild/linux-loong64": "0.16.9",
- "@esbuild/linux-mips64el": "0.16.9",
- "@esbuild/linux-ppc64": "0.16.9",
- "@esbuild/linux-riscv64": "0.16.9",
- "@esbuild/linux-s390x": "0.16.9",
- "@esbuild/linux-x64": "0.16.9",
- "@esbuild/netbsd-x64": "0.16.9",
- "@esbuild/openbsd-x64": "0.16.9",
- "@esbuild/sunos-x64": "0.16.9",
- "@esbuild/win32-arm64": "0.16.9",
- "@esbuild/win32-ia32": "0.16.9",
- "@esbuild/win32-x64": "0.16.9"
+ "@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"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "license": "MIT",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
- "node": ">=0.8.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint": {
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz",
"integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.3.3",
"eslint-plugin-import": "^2.25.2"
}
},
+ "node_modules/eslint-config-airbnb-base/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/eslint-config-prettier": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
}
},
"node_modules/eslint-module-utils": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz",
- "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==",
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"dev": true,
"dependencies": {
"debug": "^3.2.7"
"node": ">=0.10.0"
}
},
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/eslint-plugin-jsx-a11y": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz",
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
}
},
+ "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/eslint-plugin-react": {
"version": "7.31.11",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz",
}
},
"node_modules/eslint-plugin-react/node_modules/resolve": {
- "version": "2.0.0-next.4",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz",
- "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==",
+ "version": "2.0.0-next.5",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
+ "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==",
"dev": true,
"dependencies": {
- "is-core-module": "^2.9.0",
+ "is-core-module": "^2.13.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/eslint-plugin-react/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
+ "estraverse": "^4.1.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-scope/node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
}
},
"node_modules/eslint-utils": {
}
},
"node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "node_modules/eslint/node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"dev": true,
"dependencies": {
- "color-convert": "^2.0.1"
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
},
"engines": {
- "node": ">=8"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/eslint/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/eslint/node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/globals": {
- "version": "13.19.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
- "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "node_modules/eslint/node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/eslint/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
+ "node": ">=10"
},
- "engines": {
- "node": ">=8"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/espree": {
- "version": "9.4.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
- "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dev": true,
"dependencies": {
- "acorn": "^8.8.0",
+ "acorn": "^8.9.0",
"acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.3.0"
+ "eslint-visitor-keys": "^3.4.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
"dependencies": {
"estraverse": "^5.1.0"
}
},
"node_modules/estree-walker": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
- "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
- "dev": true,
- "license": "MIT"
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true
},
"node_modules/esutils": {
"version": "2.0.3",
}
},
"node_modules/eval": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.6.tgz",
- "integrity": "sha512-o0XUw+5OGkXw4pJZzQoXUk+H87DHuC+7ZE//oSrRGtatTmr12oTnLfg6QOq9DyTt0c/p4TwzgmkKrBzWTSizyQ==",
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz",
+ "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==",
"dependencies": {
+ "@types/node": "*",
"require-like": ">= 0.1.1"
},
"engines": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
- "license": "MIT",
"engines": {
"node": ">=0.8.x"
}
"dev": true
},
"node_modules/fast-glob": {
- "version": "3.2.12",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
- "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.2",
"merge2": "^1.3.0",
- "micromatch": "^4.0.4"
+ "micromatch": "^4.0.8"
},
"engines": {
"node": ">=8.6.0"
"dev": true
},
"node_modules/fast-uri": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz",
- "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz",
+ "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==",
"dev": true,
- "license": "MIT"
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ]
},
"node_modules/fastq": {
- "version": "1.14.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz",
- "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==",
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz",
+ "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==",
"dev": true,
"dependencies": {
"reusify": "^1.0.4"
}
},
"node_modules/fbjs": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.4.tgz",
- "integrity": "sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
+ "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
"dependencies": {
"cross-fetch": "^3.1.5",
"fbjs-css-vars": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
- "ua-parser-js": "^0.7.30"
+ "ua-parser-js": "^1.0.35"
}
},
"node_modules/fbjs-css-vars": {
"resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
"integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
},
- "node_modules/fbjs/node_modules/ua-parser-js": {
- "version": "0.7.35",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz",
- "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/ua-parser-js"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/faisalman"
- }
- ],
- "engines": {
- "node": "*"
- }
- },
"node_modules/fdir": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz",
- "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==",
+ "version": "6.4.3",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
+ "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
"dev": true,
- "license": "MIT",
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
"dev": true,
- "license": "Apache-2.0",
"dependencies": {
"minimatch": "^5.0.1"
}
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
- "license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
}
},
"node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
}
},
"node_modules/flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
"dev": true,
"dependencies": {
- "flatted": "^3.1.0",
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
"rimraf": "^3.0.2"
},
"engines": {
}
},
"node_modules/flatted": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
- "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
+ "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
"dev": true
},
"node_modules/flux": {
}
},
"node_modules/focus-trap": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.2.0.tgz",
- "integrity": "sha512-v4wY6HDDYvzkBy4735kW5BUEuw6Yz9ABqMYLuTNbzAFPcBOGiGHwwcNVMvUz4G0kgSYh13wa/7TG3XwTeT4O/A==",
+ "version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.4.tgz",
+ "integrity": "sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==",
"dependencies": {
- "tabbable": "^6.0.1"
+ "tabbable": "^6.2.0"
}
},
"node_modules/focus-trap-react": {
}
},
"node_modules/folds": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/folds/-/folds-2.0.0.tgz",
- "integrity": "sha512-lKv31vij4GEpEzGKWk5c3ar78fMZ9Di5n1XFR14Z2wnnpqhiiM5JTIzr127Gk5dOfy4mJkjnv/ZfMZvM2k+OQg==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/folds/-/folds-2.1.0.tgz",
+ "integrity": "sha512-KwAG8bH3jsyZ9FKPMg+6ABV2YOcpp4nL0cCelsalnaPeRThkc5fgG1Xj5mhmdffYKjEXpEbERi5qmGbepgJryg==",
"peerDependencies": {
"@vanilla-extract/css": "^1.9.2",
"@vanilla-extract/recipes": "^0.3.0",
"react": ">=16.8.0"
}
},
- "node_modules/formik/node_modules/tslib": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
- "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
+ "node_modules/formik/node_modules/deepmerge": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
+ "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
"node_modules/fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+ "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14.14"
}
},
"node_modules/fs-minipass": {
"node": ">=8"
}
},
+ "node_modules/fs-minipass/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "optional": true
+ },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
}
},
"node_modules/function.prototype.name": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
- "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "functions-have-names": "^1.2.3"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
},
"engines": {
"node": ">= 0.4"
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
+ "deprecated": "This package is no longer supported.",
"optional": true,
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
- "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
+ "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
"dev": true,
"dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "hasown": "^2.0.0"
+ "get-proto": "^1.0.0",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
"integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
+ "dev": true
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
- "license": "ISC"
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
},
"node_modules/get-symbol-description": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
- "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.5",
+ "call-bound": "^1.0.3",
"es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.4"
+ "get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
"devOptional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "license": "MIT",
"engines": {
"node": ">=4"
}
}
},
"node_modules/gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
- "dependencies": {
- "get-intrinsic": "^1.1.3"
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": {
- "version": "4.2.10",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
- "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true
},
"node_modules/grapheme-splitter": {
"dev": true
},
"node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
+ "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
"dev": true,
- "dependencies": {
- "function-bind": "^1.1.1"
- },
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/has-bigints": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
- "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "license": "MIT",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/has-property-descriptors": {
}
},
"node_modules/has-proto": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
- "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
"dev": true,
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
"engines": {
"node": ">= 0.4"
},
}
},
"node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"engines": {
"node": ">= 0.4"
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
- "license": "MIT",
"dependencies": {
"void-elements": "3.1.0"
}
}
},
"node_modules/htmlparser2": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
- "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
+ "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
],
"dependencies": {
"domelementtype": "^2.3.0",
- "domhandler": "^5.0.2",
+ "domhandler": "^5.0.3",
"domutils": "^3.0.1",
- "entities": "^4.3.0"
+ "entities": "^4.4.0"
}
},
"node_modules/https-proxy-agent": {
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
}
],
- "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.23.2"
}
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.0.tgz",
"integrity": "sha512-zhXdJXTTCoG39QsrOCiOabnWj2jecouOqbchu3EfhtSHxIB5Uugnm9JaizenOy39h7ne3+fLikIjeW88+rgszw==",
- "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.23.2"
}
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.2.tgz",
"integrity": "sha512-+K8HbDfrvc1/2X8jpb7RLhI9ZxBDpx3xogYkQwGKlWAUXLSEGXzgdt3EcUjLlBCdMwdQY+K+EUF6oh8oB6rwHw==",
- "license": "MIT",
"dependencies": {
"cross-fetch": "4.0.0"
}
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
"integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
- "license": "MIT",
"dependencies": {
"node-fetch": "^2.6.12"
}
},
- "node_modules/i18next-http-backend/node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
"node_modules/idb": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
"integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
- "dev": true,
- "license": "ISC"
+ "dev": true
},
"node_modules/ieee754": {
"version": "1.2.1",
]
},
"node_modules/ignore": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz",
- "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/immutable": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
- "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz",
+ "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==",
"dev": true
},
"node_modules/import-fresh": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"devOptional": true,
"dependencies": {
"once": "^1.3.0",
"integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q=="
},
"node_modules/internal-slot": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
- "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
- "hasown": "^2.0.0",
- "side-channel": "^1.0.4"
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/intl-messageformat": {
- "version": "10.5.4",
- "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.4.tgz",
- "integrity": "sha512-z+hrFdiJ/heRYlzegrdFYqU1m/KOMOVMqNilIArj+PbsuU8TNE7v4TWdQgSoxlxbT4AcZH3Op3/Fu15QTp+W1w==",
+ "version": "10.7.12",
+ "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.12.tgz",
+ "integrity": "sha512-4HBsPDJ61jZwNikauvm0mcLvs1AfCBbihiqOX2AGs1MX7SA1H0SNKJRSWxpZpToGoNzvoYLsJJ2pURkbEDg+Dw==",
"dependencies": {
- "@formatjs/ecma402-abstract": "1.17.2",
- "@formatjs/fast-memoize": "2.2.0",
- "@formatjs/icu-messageformat-parser": "2.7.0",
- "tslib": "^2.4.0"
+ "@formatjs/ecma402-abstract": "2.3.2",
+ "@formatjs/fast-memoize": "2.2.6",
+ "@formatjs/icu-messageformat-parser": "2.10.0",
+ "tslib": "2"
}
},
- "node_modules/intl-messageformat/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
"node_modules/is-array-buffer": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
- "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz",
+ "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.1"
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-bigint": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
- "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
"dev": true,
"dependencies": {
- "has-bigints": "^1.0.1"
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-boolean-object": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
- "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
+ "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-builtin-module": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
- "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "builtin-modules": "^3.3.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
}
},
"node_modules/is-core-module": {
- "version": "2.13.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
- "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"dev": true,
"dependencies": {
- "hasown": "^2.0.0"
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-data-view": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
- "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
"dev": true,
"dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
"is-typed-array": "^1.1.13"
},
"engines": {
}
},
"node_modules/is-date-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
- "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
"dev": true,
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
"node": ">=0.10.0"
}
},
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"node": ">=8"
}
},
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "node_modules/is-generator-function": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"dependencies": {
"is-extglob": "^2.1.1"
"resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz",
"integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw=="
},
- "node_modules/is-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
- "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/is-negative-zero": {
+ "node_modules/is-map": {
"version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
- "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
"dev": true,
"engines": {
"node": ">= 0.4"
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
+ "dev": true
+ },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
}
},
"node_modules/is-number-object": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
- "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
"dev": true,
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
}
},
"node_modules/is-regex": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
- "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
"integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-shared-array-buffer": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
- "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7"
+ "call-bound": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=8"
},
}
},
"node_modules/is-string": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
- "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
"dev": true,
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-symbol": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
- "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
"dev": true,
"dependencies": {
- "has-symbols": "^1.0.2"
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-typed-array": {
- "version": "1.1.13",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
- "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
"dev": true,
"dependencies": {
- "which-typed-array": "^1.1.14"
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
"engines": {
"node": ">= 0.4"
},
}
},
"node_modules/is-weakref": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
- "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
+ "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2"
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
"resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
"integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
"dev": true,
- "license": "Apache-2.0",
"dependencies": {
"async": "^3.2.3",
"chalk": "^4.0.2",
"node": ">=10"
}
},
- "node_modules/jake/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jake/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jake/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jake/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jake/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jake/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/javascript-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz",
}
},
"node_modules/js-sdsl": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz",
- "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==",
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz",
+ "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==",
"dev": true,
"funding": {
"type": "opencollective",
}
},
"node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
- "license": "MIT",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"bin": {
"jsesc": "bin/jsesc"
},
"engines": {
- "node": ">=4"
+ "node": ">=6"
}
},
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
"node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
- "dev": true,
- "license": "(AFL-2.1 OR BSD-3-Clause)"
+ "dev": true
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"universalify": "^2.0.0"
},
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz",
"integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/jsx-ast-utils": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz",
- "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
"dev": true,
"dependencies": {
- "array-includes": "^3.1.5",
- "object.assign": "^4.1.3"
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
},
"engines": {
"node": ">=4.0"
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
"integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
- "license": "MIT",
"engines": {
"node": ">=18"
}
},
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
"node_modules/language-subtag-registry": {
- "version": "0.3.22",
- "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz",
- "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==",
+ "version": "0.3.23",
+ "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
+ "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==",
"dev": true
},
"node_modules/language-tags": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.6.tgz",
- "integrity": "sha512-HNkaCgM8wZgE/BZACeotAAgpL9FUjEnhgF0FVQMIgH//zqTPreLYMb3rWYkYAqPoF75Jwuycp1da7uz66cfFQg==",
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz",
+ "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==",
"dev": true,
"dependencies": {
"language-subtag-registry": "^0.3.20"
+ },
+ "engines": {
+ "node": ">=0.10"
}
},
- "node_modules/legacy-swc-helpers": {
- "name": "@swc/helpers",
- "version": "0.4.14",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
- "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==",
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/legacy-swc-helpers/node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- },
"node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=6"
}
}
},
"node_modules/lilconfig": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz",
- "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
"engines": {
"node": ">=10"
}
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
"integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/loglevel": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz",
- "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==",
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz",
+ "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==",
"engines": {
"node": ">= 0.6.0"
},
}
},
"node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "devOptional": true,
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
+ "yallist": "^3.0.2"
}
},
"node_modules/magic-string": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/matrix-events-sdk": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz",
"integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA=="
},
"node_modules/matrix-js-sdk": {
- "version": "34.11.1",
- "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-34.11.1.tgz",
- "integrity": "sha512-rDbIUIqEsN/pbHb6haBQmjxxgeb9G3Df2IhPPOotUbX6R1KseA8yJ6TAY0YySM2zVaBV3yZ6dnKWexF/uWvZfA==",
- "license": "Apache-2.0",
+ "version": "35.0.0",
+ "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-35.0.0.tgz",
+ "integrity": "sha512-X8hIsd/8x1SC9vRr8DiNKQxmdrfRujtvEWPz8mY4FxVDJG8HEGDHvqUmaSy2jrtnOUn4oHzGQVLFO3DnhsSf8w==",
"dependencies": {
"@babel/runtime": "^7.12.5",
- "@matrix-org/matrix-sdk-crypto-wasm": "^9.0.0",
+ "@matrix-org/matrix-sdk-crypto-wasm": "^11.0.0",
"@matrix-org/olm": "3.2.15",
"another-json": "^0.2.0",
"bs58": "^6.0.0",
"jwt-decode": "^4.0.0",
"loglevel": "^1.7.1",
"matrix-events-sdk": "0.0.1",
- "matrix-widget-api": "^1.8.2",
+ "matrix-widget-api": "^1.10.0",
"oidc-client-ts": "^3.0.1",
"p-retry": "4",
"sdp-transform": "^2.14.1",
"unhomoglyph": "^1.0.6",
- "uuid": "10"
+ "uuid": "11"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/matrix-js-sdk/node_modules/uuid": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
- "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.5.tgz",
+ "integrity": "sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
- "license": "MIT",
"bin": {
- "uuid": "dist/bin/uuid"
+ "uuid": "dist/esm/bin/uuid"
}
},
"node_modules/matrix-widget-api": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.9.0.tgz",
- "integrity": "sha512-au8mqralNDqrEvaVAkU37bXOb8I9SCe+ACdPk11QWw58FKstVq31q2wRz+qWA6J+42KJ6s1DggWbG/S3fEs3jw==",
- "license": "Apache-2.0",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.12.0.tgz",
+ "integrity": "sha512-6JRd9fJGGvuBRhcTg9wX+Skn/Q1wox3jdp5yYQKJ6pPw4urW9bkTR90APBKVDB1vorJKT44jml+lCzkDMRBjww==",
"dependencies": {
"@types/events": "^3.0.0",
"events": "^3.2.0"
}
},
"node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"dependencies": {
- "braces": "^3.0.2",
+ "braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
+ "node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/millify": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/millify/-/millify-6.1.0.tgz",
"node": ">=8"
}
},
+ "node_modules/minizlib/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "optional": true
+ },
"node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"node": ">=10"
}
},
+ "node_modules/mlly": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
+ "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "pathe": "^2.0.1",
+ "pkg-types": "^1.3.0",
+ "ufo": "^1.5.4"
+ }
+ },
+ "node_modules/modern-ahocorasick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/modern-ahocorasick/-/modern-ahocorasick-1.1.0.tgz",
+ "integrity": "sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ=="
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/nan": {
- "version": "2.17.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
- "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
+ "version": "2.22.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz",
+ "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==",
"optional": true
},
"node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"funding": [
{
"type": "github",
"dev": true
},
"node_modules/node-fetch": {
- "version": "2.6.7",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
- "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
}
},
"node_modules/node-releases": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
- "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
- "license": "MIT"
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="
},
"node_modules/nopt": {
"version": "5.0.0",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
+ "deprecated": "This package is no longer supported.",
"optional": true,
"dependencies": {
"are-we-there-yet": "^2.0.0",
}
},
"node_modules/object-inspect": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
- "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
+ "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
}
},
"node_modules/object.assign": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
- "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.5",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
"define-properties": "^1.2.1",
- "has-symbols": "^1.0.3",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
"object-keys": "^1.1.1"
},
"engines": {
}
},
"node_modules/object.entries": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz",
- "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==",
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz",
+ "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.hasown": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz",
- "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz",
+ "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==",
"dev": true,
"dependencies": {
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object.values": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
- "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
},
}
},
"node_modules/oidc-client-ts": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-3.0.1.tgz",
- "integrity": "sha512-xX8unZNtmtw3sOz4FPSqDhkLFnxCDsdo2qhFEH2opgWnF/iXMFoYdBQzkwCxAZVgt3FT3DnuBY3k80EZHT0RYg==",
- "license": "Apache-2.0",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-3.1.0.tgz",
+ "integrity": "sha512-IDopEXjiwjkmJLYZo6BTlvwOtnlSniWZkKZoXforC/oLZHC9wkIxd25Kwtmo5yKFMMVcsp3JY6bhcNJqdYk8+g==",
"dependencies": {
"jwt-decode": "^4.0.0"
},
}
},
"node_modules/optionator": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
- "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"dependencies": {
"deep-is": "^0.1.3",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
"type-check": "^0.4.0",
- "word-wrap": "^1.2.3"
+ "word-wrap": "^1.2.5"
},
"engines": {
"node": ">= 0.8.0"
"resolved": "https://registry.npmjs.org/outdent/-/outdent-0.8.0.tgz",
"integrity": "sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A=="
},
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
"dependencies": {
- "yocto-queue": "^0.1.0"
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-locate": {
}
},
"node_modules/path2d": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.0.tgz",
- "integrity": "sha512-KdPAykQX6kmLSOO6Jpu2KNcCED7CKjmaBNGGNuctOsG0hgYO1OdYQaan6cYXJiG0WmXOwZZPILPBimu5QAIw3A==",
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.2.tgz",
+ "integrity": "sha512-+vnG6S4dYcYxZd+CZxzXCNKdELYZSKfohrk98yajCo1PtRoDgCTrrwOvK1GT0UoAdVszagDVllQc0U1vaX4NUQ==",
"optional": true,
"engines": {
"node": ">=6"
}
},
+ "node_modules/pathe": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz",
+ "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w=="
+ },
"node_modules/pdfjs-dist": {
"version": "4.2.67",
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.2.67.tgz",
}
},
"node_modules/picocolors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
- "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
- "license": "ISC"
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"engines": {
- "node": ">=8.6"
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
}
},
"node_modules/postcss": {
- "version": "8.4.32",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
- "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
+ "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
"funding": [
{
"type": "opencollective",
}
],
"dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
"integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==",
"dev": true,
- "license": "MIT",
"engines": {
"node": "^14.13.1 || >=16.0.0"
},
}
},
"node_modules/punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"engines": {
"node": ">=6"
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"safe-buffer": "^5.1.0"
}
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.0.tgz",
"integrity": "sha512-2O3IgF4zivg57Q6p6i+ChDgJ371IDcEWbuWC6gvoh5NbkDMs0Q+O7RPr4v61+Se32E0V+LmtwePAeqWZW0bi6g==",
- "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.24.8",
"html-parse-stringify": "^3.0.1"
}
},
"node_modules/react-refresh": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
- "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
+ "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
"node": ">=8.10.0"
}
},
+ "node_modules/readdirp/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/regenerate-unicode-properties": {
- "version": "10.1.1",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz",
- "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==",
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+ "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"regenerate": "^1.4.2"
},
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "license": "MIT"
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/regenerator-transform": {
"version": "0.15.2",
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
"integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.8.4"
}
},
"node_modules/regexp.prototype.flags": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
- "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-errors": "^1.3.0",
- "set-function-name": "^2.0.1"
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/regexpu-core": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
- "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+ "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/regjsgen": "^0.8.0",
"regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.1.0",
- "regjsparser": "^0.9.1",
+ "regenerate-unicode-properties": "^10.2.0",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.12.0",
"unicode-match-property-ecmascript": "^2.0.0",
"unicode-match-property-value-ecmascript": "^2.1.0"
},
"node": ">=4"
}
},
+ "node_modules/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+ "dev": true
+ },
"node_modules/regjsparser": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
- "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
"dev": true,
- "license": "BSD-2-Clause",
"dependencies": {
- "jsesc": "~0.5.0"
+ "jsesc": "~3.0.2"
},
"bin": {
"regjsparser": "bin/parser"
}
},
"node_modules/regjsparser/node_modules/jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"dev": true,
"bin": {
"jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/require-directory": {
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
}
},
"node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"dev": true,
"dependencies": {
- "is-core-module": "^2.13.0",
+ "is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
"devOptional": true,
"dependencies": {
"glob": "^7.1.3"
}
},
"node_modules/rollup": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.8.0.tgz",
- "integrity": "sha512-NpsklK2fach5CdI+PScmlE5R4Ao/FSWtF7LkoIrHDxPACY/xshNasPsbpG0VVHxUTbf74tJbVT4PrP8JsJ6ZDA==",
- "dev": true,
+ "version": "4.30.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz",
+ "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==",
+ "dependencies": {
+ "@types/estree": "1.0.6"
+ },
"bin": {
"rollup": "dist/bin/rollup"
},
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.8.0",
- "@rollup/rollup-android-arm64": "4.8.0",
- "@rollup/rollup-darwin-arm64": "4.8.0",
- "@rollup/rollup-darwin-x64": "4.8.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.8.0",
- "@rollup/rollup-linux-arm64-gnu": "4.8.0",
- "@rollup/rollup-linux-arm64-musl": "4.8.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.8.0",
- "@rollup/rollup-linux-x64-gnu": "4.8.0",
- "@rollup/rollup-linux-x64-musl": "4.8.0",
- "@rollup/rollup-win32-arm64-msvc": "4.8.0",
- "@rollup/rollup-win32-ia32-msvc": "4.8.0",
- "@rollup/rollup-win32-x64-msvc": "4.8.0",
+ "@rollup/rollup-android-arm-eabi": "4.30.1",
+ "@rollup/rollup-android-arm64": "4.30.1",
+ "@rollup/rollup-darwin-arm64": "4.30.1",
+ "@rollup/rollup-darwin-x64": "4.30.1",
+ "@rollup/rollup-freebsd-arm64": "4.30.1",
+ "@rollup/rollup-freebsd-x64": "4.30.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.30.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.30.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.30.1",
+ "@rollup/rollup-linux-arm64-musl": "4.30.1",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.30.1",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.30.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.30.1",
+ "@rollup/rollup-linux-x64-gnu": "4.30.1",
+ "@rollup/rollup-linux-x64-musl": "4.30.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.30.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.30.1",
+ "@rollup/rollup-win32-x64-msvc": "4.30.1",
"fsevents": "~2.3.2"
}
},
}
},
"node_modules/safe-array-concat": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
- "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7",
- "get-intrinsic": "^1.2.4",
- "has-symbols": "^1.0.3",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
"isarray": "^2.0.5"
},
"engines": {
}
]
},
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/safe-regex-test": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
- "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bound": "^1.0.2",
"es-errors": "^1.3.0",
- "is-regex": "^1.1.4"
+ "is-regex": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
"postcss": "^8.3.11"
}
},
- "node_modules/sanitize-html/node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/sanitize-html/node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/sass": {
"version": "1.56.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.56.2.tgz",
}
},
"node_modules/scheduler": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
- "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"dependencies": {
"loose-envify": "^1.1.0"
}
}
},
"node_modules/sdp-transform": {
- "version": "2.14.1",
- "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz",
- "integrity": "sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw==",
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.15.0.tgz",
+ "integrity": "sha512-KrOH82c/W+GYQ0LHqtr3caRpM3ITglq3ljGUIb8LTki7ByacJZ9z+piSGiwZDsRyhQbYBOBJgr2k6X4BZXi3Kw==",
"bin": {
"sdp-verify": "checker.js"
}
},
"node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "devOptional": true,
"bin": {
"semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/serialize-javascript": {
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
- "license": "BSD-3-Clause",
"dependencies": {
"randombytes": "^2.1.0"
}
"node": ">= 0.4"
}
},
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
}
},
"node_modules/side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
"integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/source-map": {
"version": "0.8.0-beta.0",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
"integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
"dev": true,
- "license": "BSD-3-Clause",
"dependencies": {
"whatwg-url": "^7.0.0"
},
}
},
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"engines": {
"node": ">=0.10.0"
}
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
- "license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
- "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
"integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"punycode": "^2.1.0"
}
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
- "dev": true,
- "license": "BSD-2-Clause"
+ "dev": true
},
"node_modules/source-map/node_modules/whatwg-url": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
"integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"lodash.sortby": "^4.7.0",
"tr46": "^1.0.1",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"deprecated": "Please use @jridgewell/sourcemap-codec instead",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/string_decoder": {
"version": "1.3.0",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/string.prototype.matchall": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz",
- "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==",
+ "version": "4.0.12",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
+ "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "get-intrinsic": "^1.1.3",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.3",
- "regexp.prototype.flags": "^1.4.3",
- "side-channel": "^1.0.4"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.6",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "regexp.prototype.flags": "^1.5.3",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trim": {
- "version": "1.2.9",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
- "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
"define-properties": "^1.2.1",
- "es-abstract": "^1.23.0",
- "es-object-atoms": "^1.0.0"
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/string.prototype.trimend": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
- "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
"resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
"integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
"dev": true,
- "license": "BSD-2-Clause",
"dependencies": {
"get-own-enumerable-property-symbols": "^3.0.0",
"is-obj": "^1.0.1",
"resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
"integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=10"
}
}
},
"node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "license": "MIT",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
- "has-flag": "^3.0.0"
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/supports-preserve-symlinks-flag": {
}
},
"node_modules/tabbable": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.0.1.tgz",
- "integrity": "sha512-SYJSIgeyXW7EuX1ytdneO5e8jip42oHWg9xl/o3oTYhmXusZVgiA+VlPvjIN+kHii9v90AmzTZEBcsEvuAY+TA=="
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
},
"node_modules/tar": {
- "version": "6.1.15",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz",
- "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"optional": true,
"dependencies": {
"chownr": "^2.0.0",
"node": ">=10"
}
},
+ "node_modules/tar/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "optional": true
+ },
"node_modules/temp-dir": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
"integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=8"
}
"resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz",
"integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==",
"dev": true,
- "license": "MIT",
"dependencies": {
"is-stream": "^2.0.0",
"temp-dir": "^2.0.0",
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/tempy/node_modules/type-fest": {
- "version": "0.16.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
- "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
- "dev": true,
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/terser": {
- "version": "5.31.6",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz",
- "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==",
+ "version": "5.37.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz",
+ "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
"dev": true,
- "license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
"node_modules/tinyglobby": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.5.tgz",
- "integrity": "sha512-Dlqgt6h0QkoHttG53/WGADNh9QhcjCAIZMTERAVhdpmIBEejSuLI9ZmGKWzB7tweBjlk30+s/ofi4SLmBeTYhw==",
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz",
+ "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==",
"dev": true,
- "license": "ISC",
"dependencies": {
- "fdir": "^6.2.0",
+ "fdir": "^6.4.2",
"picomatch": "^4.0.2"
},
"engines": {
"node": ">=12.0.0"
}
},
- "node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
- "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"node_modules/tippy.js": {
"version": "6.3.7",
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
"@popperjs/core": "^2.9.0"
}
},
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
}
},
"node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
},
"node_modules/tsutils": {
"version": "3.21.0",
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
}
},
+ "node_modules/tsutils/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
}
},
"node_modules/type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
+ "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/typed-array-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
- "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bound": "^1.0.3",
"es-errors": "^1.3.0",
- "is-typed-array": "^1.1.13"
+ "is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
- "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
"for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-proto": "^1.0.3",
- "is-typed-array": "^1.1.13"
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-offset": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
- "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
"dev": true,
"dependencies": {
"available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
"for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-proto": "^1.0.3",
- "is-typed-array": "^1.1.13"
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-length": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
- "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
- "has-proto": "^1.0.3",
"is-typed-array": "^1.1.13",
- "possible-typed-array-names": "^1.0.0"
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
},
"engines": {
"node": ">= 0.4"
"node": "*"
}
},
+ "node_modules/ufo": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
+ "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ=="
+ },
"node_modules/unbox-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
- "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bound": "^1.0.3",
"has-bigints": "^1.0.2",
- "has-symbols": "^1.0.3",
- "which-boxed-primitive": "^1.0.2"
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
"integrity": "sha512-7uvcWI3hWshSADBu4JpnyYbTVc7YlhF5GDW/oPD5AxIxl34k4wXR3WDkPnzLxkN32LiTCTKMQLtKVZiwki3zGg=="
},
"node_modules/unicode-canonical-property-names-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
- "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=4"
}
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
"integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
"unicode-canonical-property-names-ecmascript": "^2.0.0",
"unicode-property-aliases-ecmascript": "^2.0.0"
}
},
"node_modules/unicode-match-property-value-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
- "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=4"
}
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
"integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=4"
}
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
"integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"crypto-random-string": "^2.0.0"
},
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">= 10.0.0"
}
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
"integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=4",
"yarn": "*"
}
},
"node_modules/update-browserslist-db": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
- "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
+ "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
"funding": [
{
"type": "opencollective",
"url": "https://github.com/sponsors/ai"
}
],
- "license": "MIT",
"dependencies": {
- "escalade": "^3.1.2",
- "picocolors": "^1.0.1"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
"optional": true
},
"node_modules/uuid": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
- "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
+ "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
"dev": true,
"funding": [
"https://github.com/sponsors/broofa",
"version": "5.0.13",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.13.tgz",
"integrity": "sha512-/9ovhv2M2dGTuA+dY93B9trfyWMDRQw2jdVBhHNP6wr0oF34wG2i/N55801iZIpgUpnHDm4F/FabGQLyc+eOgg==",
- "dev": true,
"dependencies": {
"esbuild": "^0.19.3",
"postcss": "^8.4.32",
}
}
},
+ "node_modules/vite-node": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz",
+ "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.3.4",
+ "pathe": "^1.1.1",
+ "picocolors": "^1.0.0",
+ "vite": "^5.0.0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vite-node/node_modules/pathe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="
+ },
"node_modules/vite-plugin-pwa": {
"version": "0.20.5",
"resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.20.5.tgz",
"vite": "^5.0.0"
}
},
- "node_modules/vite-plugin-static-copy/node_modules/fs-extra": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz",
- "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=14.14"
- }
- },
"node_modules/vite-plugin-top-level-await": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.4.1.tgz",
- "integrity": "sha512-hogbZ6yT7+AqBaV6lK9JRNvJDn4/IJvHLu6ET06arNfo0t2IsyCaon7el9Xa8OumH+ESuq//SDf8xscZFE0rWw==",
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.4.4.tgz",
+ "integrity": "sha512-QyxQbvcMkgt+kDb12m2P8Ed35Sp6nXP+l8ptGrnHV9zgYDUpraO0CPdlqLSeBqvY2DToR52nutDG7mIHuysdiw==",
"dev": true,
"dependencies": {
"@rollup/plugin-virtual": "^3.0.2",
- "@swc/core": "^1.3.100",
- "uuid": "^9.0.1"
+ "@swc/core": "^1.7.0",
+ "uuid": "^10.0.0"
},
"peerDependencies": {
"vite": ">=2.8"
}
},
- "node_modules/vite/node_modules/@esbuild/android-arm": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
- "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
"engines": {
- "node": ">=12"
+ "node": ">=0.10.0"
}
},
- "node_modules/vite/node_modules/@esbuild/android-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
- "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
+ "node_modules/warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
}
},
- "node_modules/vite/node_modules/@esbuild/android-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
- "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
- "cpu": [
- "x64"
- ],
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
- "optional": true,
- "os": [
- "android"
- ],
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
"engines": {
- "node": ">=12"
+ "node": ">= 8"
}
},
- "node_modules/vite/node_modules/@esbuild/darwin-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
- "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
"dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
"engines": {
- "node": ">=12"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/vite/node_modules/@esbuild/darwin-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
- "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
- "cpu": [
- "x64"
- ],
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
"dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
"engines": {
- "node": ">=12"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/vite/node_modules/@esbuild/freebsd-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
- "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
"engines": {
- "node": ">=12"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/vite/node_modules/@esbuild/freebsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
- "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
- "cpu": [
- "x64"
- ],
+ "node_modules/which-typed-array": {
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz",
+ "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==",
"dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
"engines": {
- "node": ">=12"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/vite/node_modules/@esbuild/linux-arm": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
- "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
- "cpu": [
- "arm"
- ],
- "dev": true,
+ "node_modules/wide-align": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
+ "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
+ "dependencies": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
}
},
- "node_modules/vite/node_modules/@esbuild/linux-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
- "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
"engines": {
- "node": ">=12"
+ "node": ">=0.10.0"
}
},
- "node_modules/vite/node_modules/@esbuild/linux-ia32": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
- "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
- "cpu": [
- "ia32"
- ],
+ "node_modules/workbox-background-sync": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz",
+ "integrity": "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==",
"dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-loong64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
- "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-mips64el": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
- "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-ppc64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
- "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-riscv64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
- "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-s390x": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
- "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
- "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/netbsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
- "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/openbsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
- "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/sunos-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
- "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
- "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-ia32": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
- "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
- "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/esbuild": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
- "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
- "dev": true,
- "hasInstallScript": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=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"
- }
- },
- "node_modules/void-elements": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
- "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/warning": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
- "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
- "dependencies": {
- "loose-envify": "^1.0.0"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/which-boxed-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
- "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
- "dev": true,
- "dependencies": {
- "is-bigint": "^1.0.1",
- "is-boolean-object": "^1.1.0",
- "is-number-object": "^1.0.4",
- "is-string": "^1.0.5",
- "is-symbol": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-typed-array": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
- "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
- "dev": true,
- "dependencies": {
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.7",
- "for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/wide-align": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
- "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
- "optional": true,
- "dependencies": {
- "string-width": "^1.0.2 || 2 || 3 || 4"
- }
- },
- "node_modules/word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/workbox-background-sync": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.1.0.tgz",
- "integrity": "sha512-rMbgrzueVWDFcEq1610YyDW71z0oAXLfdRHRQcKw4SGihkfOK0JUEvqWHFwA6rJ+6TClnMIn7KQI5PNN1XQXwQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "idb": "^7.0.1",
- "workbox-core": "7.1.0"
+ "dependencies": {
+ "idb": "^7.0.1",
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-broadcast-update": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.1.0.tgz",
- "integrity": "sha512-O36hIfhjej/c5ar95pO67k1GQw0/bw5tKP7CERNgK+JdxBANQhDmIuOXZTNvwb2IHBx9hj2kxvcDyRIh5nzOgQ==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.3.0.tgz",
+ "integrity": "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-core": "7.1.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-build": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.1.1.tgz",
- "integrity": "sha512-WdkVdC70VMpf5NBCtNbiwdSZeKVuhTEd5PV3mAwpTQCGAB5XbOny1P9egEgNdetv4srAMmMKjvBk4RD58LpooA==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.3.0.tgz",
+ "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@apideck/better-ajv-errors": "^0.3.1",
"@babel/core": "^7.24.4",
"strip-comments": "^2.0.1",
"tempy": "^0.6.0",
"upath": "^1.2.0",
- "workbox-background-sync": "7.1.0",
- "workbox-broadcast-update": "7.1.0",
- "workbox-cacheable-response": "7.1.0",
- "workbox-core": "7.1.0",
- "workbox-expiration": "7.1.0",
- "workbox-google-analytics": "7.1.0",
- "workbox-navigation-preload": "7.1.0",
- "workbox-precaching": "7.1.0",
- "workbox-range-requests": "7.1.0",
- "workbox-recipes": "7.1.0",
- "workbox-routing": "7.1.0",
- "workbox-strategies": "7.1.0",
- "workbox-streams": "7.1.0",
- "workbox-sw": "7.1.0",
- "workbox-window": "7.1.0"
+ "workbox-background-sync": "7.3.0",
+ "workbox-broadcast-update": "7.3.0",
+ "workbox-cacheable-response": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-expiration": "7.3.0",
+ "workbox-google-analytics": "7.3.0",
+ "workbox-navigation-preload": "7.3.0",
+ "workbox-precaching": "7.3.0",
+ "workbox-range-requests": "7.3.0",
+ "workbox-recipes": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0",
+ "workbox-streams": "7.3.0",
+ "workbox-sw": "7.3.0",
+ "workbox-window": "7.3.0"
},
"engines": {
"node": ">=16.0.0"
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
- "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/workbox-build/node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/workbox-build/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
- "license": "MIT"
+ "dev": true
},
"node_modules/workbox-build/node_modules/pretty-bytes": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
"integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=6"
},
}
},
"node_modules/workbox-build/node_modules/rollup": {
- "version": "2.79.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
- "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "version": "2.79.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
"dev": true,
- "license": "MIT",
"bin": {
"rollup": "dist/bin/rollup"
},
}
},
"node_modules/workbox-cacheable-response": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.1.0.tgz",
- "integrity": "sha512-iwsLBll8Hvua3xCuBB9h92+/e0wdsmSVgR2ZlvcfjepZWwhd3osumQB3x9o7flj+FehtWM2VHbZn8UJeBXXo6Q==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz",
+ "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-core": "7.1.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-core": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz",
- "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==",
- "dev": true,
- "license": "MIT"
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz",
+ "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==",
+ "dev": true
},
"node_modules/workbox-expiration": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.1.0.tgz",
- "integrity": "sha512-m5DcMY+A63rJlPTbbBNtpJ20i3enkyOtSgYfv/l8h+D6YbbNiA0zKEkCUaMsdDlxggla1oOfRkyqTvl5Ni5KQQ==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.3.0.tgz",
+ "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"idb": "^7.0.1",
- "workbox-core": "7.1.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-google-analytics": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.1.0.tgz",
- "integrity": "sha512-FvE53kBQHfVTcZyczeBVRexhh7JTkyQ8HAvbVY6mXd2n2A7Oyz/9fIwnY406ZcDhvE4NFfKGjW56N4gBiqkrew==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.3.0.tgz",
+ "integrity": "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-background-sync": "7.1.0",
- "workbox-core": "7.1.0",
- "workbox-routing": "7.1.0",
- "workbox-strategies": "7.1.0"
+ "workbox-background-sync": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
}
},
"node_modules/workbox-navigation-preload": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.1.0.tgz",
- "integrity": "sha512-4wyAbo0vNI/X0uWNJhCMKxnPanNyhybsReMGN9QUpaePLTiDpKxPqFxl4oUmBNddPwIXug01eTSLVIFXimRG/A==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.3.0.tgz",
+ "integrity": "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-core": "7.1.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-precaching": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.1.0.tgz",
- "integrity": "sha512-LyxzQts+UEpgtmfnolo0hHdNjoB7EoRWcF7EDslt+lQGd0lW4iTvvSe3v5JiIckQSB5KTW5xiCqjFviRKPj1zA==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.3.0.tgz",
+ "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-core": "7.1.0",
- "workbox-routing": "7.1.0",
- "workbox-strategies": "7.1.0"
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
}
},
"node_modules/workbox-range-requests": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.1.0.tgz",
- "integrity": "sha512-m7+O4EHolNs5yb/79CrnwPR/g/PRzMFYEdo01LqwixVnc/sbzNSvKz0d04OE3aMRel1CwAAZQheRsqGDwATgPQ==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.3.0.tgz",
+ "integrity": "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-core": "7.1.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-recipes": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.1.0.tgz",
- "integrity": "sha512-NRrk4ycFN9BHXJB6WrKiRX3W3w75YNrNrzSX9cEZgFB5ubeGoO8s/SDmOYVrFYp9HMw6sh1Pm3eAY/1gVS8YLg==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.3.0.tgz",
+ "integrity": "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-cacheable-response": "7.1.0",
- "workbox-core": "7.1.0",
- "workbox-expiration": "7.1.0",
- "workbox-precaching": "7.1.0",
- "workbox-routing": "7.1.0",
- "workbox-strategies": "7.1.0"
+ "workbox-cacheable-response": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-expiration": "7.3.0",
+ "workbox-precaching": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
}
},
"node_modules/workbox-routing": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.1.0.tgz",
- "integrity": "sha512-oOYk+kLriUY2QyHkIilxUlVcFqwduLJB7oRZIENbqPGeBP/3TWHYNNdmGNhz1dvKuw7aqvJ7CQxn27/jprlTdg==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.3.0.tgz",
+ "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-core": "7.1.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-strategies": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.1.0.tgz",
- "integrity": "sha512-/UracPiGhUNehGjRm/tLUQ+9PtWmCbRufWtV0tNrALuf+HZ4F7cmObSEK+E4/Bx1p8Syx2tM+pkIrvtyetdlew==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.3.0.tgz",
+ "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-core": "7.1.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-streams": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.1.0.tgz",
- "integrity": "sha512-WyHAVxRXBMfysM8ORwiZnI98wvGWTVAq/lOyBjf00pXFvG0mNaVz4Ji+u+fKa/mf1i2SnTfikoYKto4ihHeS6w==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.3.0.tgz",
+ "integrity": "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "workbox-core": "7.1.0",
- "workbox-routing": "7.1.0"
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0"
}
},
"node_modules/workbox-sw": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.1.0.tgz",
- "integrity": "sha512-Hml/9+/njUXBglv3dtZ9WBKHI235AQJyLBV1G7EFmh4/mUdSQuXui80RtjDeVRrXnm/6QWgRUEHG3/YBVbxtsA==",
- "dev": true,
- "license": "MIT"
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.3.0.tgz",
+ "integrity": "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA==",
+ "dev": true
},
"node_modules/workbox-window": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.1.0.tgz",
- "integrity": "sha512-ZHeROyqR+AS5UPzholQRDttLFqGMwP0Np8MKWAdyxsDETxq3qOAyXvqessc3GniohG6e0mAqSQyKOHmT8zPF7g==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.3.0.tgz",
+ "integrity": "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@types/trusted-types": "^2.0.2",
- "workbox-core": "7.1.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/wrap-ansi": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
}
},
"node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "devOptional": true
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"node_modules/yaml": {
"version": "1.10.2",
"file-saver": "2.0.5",
"flux": "4.0.3",
"focus-trap-react": "10.0.2",
- "folds": "2.0.0",
+ "folds": "2.1.0",
"formik": "2.4.6",
"html-dom-parser": "4.0.0",
"html-react-parser": "4.2.0",
"jotai": "2.6.0",
"linkify-react": "4.1.3",
"linkifyjs": "4.1.3",
- "matrix-js-sdk": "34.11.1",
+ "matrix-js-sdk": "35.0.0",
"millify": "6.1.0",
"pdfjs-dist": "4.2.67",
"prismjs": "1.29.0",
"vite": "5.0.13",
"vite-plugin-pwa": "0.20.5",
"vite-plugin-static-copy": "1.0.4",
- "vite-plugin-top-level-await": "1.4.1"
+ "vite-plugin-top-level-await": "1.4.4"
}
}
--- /dev/null
+import React, { ReactNode } from 'react';
+import { AuthDict, AuthType, IAuthData, UIAFlow } from 'matrix-js-sdk';
+import { getUIAFlowForStages } from '../utils/matrix-uia';
+import { useSupportedUIAFlows, useUIACompleted, useUIAFlow } from '../hooks/useUIAFlows';
+import { UIAFlowOverlay } from './UIAFlowOverlay';
+import { PasswordStage, SSOStage } from './uia-stages';
+import { useMatrixClient } from '../hooks/useMatrixClient';
+
+export const SUPPORTED_IN_APP_UIA_STAGES = [AuthType.Password, AuthType.Sso];
+
+export const pickUIAFlow = (uiaFlows: UIAFlow[]): UIAFlow | undefined => {
+ const passwordFlow = getUIAFlowForStages(uiaFlows, [AuthType.Password]);
+ if (passwordFlow) return passwordFlow;
+ return getUIAFlowForStages(uiaFlows, [AuthType.Sso]);
+};
+
+type ActionUIAProps = {
+ authData: IAuthData;
+ ongoingFlow: UIAFlow;
+ action: (authDict: AuthDict) => void;
+ onCancel: () => void;
+};
+export function ActionUIA({ authData, ongoingFlow, action, onCancel }: ActionUIAProps) {
+ const mx = useMatrixClient();
+ const completed = useUIACompleted(authData);
+ const { getStageToComplete } = useUIAFlow(authData, ongoingFlow);
+
+ const stageToComplete = getStageToComplete();
+
+ if (!stageToComplete) return null;
+ return (
+ <UIAFlowOverlay
+ currentStep={completed.length + 1}
+ stepCount={ongoingFlow.stages.length}
+ onCancel={onCancel}
+ >
+ {stageToComplete.type === AuthType.Password && (
+ <PasswordStage
+ userId={mx.getUserId()!}
+ stageData={stageToComplete}
+ onCancel={onCancel}
+ submitAuthDict={action}
+ />
+ )}
+ {stageToComplete.type === AuthType.Sso && stageToComplete.session && (
+ <SSOStage
+ ssoRedirectURL={mx.getFallbackAuthUrl(AuthType.Sso, stageToComplete.session)}
+ stageData={stageToComplete}
+ onCancel={onCancel}
+ submitAuthDict={action}
+ />
+ )}
+ </UIAFlowOverlay>
+ );
+}
+
+type ActionUIAFlowsLoaderProps = {
+ authData: IAuthData;
+ unsupported: () => ReactNode;
+ children: (ongoingFlow: UIAFlow) => ReactNode;
+};
+export function ActionUIAFlowsLoader({
+ authData,
+ unsupported,
+ children,
+}: ActionUIAFlowsLoaderProps) {
+ const supportedFlows = useSupportedUIAFlows(authData.flows ?? [], SUPPORTED_IN_APP_UIA_STAGES);
+ const ongoingFlow = supportedFlows.length > 0 ? supportedFlows[0] : undefined;
+
+ if (!ongoingFlow) return unsupported();
+
+ return children(ongoingFlow);
+}
--- /dev/null
+import React, { MouseEventHandler, useCallback, useState } from 'react';
+import { useAtom } from 'jotai';
+import { CryptoApi, KeyBackupInfo } from 'matrix-js-sdk/lib/crypto-api';
+import {
+ Badge,
+ Box,
+ Button,
+ color,
+ config,
+ Icon,
+ IconButton,
+ Icons,
+ Menu,
+ percent,
+ PopOut,
+ ProgressBar,
+ RectCords,
+ Spinner,
+ Text,
+} from 'folds';
+import FocusTrap from 'focus-trap-react';
+import { BackupProgressStatus, backupRestoreProgressAtom } from '../state/backupRestore';
+import { InfoCard } from './info-card';
+import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
+import {
+ useKeyBackupInfo,
+ useKeyBackupStatus,
+ useKeyBackupSync,
+ useKeyBackupTrust,
+} from '../hooks/useKeyBackup';
+import { stopPropagation } from '../utils/keyboard';
+import { useRestoreBackupOnVerification } from '../hooks/useRestoreBackupOnVerification';
+
+type BackupStatusProps = {
+ enabled: boolean;
+};
+function BackupStatus({ enabled }: BackupStatusProps) {
+ return (
+ <Box as="span" gap="100" alignItems="Center">
+ <Badge variant={enabled ? 'Success' : 'Critical'} fill="Solid" size="200" radii="Pill" />
+ <Text
+ as="span"
+ size="L400"
+ style={{ color: enabled ? color.Success.Main : color.Critical.Main }}
+ >
+ {enabled ? 'Connected' : 'Disconnected'}
+ </Text>
+ </Box>
+ );
+}
+type BackupSyncingProps = {
+ count: number;
+};
+function BackupSyncing({ count }: BackupSyncingProps) {
+ return (
+ <Box as="span" gap="100" alignItems="Center">
+ <Spinner size="50" variant="Primary" fill="Soft" />
+ <Text as="span" size="L400" style={{ color: color.Primary.Main }}>
+ Syncing ({count})
+ </Text>
+ </Box>
+ );
+}
+
+function BackupProgressFetching() {
+ return (
+ <Box grow="Yes" gap="200" alignItems="Center">
+ <Badge variant="Secondary" fill="Solid" radii="300">
+ <Text size="L400">Restoring: 0%</Text>
+ </Badge>
+ <Box grow="Yes" direction="Column">
+ <ProgressBar variant="Secondary" size="300" min={0} max={1} value={0} />
+ </Box>
+ <Spinner size="50" variant="Secondary" fill="Soft" />
+ </Box>
+ );
+}
+
+type BackupProgressProps = {
+ total: number;
+ downloaded: number;
+};
+function BackupProgress({ total, downloaded }: BackupProgressProps) {
+ return (
+ <Box grow="Yes" gap="200" alignItems="Center">
+ <Badge variant="Secondary" fill="Solid" radii="300">
+ <Text size="L400">Restoring: {`${Math.round(percent(0, total, downloaded))}%`}</Text>
+ </Badge>
+ <Box grow="Yes" direction="Column">
+ <ProgressBar variant="Secondary" size="300" min={0} max={total} value={downloaded} />
+ </Box>
+ <Badge variant="Secondary" fill="Soft" radii="Pill">
+ <Text size="L400">
+ {downloaded} / {total}
+ </Text>
+ </Badge>
+ </Box>
+ );
+}
+
+type BackupTrustInfoProps = {
+ crypto: CryptoApi;
+ backupInfo: KeyBackupInfo;
+};
+function BackupTrustInfo({ crypto, backupInfo }: BackupTrustInfoProps) {
+ const trust = useKeyBackupTrust(crypto, backupInfo);
+
+ if (!trust) return null;
+
+ return (
+ <Box direction="Column">
+ {trust.matchesDecryptionKey ? (
+ <Text size="T200" style={{ color: color.Success.Main }}>
+ <b>Backup has trusted decryption key.</b>
+ </Text>
+ ) : (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>Backup does not have trusted decryption key!</b>
+ </Text>
+ )}
+ {trust.trusted ? (
+ <Text size="T200" style={{ color: color.Success.Main }}>
+ <b>Backup has trusted by signature.</b>
+ </Text>
+ ) : (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>Backup does not have trusted signature!</b>
+ </Text>
+ )}
+ </Box>
+ );
+}
+
+type BackupRestoreTileProps = {
+ crypto: CryptoApi;
+};
+export function BackupRestoreTile({ crypto }: BackupRestoreTileProps) {
+ const [restoreProgress, setRestoreProgress] = useAtom(backupRestoreProgressAtom);
+ const restoring =
+ restoreProgress.status === BackupProgressStatus.Fetching ||
+ restoreProgress.status === BackupProgressStatus.Loading;
+
+ const backupEnabled = useKeyBackupStatus(crypto);
+ const backupInfo = useKeyBackupInfo(crypto);
+ const [remainingSession, syncFailure] = useKeyBackupSync();
+
+ const [menuCords, setMenuCords] = useState<RectCords>();
+
+ const handleMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setMenuCords(evt.currentTarget.getBoundingClientRect());
+ };
+
+ const [restoreState, restoreBackup] = useAsyncCallback<void, Error, []>(
+ useCallback(async () => {
+ await crypto.restoreKeyBackup({
+ progressCallback(progress) {
+ setRestoreProgress(progress);
+ },
+ });
+ }, [crypto, setRestoreProgress])
+ );
+
+ const handleRestore = () => {
+ setMenuCords(undefined);
+ restoreBackup();
+ };
+
+ return (
+ <InfoCard
+ variant="Surface"
+ title="Encryption Backup"
+ after={
+ <Box alignItems="Center" gap="200">
+ {remainingSession === 0 ? (
+ <BackupStatus enabled={backupEnabled} />
+ ) : (
+ <BackupSyncing count={remainingSession} />
+ )}
+ <IconButton
+ aria-pressed={!!menuCords}
+ size="300"
+ variant="Surface"
+ radii="300"
+ onClick={handleMenu}
+ >
+ <Icon size="100" src={Icons.VerticalDots} />
+ </IconButton>
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu
+ style={{
+ padding: config.space.S100,
+ }}
+ >
+ <Box direction="Column" gap="100">
+ <Box direction="Column" gap="200">
+ <InfoCard
+ variant="SurfaceVariant"
+ title="Backup Details"
+ description={
+ <>
+ <span>Version: {backupInfo?.version ?? 'NIL'}</span>
+ <br />
+ <span>Keys: {backupInfo?.count ?? 'NIL'}</span>
+ </>
+ }
+ />
+ </Box>
+ <Button
+ size="300"
+ variant="Success"
+ radii="300"
+ aria-disabled={restoreState.status === AsyncStatus.Loading || restoring}
+ onClick={
+ restoreState.status === AsyncStatus.Loading || restoring
+ ? undefined
+ : handleRestore
+ }
+ before={<Icon size="100" src={Icons.Download} />}
+ >
+ <Text size="B300">Restore Backup</Text>
+ </Button>
+ </Box>
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ </Box>
+ }
+ >
+ {syncFailure && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{syncFailure}</b>
+ </Text>
+ )}
+ {!backupEnabled && backupInfo === null && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>No backup present on server!</b>
+ </Text>
+ )}
+ {!syncFailure && !backupEnabled && backupInfo && (
+ <BackupTrustInfo crypto={crypto} backupInfo={backupInfo} />
+ )}
+ {restoreState.status === AsyncStatus.Loading && !restoring && <BackupProgressFetching />}
+ {restoreProgress.status === BackupProgressStatus.Fetching && <BackupProgressFetching />}
+ {restoreProgress.status === BackupProgressStatus.Loading && (
+ <BackupProgress
+ total={restoreProgress.data.total}
+ downloaded={restoreProgress.data.downloaded}
+ />
+ )}
+ {restoreState.status === AsyncStatus.Error && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{restoreState.error.message}</b>
+ </Text>
+ )}
+ </InfoCard>
+ );
+}
+
+export function AutoRestoreBackupOnVerification() {
+ useRestoreBackupOnVerification();
+
+ return null;
+}
[]
>(
useCallback(async () => {
- const result = await Promise.allSettled([mx.getCapabilities(true), mx.getMediaConfig()]);
+ const result = await Promise.allSettled([mx.getCapabilities(), mx.getMediaConfig()]);
const capabilities = promiseFulfilledResult(result[0]);
const mediaConfig = promiseFulfilledResult(result[1]);
return [capabilities, mediaConfig];
export function CapabilitiesLoader({ children }: CapabilitiesLoaderProps) {
const mx = useMatrixClient();
- const [state, load] = useAsyncCallback(useCallback(() => mx.getCapabilities(true), [mx]));
+ const [state, load] = useAsyncCallback(useCallback(() => mx.getCapabilities(), [mx]));
useEffect(() => {
load();
--- /dev/null
+import {
+ ShowSasCallbacks,
+ VerificationPhase,
+ VerificationRequest,
+ Verifier,
+} from 'matrix-js-sdk/lib/crypto-api';
+import React, { CSSProperties, useCallback, useEffect, useState } from 'react';
+import { VerificationMethod } from 'matrix-js-sdk/lib/types';
+import {
+ Box,
+ Button,
+ config,
+ Dialog,
+ Header,
+ Icon,
+ IconButton,
+ Icons,
+ Overlay,
+ OverlayBackdrop,
+ OverlayCenter,
+ Spinner,
+ Text,
+} from 'folds';
+import FocusTrap from 'focus-trap-react';
+import {
+ useVerificationRequestPhase,
+ useVerificationRequestReceived,
+ useVerifierCancel,
+ useVerifierShowSas,
+} from '../hooks/useVerificationRequest';
+import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
+import { ContainerColor } from '../styles/ContainerColor.css';
+
+const DialogHeaderStyles: CSSProperties = {
+ padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
+ borderBottomWidth: config.borderWidth.B300,
+};
+
+type WaitingMessageProps = {
+ message: string;
+};
+function WaitingMessage({ message }: WaitingMessageProps) {
+ return (
+ <Box alignItems="Center" gap="200">
+ <Spinner variant="Secondary" size="200" />
+ <Text size="T300">{message}</Text>
+ </Box>
+ );
+}
+
+type VerificationUnexpectedProps = { message: string; onClose: () => void };
+function VerificationUnexpected({ message, onClose }: VerificationUnexpectedProps) {
+ return (
+ <Box direction="Column" gap="400">
+ <Text>{message}</Text>
+ <Button variant="Secondary" fill="Soft" onClick={onClose}>
+ <Text size="B400">Close</Text>
+ </Button>
+ </Box>
+ );
+}
+
+function VerificationWaitAccept() {
+ return (
+ <Box direction="Column" gap="400">
+ <Text>Please accept the request from other device.</Text>
+ <WaitingMessage message="Waiting for request to be accepted..." />
+ </Box>
+ );
+}
+
+type VerificationAcceptProps = {
+ onAccept: () => Promise<void>;
+};
+function VerificationAccept({ onAccept }: VerificationAcceptProps) {
+ const [acceptState, accept] = useAsyncCallback(onAccept);
+
+ const accepting = acceptState.status === AsyncStatus.Loading;
+ return (
+ <Box direction="Column" gap="400">
+ <Text>Click accept to start the verification process.</Text>
+ <Button
+ variant="Primary"
+ fill="Solid"
+ onClick={accept}
+ before={accepting && <Spinner size="100" variant="Primary" fill="Solid" />}
+ disabled={accepting}
+ >
+ <Text size="B400">Accept</Text>
+ </Button>
+ </Box>
+ );
+}
+
+function VerificationWaitStart() {
+ return (
+ <Box direction="Column" gap="400">
+ <Text>Verification request has been accepted.</Text>
+ <WaitingMessage message="Waiting for the response from other device..." />
+ </Box>
+ );
+}
+
+type VerificationStartProps = {
+ onStart: () => Promise<void>;
+};
+function AutoVerificationStart({ onStart }: VerificationStartProps) {
+ useEffect(() => {
+ onStart();
+ }, [onStart]);
+
+ return (
+ <Box direction="Column" gap="400">
+ <WaitingMessage message="Starting verification using emoji comparison..." />
+ </Box>
+ );
+}
+
+function CompareEmoji({ sasData }: { sasData: ShowSasCallbacks }) {
+ const [confirmState, confirm] = useAsyncCallback(useCallback(() => sasData.confirm(), [sasData]));
+
+ const confirming =
+ confirmState.status === AsyncStatus.Loading || confirmState.status === AsyncStatus.Success;
+
+ return (
+ <Box direction="Column" gap="400">
+ <Text>Confirm the emoji below are displayed on both devices, in the same order:</Text>
+ <Box
+ className={ContainerColor({ variant: 'SurfaceVariant' })}
+ style={{
+ borderRadius: config.radii.R400,
+ padding: config.space.S500,
+ }}
+ gap="700"
+ wrap="Wrap"
+ justifyContent="Center"
+ >
+ {sasData.sas.emoji?.map(([emoji, name], index) => (
+ <Box
+ // eslint-disable-next-line react/no-array-index-key
+ key={`${emoji}${name}${index}`}
+ direction="Column"
+ gap="100"
+ justifyContent="Center"
+ alignItems="Center"
+ >
+ <Text size="H1">{emoji}</Text>
+ <Text size="T200">{name}</Text>
+ </Box>
+ ))}
+ </Box>
+ <Box direction="Column" gap="200">
+ <Button
+ variant="Primary"
+ fill="Soft"
+ onClick={confirm}
+ disabled={confirming}
+ before={confirming && <Spinner size="100" variant="Primary" />}
+ >
+ <Text size="B400">They Match</Text>
+ </Button>
+ <Button
+ variant="Primary"
+ fill="Soft"
+ onClick={() => sasData.mismatch()}
+ disabled={confirming}
+ >
+ <Text size="B400">Do not Match</Text>
+ </Button>
+ </Box>
+ </Box>
+ );
+}
+
+type SasVerificationProps = {
+ verifier: Verifier;
+ onCancel: () => void;
+};
+function SasVerification({ verifier, onCancel }: SasVerificationProps) {
+ const [sasData, setSasData] = useState<ShowSasCallbacks>();
+
+ useVerifierShowSas(verifier, setSasData);
+ useVerifierCancel(verifier, onCancel);
+
+ useEffect(() => {
+ verifier.verify();
+ }, [verifier]);
+
+ if (sasData) {
+ return <CompareEmoji sasData={sasData} />;
+ }
+
+ return (
+ <Box direction="Column" gap="400">
+ <WaitingMessage message="Starting verification using emoji comparison..." />
+ </Box>
+ );
+}
+
+type VerificationDoneProps = {
+ onExit: () => void;
+};
+function VerificationDone({ onExit }: VerificationDoneProps) {
+ return (
+ <Box direction="Column" gap="400">
+ <div>
+ <Text>Your device is verified.</Text>
+ </div>
+ <Button variant="Primary" fill="Solid" onClick={onExit}>
+ <Text size="B400">Okay</Text>
+ </Button>
+ </Box>
+ );
+}
+
+type VerificationCanceledProps = {
+ onClose: () => void;
+};
+function VerificationCanceled({ onClose }: VerificationCanceledProps) {
+ return (
+ <Box direction="Column" gap="400">
+ <Text>Verification has been canceled.</Text>
+ <Button variant="Secondary" fill="Soft" onClick={onClose}>
+ <Text size="B400">Close</Text>
+ </Button>
+ </Box>
+ );
+}
+
+type DeviceVerificationProps = {
+ request: VerificationRequest;
+ onExit: () => void;
+};
+export function DeviceVerification({ request, onExit }: DeviceVerificationProps) {
+ const phase = useVerificationRequestPhase(request);
+
+ const handleCancel = useCallback(() => {
+ if (request.phase !== VerificationPhase.Done && request.phase !== VerificationPhase.Cancelled) {
+ request.cancel();
+ }
+ onExit();
+ }, [request, onExit]);
+
+ const handleAccept = useCallback(() => request.accept(), [request]);
+ const handleStart = useCallback(async () => {
+ await request.startVerification(VerificationMethod.Sas);
+ }, [request]);
+
+ return (
+ <Overlay open backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ clickOutsideDeactivates: false,
+ escapeDeactivates: false,
+ }}
+ >
+ <Dialog variant="Surface">
+ <Header style={DialogHeaderStyles} variant="Surface" size="500">
+ <Box grow="Yes">
+ <Text size="H4">Device Verification</Text>
+ </Box>
+ <IconButton size="300" radii="300" onClick={handleCancel}>
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Header>
+ <Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
+ {phase === VerificationPhase.Requested &&
+ (request.initiatedByMe ? (
+ <VerificationWaitAccept />
+ ) : (
+ <VerificationAccept onAccept={handleAccept} />
+ ))}
+ {phase === VerificationPhase.Ready &&
+ (request.initiatedByMe ? (
+ <AutoVerificationStart onStart={handleStart} />
+ ) : (
+ <VerificationWaitStart />
+ ))}
+ {phase === VerificationPhase.Started &&
+ (request.verifier ? (
+ <SasVerification verifier={request.verifier} onCancel={handleCancel} />
+ ) : (
+ <VerificationUnexpected
+ message="Unexpected Error! Verification is started but verifier is missing."
+ onClose={handleCancel}
+ />
+ ))}
+ {phase === VerificationPhase.Done && <VerificationDone onExit={onExit} />}
+ {phase === VerificationPhase.Cancelled && (
+ <VerificationCanceled onClose={handleCancel} />
+ )}
+ </Box>
+ </Dialog>
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ );
+}
+
+export function ReceiveSelfDeviceVerification() {
+ const [request, setRequest] = useState<VerificationRequest>();
+
+ useVerificationRequestReceived(setRequest);
+
+ const handleExit = useCallback(() => {
+ setRequest(undefined);
+ }, []);
+
+ if (!request) return null;
+
+ if (!request.isSelfVerification) {
+ return null;
+ }
+
+ return <DeviceVerification request={request} onExit={handleExit} />;
+}
--- /dev/null
+import React, { FormEventHandler, forwardRef, useCallback, useState } from 'react';
+import {
+ Dialog,
+ Header,
+ Box,
+ Text,
+ IconButton,
+ Icon,
+ Icons,
+ config,
+ Button,
+ Chip,
+ color,
+ Spinner,
+} from 'folds';
+import FileSaver from 'file-saver';
+import to from 'await-to-js';
+import { AuthDict, IAuthData, MatrixError, UIAuthCallback } from 'matrix-js-sdk';
+import { PasswordInput } from './password-input';
+import { ContainerColor } from '../styles/ContainerColor.css';
+import { copyToClipboard } from '../utils/dom';
+import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
+import { clearSecretStorageKeys } from '../../client/state/secretStorageKeys';
+import { ActionUIA, ActionUIAFlowsLoader } from './ActionUIA';
+import { useMatrixClient } from '../hooks/useMatrixClient';
+import { useAlive } from '../hooks/useAlive';
+import { UseStateProvider } from './UseStateProvider';
+
+type UIACallback<T> = (
+ authDict: AuthDict | null
+) => Promise<[IAuthData, undefined] | [undefined, T]>;
+
+type PerformAction<T> = (authDict: AuthDict | null) => Promise<T>;
+
+type UIAAction<T> = {
+ authData: IAuthData;
+ callback: UIACallback<T>;
+ cancelCallback: () => void;
+};
+
+function makeUIAAction<T>(
+ authData: IAuthData,
+ performAction: PerformAction<T>,
+ resolve: (data: T) => void,
+ reject: (error?: any) => void
+): UIAAction<T> {
+ const action: UIAAction<T> = {
+ authData,
+ callback: async (authDict) => {
+ const [error, data] = await to<T, MatrixError | Error>(performAction(authDict));
+
+ if (error instanceof MatrixError && error.httpStatus === 401) {
+ return [error.data as IAuthData, undefined];
+ }
+
+ if (error) {
+ reject(error);
+ throw error;
+ }
+
+ resolve(data);
+ return [undefined, data];
+ },
+ cancelCallback: reject,
+ };
+
+ return action;
+}
+
+type SetupVerificationProps = {
+ onComplete: (recoveryKey: string) => void;
+};
+function SetupVerification({ onComplete }: SetupVerificationProps) {
+ const mx = useMatrixClient();
+ const alive = useAlive();
+
+ const [uiaAction, setUIAAction] = useState<UIAAction<void>>();
+ const [nextAuthData, setNextAuthData] = useState<IAuthData | null>(); // null means no next action.
+
+ const handleAction = useCallback(
+ async (authDict: AuthDict) => {
+ if (!uiaAction) {
+ throw new Error('Unexpected Error! UIA action is perform without data.');
+ }
+ if (alive()) {
+ setNextAuthData(null);
+ }
+ const [authData] = await uiaAction.callback(authDict);
+
+ if (alive() && authData) {
+ setNextAuthData(authData);
+ }
+ },
+ [uiaAction, alive]
+ );
+
+ const resetUIA = useCallback(() => {
+ if (!alive()) return;
+ setUIAAction(undefined);
+ setNextAuthData(undefined);
+ }, [alive]);
+
+ const authUploadDeviceSigningKeys: UIAuthCallback<void> = useCallback(
+ (makeRequest) =>
+ new Promise<void>((resolve, reject) => {
+ makeRequest(null)
+ .then(() => {
+ resolve();
+ resetUIA();
+ })
+ .catch((error) => {
+ if (error instanceof MatrixError && error.httpStatus === 401) {
+ const authData = error.data as IAuthData;
+ const action = makeUIAAction(
+ authData,
+ makeRequest as PerformAction<void>,
+ resolve,
+ (err) => {
+ resetUIA();
+ reject(err);
+ }
+ );
+ if (alive()) {
+ setUIAAction(action);
+ } else {
+ reject(new Error('Authentication failed! Failed to setup device verification.'));
+ }
+ return;
+ }
+ reject(error);
+ });
+ }),
+ [alive, resetUIA]
+ );
+
+ const [setupState, setup] = useAsyncCallback<void, Error, [string | undefined]>(
+ useCallback(
+ async (passphrase) => {
+ const crypto = mx.getCrypto();
+ if (!crypto) throw new Error('Unexpected Error! Crypto module not found!');
+
+ const recoveryKeyData = await crypto.createRecoveryKeyFromPassphrase(passphrase);
+ if (!recoveryKeyData.encodedPrivateKey) {
+ throw new Error('Unexpected Error! Failed to create recovery key.');
+ }
+ clearSecretStorageKeys();
+
+ await crypto.bootstrapSecretStorage({
+ createSecretStorageKey: async () => recoveryKeyData,
+ setupNewSecretStorage: true,
+ });
+
+ await crypto.bootstrapCrossSigning({
+ authUploadDeviceSigningKeys,
+ setupNewCrossSigning: true,
+ });
+
+ await crypto.resetKeyBackup();
+
+ onComplete(recoveryKeyData.encodedPrivateKey);
+ },
+ [mx, onComplete, authUploadDeviceSigningKeys]
+ )
+ );
+
+ const loading = setupState.status === AsyncStatus.Loading;
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (loading) return;
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const passphraseInput = target?.passphraseInput as HTMLInputElement | undefined;
+ let passphrase: string | undefined;
+ if (passphraseInput && passphraseInput.value.length > 0) {
+ passphrase = passphraseInput.value;
+ }
+
+ setup(passphrase);
+ };
+
+ return (
+ <Box as="form" onSubmit={handleSubmit} direction="Column" gap="400">
+ <Text size="T300">
+ Generate a <b>Recovery Key</b> for verifying identity if you do not have access to other
+ devices. Additionally, setup a passphrase as a memorable alternative.
+ </Text>
+ <Box direction="Column" gap="100">
+ <Text size="L400">Passphrase (Optional)</Text>
+ <PasswordInput name="passphraseInput" size="400" readOnly={loading} />
+ </Box>
+ <Button
+ type="submit"
+ disabled={loading}
+ before={loading && <Spinner size="200" variant="Primary" fill="Solid" />}
+ >
+ <Text size="B400">Continue</Text>
+ </Button>
+ {setupState.status === AsyncStatus.Error && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{setupState.error ? setupState.error.message : 'Unexpected Error!'}</b>
+ </Text>
+ )}
+ {nextAuthData !== null && uiaAction && (
+ <ActionUIAFlowsLoader
+ authData={nextAuthData ?? uiaAction.authData}
+ unsupported={() => (
+ <Text size="T200">
+ Authentication steps to perform this action are not supported by client.
+ </Text>
+ )}
+ >
+ {(ongoingFlow) => (
+ <ActionUIA
+ authData={nextAuthData ?? uiaAction.authData}
+ ongoingFlow={ongoingFlow}
+ action={handleAction}
+ onCancel={uiaAction.cancelCallback}
+ />
+ )}
+ </ActionUIAFlowsLoader>
+ )}
+ </Box>
+ );
+}
+
+type RecoveryKeyDisplayProps = {
+ recoveryKey: string;
+};
+function RecoveryKeyDisplay({ recoveryKey }: RecoveryKeyDisplayProps) {
+ const [show, setShow] = useState(false);
+
+ const handleCopy = () => {
+ copyToClipboard(recoveryKey);
+ };
+
+ const handleDownload = () => {
+ const blob = new Blob([recoveryKey], {
+ type: 'text/plain;charset=us-ascii',
+ });
+ FileSaver.saveAs(blob, 'recovery-key.txt');
+ };
+
+ const safeToDisplayKey = show ? recoveryKey : recoveryKey.replace(/[^\s]/g, '*');
+
+ return (
+ <Box direction="Column" gap="400">
+ <Text size="T300">
+ Store the Recovery Key in a safe place for future use, as you will need it to verify your
+ identity if you do not have access to other devices.
+ </Text>
+ <Box direction="Column" gap="100">
+ <Text size="L400">Recovery Key</Text>
+ <Box
+ className={ContainerColor({ variant: 'SurfaceVariant' })}
+ style={{
+ padding: config.space.S300,
+ borderRadius: config.radii.R400,
+ }}
+ alignItems="Center"
+ justifyContent="Center"
+ gap="400"
+ >
+ <Text style={{ fontFamily: 'monospace' }} size="T200" priority="300">
+ {safeToDisplayKey}
+ </Text>
+ <Chip onClick={() => setShow(!show)} variant="Secondary" radii="Pill">
+ <Text size="B300">{show ? 'Hide' : 'Show'}</Text>
+ </Chip>
+ </Box>
+ </Box>
+ <Box direction="Column" gap="200">
+ <Button onClick={handleCopy}>
+ <Text size="B400">Copy</Text>
+ </Button>
+ <Button onClick={handleDownload} fill="Soft">
+ <Text size="B400">Download</Text>
+ </Button>
+ </Box>
+ </Box>
+ );
+}
+
+type DeviceVerificationSetupProps = {
+ onCancel: () => void;
+};
+export const DeviceVerificationSetup = forwardRef<HTMLDivElement, DeviceVerificationSetupProps>(
+ ({ onCancel }, ref) => {
+ const [recoveryKey, setRecoveryKey] = useState<string>();
+
+ return (
+ <Dialog ref={ref}>
+ <Header
+ style={{
+ padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
+ borderBottomWidth: config.borderWidth.B300,
+ }}
+ variant="Surface"
+ size="500"
+ >
+ <Box grow="Yes">
+ <Text size="H4">Setup Device Verification</Text>
+ </Box>
+ <IconButton size="300" radii="300" onClick={onCancel}>
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Header>
+ <Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
+ {recoveryKey ? (
+ <RecoveryKeyDisplay recoveryKey={recoveryKey} />
+ ) : (
+ <SetupVerification onComplete={setRecoveryKey} />
+ )}
+ </Box>
+ </Dialog>
+ );
+ }
+);
+type DeviceVerificationResetProps = {
+ onCancel: () => void;
+};
+export const DeviceVerificationReset = forwardRef<HTMLDivElement, DeviceVerificationResetProps>(
+ ({ onCancel }, ref) => {
+ const [reset, setReset] = useState(false);
+
+ return (
+ <Dialog ref={ref}>
+ <Header
+ style={{
+ padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
+ borderBottomWidth: config.borderWidth.B300,
+ }}
+ variant="Surface"
+ size="500"
+ >
+ <Box grow="Yes">
+ <Text size="H4">Reset Device Verification</Text>
+ </Box>
+ <IconButton size="300" radii="300" onClick={onCancel}>
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Header>
+ {reset ? (
+ <Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
+ <UseStateProvider initial={undefined}>
+ {(recoveryKey: string | undefined, setRecoveryKey) =>
+ recoveryKey ? (
+ <RecoveryKeyDisplay recoveryKey={recoveryKey} />
+ ) : (
+ <SetupVerification onComplete={setRecoveryKey} />
+ )
+ }
+ </UseStateProvider>
+ </Box>
+ ) : (
+ <Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
+ <Box direction="Column" gap="200">
+ <Text size="H1">✋🧑🚒🤚</Text>
+ <Text size="T300">Resetting device verification is permanent.</Text>
+ <Text size="T300">
+ Anyone you have verified with will see security alerts and your encryption backup
+ will be lost. You almost certainly do not want to do this, unless you have lost{' '}
+ <b>Recovery Key</b> or <b>Recovery Passphrase</b> and every device you can verify
+ from.
+ </Text>
+ </Box>
+ <Button variant="Critical" onClick={() => setReset(true)}>
+ <Text size="B400">Reset</Text>
+ </Button>
+ </Box>
+ )}
+ </Dialog>
+ );
+ }
+);
--- /dev/null
+import { ReactNode } from 'react';
+import { CryptoApi } from 'matrix-js-sdk/lib/crypto-api';
+import {
+ useDeviceVerificationStatus,
+ VerificationStatus,
+} from '../hooks/useDeviceVerificationStatus';
+
+type DeviceVerificationStatusProps = {
+ crypto?: CryptoApi;
+ userId: string;
+ deviceId: string;
+ children: (verificationStatus: VerificationStatus) => ReactNode;
+};
+
+export function DeviceVerificationStatus({
+ crypto,
+ userId,
+ deviceId,
+ children,
+}: DeviceVerificationStatusProps) {
+ const status = useDeviceVerificationStatus(crypto, userId, deviceId);
+
+ return children(status);
+}
--- /dev/null
+import React, { forwardRef, useCallback } from 'react';
+import { Dialog, Header, config, Box, Text, Button, Spinner, color } from 'folds';
+import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
+import { logoutClient } from '../../client/initMatrix';
+import { useMatrixClient } from '../hooks/useMatrixClient';
+import { useCrossSigningActive } from '../hooks/useCrossSigning';
+import { InfoCard } from './info-card';
+import {
+ useDeviceVerificationStatus,
+ VerificationStatus,
+} from '../hooks/useDeviceVerificationStatus';
+
+type LogoutDialogProps = {
+ handleClose: () => void;
+};
+export const LogoutDialog = forwardRef<HTMLDivElement, LogoutDialogProps>(
+ ({ handleClose }, ref) => {
+ const mx = useMatrixClient();
+ const hasEncryptedRoom = !!mx.getRooms().find((room) => room.hasEncryptionStateEvent());
+ const crossSigningActive = useCrossSigningActive();
+ const verificationStatus = useDeviceVerificationStatus(
+ mx.getCrypto(),
+ mx.getSafeUserId(),
+ mx.getDeviceId() ?? undefined
+ );
+
+ const [logoutState, logout] = useAsyncCallback<void, Error, []>(
+ useCallback(async () => {
+ await logoutClient(mx);
+ }, [mx])
+ );
+
+ const ongoingLogout = logoutState.status === AsyncStatus.Loading;
+
+ return (
+ <Dialog variant="Surface" ref={ref}>
+ <Header
+ style={{
+ padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
+ borderBottomWidth: config.borderWidth.B300,
+ }}
+ variant="Surface"
+ size="500"
+ >
+ <Box grow="Yes">
+ <Text size="H4">Logout</Text>
+ </Box>
+ </Header>
+ <Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
+ {hasEncryptedRoom &&
+ (crossSigningActive ? (
+ verificationStatus === VerificationStatus.Unverified && (
+ <InfoCard
+ variant="Critical"
+ title="Unverified Device"
+ description="Verify your device before logging out to save your encrypted messages."
+ />
+ )
+ ) : (
+ <InfoCard
+ variant="Critical"
+ title="Alert"
+ description="Enable device verification or export your encrypted data from settings to avoid losing access to your messages."
+ />
+ ))}
+ <Text priority="400">You’re about to log out. Are you sure?</Text>
+ {logoutState.status === AsyncStatus.Error && (
+ <Text style={{ color: color.Critical.Main }} size="T300">
+ Failed to logout! {logoutState.error.message}
+ </Text>
+ )}
+ <Box direction="Column" gap="200">
+ <Button
+ variant="Critical"
+ onClick={logout}
+ disabled={ongoingLogout}
+ before={ongoingLogout && <Spinner variant="Critical" fill="Solid" size="200" />}
+ >
+ <Text size="B400">Logout</Text>
+ </Button>
+ <Button variant="Secondary" fill="Soft" onClick={handleClose} disabled={ongoingLogout}>
+ <Text size="B400">Cancel</Text>
+ </Button>
+ </Box>
+ </Box>
+ </Dialog>
+ );
+ }
+);
--- /dev/null
+import React, { MouseEventHandler, ReactNode, useCallback, useState } from 'react';
+import {
+ Box,
+ Text,
+ Chip,
+ Icon,
+ Icons,
+ RectCords,
+ PopOut,
+ Menu,
+ config,
+ MenuItem,
+ color,
+} from 'folds';
+import FocusTrap from 'focus-trap-react';
+import { stopPropagation } from '../utils/keyboard';
+import { SettingTile } from './setting-tile';
+import { SecretStorageKeyContent } from '../../types/matrix/accountData';
+import { SecretStorageRecoveryKey, SecretStorageRecoveryPassphrase } from './SecretStorage';
+import { useMatrixClient } from '../hooks/useMatrixClient';
+import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
+import { storePrivateKey } from '../../client/state/secretStorageKeys';
+
+export enum ManualVerificationMethod {
+ RecoveryPassphrase = 'passphrase',
+ RecoveryKey = 'key',
+}
+type ManualVerificationMethodSwitcherProps = {
+ value: ManualVerificationMethod;
+ onChange: (value: ManualVerificationMethod) => void;
+};
+export function ManualVerificationMethodSwitcher({
+ value,
+ onChange,
+}: ManualVerificationMethodSwitcherProps) {
+ const [menuCords, setMenuCords] = useState<RectCords>();
+
+ const handleMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setMenuCords(evt.currentTarget.getBoundingClientRect());
+ };
+
+ const handleSelect = (method: ManualVerificationMethod) => {
+ setMenuCords(undefined);
+ onChange(method);
+ };
+
+ return (
+ <>
+ <Chip
+ type="button"
+ variant="Secondary"
+ fill="Soft"
+ radii="Pill"
+ before={<Icon size="100" src={Icons.ChevronBottom} />}
+ onClick={handleMenu}
+ >
+ <Text as="span" size="B300">
+ {value === ManualVerificationMethod.RecoveryPassphrase && 'Recovery Passphrase'}
+ {value === ManualVerificationMethod.RecoveryKey && 'Recovery Key'}
+ </Text>
+ </Chip>
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu>
+ <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
+ <MenuItem
+ size="300"
+ variant="Surface"
+ aria-selected={value === ManualVerificationMethod.RecoveryPassphrase}
+ radii="300"
+ onClick={() => handleSelect(ManualVerificationMethod.RecoveryPassphrase)}
+ >
+ <Box grow="Yes">
+ <Text size="T300">Recovery Passphrase</Text>
+ </Box>
+ </MenuItem>
+ <MenuItem
+ size="300"
+ variant="Surface"
+ aria-selected={value === ManualVerificationMethod.RecoveryKey}
+ radii="300"
+ onClick={() => handleSelect(ManualVerificationMethod.RecoveryKey)}
+ >
+ <Box grow="Yes">
+ <Text size="T300">Recovery Key</Text>
+ </Box>
+ </MenuItem>
+ </Box>
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ </>
+ );
+}
+
+type ManualVerificationTileProps = {
+ secretStorageKeyId: string;
+ secretStorageKeyContent: SecretStorageKeyContent;
+ options?: ReactNode;
+};
+export function ManualVerificationTile({
+ secretStorageKeyId,
+ secretStorageKeyContent,
+ options,
+}: ManualVerificationTileProps) {
+ const mx = useMatrixClient();
+
+ const hasPassphrase = !!secretStorageKeyContent.passphrase;
+ const [method, setMethod] = useState(
+ hasPassphrase
+ ? ManualVerificationMethod.RecoveryPassphrase
+ : ManualVerificationMethod.RecoveryKey
+ );
+
+ const verifyAndRestoreBackup = useCallback(
+ async (recoveryKey: Uint8Array) => {
+ const crypto = mx.getCrypto();
+ if (!crypto) {
+ throw new Error('Unexpected Error! Crypto object not found.');
+ }
+
+ storePrivateKey(secretStorageKeyId, recoveryKey);
+
+ await crypto.bootstrapCrossSigning({});
+ await crypto.bootstrapSecretStorage({});
+
+ await crypto.loadSessionBackupPrivateKeyFromSecretStorage();
+ },
+ [mx, secretStorageKeyId]
+ );
+
+ const [verifyState, handleDecodedRecoveryKey] = useAsyncCallback<void, Error, [Uint8Array]>(
+ verifyAndRestoreBackup
+ );
+ const verifying = verifyState.status === AsyncStatus.Loading;
+
+ return (
+ <Box direction="Column" gap="200">
+ <SettingTile
+ title="Verify Manually"
+ description={hasPassphrase ? 'Select a verification method.' : 'Provide recovery key.'}
+ after={
+ <Box alignItems="Center" gap="200">
+ {hasPassphrase && (
+ <ManualVerificationMethodSwitcher value={method} onChange={setMethod} />
+ )}
+ {options}
+ </Box>
+ }
+ />
+ {verifyState.status === AsyncStatus.Success ? (
+ <Text size="T200" style={{ color: color.Success.Main }}>
+ <b>Device verified!</b>
+ </Text>
+ ) : (
+ <Box direction="Column" gap="100">
+ {method === ManualVerificationMethod.RecoveryKey && (
+ <SecretStorageRecoveryKey
+ processing={verifying}
+ keyContent={secretStorageKeyContent}
+ onDecodedRecoveryKey={handleDecodedRecoveryKey}
+ />
+ )}
+ {method === ManualVerificationMethod.RecoveryPassphrase &&
+ secretStorageKeyContent.passphrase && (
+ <SecretStorageRecoveryPassphrase
+ processing={verifying}
+ keyContent={secretStorageKeyContent}
+ passphraseContent={secretStorageKeyContent.passphrase}
+ onDecodedRecoveryKey={handleDecodedRecoveryKey}
+ />
+ )}
+ {verifyState.status === AsyncStatus.Error && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{verifyState.error.message}</b>
+ </Text>
+ )}
+ </Box>
+ )}
+ </Box>
+ );
+}
--- /dev/null
+import React, { ReactNode } from 'react';
+import FocusTrap from 'focus-trap-react';
+import { Modal, Overlay, OverlayBackdrop, OverlayCenter } from 'folds';
+import { stopPropagation } from '../utils/keyboard';
+
+type Modal500Props = {
+ requestClose: () => void;
+ children: ReactNode;
+};
+export function Modal500({ requestClose, children }: Modal500Props) {
+ return (
+ <Overlay open backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ clickOutsideDeactivates: true,
+ onDeactivate: requestClose,
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Modal size="500" variant="Background">
+ {children}
+ </Modal>
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ );
+}
--- /dev/null
+import React, { FormEventHandler, useCallback } from 'react';
+import { Box, Text, Button, Spinner, color } from 'folds';
+import { decodeRecoveryKey } from 'matrix-js-sdk/lib/crypto-api';
+import { deriveKey } from 'matrix-js-sdk/lib/crypto/key_passphrase';
+import { PasswordInput } from './password-input';
+import {
+ SecretStorageKeyContent,
+ SecretStoragePassphraseContent,
+} from '../../types/matrix/accountData';
+import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
+import { useMatrixClient } from '../hooks/useMatrixClient';
+import { useAlive } from '../hooks/useAlive';
+
+type SecretStorageRecoveryPassphraseProps = {
+ processing?: boolean;
+ keyContent: SecretStorageKeyContent;
+ passphraseContent: SecretStoragePassphraseContent;
+ onDecodedRecoveryKey: (recoveryKey: Uint8Array) => void;
+};
+export function SecretStorageRecoveryPassphrase({
+ processing,
+ keyContent,
+ passphraseContent,
+ onDecodedRecoveryKey,
+}: SecretStorageRecoveryPassphraseProps) {
+ const mx = useMatrixClient();
+ const alive = useAlive();
+
+ const [driveKeyState, submitPassphrase] = useAsyncCallback<
+ Uint8Array,
+ Error,
+ Parameters<typeof deriveKey>
+ >(
+ useCallback(
+ async (passphrase, salt, iterations, bits) => {
+ const decodedRecoveryKey = await deriveKey(passphrase, salt, iterations, bits);
+
+ const match = await mx.secretStorage.checkKey(decodedRecoveryKey, keyContent as any);
+
+ if (!match) {
+ throw new Error('Invalid recovery passphrase.');
+ }
+
+ return decodedRecoveryKey;
+ },
+ [mx, keyContent]
+ )
+ );
+
+ const drivingKey = driveKeyState.status === AsyncStatus.Loading;
+ const loading = drivingKey || processing;
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ if (loading) return;
+ evt.preventDefault();
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const recoveryPassphraseInput = target?.recoveryPassphraseInput as HTMLInputElement | undefined;
+ if (!recoveryPassphraseInput) return;
+ const recoveryPassphrase = recoveryPassphraseInput.value.trim();
+ if (!recoveryPassphrase) return;
+
+ const { salt, iterations, bits } = passphraseContent;
+ submitPassphrase(recoveryPassphrase, salt, iterations, bits).then((decodedRecoveryKey) => {
+ if (alive()) {
+ recoveryPassphraseInput.value = '';
+ onDecodedRecoveryKey(decodedRecoveryKey);
+ }
+ });
+ };
+
+ return (
+ <Box as="form" onSubmit={handleSubmit} direction="Column" gap="100">
+ <Box gap="200" alignItems="End">
+ <Box grow="Yes" direction="Column" gap="100">
+ <Text size="L400">Recovery Passphrase</Text>
+ <PasswordInput
+ name="recoveryPassphraseInput"
+ size="400"
+ variant="Secondary"
+ radii="300"
+ autoFocus
+ required
+ outlined
+ readOnly={loading}
+ />
+ </Box>
+ <Box shrink="No" gap="200">
+ <Button
+ type="submit"
+ variant="Success"
+ size="400"
+ radii="300"
+ disabled={loading}
+ before={loading && <Spinner size="200" variant="Success" fill="Solid" />}
+ >
+ <Text as="span" size="B400">
+ Verify
+ </Text>
+ </Button>
+ </Box>
+ </Box>
+ {driveKeyState.status === AsyncStatus.Error && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{driveKeyState.error.message}</b>
+ </Text>
+ )}
+ </Box>
+ );
+}
+
+type SecretStorageRecoveryKeyProps = {
+ processing?: boolean;
+ keyContent: SecretStorageKeyContent;
+ onDecodedRecoveryKey: (recoveryKey: Uint8Array) => void;
+};
+export function SecretStorageRecoveryKey({
+ processing,
+ keyContent,
+ onDecodedRecoveryKey,
+}: SecretStorageRecoveryKeyProps) {
+ const mx = useMatrixClient();
+ const alive = useAlive();
+
+ const [driveKeyState, submitRecoveryKey] = useAsyncCallback<Uint8Array, Error, [string]>(
+ useCallback(
+ async (recoveryKey) => {
+ const decodedRecoveryKey = decodeRecoveryKey(recoveryKey);
+
+ const match = await mx.secretStorage.checkKey(decodedRecoveryKey, keyContent as any);
+
+ if (!match) {
+ throw new Error('Invalid recovery key.');
+ }
+
+ return decodedRecoveryKey;
+ },
+ [mx, keyContent]
+ )
+ );
+
+ const drivingKey = driveKeyState.status === AsyncStatus.Loading;
+ const loading = drivingKey || processing;
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const recoveryKeyInput = target?.recoveryKeyInput as HTMLInputElement | undefined;
+ if (!recoveryKeyInput) return;
+ const recoveryKey = recoveryKeyInput.value.trim();
+ if (!recoveryKey) return;
+
+ submitRecoveryKey(recoveryKey).then((decodedRecoveryKey) => {
+ if (alive()) {
+ recoveryKeyInput.value = '';
+ onDecodedRecoveryKey(decodedRecoveryKey);
+ }
+ });
+ };
+
+ return (
+ <Box as="form" onSubmit={handleSubmit} direction="Column" gap="100">
+ <Box gap="200" alignItems="End">
+ <Box grow="Yes" direction="Column" gap="100">
+ <Text size="L400">Recovery Key</Text>
+ <PasswordInput
+ name="recoveryKeyInput"
+ size="400"
+ variant="Secondary"
+ radii="300"
+ autoFocus
+ required
+ outlined
+ readOnly={loading}
+ />
+ </Box>
+ <Box shrink="No" gap="200">
+ <Button
+ type="submit"
+ variant="Success"
+ size="400"
+ radii="300"
+ disabled={loading}
+ before={loading && <Spinner size="200" variant="Success" fill="Solid" />}
+ >
+ <Text as="span" size="B400">
+ Verify
+ </Text>
+ </Button>
+ </Box>
+ </Box>
+ {driveKeyState.status === AsyncStatus.Error && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{driveKeyState.error.message}</b>
+ </Text>
+ )}
+ </Box>
+ );
+}
IconButton,
} from 'folds';
import FocusTrap from 'focus-trap-react';
-import { stopPropagation } from '../utils/keyboard';
export type UIAFlowOverlayProps = {
currentStep: number;
}: UIAFlowOverlayProps) {
return (
<Overlay open backdrop={<OverlayBackdrop />}>
- <FocusTrap focusTrapOptions={{ initialFocus: false, escapeDeactivates: stopPropagation }}>
+ <FocusTrap focusTrapOptions={{ initialFocus: false, escapeDeactivates: false }}>
<Box style={{ height: '100%' }} direction="Column" grow="Yes" gap="400">
<Box grow="Yes" direction="Column" alignItems="Center" justifyContent="Center">
{children}
import { useRecentEmoji } from '../../../hooks/useRecentEmoji';
import { useRelevantImagePacks } from '../../../hooks/useImagePacks';
import { IEmoji, emojis } from '../../../plugins/emoji';
-import { ExtendedPackImage, PackUsage } from '../../../plugins/custom-emoji';
import { useKeyDown } from '../../../hooks/useKeyDown';
import { mxcUrlToHttp } from '../../../utils/matrix';
import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
+import { ImageUsage, PackImageReader } from '../../../plugins/custom-emoji';
type EmoticonCompleteHandler = (key: string, shortcode: string) => void;
-type EmoticonSearchItem = ExtendedPackImage | IEmoji;
+type EmoticonSearchItem = PackImageReader | IEmoji;
type EmoticonAutocompleteProps = {
imagePackRooms: Room[];
const mx = useMatrixClient();
const useAuthentication = useMediaAuthentication();
- const imagePacks = useRelevantImagePacks(mx, PackUsage.Emoticon, imagePackRooms);
+ const imagePacks = useRelevantImagePacks(ImageUsage.Emoticon, imagePackRooms);
const recentEmoji = useRecentEmoji(mx, 20);
const searchList = useMemo(() => {
const list: Array<EmoticonSearchItem> = [];
- return list
- .concat(
- imagePacks.flatMap((pack) => pack.getImagesFor(PackUsage.Emoticon)),
- emojis
- )
+ return list.concat(
+ imagePacks.flatMap((pack) => pack.getImages(ImageUsage.Emoticon)),
+ emojis
+ );
}, [imagePacks]);
const [result, search, resetSearch] = useAsyncSearch(searchList, getEmoticonStr, SEARCH_OPTIONS);
- const autoCompleteEmoticon = (result ? result.items : recentEmoji)
- .sort((a, b) => a.shortcode.localeCompare(b.shortcode));
+ const autoCompleteEmoticon = (result ? result.items : recentEmoji).sort((a, b) =>
+ a.shortcode.localeCompare(b.shortcode)
+ );
useEffect(() => {
if (query.text) search(query.text);
import { useRelevantImagePacks } from '../../hooks/useImagePacks';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useRecentEmoji } from '../../hooks/useRecentEmoji';
-import { ExtendedPackImage, ImagePack, PackUsage } from '../../plugins/custom-emoji';
import { isUserId, mxcUrlToHttp } from '../../utils/matrix';
import { editableActiveElement, isIntersectingScrollView, targetFromEvent } from '../../utils/dom';
import { useAsyncSearch, UseAsyncSearchOptions } from '../../hooks/useAsyncSearch';
import { addRecentEmoji } from '../../plugins/recent-emoji';
import { mobileOrTablet } from '../../utils/user-agent';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
+import { ImagePack, ImageUsage, PackImageReader } from '../../plugins/custom-emoji';
const RECENT_GROUP_ID = 'recent_group';
const SEARCH_GROUP_ID = 'search_group';
}: {
mx: MatrixClient;
packs: ImagePack[];
- usage: PackUsage;
+ usage: ImageUsage;
onItemClick: (id: string) => void;
useAuthentication?: boolean;
}) {
const activeGroupId = useAtomValue(activeGroupIdAtom);
return (
<SidebarStack>
- {usage === PackUsage.Emoticon && <SidebarDivider />}
+ {usage === ImageUsage.Emoticon && <SidebarDivider />}
{packs.map((pack) => {
- let label = pack.displayName;
+ let label = pack.meta.name;
if (!label) label = isUserId(pack.id) ? 'Personal Pack' : mx.getRoom(pack.id)?.name;
return (
<SidebarBtn
height: toRem(24),
objectFit: 'contain',
}}
- src={mxcUrlToHttp(mx, pack.getPackAvatarUrl(usage) ?? '', useAuthentication) || pack.avatarUrl}
+ src={
+ mxcUrlToHttp(mx, pack.getAvatarUrl(usage) ?? '', useAuthentication) ||
+ pack.meta.avatar
+ }
alt={label || 'Unknown Pack'}
/>
</SidebarBtn>
tab: EmojiBoardTab;
label: string;
id: string;
- emojis: Array<ExtendedPackImage | IEmoji>;
+ emojis: Array<PackImageReader | IEmoji>;
useAuthentication?: boolean;
}) {
return (
<EmojiGroup key={id} id={id} label={label}>
{tab === EmojiBoardTab.Emoji
- ? searchResult.sort((a, b) => a.shortcode.localeCompare(b.shortcode)).map((emoji) =>
- 'unicode' in emoji ? (
- <EmojiItem
- key={emoji.unicode}
- label={emoji.label}
- type={EmojiType.Emoji}
- data={emoji.unicode}
- shortcode={emoji.shortcode}
- >
- {emoji.unicode}
- </EmojiItem>
- ) : (
- <EmojiItem
- key={emoji.shortcode}
- label={emoji.body || emoji.shortcode}
- type={EmojiType.CustomEmoji}
- data={emoji.url}
- shortcode={emoji.shortcode}
- >
- <img
- loading="lazy"
- className={css.CustomEmojiImg}
- alt={emoji.body || emoji.shortcode}
- src={mxcUrlToHttp(mx, emoji.url, useAuthentication) ?? emoji.url}
- />
- </EmojiItem>
- )
- )
+ ? searchResult
+ .sort((a, b) => a.shortcode.localeCompare(b.shortcode))
+ .map((emoji) =>
+ 'unicode' in emoji ? (
+ <EmojiItem
+ key={emoji.unicode}
+ label={emoji.label}
+ type={EmojiType.Emoji}
+ data={emoji.unicode}
+ shortcode={emoji.shortcode}
+ >
+ {emoji.unicode}
+ </EmojiItem>
+ ) : (
+ <EmojiItem
+ key={emoji.shortcode}
+ label={emoji.body || emoji.shortcode}
+ type={EmojiType.CustomEmoji}
+ data={emoji.url}
+ shortcode={emoji.shortcode}
+ >
+ <img
+ loading="lazy"
+ className={css.CustomEmojiImg}
+ alt={emoji.body || emoji.shortcode}
+ src={mxcUrlToHttp(mx, emoji.url, useAuthentication) ?? emoji.url}
+ />
+ </EmojiItem>
+ )
+ )
: searchResult.map((emoji) =>
- 'unicode' in emoji ? null : (
- <StickerItem
- key={emoji.shortcode}
- label={emoji.body || emoji.shortcode}
- type={EmojiType.Sticker}
- data={emoji.url}
- shortcode={emoji.shortcode}
- >
- <img
- loading="lazy"
- className={css.StickerImg}
- alt={emoji.body || emoji.shortcode}
- src={mxcUrlToHttp(mx, emoji.url, useAuthentication) ?? emoji.url}
- />
- </StickerItem>
- )
- )}
+ 'unicode' in emoji ? null : (
+ <StickerItem
+ key={emoji.shortcode}
+ label={emoji.body || emoji.shortcode}
+ type={EmojiType.Sticker}
+ data={emoji.url}
+ shortcode={emoji.shortcode}
+ >
+ <img
+ loading="lazy"
+ className={css.StickerImg}
+ alt={emoji.body || emoji.shortcode}
+ src={mxcUrlToHttp(mx, emoji.url, useAuthentication) ?? emoji.url}
+ />
+ </StickerItem>
+ )
+ )}
</EmojiGroup>
);
}
export const CustomEmojiGroups = memo(
- ({ mx, groups, useAuthentication }: { mx: MatrixClient; groups: ImagePack[]; useAuthentication?: boolean }) => (
+ ({
+ mx,
+ groups,
+ useAuthentication,
+ }: {
+ mx: MatrixClient;
+ groups: ImagePack[];
+ useAuthentication?: boolean;
+ }) => (
<>
{groups.map((pack) => (
- <EmojiGroup key={pack.id} id={pack.id} label={pack.displayName || 'Unknown'}>
- {pack.getEmojis().sort((a, b) => a.shortcode.localeCompare(b.shortcode)).map((image) => (
- <EmojiItem
- key={image.shortcode}
- label={image.body || image.shortcode}
- type={EmojiType.CustomEmoji}
- data={image.url}
- shortcode={image.shortcode}
- >
- <img
- loading="lazy"
- className={css.CustomEmojiImg}
- alt={image.body || image.shortcode}
- src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? image.url}
- />
- </EmojiItem>
- ))}
+ <EmojiGroup key={pack.id} id={pack.id} label={pack.meta.name || 'Unknown'}>
+ {pack
+ .getImages(ImageUsage.Emoticon)
+ .sort((a, b) => a.shortcode.localeCompare(b.shortcode))
+ .map((image) => (
+ <EmojiItem
+ key={image.shortcode}
+ label={image.body || image.shortcode}
+ type={EmojiType.CustomEmoji}
+ data={image.url}
+ shortcode={image.shortcode}
+ >
+ <img
+ loading="lazy"
+ className={css.CustomEmojiImg}
+ alt={image.body || image.shortcode}
+ src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? image.url}
+ />
+ </EmojiItem>
+ ))}
</EmojiGroup>
))}
</>
)
);
-export const StickerGroups = memo(({ mx, groups, useAuthentication }: { mx: MatrixClient; groups: ImagePack[]; useAuthentication?: boolean }) => (
- <>
- {groups.length === 0 && (
- <Box
- style={{ padding: `${toRem(60)} ${config.space.S500}` }}
- alignItems="Center"
- justifyContent="Center"
- direction="Column"
- gap="300"
- >
- <Icon size="600" src={Icons.Sticker} />
- <Box direction="Inherit">
- <Text align="Center">No Sticker Packs!</Text>
- <Text priority="300" align="Center" size="T200">
- Add stickers from user, room or space settings.
- </Text>
+export const StickerGroups = memo(
+ ({
+ mx,
+ groups,
+ useAuthentication,
+ }: {
+ mx: MatrixClient;
+ groups: ImagePack[];
+ useAuthentication?: boolean;
+ }) => (
+ <>
+ {groups.length === 0 && (
+ <Box
+ style={{ padding: `${toRem(60)} ${config.space.S500}` }}
+ alignItems="Center"
+ justifyContent="Center"
+ direction="Column"
+ gap="300"
+ >
+ <Icon size="600" src={Icons.Sticker} />
+ <Box direction="Inherit">
+ <Text align="Center">No Sticker Packs!</Text>
+ <Text priority="300" align="Center" size="T200">
+ Add stickers from user, room or space settings.
+ </Text>
+ </Box>
</Box>
- </Box>
- )}
- {groups.map((pack) => (
- <EmojiGroup key={pack.id} id={pack.id} label={pack.displayName || 'Unknown'}>
- {pack.getStickers().sort((a, b) => a.shortcode.localeCompare(b.shortcode)).map((image) => (
- <StickerItem
- key={image.shortcode}
- label={image.body || image.shortcode}
- type={EmojiType.Sticker}
- data={image.url}
- shortcode={image.shortcode}
- >
- <img
- loading="lazy"
- className={css.StickerImg}
- alt={image.body || image.shortcode}
- src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? image.url}
- />
- </StickerItem>
- ))}
- </EmojiGroup>
- ))}
- </>
-));
+ )}
+ {groups.map((pack) => (
+ <EmojiGroup key={pack.id} id={pack.id} label={pack.meta.name || 'Unknown'}>
+ {pack
+ .getImages(ImageUsage.Sticker)
+ .sort((a, b) => a.shortcode.localeCompare(b.shortcode))
+ .map((image) => (
+ <StickerItem
+ key={image.shortcode}
+ label={image.body || image.shortcode}
+ type={EmojiType.Sticker}
+ data={image.url}
+ shortcode={image.shortcode}
+ >
+ <img
+ loading="lazy"
+ className={css.StickerImg}
+ alt={image.body || image.shortcode}
+ src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? image.url}
+ />
+ </StickerItem>
+ ))}
+ </EmojiGroup>
+ ))}
+ </>
+ )
+);
export const NativeEmojiGroups = memo(
({ groups, labels }: { groups: IEmojiGroup[]; labels: IEmojiGroupLabels }) => (
)
);
-const getSearchListItemStr = (item: ExtendedPackImage | IEmoji) => {
+const getSearchListItemStr = (item: PackImageReader | IEmoji) => {
const shortcode = `:${item.shortcode}:`;
if ('body' in item) {
return [shortcode, item.body ?? ''];
}) {
const emojiTab = tab === EmojiBoardTab.Emoji;
const stickerTab = tab === EmojiBoardTab.Sticker;
- const usage = emojiTab ? PackUsage.Emoticon : PackUsage.Sticker;
+ const usage = emojiTab ? ImageUsage.Emoticon : ImageUsage.Sticker;
const setActiveGroupId = useSetAtom(activeGroupIdAtom);
const mx = useMatrixClient();
const useAuthentication = useMediaAuthentication();
const emojiGroupLabels = useEmojiGroupLabels();
const emojiGroupIcons = useEmojiGroupIcons();
- const imagePacks = useRelevantImagePacks(mx, usage, imagePackRooms);
+ const imagePacks = useRelevantImagePacks(usage, imagePackRooms);
const recentEmojis = useRecentEmoji(mx, 21);
const contentScrollRef = useRef<HTMLDivElement>(null);
const emojiPreviewTextRef = useRef<HTMLParagraphElement>(null);
const searchList = useMemo(() => {
- let list: Array<ExtendedPackImage | IEmoji> = [];
- list = list.concat(imagePacks.flatMap((pack) => pack.getImagesFor(usage)));
+ let list: Array<PackImageReader | IEmoji> = [];
+ list = list.concat(imagePacks.flatMap((pack) => pack.getImages(usage)));
if (emojiTab) list = list.concat(emojis);
return list;
}, [emojiTab, usage, imagePacks]);
const syncActiveGroupId = useCallback(() => {
const targetEl = contentScrollRef.current;
if (!targetEl) return;
- const groupEls = [...targetEl.querySelectorAll('div[data-group-id]')] as HTMLElement[];
+ const groupEls = Array.from(targetEl.querySelectorAll('div[data-group-id]')) as HTMLElement[];
const groupEl = groupEls.find((el) => isIntersectingScrollView(targetEl, el));
const groupId = groupEl?.getAttribute('data-group-id') ?? undefined;
setActiveGroupId(groupId);
} else if (emojiInfo.type === EmojiType.CustomEmoji && emojiPreviewRef.current) {
const img = document.createElement('img');
img.className = css.CustomEmojiImg;
- img.setAttribute('src', mxcUrlToHttp(mx, emojiInfo.data, useAuthentication) || emojiInfo.data);
+ img.setAttribute(
+ 'src',
+ mxcUrlToHttp(mx, emojiInfo.data, useAuthentication) || emojiInfo.data
+ );
img.setAttribute('alt', emojiInfo.shortcode);
emojiPreviewRef.current.textContent = '';
emojiPreviewRef.current.appendChild(img);
{emojiTab && recentEmojis.length > 0 && (
<RecentEmojiGroup id={RECENT_GROUP_ID} label="Recent" emojis={recentEmojis} />
)}
- {emojiTab && <CustomEmojiGroups mx={mx} groups={imagePacks} useAuthentication={useAuthentication} />}
- {stickerTab && <StickerGroups mx={mx} groups={imagePacks} useAuthentication={useAuthentication} />}
+ {emojiTab && (
+ <CustomEmojiGroups
+ mx={mx}
+ groups={imagePacks}
+ useAuthentication={useAuthentication}
+ />
+ )}
+ {stickerTab && (
+ <StickerGroups mx={mx} groups={imagePacks} useAuthentication={useAuthentication} />
+ )}
{emojiTab && <NativeEmojiGroups groups={emojiGroups} labels={emojiGroupLabels} />}
</Box>
</Scroll>
--- /dev/null
+import { style } from '@vanilla-extract/css';
+import { DefaultReset, color, config } from 'folds';
+
+export const ImageEditor = style([
+ DefaultReset,
+ {
+ height: '100%',
+ },
+]);
+
+export const ImageEditorHeader = style([
+ DefaultReset,
+ {
+ paddingLeft: config.space.S200,
+ paddingRight: config.space.S200,
+ borderBottomWidth: config.borderWidth.B300,
+ flexShrink: 0,
+ gap: config.space.S200,
+ },
+]);
+
+export const ImageEditorContent = style([
+ DefaultReset,
+ {
+ backgroundColor: color.Background.Container,
+ color: color.Background.OnContainer,
+ overflow: 'hidden',
+ },
+]);
+
+export const Image = style({
+ width: '100%',
+ height: '100%',
+ objectFit: 'contain',
+});
--- /dev/null
+import React from 'react';
+import classNames from 'classnames';
+import { Box, Chip, Header, Icon, IconButton, Icons, Text, as } from 'folds';
+import * as css from './ImageEditor.css';
+
+export type ImageEditorProps = {
+ name: string;
+ url: string;
+ requestClose: () => void;
+};
+
+export const ImageEditor = as<'div', ImageEditorProps>(
+ ({ className, name, url, requestClose, ...props }, ref) => {
+ const handleApply = () => {
+ //
+ };
+
+ return (
+ <Box
+ className={classNames(css.ImageEditor, className)}
+ direction="Column"
+ {...props}
+ ref={ref}
+ >
+ <Header className={css.ImageEditorHeader} size="400">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <IconButton size="300" radii="300" onClick={requestClose}>
+ <Icon size="50" src={Icons.ArrowLeft} />
+ </IconButton>
+ <Text size="T300" truncate>
+ Image Editor
+ </Text>
+ </Box>
+ <Box shrink="No" alignItems="Center" gap="200">
+ <Chip variant="Primary" radii="300" onClick={handleApply}>
+ <Text size="B300">Save</Text>
+ </Chip>
+ </Box>
+ </Header>
+ <Box
+ grow="Yes"
+ className={css.ImageEditorContent}
+ justifyContent="Center"
+ alignItems="Center"
+ >
+ <img className={css.Image} src={url} alt={name} />
+ </Box>
+ </Box>
+ );
+ }
+);
--- /dev/null
+export * from './ImageEditor';
--- /dev/null
+import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import { as, Box, Text, config, Button, Menu, Spinner } from 'folds';
+import {
+ ImagePack,
+ ImageUsage,
+ PackContent,
+ PackImage,
+ PackImageReader,
+ packMetaEqual,
+ PackMetaReader,
+} from '../../plugins/custom-emoji';
+import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
+import { SequenceCard } from '../sequence-card';
+import { ImageTile, ImageTileEdit, ImageTileUpload } from './ImageTile';
+import { SettingTile } from '../setting-tile';
+import { UsageSwitcher } from './UsageSwitcher';
+import { ImagePackProfile, ImagePackProfileEdit } from './PackMeta';
+import * as css from './style.css';
+import { useFilePicker } from '../../hooks/useFilePicker';
+import { CompactUploadCardRenderer } from '../upload-card';
+import { UploadSuccess } from '../../state/upload';
+import { getImageInfo, TUploadContent } from '../../utils/matrix';
+import { getImageFileUrl, loadImageElement, renameFile } from '../../utils/dom';
+import { replaceSpaceWithDash, suffixRename } from '../../utils/common';
+import { getFileNameWithoutExt } from '../../utils/mimeTypes';
+import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
+
+export type ImagePackContentProps = {
+ imagePack: ImagePack;
+ canEdit?: boolean;
+ onUpdate?: (packContent: PackContent) => Promise<void>;
+};
+
+export const ImagePackContent = as<'div', ImagePackContentProps>(
+ ({ imagePack, canEdit, onUpdate, ...props }, ref) => {
+ const useAuthentication = useMediaAuthentication();
+
+ const [metaEditing, setMetaEditing] = useState(false);
+ const [savedMeta, setSavedMeta] = useState<PackMetaReader>();
+ const currentMeta = savedMeta ?? imagePack.meta;
+
+ const images = useMemo(() => Array.from(imagePack.images.collection.values()), [imagePack]);
+ const [files, setFiles] = useState<File[]>([]);
+ const [uploadedImages, setUploadedImages] = useState<PackImageReader[]>([]);
+ const [imagesEditing, setImagesEditing] = useState<Set<string>>(new Set());
+ const [savedImages, setSavedImages] = useState<Map<string, PackImageReader>>(new Map());
+ const [deleteImages, setDeleteImages] = useState<Set<string>>(new Set());
+
+ const hasImageWithShortcode = useCallback(
+ (shortcode: string): boolean => {
+ const hasInPack = imagePack.images.collection.has(shortcode);
+ if (hasInPack) return true;
+ const hasInUploaded =
+ uploadedImages.find((img) => img.shortcode === shortcode) !== undefined;
+ if (hasInUploaded) return true;
+ const hasInSaved =
+ Array.from(savedImages).find(([, img]) => img.shortcode === shortcode) !== undefined;
+ return hasInSaved;
+ },
+ [imagePack, savedImages, uploadedImages]
+ );
+
+ const pickFiles = useFilePicker(
+ useCallback(
+ (pickedFiles: File[]) => {
+ const uniqueFiles = pickedFiles.map((file) => {
+ const fileName = replaceSpaceWithDash(file.name);
+ if (hasImageWithShortcode(fileName)) {
+ const uniqueName = suffixRename(fileName, hasImageWithShortcode);
+ return renameFile(file, uniqueName);
+ }
+ return fileName !== file.name ? renameFile(file, fileName) : file;
+ });
+
+ setFiles((f) => [...f, ...uniqueFiles]);
+ },
+ [hasImageWithShortcode]
+ ),
+ true
+ );
+
+ const handleMetaSave = useCallback(
+ (editedMeta: PackMetaReader) => {
+ setMetaEditing(false);
+ setSavedMeta(
+ (m) =>
+ new PackMetaReader({
+ ...imagePack.meta.content,
+ ...m?.content,
+ ...editedMeta.content,
+ })
+ );
+ },
+ [imagePack.meta]
+ );
+
+ const handleMetaCancel = () => setMetaEditing(false);
+
+ const handlePackUsageChange = useCallback(
+ (usg: ImageUsage[]) => {
+ setSavedMeta(
+ (m) =>
+ new PackMetaReader({
+ ...imagePack.meta.content,
+ ...m?.content,
+ usage: usg,
+ })
+ );
+ },
+ [imagePack.meta]
+ );
+
+ const handleUploadRemove = useCallback((file: TUploadContent) => {
+ setFiles((fs) => fs.filter((f) => f !== file));
+ }, []);
+
+ const handleUploadComplete = useCallback(
+ async (data: UploadSuccess) => {
+ const imgEl = await loadImageElement(getImageFileUrl(data.file));
+ const packImage: PackImage = {
+ url: data.mxc,
+ info: getImageInfo(imgEl, data.file),
+ };
+ const image = PackImageReader.fromPackImage(
+ getFileNameWithoutExt(data.file.name),
+ packImage
+ );
+ if (!image) return;
+ handleUploadRemove(data.file);
+ setUploadedImages((imgs) => [image, ...imgs]);
+ },
+ [handleUploadRemove]
+ );
+
+ const handleImageEdit = (shortcode: string) => {
+ setImagesEditing((shortcodes) => {
+ const shortcodeSet = new Set(shortcodes);
+ shortcodeSet.add(shortcode);
+ return shortcodeSet;
+ });
+ };
+ const handleDeleteToggle = (shortcode: string) => {
+ setDeleteImages((shortcodes) => {
+ const shortcodeSet = new Set(shortcodes);
+ if (shortcodeSet.has(shortcode)) shortcodeSet.delete(shortcode);
+ else shortcodeSet.add(shortcode);
+ return shortcodeSet;
+ });
+ };
+
+ const handleImageEditCancel = (shortcode: string) => {
+ setImagesEditing((shortcodes) => {
+ const shortcodeSet = new Set(shortcodes);
+ shortcodeSet.delete(shortcode);
+ return shortcodeSet;
+ });
+ };
+
+ const handleImageEditSave = (shortcode: string, image: PackImageReader) => {
+ handleImageEditCancel(shortcode);
+
+ const saveImage =
+ shortcode !== image.shortcode && hasImageWithShortcode(image.shortcode)
+ ? new PackImageReader(
+ suffixRename(image.shortcode, hasImageWithShortcode),
+ image.url,
+ image.content
+ )
+ : image;
+
+ setSavedImages((sImgs) => {
+ const imgs = new Map(sImgs);
+ imgs.set(shortcode, saveImage);
+ return imgs;
+ });
+ };
+
+ const handleResetSavedChanges = () => {
+ setSavedMeta(undefined);
+ setFiles([]);
+ setUploadedImages([]);
+ setSavedImages(new Map());
+ setDeleteImages(new Set());
+ };
+
+ const [applyState, applyChanges] = useAsyncCallback(
+ useCallback(async () => {
+ const pack: PackContent = {
+ pack: savedMeta?.content ?? imagePack.meta.content,
+ images: {},
+ };
+ const pushImage = (img: PackImageReader) => {
+ if (deleteImages.has(img.shortcode)) return;
+ if (!pack.images) return;
+ const imgToPush = savedImages.get(img.shortcode) ?? img;
+ pack.images[imgToPush.shortcode] = imgToPush.content;
+ };
+ uploadedImages.forEach((img) => pushImage(img));
+ images.forEach((img) => pushImage(img));
+
+ return onUpdate?.(pack);
+ }, [imagePack, images, savedMeta, uploadedImages, savedImages, deleteImages, onUpdate])
+ );
+
+ useEffect(() => {
+ if (applyState.status === AsyncStatus.Success) {
+ handleResetSavedChanges();
+ }
+ }, [applyState]);
+
+ const savedChanges =
+ (savedMeta && !packMetaEqual(imagePack.meta, savedMeta)) ||
+ uploadedImages.length > 0 ||
+ savedImages.size > 0 ||
+ deleteImages.size > 0;
+ const canApplyChanges = !metaEditing && imagesEditing.size === 0 && files.length === 0;
+ const applying = applyState.status === AsyncStatus.Loading;
+
+ const renderImage = (image: PackImageReader) => (
+ <SequenceCard
+ key={image.shortcode}
+ style={{ padding: config.space.S300 }}
+ variant={deleteImages.has(image.shortcode) ? 'Critical' : 'SurfaceVariant'}
+ direction="Column"
+ gap="400"
+ >
+ {imagesEditing.has(image.shortcode) ? (
+ <ImageTileEdit
+ defaultShortcode={image.shortcode}
+ image={savedImages.get(image.shortcode) ?? image}
+ packUsage={currentMeta.usage}
+ useAuthentication={useAuthentication}
+ onCancel={handleImageEditCancel}
+ onSave={handleImageEditSave}
+ />
+ ) : (
+ <ImageTile
+ defaultShortcode={image.shortcode}
+ image={savedImages.get(image.shortcode) ?? image}
+ packUsage={currentMeta.usage}
+ useAuthentication={useAuthentication}
+ canEdit={canEdit}
+ onEdit={handleImageEdit}
+ deleted={deleteImages.has(image.shortcode)}
+ onDeleteToggle={handleDeleteToggle}
+ />
+ )}
+ </SequenceCard>
+ );
+
+ return (
+ <Box grow="Yes" direction="Column" gap="700" {...props} ref={ref}>
+ {savedChanges && (
+ <Menu className={css.UnsavedMenu} variant="Success">
+ <Box alignItems="Center" gap="400">
+ <Box grow="Yes" direction="Column">
+ {applyState.status === AsyncStatus.Error ? (
+ <Text size="T200">
+ <b>Failed to apply changes! Please try again.</b>
+ </Text>
+ ) : (
+ <Text size="T200">
+ <b>Changes saved! Apply when ready.</b>
+ </Text>
+ )}
+ </Box>
+ <Box shrink="No" gap="200">
+ <Button
+ size="300"
+ variant="Success"
+ fill="None"
+ radii="300"
+ disabled={!canApplyChanges || applying}
+ onClick={handleResetSavedChanges}
+ >
+ <Text size="B300">Reset</Text>
+ </Button>
+ <Button
+ size="300"
+ variant="Success"
+ radii="300"
+ disabled={!canApplyChanges || applying}
+ before={applying && <Spinner variant="Success" fill="Solid" size="100" />}
+ onClick={applyChanges}
+ >
+ <Text size="B300">Apply Changes</Text>
+ </Button>
+ </Box>
+ </Box>
+ </Menu>
+ )}
+ <Box direction="Column" gap="100">
+ <Text size="L400">Pack</Text>
+ <SequenceCard
+ style={{ padding: config.space.S300 }}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ {metaEditing ? (
+ <ImagePackProfileEdit
+ meta={currentMeta}
+ onCancel={handleMetaCancel}
+ onSave={handleMetaSave}
+ />
+ ) : (
+ <ImagePackProfile
+ meta={currentMeta}
+ canEdit={canEdit}
+ onEdit={() => setMetaEditing(true)}
+ />
+ )}
+ </SequenceCard>
+ <SequenceCard
+ style={{ padding: config.space.S300 }}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Images Usage"
+ description="Select how the images are being used: as emojis, as stickers, or as both."
+ after={
+ <UsageSwitcher
+ usage={currentMeta.usage}
+ canEdit={canEdit}
+ onChange={handlePackUsageChange}
+ />
+ }
+ />
+ </SequenceCard>
+ </Box>
+ {images.length === 0 && !canEdit ? null : (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Images</Text>
+ {canEdit && (
+ <SequenceCard
+ style={{ padding: config.space.S300 }}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Upload Images"
+ description="Select images from your storage to upload them in pack."
+ after={
+ <Button
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ type="button"
+ outlined
+ onClick={() => pickFiles('image/*')}
+ >
+ <Text size="B300">Select</Text>
+ </Button>
+ }
+ />
+ </SequenceCard>
+ )}
+ {files.map((file) => (
+ <SequenceCard
+ key={file.name}
+ style={{ padding: config.space.S300 }}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <ImageTileUpload file={file}>
+ {(uploadAtom) => (
+ <CompactUploadCardRenderer
+ uploadAtom={uploadAtom}
+ onRemove={handleUploadRemove}
+ onComplete={handleUploadComplete}
+ />
+ )}
+ </ImageTileUpload>
+ </SequenceCard>
+ ))}
+ {uploadedImages.map(renderImage)}
+ {images.map(renderImage)}
+ </Box>
+ )}
+ </Box>
+ );
+ }
+);
--- /dev/null
+import React from 'react';
+import { Box, IconButton, Text, Icon, Icons, Scroll, Chip } from 'folds';
+import { PackAddress } from '../../plugins/custom-emoji';
+import { Page, PageHeader, PageContent } from '../page';
+import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { RoomImagePack } from './RoomImagePack';
+import { UserImagePack } from './UserImagePack';
+
+type ImagePackViewProps = {
+ address: PackAddress | undefined;
+ requestClose: () => void;
+};
+export function ImagePackView({ address, requestClose }: ImagePackViewProps) {
+ const mx = useMatrixClient();
+ const room = address && mx.getRoom(address.roomId);
+
+ return (
+ <Page>
+ <PageHeader outlined={false} balance>
+ <Box alignItems="Center" grow="Yes" gap="200">
+ <Box alignItems="Inherit" grow="Yes" gap="200">
+ <Chip
+ size="500"
+ radii="Pill"
+ onClick={requestClose}
+ before={<Icon size="100" src={Icons.ArrowLeft} />}
+ >
+ <Text size="T300">Emojis & Stickers</Text>
+ </Chip>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </PageHeader>
+ <Box grow="Yes">
+ <Scroll hideTrack visibility="Hover">
+ <PageContent>
+ {room && address ? (
+ <RoomImagePack room={room} stateKey={address.stateKey} />
+ ) : (
+ <UserImagePack />
+ )}
+ </PageContent>
+ </Scroll>
+ </Box>
+ </Page>
+ );
+}
--- /dev/null
+import React, { FormEventHandler, ReactNode, useMemo, useState } from 'react';
+import { Badge, Box, Button, Chip, Icon, Icons, Input, Text } from 'folds';
+import { UsageSwitcher, useUsageStr } from './UsageSwitcher';
+import { mxcUrlToHttp } from '../../utils/matrix';
+import * as css from './style.css';
+import { ImageUsage, imageUsageEqual, PackImageReader } from '../../plugins/custom-emoji';
+import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { SettingTile } from '../setting-tile';
+import { useObjectURL } from '../../hooks/useObjectURL';
+import { createUploadAtom, TUploadAtom } from '../../state/upload';
+import { replaceSpaceWithDash } from '../../utils/common';
+
+type ImageTileProps = {
+ defaultShortcode: string;
+ useAuthentication: boolean;
+ packUsage: ImageUsage[];
+ image: PackImageReader;
+ canEdit?: boolean;
+ onEdit?: (defaultShortcode: string, image: PackImageReader) => void;
+ deleted?: boolean;
+ onDeleteToggle?: (defaultShortcode: string) => void;
+};
+export function ImageTile({
+ defaultShortcode,
+ image,
+ packUsage,
+ useAuthentication,
+ canEdit,
+ onEdit,
+ onDeleteToggle,
+ deleted,
+}: ImageTileProps) {
+ const mx = useMatrixClient();
+ const getUsageStr = useUsageStr();
+
+ return (
+ <SettingTile
+ before={
+ <img
+ className={css.ImagePackImage}
+ src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? ''}
+ alt={image.shortcode}
+ loading="lazy"
+ />
+ }
+ title={
+ deleted ? (
+ <span className={css.DeleteImageShortcode}>{image.shortcode}</span>
+ ) : (
+ image.shortcode
+ )
+ }
+ description={
+ <Box as="span" gap="200">
+ {image.usage && getUsageStr(image.usage) !== getUsageStr(packUsage) && (
+ <Badge as="span" variant="Secondary" size="400" radii="300" outlined>
+ <Text as="span" size="L400">
+ {getUsageStr(image.usage)}
+ </Text>
+ </Badge>
+ )}
+ {image.body}
+ </Box>
+ }
+ after={
+ canEdit ? (
+ <Box shrink="No" alignItems="Center" gap="200">
+ <Chip
+ variant={deleted ? 'Critical' : 'Secondary'}
+ fill="None"
+ radii="Pill"
+ onClick={() => onDeleteToggle?.(defaultShortcode)}
+ >
+ {deleted ? <Text size="B300">Undo</Text> : <Icon size="50" src={Icons.Delete} />}
+ </Chip>
+ {!deleted && (
+ <Chip
+ variant="Secondary"
+ radii="Pill"
+ onClick={() => onEdit?.(defaultShortcode, image)}
+ >
+ <Text size="B300">Edit</Text>
+ </Chip>
+ )}
+ </Box>
+ ) : undefined
+ }
+ />
+ );
+}
+
+type ImageTileUploadProps = {
+ file: File;
+ children: (uploadAtom: TUploadAtom) => ReactNode;
+};
+export function ImageTileUpload({ file, children }: ImageTileUploadProps) {
+ const url = useObjectURL(file);
+ const uploadAtom = useMemo(() => createUploadAtom(file), [file]);
+
+ return (
+ <SettingTile before={<img className={css.ImagePackImage} src={url} alt={file.name} />}>
+ {children(uploadAtom)}
+ </SettingTile>
+ );
+}
+
+type ImageTileEditProps = {
+ defaultShortcode: string;
+ useAuthentication: boolean;
+ packUsage: ImageUsage[];
+ image: PackImageReader;
+ onCancel: (shortcode: string) => void;
+ onSave: (shortcode: string, image: PackImageReader) => void;
+};
+export function ImageTileEdit({
+ defaultShortcode,
+ useAuthentication,
+ packUsage,
+ image,
+ onCancel,
+ onSave,
+}: ImageTileEditProps) {
+ const mx = useMatrixClient();
+ const defaultUsage = image.usage ?? packUsage;
+
+ const [unsavedUsage, setUnsavedUsages] = useState(defaultUsage);
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const shortcodeInput = target?.shortcodeInput as HTMLInputElement | undefined;
+ const bodyInput = target?.bodyInput as HTMLTextAreaElement | undefined;
+ if (!shortcodeInput || !bodyInput) return;
+
+ const shortcode = replaceSpaceWithDash(shortcodeInput.value.trim());
+ const body = bodyInput.value.trim() || undefined;
+ const usage = unsavedUsage;
+
+ if (!shortcode) return;
+
+ if (
+ shortcode === image.shortcode &&
+ body === image.body &&
+ imageUsageEqual(usage, defaultUsage)
+ ) {
+ onCancel(defaultShortcode);
+ return;
+ }
+
+ const imageReader = new PackImageReader(shortcode, image.url, {
+ info: image.info,
+ body,
+ usage: imageUsageEqual(usage, packUsage) ? undefined : usage,
+ });
+
+ onSave(defaultShortcode, imageReader);
+ };
+
+ return (
+ <SettingTile
+ before={
+ <img
+ className={css.ImagePackImage}
+ src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? ''}
+ alt={image.shortcode}
+ loading="lazy"
+ />
+ }
+ >
+ <Box as="form" onSubmit={handleSubmit} direction="Column" gap="200">
+ <Box direction="Column" className={css.ImagePackImageInputs}>
+ <Input
+ before={<Text size="L400">Shortcode:</Text>}
+ defaultValue={image.shortcode}
+ name="shortcodeInput"
+ variant="Secondary"
+ size="300"
+ radii="0"
+ required
+ autoFocus
+ />
+ <Input
+ before={<Text size="L400">Body:</Text>}
+ defaultValue={image.body}
+ name="bodyInput"
+ variant="Secondary"
+ size="300"
+ radii="0"
+ />
+ </Box>
+ <Box gap="200">
+ <Box shrink="No" direction="Column">
+ <UsageSwitcher usage={unsavedUsage} onChange={setUnsavedUsages} canEdit />
+ </Box>
+ <Box grow="Yes" />
+ <Button type="submit" variant="Success" size="300" radii="300">
+ <Text size="B300">Save</Text>
+ </Button>
+ <Button
+ type="reset"
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ onClick={() => onCancel(defaultShortcode)}
+ >
+ <Text size="B300">Cancel</Text>
+ </Button>
+ </Box>
+ </Box>
+ </SettingTile>
+ );
+}
--- /dev/null
+import React, { FormEventHandler, useCallback, useMemo, useState } from 'react';
+import {
+ Box,
+ Text,
+ Avatar,
+ AvatarImage,
+ AvatarFallback,
+ Button,
+ Icon,
+ Icons,
+ Input,
+ TextArea,
+ Chip,
+} from 'folds';
+import Linkify from 'linkify-react';
+import { mxcUrlToHttp } from '../../utils/matrix';
+import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { nameInitials } from '../../utils/common';
+import { BreakWord } from '../../styles/Text.css';
+import { LINKIFY_OPTS } from '../../plugins/react-custom-html-parser';
+import { ContainerColor } from '../../styles/ContainerColor.css';
+import { useFilePicker } from '../../hooks/useFilePicker';
+import { useObjectURL } from '../../hooks/useObjectURL';
+import { createUploadAtom, UploadSuccess } from '../../state/upload';
+import { CompactUploadCardRenderer } from '../upload-card';
+import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
+import { PackMetaReader } from '../../plugins/custom-emoji';
+
+type ImagePackAvatarProps = {
+ url?: string;
+ name?: string;
+};
+function ImagePackAvatar({ url, name }: ImagePackAvatarProps) {
+ return (
+ <Avatar size="500" className={ContainerColor({ variant: 'Secondary' })}>
+ {url ? (
+ <AvatarImage src={url} alt={name ?? 'Unknown'} />
+ ) : (
+ <AvatarFallback>
+ <Text size="H2">{nameInitials(name ?? 'Unknown')}</Text>
+ </AvatarFallback>
+ )}
+ </Avatar>
+ );
+}
+
+type ImagePackProfileProps = {
+ meta: PackMetaReader;
+ canEdit?: boolean;
+ onEdit?: () => void;
+};
+export function ImagePackProfile({ meta, canEdit, onEdit }: ImagePackProfileProps) {
+ const mx = useMatrixClient();
+ const useAuthentication = useMediaAuthentication();
+ const avatarUrl = meta.avatar
+ ? mxcUrlToHttp(mx, meta.avatar, useAuthentication) ?? undefined
+ : undefined;
+
+ return (
+ <Box gap="400">
+ <Box grow="Yes" direction="Column" gap="300">
+ <Box direction="Column" gap="100">
+ <Text className={BreakWord} size="H5">
+ {meta.name ?? 'Unknown'}
+ </Text>
+ {meta.attribution && (
+ <Text className={BreakWord} size="T200">
+ <Linkify options={LINKIFY_OPTS}>{meta.attribution}</Linkify>
+ </Text>
+ )}
+ </Box>
+ {canEdit && (
+ <Box gap="200">
+ <Chip
+ variant="Secondary"
+ fill="Soft"
+ radii="300"
+ before={<Icon size="50" src={Icons.Pencil} />}
+ onClick={onEdit}
+ outlined
+ >
+ <Text size="B300">Edit</Text>
+ </Chip>
+ </Box>
+ )}
+ </Box>
+ <Box shrink="No">
+ <ImagePackAvatar url={avatarUrl} name={meta.name} />
+ </Box>
+ </Box>
+ );
+}
+
+type ImagePackProfileEditProps = {
+ meta: PackMetaReader;
+ onCancel: () => void;
+ onSave: (meta: PackMetaReader) => void;
+};
+export function ImagePackProfileEdit({ meta, onCancel, onSave }: ImagePackProfileEditProps) {
+ const mx = useMatrixClient();
+ const useAuthentication = useMediaAuthentication();
+ const [avatar, setAvatar] = useState(meta.avatar);
+
+ const avatarUrl = avatar ? mxcUrlToHttp(mx, avatar, useAuthentication) ?? undefined : undefined;
+
+ const [imageFile, setImageFile] = useState<File>();
+ const avatarFileUrl = useObjectURL(imageFile);
+ const uploadingAvatar = avatarFileUrl ? avatar === meta.avatar : false;
+ const uploadAtom = useMemo(() => {
+ if (imageFile) return createUploadAtom(imageFile);
+ return undefined;
+ }, [imageFile]);
+
+ const pickFile = useFilePicker(setImageFile, false);
+
+ const handleRemoveUpload = useCallback(() => {
+ setImageFile(undefined);
+ setAvatar(meta.avatar);
+ }, [meta.avatar]);
+
+ const handleUploaded = useCallback((upload: UploadSuccess) => {
+ setAvatar(upload.mxc);
+ }, []);
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (uploadingAvatar) return;
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const nameInput = target?.nameInput as HTMLInputElement | undefined;
+ const attributionTextArea = target?.attributionTextArea as HTMLTextAreaElement | undefined;
+ if (!nameInput || !attributionTextArea) return;
+
+ const name = nameInput.value.trim();
+ const attribution = attributionTextArea.value.trim();
+ if (!name) return;
+
+ const metaReader = new PackMetaReader({
+ avatar_url: avatar,
+ display_name: name,
+ attribution,
+ });
+ onSave(metaReader);
+ };
+
+ return (
+ <Box as="form" onSubmit={handleSubmit} direction="Column" gap="400">
+ <Box gap="400">
+ <Box grow="Yes" direction="Column" gap="100">
+ <Text size="L400">Pack Avatar</Text>
+ {uploadAtom ? (
+ <Box gap="200" direction="Column">
+ <CompactUploadCardRenderer
+ uploadAtom={uploadAtom}
+ onRemove={handleRemoveUpload}
+ onComplete={handleUploaded}
+ />
+ </Box>
+ ) : (
+ <Box gap="200">
+ <Button
+ type="button"
+ size="300"
+ variant="Secondary"
+ fill="Soft"
+ radii="300"
+ onClick={() => pickFile('image/*')}
+ >
+ <Text size="B300">Upload</Text>
+ </Button>
+ {!avatar && meta.avatar && (
+ <Button
+ type="button"
+ size="300"
+ variant="Success"
+ fill="None"
+ radii="300"
+ onClick={() => setAvatar(meta.avatar)}
+ >
+ <Text size="B300">Reset</Text>
+ </Button>
+ )}
+ {avatar && (
+ <Button
+ type="button"
+ size="300"
+ variant="Critical"
+ fill="None"
+ radii="300"
+ onClick={() => setAvatar(undefined)}
+ >
+ <Text size="B300">Remove</Text>
+ </Button>
+ )}
+ </Box>
+ )}
+ </Box>
+ <Box shrink="No">
+ <ImagePackAvatar url={avatarFileUrl ?? avatarUrl} name={meta.name} />
+ </Box>
+ </Box>
+ <Box direction="Inherit" gap="100">
+ <Text size="L400">Name</Text>
+ <Input name="nameInput" defaultValue={meta.name} variant="Secondary" radii="300" required />
+ </Box>
+ <Box direction="Inherit" gap="100">
+ <Text size="L400">Attribution</Text>
+ <TextArea
+ name="attributionTextArea"
+ defaultValue={meta.attribution}
+ variant="Secondary"
+ radii="300"
+ />
+ </Box>
+ <Box gap="300">
+ <Button type="submit" variant="Success" size="300" radii="300" disabled={uploadingAvatar}>
+ <Text size="B300">Save</Text>
+ </Button>
+ <Button
+ type="reset"
+ onClick={onCancel}
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ >
+ <Text size="B300">Cancel</Text>
+ </Button>
+ </Box>
+ </Box>
+ );
+}
--- /dev/null
+import React, { useCallback, useMemo } from 'react';
+import { Room } from 'matrix-js-sdk';
+import { usePowerLevels, usePowerLevelsAPI } from '../../hooks/usePowerLevels';
+import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { ImagePackContent } from './ImagePackContent';
+import { ImagePack, PackContent } from '../../plugins/custom-emoji';
+import { StateEvent } from '../../../types/matrix/room';
+import { useRoomImagePack } from '../../hooks/useImagePacks';
+import { randomStr } from '../../utils/common';
+
+type RoomImagePackProps = {
+ room: Room;
+ stateKey: string;
+};
+
+export function RoomImagePack({ room, stateKey }: RoomImagePackProps) {
+ const mx = useMatrixClient();
+ const userId = mx.getUserId()!;
+ const powerLevels = usePowerLevels(room);
+
+ const { getPowerLevel, canSendStateEvent } = usePowerLevelsAPI(powerLevels);
+ const canEditImagePack = canSendStateEvent(StateEvent.PoniesRoomEmotes, getPowerLevel(userId));
+
+ const fallbackPack = useMemo(() => {
+ const fakePackId = randomStr(4);
+ return new ImagePack(
+ fakePackId,
+ {},
+ {
+ roomId: room.roomId,
+ stateKey,
+ }
+ );
+ }, [room.roomId, stateKey]);
+ const imagePack = useRoomImagePack(room, stateKey) ?? fallbackPack;
+
+ const handleUpdate = useCallback(
+ async (packContent: PackContent) => {
+ const { address } = imagePack;
+ if (!address) return;
+
+ await mx.sendStateEvent(
+ address.roomId,
+ StateEvent.PoniesRoomEmotes,
+ packContent,
+ address.stateKey
+ );
+ },
+ [mx, imagePack]
+ );
+
+ return (
+ <ImagePackContent imagePack={imagePack} canEdit={canEditImagePack} onUpdate={handleUpdate} />
+ );
+}
--- /dev/null
+import React, { MouseEventHandler, useMemo, useState } from 'react';
+import { Box, Button, config, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text } from 'folds';
+import FocusTrap from 'focus-trap-react';
+import { ImageUsage } from '../../plugins/custom-emoji';
+import { stopPropagation } from '../../utils/keyboard';
+
+export const useUsageStr = (): ((usage: ImageUsage[]) => string) => {
+ const getUsageStr = (usage: ImageUsage[]): string => {
+ const sticker = usage.includes(ImageUsage.Sticker);
+ const emoticon = usage.includes(ImageUsage.Emoticon);
+
+ if (sticker && emoticon) return 'Both';
+ if (sticker) return 'Sticker';
+ if (emoticon) return 'Emoji';
+ return 'Both';
+ };
+ return getUsageStr;
+};
+
+type UsageSelectorProps = {
+ selected: ImageUsage[];
+ onChange: (usage: ImageUsage[]) => void;
+};
+export function UsageSelector({ selected, onChange }: UsageSelectorProps) {
+ const getUsageStr = useUsageStr();
+
+ const selectedUsageStr = getUsageStr(selected);
+ const isSelected = (usage: ImageUsage[]) => getUsageStr(usage) === selectedUsageStr;
+
+ const allUsages: ImageUsage[][] = useMemo(
+ () => [[ImageUsage.Emoticon], [ImageUsage.Sticker], [ImageUsage.Sticker, ImageUsage.Emoticon]],
+ []
+ );
+
+ return (
+ <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
+ {allUsages.map((usage) => (
+ <MenuItem
+ key={getUsageStr(usage)}
+ size="300"
+ variant={isSelected(usage) ? 'SurfaceVariant' : 'Surface'}
+ aria-selected={isSelected(usage)}
+ radii="300"
+ onClick={() => onChange(usage)}
+ >
+ <Box grow="Yes">
+ <Text size="T300">{getUsageStr(usage)}</Text>
+ </Box>
+ </MenuItem>
+ ))}
+ </Box>
+ );
+}
+
+type UsageSwitcherProps = {
+ usage: ImageUsage[];
+ canEdit?: boolean;
+ onChange: (usage: ImageUsage[]) => void;
+};
+export function UsageSwitcher({ usage, onChange, canEdit }: UsageSwitcherProps) {
+ const getUsageStr = useUsageStr();
+
+ const [menuCords, setMenuCords] = useState<RectCords>();
+
+ const handleSelectUsage: MouseEventHandler<HTMLButtonElement> = (event) => {
+ setMenuCords(event.currentTarget.getBoundingClientRect());
+ };
+
+ return (
+ <>
+ <Button
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ type="button"
+ outlined
+ aria-disabled={!canEdit}
+ after={canEdit && <Icon src={Icons.ChevronBottom} size="100" />}
+ onClick={canEdit ? handleSelectUsage : undefined}
+ >
+ <Text size="B300">{getUsageStr(usage)}</Text>
+ </Button>
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu>
+ <UsageSelector
+ selected={usage}
+ onChange={(usg) => {
+ setMenuCords(undefined);
+ onChange(usg);
+ }}
+ />
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ </>
+ );
+}
--- /dev/null
+import React, { useCallback, useMemo } from 'react';
+import { ImagePackContent } from './ImagePackContent';
+import { ImagePack, PackContent } from '../../plugins/custom-emoji';
+import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { AccountDataEvent } from '../../../types/matrix/accountData';
+import { useUserImagePack } from '../../hooks/useImagePacks';
+
+export function UserImagePack() {
+ const mx = useMatrixClient();
+
+ const defaultPack = useMemo(() => new ImagePack(mx.getUserId() ?? '', {}, undefined), [mx]);
+ const imagePack = useUserImagePack();
+
+ const handleUpdate = useCallback(
+ async (packContent: PackContent) => {
+ await mx.setAccountData(AccountDataEvent.PoniesUserEmotes, packContent);
+ },
+ [mx]
+ );
+
+ return <ImagePackContent imagePack={imagePack ?? defaultPack} canEdit onUpdate={handleUpdate} />;
+}
--- /dev/null
+export * from './ImagePackView';
--- /dev/null
+import { style } from '@vanilla-extract/css';
+import { color, config, DefaultReset, toRem } from 'folds';
+
+export const ImagePackImage = style([
+ DefaultReset,
+ {
+ width: toRem(36),
+ height: toRem(36),
+ objectFit: 'contain',
+ },
+]);
+
+export const DeleteImageShortcode = style([
+ DefaultReset,
+ {
+ color: color.Critical.Main,
+ textDecoration: 'line-through',
+ },
+]);
+
+export const ImagePackImageInputs = style([
+ DefaultReset,
+ {
+ overflow: 'hidden',
+ borderRadius: config.radii.R300,
+ },
+]);
+
+export const UnsavedMenu = style({
+ position: 'sticky',
+ padding: config.space.S200,
+ paddingLeft: config.space.S400,
+ top: config.space.S400,
+ left: config.space.S400,
+ right: 0,
+ zIndex: 1,
+});
--- /dev/null
+import { Box, ContainerColor, Text } from 'folds';
+import React, { ReactNode } from 'react';
+import classNames from 'classnames';
+import { BreakWord } from '../../styles/Text.css';
+import { ContainerColor as ContainerClr } from '../../styles/ContainerColor.css';
+import * as css from './styles.css';
+
+type InfoCardProps = {
+ variant?: ContainerColor;
+ title?: ReactNode;
+ description?: ReactNode;
+ before?: ReactNode;
+ after?: ReactNode;
+ children?: ReactNode;
+};
+export function InfoCard({
+ variant = 'Primary',
+ title,
+ description,
+ before,
+ after,
+ children,
+}: InfoCardProps) {
+ return (
+ <Box
+ direction="Column"
+ className={classNames(css.InfoCard, ContainerClr({ variant }))}
+ gap="300"
+ >
+ <Box gap="200" alignItems="Center">
+ {before && (
+ <Box shrink="No" alignSelf="Start">
+ {before}
+ </Box>
+ )}
+ <Box grow="Yes" direction="Column" gap="100">
+ {title && (
+ <Text size="L400" className={BreakWord}>
+ {title}
+ </Text>
+ )}
+ {description && (
+ <Text size="T200" className={BreakWord}>
+ {description}
+ </Text>
+ )}
+ </Box>
+ {after && <Box shrink="No">{after}</Box>}
+ </Box>
+ {children}
+ </Box>
+ );
+}
--- /dev/null
+export * from './InfoCard';
--- /dev/null
+import { style } from '@vanilla-extract/css';
+import { config } from 'folds';
+
+export const InfoCard = style([
+ {
+ padding: config.space.S200,
+ borderRadius: config.radii.R300,
+ borderWidth: config.borderWidth.B300,
+ },
+]);
import { Box, Icon, IconSrc } from 'folds';
import React, { ReactNode } from 'react';
import { CompactLayout, ModernLayout } from '..';
+import { MessageLayout } from '../../../state/settings';
export type EventContentProps = {
messageLayout: number;
export function EventContent({ messageLayout, time, iconSrc, content }: EventContentProps) {
const beforeJSX = (
<Box gap="300" justifyContent="SpaceBetween" alignItems="Center" grow="Yes">
- {messageLayout === 1 && time}
+ {messageLayout === MessageLayout.Compact && time}
<Box
- grow={messageLayout === 1 ? undefined : 'Yes'}
+ grow={messageLayout === MessageLayout.Compact ? undefined : 'Yes'}
alignItems="Center"
justifyContent="Center"
>
const msgContentJSX = (
<Box justifyContent="SpaceBetween" alignItems="Baseline" gap="200">
{content}
- {messageLayout !== 1 && time}
+ {messageLayout !== MessageLayout.Compact && time}
</Box>
);
- return messageLayout === 1 ? (
+ return messageLayout === MessageLayout.Compact ? (
<CompactLayout before={beforeJSX}>{msgContentJSX}</CompactLayout>
) : (
<ModernLayout before={beforeJSX}>{msgContentJSX}</ModernLayout>
getFileNameExt,
mimeTypeToExt,
} from '../../../utils/mimeTypes';
-import * as css from './style.css';
import { stopPropagation } from '../../../utils/keyboard';
import {
decryptFile,
mxcUrlToHttp,
} from '../../../utils/matrix';
import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
+import { ModalWide } from '../../../styles/Modal.css';
const renderErrorButton = (retry: () => void, text: string) => (
<TooltipProvider
}}
>
<Modal
- className={css.ModalWide}
+ className={ModalWide}
size="500"
onContextMenu={(evt: any) => evt.stopPropagation()}
>
}}
>
<Modal
- className={css.ModalWide}
+ className={ModalWide}
size="500"
onContextMenu={(evt: any) => evt.stopPropagation()}
>
import { stopPropagation } from '../../../utils/keyboard';
import { decryptFile, downloadEncryptedMedia, mxcUrlToHttp } from '../../../utils/matrix';
import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
+import { ModalWide } from '../../../styles/Modal.css';
type RenderViewerProps = {
src: string;
}}
>
<Modal
- className={css.ModalWide}
+ className={ModalWide}
size="500"
onContextMenu={(evt: any) => evt.stopPropagation()}
>
right: config.space.S100,
},
]);
-
-export const ModalWide = style({
- minWidth: '85vw',
- minHeight: '90vh',
-});
type ClientDrawerLayoutProps = {
children: ReactNode;
};
-export function PageNav({ children }: ClientDrawerLayoutProps) {
+export function PageNav({ size, children }: ClientDrawerLayoutProps & css.PageNavVariants) {
const screenSize = useScreenSizeContext();
const isMobile = screenSize === ScreenSize.Mobile;
return (
<Box
grow={isMobile ? 'Yes' : undefined}
- className={css.PageNav}
+ className={css.PageNav({ size })}
shrink={isMobile ? 'Yes' : 'No'}
>
<Box grow="Yes" direction="Column">
);
}
-export const PageNavHeader = as<'header'>(({ className, ...props }, ref) => (
- <Header
- className={classNames(css.PageNavHeader, className)}
- variant="Background"
- size="600"
- {...props}
- ref={ref}
- />
-));
+export const PageNavHeader = as<'header', css.PageNavHeaderVariants>(
+ ({ className, outlined, ...props }, ref) => (
+ <Header
+ className={classNames(css.PageNavHeader({ outlined }), className)}
+ variant="Background"
+ size="600"
+ {...props}
+ ref={ref}
+ />
+ )
+);
export function PageNavContent({
scrollRef,
));
export const PageHeader = as<'div', css.PageHeaderVariants>(
- ({ className, balance, ...props }, ref) => (
+ ({ className, outlined, balance, ...props }, ref) => (
<Header
as="header"
size="600"
- className={classNames(css.PageHeader({ balance }), className)}
+ className={classNames(css.PageHeader({ balance, outlined }), className)}
{...props}
ref={ref}
/>
import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
import { DefaultReset, color, config, toRem } from 'folds';
-export const PageNav = style({
- width: toRem(256),
+export const PageNav = recipe({
+ variants: {
+ size: {
+ '400': {
+ width: toRem(256),
+ },
+ '300': {
+ width: toRem(222),
+ },
+ },
+ },
+ defaultVariants: {
+ size: '400',
+ },
});
+export type PageNavVariants = RecipeVariants<typeof PageNav>;
-export const PageNavHeader = style({
- padding: `0 ${config.space.S200} 0 ${config.space.S300}`,
- flexShrink: 0,
- borderBottomWidth: 1,
-
- selectors: {
- 'button&': {
- cursor: 'pointer',
- },
- 'button&[aria-pressed=true]': {
- backgroundColor: color.Background.ContainerActive,
- },
- 'button&:hover, button&:focus-visible': {
- backgroundColor: color.Background.ContainerHover,
+export const PageNavHeader = recipe({
+ base: {
+ padding: `0 ${config.space.S200} 0 ${config.space.S300}`,
+ flexShrink: 0,
+ selectors: {
+ 'button&': {
+ cursor: 'pointer',
+ },
+ 'button&[aria-pressed=true]': {
+ backgroundColor: color.Background.ContainerActive,
+ },
+ 'button&:hover, button&:focus-visible': {
+ backgroundColor: color.Background.ContainerHover,
+ },
+ 'button&:active': {
+ backgroundColor: color.Background.ContainerActive,
+ },
},
- 'button&:active': {
- backgroundColor: color.Background.ContainerActive,
+ },
+
+ variants: {
+ outlined: {
+ true: {
+ borderBottomWidth: 1,
+ },
},
},
+ defaultVariants: {
+ outlined: true,
+ },
});
+export type PageNavHeaderVariants = RecipeVariants<typeof PageNavHeader>;
export const PageNavContent = style({
minHeight: '100%',
base: {
paddingLeft: config.space.S400,
paddingRight: config.space.S200,
- borderBottomWidth: config.borderWidth.B300,
},
variants: {
balance: {
paddingLeft: config.space.S200,
},
},
+ outlined: {
+ true: {
+ borderBottomWidth: config.borderWidth.B300,
+ },
+ },
+ },
+ defaultVariants: {
+ outlined: true,
},
});
export type PageHeaderVariants = RecipeVariants<typeof PageHeader>;
size: '400' | '500';
};
export const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>(
- ({ variant, size, style, after, ...props }, ref) => {
+ ({ variant = 'Background', size, style, after, ...props }, ref) => {
const paddingRight: string = size === '500' ? config.space.S300 : config.space.S200;
return (
--- /dev/null
+export * from './PasswordInput';
--- /dev/null
+import React, { ReactNode } from 'react';
+import { Box, Text } from 'folds';
+import { BreakWord } from '../../styles/Text.css';
+
+type SettingTileProps = {
+ title?: ReactNode;
+ description?: ReactNode;
+ before?: ReactNode;
+ after?: ReactNode;
+ children?: ReactNode;
+};
+export function SettingTile({ title, description, before, after, children }: SettingTileProps) {
+ return (
+ <Box alignItems="Center" gap="300">
+ {before && <Box shrink="No">{before}</Box>}
+ <Box grow="Yes" direction="Column" gap="100">
+ {title && (
+ <Text className={BreakWord} size="T300">
+ {title}
+ </Text>
+ )}
+ {description && (
+ <Text className={BreakWord} size="T200" priority="300">
+ {description}
+ </Text>
+ )}
+ {children}
+ </Box>
+ {after && <Box shrink="No">{after}</Box>}
+ </Box>
+ );
+}
--- /dev/null
+export * from './SettingTile';
--- /dev/null
+import { Box, Button, color, config, Dialog, Header, Icon, IconButton, Icons, Text } from 'folds';
+import React, { FormEventHandler } from 'react';
+import { AuthType } from 'matrix-js-sdk';
+import { StageComponentProps } from './types';
+import { ErrorCode } from '../../cs-errorcode';
+import { PasswordInput } from '../password-input';
+
+export function PasswordStage({
+ stageData,
+ submitAuthDict,
+ onCancel,
+ userId,
+}: StageComponentProps & {
+ userId: string;
+}) {
+ const { errorCode, error, session } = stageData;
+
+ const handleFormSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ const { passwordInput } = evt.target as HTMLFormElement & {
+ passwordInput: HTMLInputElement;
+ };
+ const password = passwordInput.value;
+ if (!password) return;
+ submitAuthDict({
+ type: AuthType.Password,
+ identifier: {
+ type: 'm.id.user',
+ user: userId,
+ },
+ password,
+ session,
+ });
+ };
+
+ return (
+ <Dialog>
+ <Header
+ style={{
+ padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
+ }}
+ variant="Surface"
+ size="500"
+ >
+ <Box grow="Yes">
+ <Text size="H4">Account Password</Text>
+ </Box>
+ <IconButton size="300" onClick={onCancel} radii="300">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Header>
+ <Box
+ as="form"
+ onSubmit={handleFormSubmit}
+ style={{ padding: `0 ${config.space.S400} ${config.space.S400}` }}
+ direction="Column"
+ gap="400"
+ >
+ <Box direction="Column" gap="400">
+ <Text size="T200">
+ To perform this action you need to authenticate yourself by entering you account
+ password.
+ </Text>
+ <Box direction="Column" gap="100">
+ <Text size="L400">Password</Text>
+ <PasswordInput size="400" name="passwordInput" outlined autoFocus required />
+ {errorCode && (
+ <Box alignItems="Center" gap="100" style={{ color: color.Critical.Main }}>
+ <Icon size="50" src={Icons.Warning} filled />
+ <Text size="T200">
+ <b>
+ {errorCode === ErrorCode.M_FORBIDDEN
+ ? 'Invalid Password!'
+ : `${errorCode}: ${error}`}
+ </b>
+ </Text>
+ </Box>
+ )}
+ </Box>
+ </Box>
+ <Button variant="Primary" type="submit">
+ <Text as="span" size="B400">
+ Continue
+ </Text>
+ </Button>
+ </Box>
+ </Dialog>
+ );
+}
--- /dev/null
+import { Box, Button, color, config, Dialog, Header, Icon, IconButton, Icons, Text } from 'folds';
+import React, { useCallback, useEffect, useState } from 'react';
+import { StageComponentProps } from './types';
+
+export function SSOStage({
+ ssoRedirectURL,
+ stageData,
+ submitAuthDict,
+ onCancel,
+}: StageComponentProps & {
+ ssoRedirectURL: string;
+}) {
+ const { errorCode, error, session } = stageData;
+ const [ssoWindow, setSSOWindow] = useState<Window>();
+
+ const handleSubmit = useCallback(() => {
+ submitAuthDict({
+ session,
+ });
+ }, [submitAuthDict, session]);
+
+ const handleContinue = () => {
+ const w = window.open(ssoRedirectURL, '_blank');
+ setSSOWindow(w ?? undefined);
+ };
+
+ useEffect(() => {
+ const handleMessage = (evt: MessageEvent) => {
+ if (ssoWindow && evt.data === 'authDone' && evt.source === ssoWindow) {
+ ssoWindow.close();
+ setSSOWindow(undefined);
+ handleSubmit();
+ }
+ };
+
+ window.addEventListener('message', handleMessage);
+ return () => {
+ window.removeEventListener('message', handleMessage);
+ };
+ }, [ssoWindow, handleSubmit]);
+
+ return (
+ <Dialog>
+ <Header
+ style={{
+ padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
+ }}
+ variant="Surface"
+ size="500"
+ >
+ <Box grow="Yes">
+ <Text size="H4">SSO Login</Text>
+ </Box>
+ <IconButton size="300" onClick={onCancel} radii="300">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Header>
+ <Box
+ style={{ padding: `0 ${config.space.S400} ${config.space.S400}` }}
+ direction="Column"
+ gap="400"
+ >
+ <Text size="T200">
+ To perform this action you need to authenticate yourself by SSO login.
+ </Text>
+ {errorCode && (
+ <Box alignItems="Center" gap="100" style={{ color: color.Critical.Main }}>
+ <Icon size="50" src={Icons.Warning} filled />
+ <Text size="T200">
+ <b>{`${errorCode}: ${error}`}</b>
+ </Text>
+ </Box>
+ )}
+
+ {ssoWindow ? (
+ <Button variant="Primary" onClick={handleSubmit}>
+ <Text as="span" size="B400">
+ Continue
+ </Text>
+ </Button>
+ ) : (
+ <Button variant="Primary" onClick={handleContinue}>
+ <Text as="span" size="B400">
+ Continue with SSO
+ </Text>
+ </Button>
+ )}
+ </Box>
+ </Dialog>
+ );
+}
export * from './types';
export * from './DummyStage';
export * from './EmailStage';
+export * from './PasswordStage';
export * from './ReCaptchaStage';
export * from './RegistrationTokenStage';
+export * from './SSOStage';
export * from './TermsStage';
--- /dev/null
+import React, { useEffect } from 'react';
+import { Chip, Icon, IconButton, Icons, Text, color } from 'folds';
+import { UploadCard, UploadCardError, CompactUploadCardProgress } from './UploadCard';
+import { TUploadAtom, UploadStatus, UploadSuccess, useBindUploadAtom } from '../../state/upload';
+import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { TUploadContent } from '../../utils/matrix';
+import { getFileTypeIcon } from '../../utils/common';
+
+type CompactUploadCardRendererProps = {
+ isEncrypted?: boolean;
+ uploadAtom: TUploadAtom;
+ onRemove: (file: TUploadContent) => void;
+ onComplete?: (upload: UploadSuccess) => void;
+};
+export function CompactUploadCardRenderer({
+ isEncrypted,
+ uploadAtom,
+ onRemove,
+ onComplete,
+}: CompactUploadCardRendererProps) {
+ const mx = useMatrixClient();
+ const { upload, startUpload, cancelUpload } = useBindUploadAtom(mx, uploadAtom, isEncrypted);
+ const { file } = upload;
+
+ if (upload.status === UploadStatus.Idle) startUpload();
+
+ const removeUpload = () => {
+ cancelUpload();
+ onRemove(file);
+ };
+
+ useEffect(() => {
+ if (upload.status === UploadStatus.Success) {
+ onComplete?.(upload);
+ }
+ }, [upload, onComplete]);
+
+ return (
+ <UploadCard
+ compact
+ outlined
+ radii="300"
+ before={<Icon src={getFileTypeIcon(Icons, file.type)} />}
+ after={
+ <>
+ {upload.status === UploadStatus.Error && (
+ <Chip
+ as="button"
+ onClick={startUpload}
+ aria-label="Retry Upload"
+ variant="Critical"
+ radii="Pill"
+ outlined
+ >
+ <Text size="B300">Retry</Text>
+ </Chip>
+ )}
+ <IconButton
+ onClick={removeUpload}
+ aria-label="Cancel Upload"
+ variant="SurfaceVariant"
+ radii="Pill"
+ size="300"
+ >
+ <Icon src={Icons.Cross} size="200" />
+ </IconButton>
+ </>
+ }
+ >
+ {upload.status === UploadStatus.Success ? (
+ <>
+ <Text size="H6" truncate>
+ {file.name}
+ </Text>
+ <Icon style={{ color: color.Success.Main }} src={Icons.Check} size="100" />
+ </>
+ ) : (
+ <>
+ {upload.status === UploadStatus.Idle && (
+ <CompactUploadCardProgress sentBytes={0} totalBytes={file.size} />
+ )}
+ {upload.status === UploadStatus.Loading && (
+ <CompactUploadCardProgress sentBytes={upload.progress.loaded} totalBytes={file.size} />
+ )}
+ {upload.status === UploadStatus.Error && (
+ <UploadCardError>
+ <Text size="T200">{upload.error.message}</Text>
+ </UploadCardError>
+ )}
+ </>
+ )}
+ </UploadCard>
+ );
+}
padding: config.space.S300,
backgroundColor: color.SurfaceVariant.Container,
color: color.SurfaceVariant.OnContainer,
+ borderColor: color.SurfaceVariant.ContainerLine,
},
variants: {
radii: RadiiVariant,
+ outlined: {
+ true: {
+ borderStyle: 'solid',
+ borderWidth: config.borderWidth.B300,
+ },
+ },
+ compact: {
+ true: {
+ padding: config.space.S100,
+ },
+ },
},
defaultVariants: {
radii: '400',
};
export const UploadCard = forwardRef<HTMLDivElement, UploadCardProps & css.UploadCardVariant>(
- ({ before, after, children, bottom, radii }, ref) => (
- <Box className={css.UploadCard({ radii })} direction="Column" gap="200" ref={ref}>
+ ({ before, after, children, bottom, radii, outlined, compact }, ref) => (
+ <Box
+ className={css.UploadCard({ radii, outlined, compact })}
+ direction="Column"
+ gap="200"
+ ref={ref}
+ >
<Box alignItems="Center" gap="200">
{before}
<Box alignItems="Center" grow="Yes" gap="200">
export function UploadCardProgress({ sentBytes, totalBytes }: UploadCardProgressProps) {
return (
- <Box direction="Column" gap="200">
+ <Box grow="Yes" direction="Column" gap="200">
<ProgressBar variant="Secondary" size="300" min={0} max={totalBytes} value={sentBytes} />
<Box alignItems="Center" justifyContent="SpaceBetween">
<Badge variant="Secondary" fill="Solid" radii="Pill">
);
}
+export function CompactUploadCardProgress({ sentBytes, totalBytes }: UploadCardProgressProps) {
+ return (
+ <Box grow="Yes" gap="200" alignItems="Center">
+ <Badge variant="Secondary" fill="Solid" radii="Pill">
+ <Text size="L400">{`${Math.round(percent(0, totalBytes, sentBytes))}%`}</Text>
+ </Badge>
+ <Box grow="Yes" direction="Column">
+ <ProgressBar variant="Secondary" size="300" min={0} max={totalBytes} value={sentBytes} />
+ </Box>
+ <Badge variant="Secondary" fill="Soft" radii="Pill">
+ <Text size="L400">
+ {bytesToSize(sentBytes)} / {bytesToSize(totalBytes)}
+ </Text>
+ </Badge>
+ </Box>
+ );
+}
+
type UploadCardErrorProps = {
children: ReactNode;
};
-import React from 'react';
+import React, { useEffect } from 'react';
import { Chip, Icon, IconButton, Icons, Text, color } from 'folds';
import { UploadCard, UploadCardError, UploadCardProgress } from './UploadCard';
-import { TUploadAtom, UploadStatus, useBindUploadAtom } from '../../state/upload';
+import { TUploadAtom, UploadStatus, UploadSuccess, useBindUploadAtom } from '../../state/upload';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { TUploadContent } from '../../utils/matrix';
import { getFileTypeIcon } from '../../utils/common';
type UploadCardRendererProps = {
- file: TUploadContent;
isEncrypted?: boolean;
uploadAtom: TUploadAtom;
onRemove: (file: TUploadContent) => void;
+ onComplete?: (upload: UploadSuccess) => void;
};
export function UploadCardRenderer({
- file,
isEncrypted,
uploadAtom,
onRemove,
+ onComplete,
}: UploadCardRendererProps) {
const mx = useMatrixClient();
- const { upload, startUpload, cancelUpload } = useBindUploadAtom(
- mx,
- file,
- uploadAtom,
- isEncrypted
- );
+ const { upload, startUpload, cancelUpload } = useBindUploadAtom(mx, uploadAtom, isEncrypted);
+ const { file } = upload;
if (upload.status === UploadStatus.Idle) startUpload();
onRemove(file);
};
+ useEffect(() => {
+ if (upload.status === UploadStatus.Success) {
+ onComplete?.(upload);
+ }
+ }, [upload, onComplete]);
+
return (
<UploadCard
radii="300"
export * from './UploadCard';
export * from './UploadCardRenderer';
+export * from './CompactUploadCardRenderer';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useAtom, useAtomValue } from 'jotai';
import { useNavigate } from 'react-router-dom';
-import { IJoinRuleEventContent, JoinRule, RestrictedAllowType, Room } from 'matrix-js-sdk';
+import { JoinRule, RestrictedAllowType, Room } from 'matrix-js-sdk';
+import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
import { useSpace } from '../../hooks/useSpace';
import { Page, PageContent, PageContentCenter, PageHeroSection } from '../../components/page';
import { HierarchyItem, useSpaceHierarchy } from '../../hooks/useSpaceHierarchy';
const joinRuleContent = getStateEvent(
itemRoom,
StateEvent.RoomJoinRules
- )?.getContent<IJoinRuleEventContent>();
+ )?.getContent<RoomJoinRulesEventContent>();
if (joinRuleContent) {
const allow =
} from '../../components/editor';
import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board';
import { UseStateProvider } from '../../components/UseStateProvider';
-import { TUploadContent, encryptFile, getImageInfo, getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
+import {
+ TUploadContent,
+ encryptFile,
+ getImageInfo,
+ getMxIdLocalPart,
+ mxcUrlToHttp,
+} from '../../utils/matrix';
import { useTypingStatusUpdater } from '../../hooks/useTypingStatusUpdater';
import { useFilePicker } from '../../hooks/useFilePicker';
import { useFilePasteHandler } from '../../hooks/useFilePasteHandler';
const safeFiles = files.map(safeFile);
const fileItems: TUploadItem[] = [];
- if (mx.isRoomEncrypted(roomId)) {
+ if (room.hasEncryptionStateEvent()) {
const encryptFiles = fulfilledPromiseSettledResult(
await Promise.allSettled(safeFiles.map((f) => encryptFile(f)))
);
item: fileItems,
});
},
- [setSelectedFiles, roomId, mx]
+ [setSelectedFiles, room]
);
const pickFile = useFilePicker(handleFiles, true);
const handlePaste = useFilePasteHandler(handleFiles);
<UploadCardRenderer
// eslint-disable-next-line react/no-array-index-key
key={index}
- file={fileItem.file}
isEncrypted={!!fileItem.encInfo}
uploadAtom={roomUploadAtomFamily(fileItem.file)}
onRemove={handleRemoveUpload}
reactionOrEditEvent,
} from '../../utils/room';
import { useSetting } from '../../state/hooks/settings';
-import { settingsAtom } from '../../state/settings';
+import { MessageLayout, settingsAtom } from '../../state/settings';
import { openProfileViewer } from '../../../client/action/navigation';
import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer';
import { Reactions, Message, Event, EncryptedContent } from './message';
backwards ? Direction.Backward : Direction.Forward
) ?? timelineToPaginate;
// Decrypt all event ahead of render cycle
- if (mx.isRoomEncrypted(fetchedTimeline.getRoomId() ?? '')) {
+ const roomId = fetchedTimeline.getRoomId();
+ const room = roomId ? mx.getRoom(roomId) : null;
+
+ if (room?.hasEncryptionStateEvent()) {
await to(decryptAllTimelineEvent(mx, fetchedTimeline));
}
export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimelineProps) {
const mx = useMatrixClient();
const useAuthentication = useMediaAuthentication();
- const encryptedRoom = mx.isRoomEncrypted(room.roomId);
const [messageLayout] = useSetting(settingsAtom, 'messageLayout');
const [messageSpacing] = useSetting(settingsAtom, 'messageSpacing');
const [hideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents');
const [mediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad');
const [urlPreview] = useSetting(settingsAtom, 'urlPreview');
const [encUrlPreview] = useSetting(settingsAtom, 'encUrlPreview');
- const showUrlPreview = encryptedRoom ? encUrlPreview : urlPreview;
+ const showUrlPreview = room.hasEncryptionStateEvent() ? encUrlPreview : urlPreview;
const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents');
const setReplyDraft = useSetAtom(roomIdToReplyDraftAtomFamily(room.roomId));
const powerLevels = usePowerLevelsContext();
urlPreview={showUrlPreview}
htmlReactParserOptions={htmlReactParserOptions}
linkifyOpts={linkifyOpts}
- outlineAttachment={messageLayout === 2}
+ outlineAttachment={messageLayout === MessageLayout.Bubble}
/>
)}
</Message>
urlPreview={showUrlPreview}
htmlReactParserOptions={htmlReactParserOptions}
linkifyOpts={linkifyOpts}
- outlineAttachment={messageLayout === 2}
+ outlineAttachment={messageLayout === MessageLayout.Bubble}
/>
);
}
const highlighted = focusItem?.index === item && focusItem.highlight;
const parsed = parseMemberEvent(mEvent);
- const timeJSX = <Time ts={mEvent.getTs()} compact={messageLayout === 1} />;
+ const timeJSX = (
+ <Time ts={mEvent.getTs()} compact={messageLayout === MessageLayout.Compact} />
+ );
return (
<Event
const senderId = mEvent.getSender() ?? '';
const senderName = getMemberDisplayName(room, senderId) || getMxIdLocalPart(senderId);
- const timeJSX = <Time ts={mEvent.getTs()} compact={messageLayout === 1} />;
+ const timeJSX = (
+ <Time ts={mEvent.getTs()} compact={messageLayout === MessageLayout.Compact} />
+ );
return (
<Event
const senderId = mEvent.getSender() ?? '';
const senderName = getMemberDisplayName(room, senderId) || getMxIdLocalPart(senderId);
- const timeJSX = <Time ts={mEvent.getTs()} compact={messageLayout === 1} />;
+ const timeJSX = (
+ <Time ts={mEvent.getTs()} compact={messageLayout === MessageLayout.Compact} />
+ );
return (
<Event
const senderId = mEvent.getSender() ?? '';
const senderName = getMemberDisplayName(room, senderId) || getMxIdLocalPart(senderId);
- const timeJSX = <Time ts={mEvent.getTs()} compact={messageLayout === 1} />;
+ const timeJSX = (
+ <Time ts={mEvent.getTs()} compact={messageLayout === MessageLayout.Compact} />
+ );
return (
<Event
const senderId = mEvent.getSender() ?? '';
const senderName = getMemberDisplayName(room, senderId) || getMxIdLocalPart(senderId);
- const timeJSX = <Time ts={mEvent.getTs()} compact={messageLayout === 1} />;
+ const timeJSX = (
+ <Time ts={mEvent.getTs()} compact={messageLayout === MessageLayout.Compact} />
+ );
return (
<Event
const senderId = mEvent.getSender() ?? '';
const senderName = getMemberDisplayName(room, senderId) || getMxIdLocalPart(senderId);
- const timeJSX = <Time ts={mEvent.getTs()} compact={messageLayout === 1} />;
+ const timeJSX = (
+ <Time ts={mEvent.getTs()} compact={messageLayout === MessageLayout.Compact} />
+ );
return (
<Event
<div
style={{
padding: `${config.space.S700} ${config.space.S400} ${config.space.S600} ${
- messageLayout === 1 ? config.space.S400 : toRem(64)
+ messageLayout === MessageLayout.Compact ? config.space.S400 : toRem(64)
}`,
}}
>
</div>
)}
{(canPaginateBack || !rangeAtStart) &&
- (messageLayout === 1 ? (
+ (messageLayout === MessageLayout.Compact ? (
<>
<MessageBase>
<CompactPlaceholder key={getItems().length} />
{getItems().map(eventRenderer)}
{(!liveTimelineLinked || !rangeAtEnd) &&
- (messageLayout === 1 ? (
+ (messageLayout === MessageLayout.Compact ? (
<>
<MessageBase ref={observeFrontAnchor}>
<CompactPlaceholder key={getItems().length} />
const headerJSX = !collapse && (
<Box
gap="300"
- direction={messageLayout === 1 ? 'RowReverse' : 'Row'}
+ direction={messageLayout === MessageLayout.Compact ? 'RowReverse' : 'Row'}
justifyContent="SpaceBetween"
alignItems="Baseline"
grow="Yes"
onContextMenu={onUserClick}
onClick={onUsernameClick}
>
- <Text as="span" size={messageLayout === 2 ? 'T300' : 'T400'} truncate>
+ <Text as="span" size={messageLayout === MessageLayout.Bubble ? 'T300' : 'T400'} truncate>
<b>{senderDisplayName}</b>
</Text>
</Username>
<Box shrink="No" gap="100">
- {messageLayout === 0 && hover && (
+ {messageLayout === MessageLayout.Modern && hover && (
<>
<Text as="span" size="T200" priority="300">
{senderId}
</Text>
</>
)}
- <Time ts={mEvent.getTs()} compact={messageLayout === 1} />
+ <Time ts={mEvent.getTs()} compact={messageLayout === MessageLayout.Compact} />
</Box>
</Box>
);
- const avatarJSX = !collapse && messageLayout !== 1 && (
+ const avatarJSX = !collapse && messageLayout !== MessageLayout.Compact && (
<AvatarBase>
<Avatar
className={css.MessageAvatar}
</Menu>
</div>
)}
- {messageLayout === 1 && (
+ {messageLayout === MessageLayout.Compact && (
<CompactLayout before={headerJSX} onContextMenu={handleContextMenu}>
{msgContentJSX}
</CompactLayout>
)}
- {messageLayout === 2 && (
+ {messageLayout === MessageLayout.Bubble && (
<BubbleLayout before={avatarJSX} onContextMenu={handleContextMenu}>
{headerJSX}
{msgContentJSX}
</BubbleLayout>
)}
- {messageLayout !== 1 && messageLayout !== 2 && (
+ {messageLayout !== MessageLayout.Compact && messageLayout !== MessageLayout.Bubble && (
<ModernLayout before={avatarJSX} onContextMenu={handleContextMenu}>
{headerJSX}
{msgContentJSX}
--- /dev/null
+import React, { useMemo, useState } from 'react';
+import {
+ Avatar,
+ Box,
+ Button,
+ config,
+ Icon,
+ IconButton,
+ Icons,
+ IconSrc,
+ MenuItem,
+ Overlay,
+ OverlayBackdrop,
+ OverlayCenter,
+ Text,
+} from 'folds';
+import FocusTrap from 'focus-trap-react';
+import { General } from './general';
+import { PageNav, PageNavContent, PageNavHeader, PageRoot } from '../../components/page';
+import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
+import { Account } from './account';
+import { useUserProfile } from '../../hooks/useUserProfile';
+import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
+import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
+import { UserAvatar } from '../../components/user-avatar';
+import { nameInitials } from '../../utils/common';
+import { Notifications } from './notifications';
+import { Devices } from './devices';
+import { EmojisStickers } from './emojis-stickers';
+import { DeveloperTools } from './developer-tools';
+import { About } from './about';
+import { UseStateProvider } from '../../components/UseStateProvider';
+import { stopPropagation } from '../../utils/keyboard';
+import { LogoutDialog } from '../../components/LogoutDialog';
+
+export enum SettingsPages {
+ GeneralPage,
+ AccountPage,
+ NotificationPage,
+ DevicesPage,
+ EmojisStickersPage,
+ DeveloperToolsPage,
+ AboutPage,
+}
+
+type SettingsMenuItem = {
+ page: SettingsPages;
+ name: string;
+ icon: IconSrc;
+};
+
+const useSettingsMenuItems = (): SettingsMenuItem[] =>
+ useMemo(
+ () => [
+ {
+ page: SettingsPages.GeneralPage,
+ name: 'General',
+ icon: Icons.Setting,
+ },
+ {
+ page: SettingsPages.AccountPage,
+ name: 'Account',
+ icon: Icons.User,
+ },
+ {
+ page: SettingsPages.NotificationPage,
+ name: 'Notifications',
+ icon: Icons.Bell,
+ },
+ {
+ page: SettingsPages.DevicesPage,
+ name: 'Devices',
+ icon: Icons.Category,
+ },
+ {
+ page: SettingsPages.EmojisStickersPage,
+ name: 'Emojis & Stickers',
+ icon: Icons.Smile,
+ },
+ {
+ page: SettingsPages.DeveloperToolsPage,
+ name: 'Developer Tools',
+ icon: Icons.Terminal,
+ },
+ {
+ page: SettingsPages.AboutPage,
+ name: 'About',
+ icon: Icons.Info,
+ },
+ ],
+ []
+ );
+
+type SettingsProps = {
+ initialPage?: SettingsPages;
+ requestClose: () => void;
+};
+export function Settings({ initialPage, requestClose }: SettingsProps) {
+ const mx = useMatrixClient();
+ const useAuthentication = useMediaAuthentication();
+ const userId = mx.getUserId()!;
+ const profile = useUserProfile(userId);
+ const displayName = profile.displayName ?? getMxIdLocalPart(userId) ?? userId;
+ const avatarUrl = profile.avatarUrl
+ ? mxcUrlToHttp(mx, profile.avatarUrl, useAuthentication, 96, 96, 'crop') ?? undefined
+ : undefined;
+
+ const screenSize = useScreenSizeContext();
+ const [activePage, setActivePage] = useState<SettingsPages | undefined>(() => {
+ if (initialPage) return initialPage;
+ return screenSize === ScreenSize.Mobile ? undefined : SettingsPages.GeneralPage;
+ });
+ const menuItems = useSettingsMenuItems();
+
+ const handlePageRequestClose = () => {
+ if (screenSize === ScreenSize.Mobile) {
+ setActivePage(undefined);
+ return;
+ }
+ requestClose();
+ };
+
+ return (
+ <PageRoot
+ nav={
+ screenSize === ScreenSize.Mobile && activePage !== undefined ? undefined : (
+ <PageNav size="300">
+ <PageNavHeader outlined={false}>
+ <Box grow="Yes" gap="200">
+ <Avatar size="200" radii="300">
+ <UserAvatar
+ userId={userId}
+ src={avatarUrl}
+ renderFallback={() => <Text size="H6">{nameInitials(displayName)}</Text>}
+ />
+ </Avatar>
+ <Text size="H4" truncate>
+ Settings
+ </Text>
+ </Box>
+ <Box shrink="No">
+ {screenSize === ScreenSize.Mobile && (
+ <IconButton onClick={requestClose} variant="Background">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ )}
+ </Box>
+ </PageNavHeader>
+ <Box grow="Yes" direction="Column">
+ <PageNavContent>
+ <div style={{ flexGrow: 1 }}>
+ {menuItems.map((item) => (
+ <MenuItem
+ key={item.name}
+ variant="Background"
+ radii="400"
+ aria-pressed={activePage === item.page}
+ before={<Icon src={item.icon} size="100" filled={activePage === item.page} />}
+ onClick={() => setActivePage(item.page)}
+ >
+ <Text
+ style={{
+ fontWeight: activePage === item.page ? config.fontWeight.W600 : undefined,
+ }}
+ size="T300"
+ truncate
+ >
+ {item.name}
+ </Text>
+ </MenuItem>
+ ))}
+ </div>
+ </PageNavContent>
+ <Box style={{ padding: config.space.S200 }} shrink="No" direction="Column">
+ <UseStateProvider initial={false}>
+ {(logout, setLogout) => (
+ <>
+ <Button
+ size="300"
+ variant="Critical"
+ fill="None"
+ radii="Pill"
+ before={<Icon src={Icons.Power} size="100" />}
+ onClick={() => setLogout(true)}
+ >
+ <Text size="B400">Logout</Text>
+ </Button>
+ {logout && (
+ <Overlay open backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ onDeactivate: () => setLogout(false),
+ clickOutsideDeactivates: true,
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <LogoutDialog handleClose={() => setLogout(false)} />
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ )}
+ </>
+ )}
+ </UseStateProvider>
+ </Box>
+ </Box>
+ </PageNav>
+ )
+ }
+ >
+ {activePage === SettingsPages.GeneralPage && (
+ <General requestClose={handlePageRequestClose} />
+ )}
+ {activePage === SettingsPages.AccountPage && (
+ <Account requestClose={handlePageRequestClose} />
+ )}
+ {activePage === SettingsPages.NotificationPage && (
+ <Notifications requestClose={handlePageRequestClose} />
+ )}
+ {activePage === SettingsPages.DevicesPage && (
+ <Devices requestClose={handlePageRequestClose} />
+ )}
+ {activePage === SettingsPages.EmojisStickersPage && (
+ <EmojisStickers requestClose={handlePageRequestClose} />
+ )}
+ {activePage === SettingsPages.DeveloperToolsPage && (
+ <DeveloperTools requestClose={handlePageRequestClose} />
+ )}
+ {activePage === SettingsPages.AboutPage && <About requestClose={handlePageRequestClose} />}
+ </PageRoot>
+ );
+}
--- /dev/null
+import React from 'react';
+import { Box, Text, IconButton, Icon, Icons, Scroll, Button, config, toRem } from 'folds';
+import { Page, PageContent, PageHeader } from '../../../components/page';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import CinnySVG from '../../../../../public/res/svg/cinny.svg';
+import cons from '../../../../client/state/cons';
+import { clearCacheAndReload } from '../../../../client/initMatrix';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+
+type AboutProps = {
+ requestClose: () => void;
+};
+export function About({ requestClose }: AboutProps) {
+ const mx = useMatrixClient();
+
+ return (
+ <Page>
+ <PageHeader outlined={false}>
+ <Box grow="Yes" gap="200">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <Text size="H3" truncate>
+ About
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </PageHeader>
+ <Box grow="Yes">
+ <Scroll hideTrack visibility="Hover">
+ <PageContent>
+ <Box direction="Column" gap="700">
+ <Box gap="400">
+ <Box shrink="No">
+ <img
+ style={{ width: toRem(60), height: toRem(60) }}
+ src={CinnySVG}
+ alt="Cinny logo"
+ />
+ </Box>
+ <Box direction="Column" gap="300">
+ <Box direction="Column" gap="100">
+ <Box gap="100" alignItems="End">
+ <Text size="H3">Cinny</Text>
+ <Text size="T200">v{cons.version}</Text>
+ </Box>
+ <Text>Yet another matrix client.</Text>
+ </Box>
+
+ <Box gap="200" wrap="Wrap">
+ <Button
+ as="a"
+ href="https://github.com/cinnyapp/cinny"
+ rel="noreferrer noopener"
+ target="_blank"
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ before={<Icon src={Icons.Code} size="100" filled />}
+ >
+ <Text size="B300">Source Code</Text>
+ </Button>
+ <Button
+ as="a"
+ href="https://cinny.in/#sponsor"
+ rel="noreferrer noopener"
+ target="_blank"
+ variant="Critical"
+ fill="Soft"
+ size="300"
+ radii="300"
+ before={<Icon src={Icons.Heart} size="100" filled />}
+ >
+ <Text size="B300">Support</Text>
+ </Button>
+ </Box>
+ </Box>
+ </Box>
+ <Box direction="Column" gap="100">
+ <Text size="L400">Options</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Clear Cache & Reload"
+ description="Clear all your locally stored data and reload from server."
+ after={
+ <Button
+ onClick={() => clearCacheAndReload(mx)}
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ outlined
+ >
+ <Text size="B300">Clear Cache</Text>
+ </Button>
+ }
+ />
+ </SequenceCard>
+ </Box>
+ <Box direction="Column" gap="100">
+ <Text size="L400">Credits</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <Box
+ as="ul"
+ direction="Column"
+ gap="200"
+ style={{
+ margin: 0,
+ paddingLeft: config.space.S400,
+ }}
+ >
+ <li>
+ <Text size="T300">
+ The{' '}
+ <a
+ href="https://github.com/matrix-org/matrix-js-sdk"
+ rel="noreferrer noopener"
+ target="_blank"
+ >
+ matrix-js-sdk
+ </a>{' '}
+ is ©{' '}
+ <a
+ href="https://matrix.org/foundation"
+ rel="noreferrer noopener"
+ target="_blank"
+ >
+ The Matrix.org Foundation C.I.C
+ </a>{' '}
+ used under the terms of{' '}
+ <a
+ href="http://www.apache.org/licenses/LICENSE-2.0"
+ rel="noreferrer noopener"
+ target="_blank"
+ >
+ Apache 2.0
+ </a>
+ .
+ </Text>
+ </li>
+ <li>
+ <Text size="T300">
+ The{' '}
+ <a
+ href="https://github.com/mozilla/twemoji-colr"
+ target="_blank"
+ rel="noreferrer noopener"
+ >
+ twemoji-colr
+ </a>{' '}
+ font is ©{' '}
+ <a href="https://mozilla.org/" target="_blank" rel="noreferrer noopener">
+ Mozilla Foundation
+ </a>{' '}
+ used under the terms of{' '}
+ <a
+ href="http://www.apache.org/licenses/LICENSE-2.0"
+ target="_blank"
+ rel="noreferrer noopener"
+ >
+ Apache 2.0
+ </a>
+ .
+ </Text>
+ </li>
+ <li>
+ <Text size="T300">
+ The{' '}
+ <a
+ href="https://twemoji.twitter.com"
+ target="_blank"
+ rel="noreferrer noopener"
+ >
+ Twemoji
+ </a>{' '}
+ emoji art is ©{' '}
+ <a
+ href="https://twemoji.twitter.com"
+ target="_blank"
+ rel="noreferrer noopener"
+ >
+ Twitter, Inc and other contributors
+ </a>{' '}
+ used under the terms of{' '}
+ <a
+ href="https://creativecommons.org/licenses/by/4.0/"
+ target="_blank"
+ rel="noreferrer noopener"
+ >
+ CC-BY 4.0
+ </a>
+ .
+ </Text>
+ </li>
+ <li>
+ <Text size="T300">
+ The{' '}
+ <a
+ href="https://material.io/design/sound/sound-resources.html"
+ target="_blank"
+ rel="noreferrer noopener"
+ >
+ Material sound resources
+ </a>{' '}
+ are ©{' '}
+ <a href="https://google.com" target="_blank" rel="noreferrer noopener">
+ Google
+ </a>{' '}
+ used under the terms of{' '}
+ <a
+ href="https://creativecommons.org/licenses/by/4.0/"
+ target="_blank"
+ rel="noreferrer noopener"
+ >
+ CC-BY 4.0
+ </a>
+ .
+ </Text>
+ </li>
+ </Box>
+ </SequenceCard>
+ </Box>
+ </Box>
+ </PageContent>
+ </Scroll>
+ </Box>
+ </Page>
+ );
+}
--- /dev/null
+export * from './About';
--- /dev/null
+import React, {
+ ChangeEventHandler,
+ FormEventHandler,
+ useCallback,
+ useEffect,
+ useMemo,
+ useState,
+} from 'react';
+import {
+ Box,
+ Text,
+ IconButton,
+ Icon,
+ Icons,
+ Scroll,
+ Input,
+ Avatar,
+ Button,
+ Chip,
+ Overlay,
+ OverlayBackdrop,
+ OverlayCenter,
+ Modal,
+ Dialog,
+ Header,
+ config,
+ Spinner,
+} from 'folds';
+import FocusTrap from 'focus-trap-react';
+import { Page, PageContent, PageHeader } from '../../../components/page';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { UserProfile, useUserProfile } from '../../../hooks/useUserProfile';
+import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix';
+import { UserAvatar } from '../../../components/user-avatar';
+import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
+import { nameInitials } from '../../../utils/common';
+import { copyToClipboard } from '../../../utils/dom';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+import { useFilePicker } from '../../../hooks/useFilePicker';
+import { useObjectURL } from '../../../hooks/useObjectURL';
+import { stopPropagation } from '../../../utils/keyboard';
+import { ImageEditor } from '../../../components/image-editor';
+import { ModalWide } from '../../../styles/Modal.css';
+import { createUploadAtom, UploadSuccess } from '../../../state/upload';
+import { CompactUploadCardRenderer } from '../../../components/upload-card';
+import { useCapabilities } from '../../../hooks/useCapabilities';
+
+function MatrixId() {
+ const mx = useMatrixClient();
+ const userId = mx.getUserId()!;
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Matrix ID</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title={userId}
+ after={
+ <Chip variant="Secondary" radii="Pill" onClick={() => copyToClipboard(userId)}>
+ <Text size="T200">Copy</Text>
+ </Chip>
+ }
+ />
+ </SequenceCard>
+ </Box>
+ );
+}
+
+type ProfileProps = {
+ profile: UserProfile;
+ userId: string;
+};
+function ProfileAvatar({ profile, userId }: ProfileProps) {
+ const mx = useMatrixClient();
+ const useAuthentication = useMediaAuthentication();
+ const capabilities = useCapabilities();
+ const [alertRemove, setAlertRemove] = useState(false);
+ const disableSetAvatar = capabilities['m.set_avatar_url']?.enabled === false;
+
+ const defaultDisplayName = profile.displayName ?? getMxIdLocalPart(userId) ?? userId;
+ const avatarUrl = profile.avatarUrl
+ ? mxcUrlToHttp(mx, profile.avatarUrl, useAuthentication, 96, 96, 'crop') ?? undefined
+ : undefined;
+
+ const [imageFile, setImageFile] = useState<File>();
+ const imageFileURL = useObjectURL(imageFile);
+ const uploadAtom = useMemo(() => {
+ if (imageFile) return createUploadAtom(imageFile);
+ return undefined;
+ }, [imageFile]);
+
+ const pickFile = useFilePicker(setImageFile, false);
+
+ const handleRemoveUpload = useCallback(() => {
+ setImageFile(undefined);
+ }, []);
+
+ const handleUploaded = useCallback(
+ (upload: UploadSuccess) => {
+ const { mxc } = upload;
+ mx.setAvatarUrl(mxc);
+ handleRemoveUpload();
+ },
+ [mx, handleRemoveUpload]
+ );
+
+ const handleRemoveAvatar = () => {
+ mx.setAvatarUrl('');
+ setAlertRemove(false);
+ };
+
+ return (
+ <SettingTile
+ title={
+ <Text as="span" size="L400">
+ Avatar
+ </Text>
+ }
+ after={
+ <Avatar size="500" radii="300">
+ <UserAvatar
+ userId={userId}
+ src={avatarUrl}
+ renderFallback={() => <Text size="H4">{nameInitials(defaultDisplayName)}</Text>}
+ />
+ </Avatar>
+ }
+ >
+ {uploadAtom ? (
+ <Box gap="200" direction="Column">
+ <CompactUploadCardRenderer
+ uploadAtom={uploadAtom}
+ onRemove={handleRemoveUpload}
+ onComplete={handleUploaded}
+ />
+ </Box>
+ ) : (
+ <Box gap="200">
+ <Button
+ onClick={() => pickFile('image/*')}
+ size="300"
+ variant="Secondary"
+ fill="Soft"
+ outlined
+ radii="300"
+ disabled={disableSetAvatar}
+ >
+ <Text size="B300">Upload</Text>
+ </Button>
+ {avatarUrl && (
+ <Button
+ size="300"
+ variant="Critical"
+ fill="None"
+ radii="300"
+ disabled={disableSetAvatar}
+ onClick={() => setAlertRemove(true)}
+ >
+ <Text size="B300">Remove</Text>
+ </Button>
+ )}
+ </Box>
+ )}
+
+ {imageFileURL && (
+ <Overlay open={false} backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: handleRemoveUpload,
+ clickOutsideDeactivates: true,
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Modal className={ModalWide} variant="Surface" size="500">
+ <ImageEditor
+ name={imageFile?.name ?? 'Unnamed'}
+ url={imageFileURL}
+ requestClose={handleRemoveUpload}
+ />
+ </Modal>
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ )}
+
+ <Overlay open={alertRemove} backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setAlertRemove(false),
+ clickOutsideDeactivates: true,
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Dialog variant="Surface">
+ <Header
+ style={{
+ padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
+ borderBottomWidth: config.borderWidth.B300,
+ }}
+ variant="Surface"
+ size="500"
+ >
+ <Box grow="Yes">
+ <Text size="H4">Remove Avatar</Text>
+ </Box>
+ <IconButton size="300" onClick={() => setAlertRemove(false)} radii="300">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Header>
+ <Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
+ <Box direction="Column" gap="200">
+ <Text priority="400">Are you sure you want to remove profile avatar?</Text>
+ </Box>
+ <Button variant="Critical" onClick={handleRemoveAvatar}>
+ <Text size="B400">Remove</Text>
+ </Button>
+ </Box>
+ </Dialog>
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ </SettingTile>
+ );
+}
+
+function ProfileDisplayName({ profile, userId }: ProfileProps) {
+ const mx = useMatrixClient();
+ const capabilities = useCapabilities();
+ const disableSetDisplayname = capabilities['m.set_displayname']?.enabled === false;
+
+ const defaultDisplayName = profile.displayName ?? getMxIdLocalPart(userId) ?? userId;
+ const [displayName, setDisplayName] = useState<string>();
+
+ const [changeState, changeDisplayName] = useAsyncCallback(
+ useCallback((name: string) => mx.setDisplayName(name), [mx])
+ );
+ const changingDisplayName = changeState.status === AsyncStatus.Loading;
+
+ useEffect(() => {
+ setDisplayName(defaultDisplayName);
+ }, [defaultDisplayName]);
+
+ const handleChange: ChangeEventHandler<HTMLInputElement> = (evt) => {
+ const name = evt.currentTarget.value;
+ setDisplayName(name);
+ };
+
+ const handleReset = () => {
+ setDisplayName(defaultDisplayName);
+ };
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (changingDisplayName) return;
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const displayNameInput = target?.displayNameInput as HTMLInputElement | undefined;
+ const name = displayNameInput?.value;
+ if (!name) return;
+
+ changeDisplayName(name);
+ };
+
+ const hasChanges = displayName !== defaultDisplayName;
+ return (
+ <SettingTile
+ title={
+ <Text as="span" size="L400">
+ Display Name
+ </Text>
+ }
+ >
+ <Box direction="Column" grow="Yes" gap="100">
+ <Box
+ as="form"
+ onSubmit={handleSubmit}
+ gap="200"
+ aria-disabled={changingDisplayName || disableSetDisplayname}
+ >
+ <Box grow="Yes" direction="Column">
+ <Input
+ required
+ name="displayNameInput"
+ value={displayName}
+ onChange={handleChange}
+ variant="Secondary"
+ radii="300"
+ style={{ paddingRight: config.space.S200 }}
+ readOnly={changingDisplayName || disableSetDisplayname}
+ after={
+ hasChanges &&
+ !changingDisplayName && (
+ <IconButton
+ type="reset"
+ onClick={handleReset}
+ size="300"
+ radii="300"
+ variant="Secondary"
+ >
+ <Icon src={Icons.Cross} size="100" />
+ </IconButton>
+ )
+ }
+ />
+ </Box>
+ <Button
+ size="400"
+ variant={hasChanges ? 'Success' : 'Secondary'}
+ fill={hasChanges ? 'Solid' : 'Soft'}
+ outlined
+ radii="300"
+ disabled={!hasChanges || changingDisplayName}
+ type="submit"
+ >
+ {changingDisplayName && <Spinner variant="Success" fill="Solid" size="300" />}
+ <Text size="B400">Save</Text>
+ </Button>
+ </Box>
+ </Box>
+ </SettingTile>
+ );
+}
+
+function Profile() {
+ const mx = useMatrixClient();
+ const userId = mx.getUserId()!;
+ const profile = useUserProfile(userId);
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Profile</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <ProfileAvatar userId={userId} profile={profile} />
+ <ProfileDisplayName userId={userId} profile={profile} />
+ </SequenceCard>
+ </Box>
+ );
+}
+
+function ContactInformation() {
+ const mx = useMatrixClient();
+ const [threePIdsState, loadThreePIds] = useAsyncCallback(
+ useCallback(() => mx.getThreePids(), [mx])
+ );
+ const threePIds =
+ threePIdsState.status === AsyncStatus.Success ? threePIdsState.data.threepids : undefined;
+
+ const emailIds = threePIds?.filter((id) => id.medium === 'email');
+
+ useEffect(() => {
+ loadThreePIds();
+ }, [loadThreePIds]);
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Contact Information</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile title="Email Address" description="Email address attached to your account.">
+ <Box>
+ {emailIds?.map((email) => (
+ <Chip key={email.address} as="span" variant="Secondary" radii="Pill">
+ <Text size="T200">{email.address}</Text>
+ </Chip>
+ ))}
+ </Box>
+ {/* <Input defaultValue="" variant="Secondary" radii="300" /> */}
+ </SettingTile>
+ </SequenceCard>
+ </Box>
+ );
+}
+
+type AccountProps = {
+ requestClose: () => void;
+};
+export function Account({ requestClose }: AccountProps) {
+ return (
+ <Page>
+ <PageHeader outlined={false}>
+ <Box grow="Yes" gap="200">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <Text size="H3" truncate>
+ Account
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </PageHeader>
+ <Box grow="Yes">
+ <Scroll hideTrack visibility="Hover">
+ <PageContent>
+ <Box direction="Column" gap="700">
+ <Profile />
+ <MatrixId />
+ <ContactInformation />
+ </Box>
+ </PageContent>
+ </Scroll>
+ </Box>
+ </Page>
+ );
+}
--- /dev/null
+export * from './Account';
--- /dev/null
+import React, {
+ FormEventHandler,
+ KeyboardEventHandler,
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from 'react';
+import {
+ as,
+ Box,
+ Header,
+ Text,
+ Icon,
+ Icons,
+ IconButton,
+ Input,
+ Button,
+ TextArea as TextAreaComponent,
+ color,
+ Spinner,
+} from 'folds';
+import { isKeyHotkey } from 'is-hotkey';
+import { MatrixError } from 'matrix-js-sdk';
+import * as css from './styles.css';
+import { useTextAreaIntentHandler } from '../../../hooks/useTextAreaIntent';
+import { Cursor, Intent, TextArea, TextAreaOperations } from '../../../plugins/text-area';
+import { GetTarget } from '../../../plugins/text-area/type';
+import { syntaxErrorPosition } from '../../../utils/dom';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+
+const EDITOR_INTENT_SPACE_COUNT = 2;
+
+export type AccountDataEditorProps = {
+ type?: string;
+ content?: object;
+ requestClose: () => void;
+};
+
+export const AccountDataEditor = as<'div', AccountDataEditorProps>(
+ ({ type, content, requestClose, ...props }, ref) => {
+ const mx = useMatrixClient();
+ const defaultContent = useMemo(
+ () => JSON.stringify(content, null, EDITOR_INTENT_SPACE_COUNT),
+ [content]
+ );
+ const textAreaRef = useRef<HTMLTextAreaElement>(null);
+ const [jsonError, setJSONError] = useState<SyntaxError>();
+
+ const getTarget: GetTarget = useCallback(() => {
+ const target = textAreaRef.current;
+ if (!target) throw new Error('TextArea element not found!');
+ return target;
+ }, []);
+
+ const { textArea, operations, intent } = useMemo(() => {
+ const ta = new TextArea(getTarget);
+ const op = new TextAreaOperations(getTarget);
+ return {
+ textArea: ta,
+ operations: op,
+ intent: new Intent(EDITOR_INTENT_SPACE_COUNT, ta, op),
+ };
+ }, [getTarget]);
+
+ const intentHandler = useTextAreaIntentHandler(textArea, operations, intent);
+
+ const handleKeyDown: KeyboardEventHandler<HTMLTextAreaElement> = (evt) => {
+ intentHandler(evt);
+ if (isKeyHotkey('escape', evt)) {
+ const cursor = Cursor.fromTextAreaElement(getTarget());
+ operations.deselect(cursor);
+ }
+ };
+
+ const [submitState, submit] = useAsyncCallback<object, MatrixError, [string, object]>(
+ useCallback((dataType, data) => mx.setAccountData(dataType, data), [mx])
+ );
+ const submitting = submitState.status === AsyncStatus.Loading;
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (submitting) return;
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const typeInput = target?.typeInput as HTMLInputElement | undefined;
+ const contentTextArea = target?.contentTextArea as HTMLTextAreaElement | undefined;
+ if (!typeInput || !contentTextArea) return;
+
+ const typeStr = typeInput.value.trim();
+ const contentStr = contentTextArea.value.trim();
+
+ let parsedContent: object;
+ try {
+ parsedContent = JSON.parse(contentStr);
+ } catch (e) {
+ setJSONError(e as SyntaxError);
+ return;
+ }
+ setJSONError(undefined);
+
+ if (
+ !typeStr ||
+ parsedContent === null ||
+ defaultContent === JSON.stringify(parsedContent, null, EDITOR_INTENT_SPACE_COUNT)
+ ) {
+ return;
+ }
+
+ submit(typeStr, parsedContent);
+ };
+
+ useEffect(() => {
+ if (jsonError) {
+ const errorPosition = syntaxErrorPosition(jsonError) ?? 0;
+ const cursor = new Cursor(errorPosition, errorPosition, 'none');
+ operations.select(cursor);
+ getTarget()?.focus();
+ }
+ }, [jsonError, operations, getTarget]);
+
+ useEffect(() => {
+ if (submitState.status === AsyncStatus.Success) {
+ requestClose();
+ }
+ }, [submitState, requestClose]);
+
+ return (
+ <Box grow="Yes" direction="Column" {...props} ref={ref}>
+ <Header className={css.EditorHeader} size="600">
+ <Box grow="Yes" gap="200">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <Text size="H3" truncate>
+ Account Data
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </Header>
+ <Box
+ as="form"
+ onSubmit={handleSubmit}
+ grow="Yes"
+ className={css.EditorContent}
+ direction="Column"
+ gap="400"
+ aria-disabled={submitting}
+ >
+ <Box shrink="No" direction="Column" gap="100">
+ <Text size="L400">Type</Text>
+ <Box gap="300">
+ <Box grow="Yes" direction="Column">
+ <Input
+ name="typeInput"
+ size="400"
+ readOnly={!!type || submitting}
+ defaultValue={type}
+ required
+ />
+ </Box>
+ <Button
+ variant="Primary"
+ size="400"
+ type="submit"
+ disabled={submitting}
+ before={submitting && <Spinner variant="Primary" fill="Solid" size="300" />}
+ >
+ <Text size="B400">Save</Text>
+ </Button>
+ </Box>
+
+ {submitState.status === AsyncStatus.Error && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{submitState.error.message}</b>
+ </Text>
+ )}
+ </Box>
+ <Box grow="Yes" direction="Column" gap="100">
+ <Box shrink="No">
+ <Text size="L400">JSON Content</Text>
+ </Box>
+ <TextAreaComponent
+ ref={textAreaRef}
+ name="contentTextArea"
+ className={css.EditorTextArea}
+ onKeyDown={handleKeyDown}
+ defaultValue={defaultContent}
+ resize="None"
+ spellCheck="false"
+ required
+ readOnly={submitting}
+ />
+ {jsonError && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>
+ {jsonError.name}: {jsonError.message}
+ </b>
+ </Text>
+ )}
+ </Box>
+ </Box>
+ </Box>
+ );
+ }
+);
--- /dev/null
+import React, { MouseEventHandler, useCallback, useState } from 'react';
+import {
+ Box,
+ Text,
+ IconButton,
+ Icon,
+ Icons,
+ Scroll,
+ Switch,
+ Overlay,
+ OverlayBackdrop,
+ OverlayCenter,
+ Modal,
+ Chip,
+ Button,
+ PopOut,
+ RectCords,
+ Menu,
+ config,
+ MenuItem,
+} from 'folds';
+import { MatrixEvent } from 'matrix-js-sdk';
+import FocusTrap from 'focus-trap-react';
+import { Page, PageContent, PageHeader } from '../../../components/page';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { useSetting } from '../../../state/hooks/settings';
+import { settingsAtom } from '../../../state/settings';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { useAccountDataCallback } from '../../../hooks/useAccountDataCallback';
+import { TextViewer } from '../../../components/text-viewer';
+import { stopPropagation } from '../../../utils/keyboard';
+import { AccountDataEditor } from './AccountDataEditor';
+import { copyToClipboard } from '../../../utils/dom';
+
+function AccountData() {
+ const mx = useMatrixClient();
+ const [view, setView] = useState(false);
+ const [accountData, setAccountData] = useState(() => Array.from(mx.store.accountData.values()));
+ const [selectedEvent, selectEvent] = useState<MatrixEvent>();
+ const [menuCords, setMenuCords] = useState<RectCords>();
+ const [selectedOption, selectOption] = useState<'edit' | 'inspect'>();
+
+ useAccountDataCallback(
+ mx,
+ useCallback(
+ () => setAccountData(Array.from(mx.store.accountData.values())),
+ [mx, setAccountData]
+ )
+ );
+
+ const handleMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ const target = evt.currentTarget;
+ const eventType = target.getAttribute('data-event-type');
+ if (eventType) {
+ const mEvent = accountData.find((mEvt) => mEvt.getType() === eventType);
+ setMenuCords(evt.currentTarget.getBoundingClientRect());
+ selectEvent(mEvent);
+ }
+ };
+
+ const handleMenuClose = () => setMenuCords(undefined);
+
+ const handleEdit = () => {
+ selectOption('edit');
+ setMenuCords(undefined);
+ };
+ const handleInspect = () => {
+ selectOption('inspect');
+ setMenuCords(undefined);
+ };
+ const handleClose = useCallback(() => {
+ selectEvent(undefined);
+ selectOption(undefined);
+ }, []);
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Account Data</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Global"
+ description="Data stored in your global account data."
+ after={
+ <Button
+ onClick={() => setView(!view)}
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ outlined
+ before={
+ <Icon src={view ? Icons.ChevronTop : Icons.ChevronBottom} size="100" filled />
+ }
+ >
+ <Text size="B300">{view ? 'Collapse' : 'Expand'}</Text>
+ </Button>
+ }
+ />
+ {view && (
+ <SettingTile>
+ <Box direction="Column" gap="200">
+ <Text size="L400">Types</Text>
+ <Box gap="200" wrap="Wrap">
+ <Chip
+ variant="Secondary"
+ fill="Soft"
+ radii="Pill"
+ onClick={handleEdit}
+ before={<Icon size="50" src={Icons.Plus} />}
+ >
+ <Text size="T200" truncate>
+ Add New
+ </Text>
+ </Chip>
+ {accountData.map((mEvent) => (
+ <Chip
+ key={mEvent.getType()}
+ variant="Secondary"
+ fill="Soft"
+ radii="Pill"
+ aria-pressed={menuCords && selectedEvent?.getType() === mEvent.getType()}
+ onClick={handleMenu}
+ data-event-type={mEvent.getType()}
+ >
+ <Text size="T200" truncate>
+ {mEvent.getType()}
+ </Text>
+ </Chip>
+ ))}
+ </Box>
+ </Box>
+ </SettingTile>
+ )}
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: handleMenuClose,
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu>
+ <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
+ <MenuItem size="300" variant="Surface" radii="300" onClick={handleInspect}>
+ <Text size="T300">Inspect</Text>
+ </MenuItem>
+ <MenuItem size="300" variant="Surface" radii="300" onClick={handleEdit}>
+ <Text size="T300">Edit</Text>
+ </MenuItem>
+ </Box>
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ </SequenceCard>
+ {selectedEvent && selectedOption === 'inspect' && (
+ <Overlay open backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: handleClose,
+ clickOutsideDeactivates: true,
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Modal variant="Surface" size="500">
+ <TextViewer
+ name={selectedEvent.getType() ?? 'Source Code'}
+ langName="json"
+ text={JSON.stringify(selectedEvent.getContent(), null, 2)}
+ requestClose={handleClose}
+ />
+ </Modal>
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ )}
+ {selectedOption === 'edit' && (
+ <Overlay open backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: handleClose,
+ clickOutsideDeactivates: true,
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Modal variant="Surface" size="500">
+ <AccountDataEditor
+ type={selectedEvent?.getType()}
+ content={selectedEvent?.getContent()}
+ requestClose={handleClose}
+ />
+ </Modal>
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ )}
+ </Box>
+ );
+}
+
+type DeveloperToolsProps = {
+ requestClose: () => void;
+};
+export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
+ const mx = useMatrixClient();
+ const [developerTools, setDeveloperTools] = useSetting(settingsAtom, 'developerTools');
+
+ return (
+ <Page>
+ <PageHeader outlined={false}>
+ <Box grow="Yes" gap="200">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <Text size="H3" truncate>
+ Developer Tools
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </PageHeader>
+ <Box grow="Yes">
+ <Scroll hideTrack visibility="Hover">
+ <PageContent>
+ <Box direction="Column" gap="700">
+ <Box direction="Column" gap="100">
+ <Text size="L400">Options</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Enable Developer Tools"
+ after={
+ <Switch
+ variant="Primary"
+ value={developerTools}
+ onChange={setDeveloperTools}
+ />
+ }
+ />
+ </SequenceCard>
+ {developerTools && (
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Access Token"
+ description="Copy access token to clipboard."
+ after={
+ <Button
+ onClick={() =>
+ copyToClipboard(mx.getAccessToken() ?? '<NO_ACCESS_TOKEN_FOUND>')
+ }
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ outlined
+ >
+ <Text size="B300">Copy</Text>
+ </Button>
+ }
+ />
+ </SequenceCard>
+ )}
+ </Box>
+ {developerTools && <AccountData />}
+ </Box>
+ </PageContent>
+ </Scroll>
+ </Box>
+ </Page>
+ );
+}
--- /dev/null
+export * from './DevelopTools';
--- /dev/null
+import { style } from '@vanilla-extract/css';
+import { DefaultReset, config } from 'folds';
+
+export const EditorHeader = style([
+ DefaultReset,
+ {
+ paddingLeft: config.space.S400,
+ paddingRight: config.space.S200,
+ borderBottomWidth: config.borderWidth.B300,
+ flexShrink: 0,
+ gap: config.space.S200,
+ },
+]);
+
+export const EditorContent = style([
+ DefaultReset,
+ {
+ padding: config.space.S400,
+ },
+]);
+
+export const EditorTextArea = style({
+ fontFamily: 'monospace',
+});
--- /dev/null
+import React, { FormEventHandler, ReactNode, useCallback, useEffect, useState } from 'react';
+import {
+ Box,
+ Text,
+ IconButton,
+ Icon,
+ Icons,
+ Chip,
+ Input,
+ Button,
+ color,
+ Spinner,
+ toRem,
+ Overlay,
+ OverlayBackdrop,
+ OverlayCenter,
+} from 'folds';
+import { CryptoApi } from 'matrix-js-sdk/lib/crypto-api';
+import FocusTrap from 'focus-trap-react';
+import { IMyDevice, MatrixError } from 'matrix-js-sdk';
+import { SettingTile } from '../../../components/setting-tile';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { timeDayMonYear, timeHourMinute, today, yesterday } from '../../../utils/time';
+import { BreakWord } from '../../../styles/Text.css';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { LogoutDialog } from '../../../components/LogoutDialog';
+import { stopPropagation } from '../../../utils/keyboard';
+
+export function DeviceTilePlaceholder() {
+ return (
+ <SequenceCard
+ className={SequenceCardStyle}
+ style={{ height: toRem(66) }}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ />
+ );
+}
+
+function DeviceActiveTime({ ts }: { ts: number }) {
+ return (
+ <Text className={BreakWord} size="T200">
+ <Text size="Inherit" as="span" priority="300">
+ {'Last activity: '}
+ </Text>
+ <>
+ {today(ts) && 'Today'}
+ {yesterday(ts) && 'Yesterday'}
+ {!today(ts) && !yesterday(ts) && timeDayMonYear(ts)} {timeHourMinute(ts)}
+ </>
+ </Text>
+ );
+}
+
+function DeviceDetails({ device }: { device: IMyDevice }) {
+ return (
+ <>
+ {typeof device.device_id === 'string' && (
+ <Text className={BreakWord} size="T200" priority="300">
+ Device ID: <i>{device.device_id}</i>
+ </Text>
+ )}
+ {typeof device.last_seen_ip === 'string' && (
+ <Text className={BreakWord} size="T200" priority="300">
+ IP Address: <i>{device.last_seen_ip}</i>
+ </Text>
+ )}
+ </>
+ );
+}
+
+type DeviceKeyDetailsProps = {
+ crypto: CryptoApi;
+};
+export function DeviceKeyDetails({ crypto }: DeviceKeyDetailsProps) {
+ const [keysState, loadKeys] = useAsyncCallback(
+ useCallback(() => {
+ const keys = crypto.getOwnDeviceKeys();
+ return keys;
+ }, [crypto])
+ );
+
+ useEffect(() => {
+ loadKeys();
+ }, [loadKeys]);
+
+ if (keysState.status === AsyncStatus.Error) return null;
+
+ return (
+ <Text className={BreakWord} size="T200" priority="300">
+ Device Key:{' '}
+ <i>{keysState.status === AsyncStatus.Success ? keysState.data.ed25519 : 'loading...'}</i>
+ </Text>
+ );
+}
+
+type DeviceRenameProps = {
+ device: IMyDevice;
+ onCancel: () => void;
+ onRename: () => void;
+ refreshDeviceList: () => Promise<void>;
+};
+function DeviceRename({ device, onCancel, onRename, refreshDeviceList }: DeviceRenameProps) {
+ const mx = useMatrixClient();
+
+ const [renameState, rename] = useAsyncCallback<void, MatrixError, [string]>(
+ useCallback(
+ async (name: string) => {
+ await mx.setDeviceDetails(device.device_id, { display_name: name });
+ await refreshDeviceList();
+ },
+ [mx, device.device_id, refreshDeviceList]
+ )
+ );
+
+ const renaming = renameState.status === AsyncStatus.Loading;
+
+ useEffect(() => {
+ if (renameState.status === AsyncStatus.Success) {
+ onRename();
+ }
+ }, [renameState, onRename]);
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (renaming) return;
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const nameInput = target?.nameInput as HTMLInputElement | undefined;
+ if (!nameInput) return;
+ const deviceName = nameInput.value.trim();
+ if (!deviceName || deviceName === device.display_name) return;
+
+ rename(deviceName);
+ };
+
+ return (
+ <Box as="form" onSubmit={handleSubmit} direction="Column" gap="100">
+ <Text size="L400">Device Name</Text>
+ <Box gap="200">
+ <Box grow="Yes" direction="Column">
+ <Input
+ name="nameInput"
+ size="300"
+ variant="Secondary"
+ radii="300"
+ defaultValue={device.display_name}
+ autoFocus
+ required
+ readOnly={renaming}
+ />
+ </Box>
+ <Box shrink="No" gap="200">
+ <Button
+ type="submit"
+ size="300"
+ variant="Success"
+ radii="300"
+ fill="Solid"
+ disabled={renaming}
+ before={renaming && <Spinner size="100" variant="Success" fill="Solid" />}
+ >
+ <Text size="B300">Save</Text>
+ </Button>
+ <Button
+ type="button"
+ size="300"
+ variant="Secondary"
+ radii="300"
+ fill="Soft"
+ onClick={onCancel}
+ disabled={renaming}
+ >
+ <Text size="B300">Cancel</Text>
+ </Button>
+ </Box>
+ </Box>
+ {renameState.status === AsyncStatus.Error ? (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ {renameState.error.message}
+ </Text>
+ ) : (
+ <Text size="T200">Device names are visible to public.</Text>
+ )}
+ </Box>
+ );
+}
+
+export function DeviceLogoutBtn() {
+ const [prompt, setPrompt] = useState(false);
+
+ const handleClose = () => setPrompt(false);
+
+ return (
+ <>
+ <Chip variant="Secondary" fill="Soft" radii="Pill" onClick={() => setPrompt(true)}>
+ <Text size="B300">Logout</Text>
+ </Chip>
+ {prompt && (
+ <Overlay open backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ onDeactivate: handleClose,
+ clickOutsideDeactivates: true,
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <LogoutDialog handleClose={handleClose} />
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ )}
+ </>
+ );
+}
+
+type DeviceDeleteBtnProps = {
+ deviceId: string;
+ deleted: boolean;
+ onDeleteToggle: (deviceId: string) => void;
+ disabled?: boolean;
+};
+export function DeviceDeleteBtn({
+ deviceId,
+ deleted,
+ onDeleteToggle,
+ disabled,
+}: DeviceDeleteBtnProps) {
+ return deleted ? (
+ <Chip
+ variant="Critical"
+ fill="None"
+ radii="Pill"
+ onClick={() => onDeleteToggle(deviceId)}
+ disabled={disabled}
+ >
+ <Text size="B300">Undo</Text>
+ </Chip>
+ ) : (
+ <Chip
+ variant="Secondary"
+ fill="None"
+ radii="Pill"
+ onClick={() => onDeleteToggle(deviceId)}
+ disabled={disabled}
+ >
+ <Icon size="50" src={Icons.Delete} />
+ </Chip>
+ );
+}
+
+type DeviceTileProps = {
+ device: IMyDevice;
+ deleted?: boolean;
+ refreshDeviceList: () => Promise<void>;
+ disabled?: boolean;
+ options?: ReactNode;
+ children?: ReactNode;
+};
+export function DeviceTile({
+ device,
+ deleted,
+ refreshDeviceList,
+ disabled,
+ options,
+ children,
+}: DeviceTileProps) {
+ const activeTs = device.last_seen_ts;
+ const [details, setDetails] = useState(false);
+ const [edit, setEdit] = useState(false);
+
+ const handleRename = useCallback(() => {
+ setEdit(false);
+ }, []);
+
+ return (
+ <>
+ <SettingTile
+ before={
+ <IconButton
+ variant={deleted ? 'Critical' : 'Secondary'}
+ outlined={deleted}
+ radii="300"
+ onClick={() => setDetails(!details)}
+ >
+ <Icon size="50" src={details ? Icons.ChevronBottom : Icons.ChevronRight} />
+ </IconButton>
+ }
+ after={
+ !edit && (
+ <Box shrink="No" alignItems="Center" gap="200">
+ {options}
+ {!deleted && (
+ <Chip
+ variant="Secondary"
+ radii="Pill"
+ onClick={() => setEdit(true)}
+ disabled={disabled}
+ >
+ <Text size="B300">Edit</Text>
+ </Chip>
+ )}
+ </Box>
+ )
+ }
+ >
+ <Text size="T300">{device.display_name ?? device.device_id}</Text>
+ <Box direction="Column">
+ {typeof activeTs === 'number' && <DeviceActiveTime ts={activeTs} />}
+ {details && (
+ <>
+ <DeviceDetails device={device} />
+ {children}
+ </>
+ )}
+ </Box>
+ </SettingTile>
+ {edit && (
+ <DeviceRename
+ device={device}
+ onCancel={() => setEdit(false)}
+ onRename={handleRename}
+ refreshDeviceList={refreshDeviceList}
+ />
+ )}
+ </>
+ );
+}
--- /dev/null
+import React from 'react';
+import { Box, Text, IconButton, Icon, Icons, Scroll } from 'folds';
+import { Page, PageContent, PageHeader } from '../../../components/page';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { useDeviceIds, useDeviceList, useSplitCurrentDevice } from '../../../hooks/useDeviceList';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { LocalBackup } from './LocalBackup';
+import { DeviceLogoutBtn, DeviceKeyDetails, DeviceTile, DeviceTilePlaceholder } from './DeviceTile';
+import { OtherDevices } from './OtherDevices';
+import {
+ DeviceVerificationOptions,
+ EnableVerification,
+ VerificationStatusBadge,
+ VerifyCurrentDeviceTile,
+} from './Verification';
+import {
+ useDeviceVerificationStatus,
+ useUnverifiedDeviceCount,
+ VerificationStatus,
+} from '../../../hooks/useDeviceVerificationStatus';
+import {
+ useSecretStorageDefaultKeyId,
+ useSecretStorageKeyContent,
+} from '../../../hooks/useSecretStorage';
+import { useCrossSigningActive } from '../../../hooks/useCrossSigning';
+import { BackupRestoreTile } from '../../../components/BackupRestore';
+
+function DevicesPlaceholder() {
+ return (
+ <Box direction="Column" gap="100">
+ <DeviceTilePlaceholder />
+ <DeviceTilePlaceholder />
+ </Box>
+ );
+}
+
+type DevicesProps = {
+ requestClose: () => void;
+};
+export function Devices({ requestClose }: DevicesProps) {
+ const mx = useMatrixClient();
+ const crypto = mx.getCrypto();
+ const crossSigningActive = useCrossSigningActive();
+ const [devices, refreshDeviceList] = useDeviceList();
+
+ const [currentDevice, otherDevices] = useSplitCurrentDevice(devices);
+ const verificationStatus = useDeviceVerificationStatus(
+ crypto,
+ mx.getSafeUserId(),
+ currentDevice?.device_id
+ );
+
+ const otherDevicesId = useDeviceIds(otherDevices);
+ const unverifiedDeviceCount = useUnverifiedDeviceCount(
+ crypto,
+ mx.getSafeUserId(),
+ otherDevicesId
+ );
+
+ const defaultSecretStorageKeyId = useSecretStorageDefaultKeyId();
+ const defaultSecretStorageKeyContent = useSecretStorageKeyContent(
+ defaultSecretStorageKeyId ?? ''
+ );
+
+ return (
+ <Page>
+ <PageHeader outlined={false}>
+ <Box grow="Yes" gap="200">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <Text size="H3" truncate>
+ Devices
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </PageHeader>
+ <Box grow="Yes">
+ <Scroll hideTrack visibility="Hover">
+ <PageContent>
+ <Box direction="Column" gap="700">
+ <Box direction="Column" gap="100">
+ <Text size="L400">Security</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Device Verification"
+ description="To verify device identity and grant access to encrypted messages."
+ after={
+ <>
+ <EnableVerification visible={!crossSigningActive} />
+ {crossSigningActive && (
+ <Box gap="200" alignItems="Center">
+ <VerificationStatusBadge
+ verificationStatus={verificationStatus}
+ otherUnverifiedCount={unverifiedDeviceCount}
+ />
+ <DeviceVerificationOptions />
+ </Box>
+ )}
+ </>
+ }
+ />
+ </SequenceCard>
+ </Box>
+ <Box direction="Column" gap="100">
+ <Text size="L400">Current</Text>
+ {currentDevice ? (
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <DeviceTile
+ device={currentDevice}
+ refreshDeviceList={refreshDeviceList}
+ options={<DeviceLogoutBtn />}
+ >
+ {crypto && <DeviceKeyDetails crypto={crypto} />}
+ </DeviceTile>
+ {crossSigningActive &&
+ verificationStatus === VerificationStatus.Unverified &&
+ defaultSecretStorageKeyId &&
+ defaultSecretStorageKeyContent && (
+ <VerifyCurrentDeviceTile
+ secretStorageKeyId={defaultSecretStorageKeyId}
+ secretStorageKeyContent={defaultSecretStorageKeyContent}
+ />
+ )}
+ {crypto && verificationStatus === VerificationStatus.Verified && (
+ <BackupRestoreTile crypto={crypto} />
+ )}
+ </SequenceCard>
+ ) : (
+ <DeviceTilePlaceholder />
+ )}
+ </Box>
+ {devices === undefined && <DevicesPlaceholder />}
+ {otherDevices && (
+ <OtherDevices
+ devices={otherDevices}
+ refreshDeviceList={refreshDeviceList}
+ showVerification={
+ crossSigningActive && verificationStatus === VerificationStatus.Verified
+ }
+ />
+ )}
+ <LocalBackup />
+ </Box>
+ </PageContent>
+ </Scroll>
+ </Box>
+ </Page>
+ );
+}
--- /dev/null
+import React, { FormEventHandler, useCallback, useEffect, useState } from 'react';
+import { Box, Button, color, Icon, Icons, Spinner, Text, toRem } from 'folds';
+import FileSaver from 'file-saver';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SettingTile } from '../../../components/setting-tile';
+import { SequenceCardStyle } from '../styles.css';
+import { PasswordInput } from '../../../components/password-input';
+import { ConfirmPasswordMatch } from '../../../components/ConfirmPasswordMatch';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+import { decryptMegolmKeyFile, encryptMegolmKeyFile } from '../../../../util/cryptE2ERoomKeys';
+import { useAlive } from '../../../hooks/useAlive';
+import { useFilePicker } from '../../../hooks/useFilePicker';
+
+function ExportKeys() {
+ const mx = useMatrixClient();
+ const alive = useAlive();
+
+ const [exportState, exportKeys] = useAsyncCallback<void, Error, [string]>(
+ useCallback(
+ async (password) => {
+ const crypto = mx.getCrypto();
+ if (!crypto) throw new Error('Unexpected Error! Crypto module not found!');
+ const keysJSON = await crypto.exportRoomKeysAsJson();
+
+ const encKeys = await encryptMegolmKeyFile(keysJSON, password);
+
+ const blob = new Blob([encKeys], {
+ type: 'text/plain;charset=us-ascii',
+ });
+ FileSaver.saveAs(blob, 'cinny-keys.txt');
+ },
+ [mx]
+ )
+ );
+
+ const exporting = exportState.status === AsyncStatus.Loading;
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (exporting) return;
+
+ const { passwordInput, confirmPasswordInput } = evt.target as HTMLFormElement & {
+ passwordInput: HTMLInputElement;
+ confirmPasswordInput: HTMLInputElement;
+ };
+
+ const password = passwordInput.value;
+ const confirmPassword = confirmPasswordInput.value;
+
+ if (password !== confirmPassword) return;
+
+ exportKeys(password).then(() => {
+ if (alive()) {
+ passwordInput.value = '';
+ confirmPasswordInput.value = '';
+ }
+ });
+ };
+
+ return (
+ <SettingTile>
+ <Box as="form" onSubmit={handleSubmit} direction="Column" gap="100">
+ <Box gap="200" alignItems="End">
+ <ConfirmPasswordMatch initialValue>
+ {(match, doMatch, passRef, confPassRef) => (
+ <>
+ <Box grow="Yes" direction="Column" gap="100">
+ <Text size="L400">New Password</Text>
+ <PasswordInput
+ ref={passRef}
+ name="passwordInput"
+ size="400"
+ variant="Secondary"
+ radii="300"
+ required
+ onChange={doMatch}
+ readOnly={exporting}
+ autoFocus
+ />
+ </Box>
+ <Box grow="Yes" direction="Column" gap="100">
+ <Text size="L400">Confirm Password</Text>
+ <PasswordInput
+ ref={confPassRef}
+ style={{ color: match ? undefined : color.Critical.Main }}
+ name="confirmPasswordInput"
+ size="400"
+ variant="Secondary"
+ radii="300"
+ required
+ onChange={doMatch}
+ readOnly={exporting}
+ />
+ </Box>
+ </>
+ )}
+ </ConfirmPasswordMatch>
+ <Button
+ type="submit"
+ size="400"
+ variant="Secondary"
+ fill="Soft"
+ outlined
+ radii="300"
+ disabled={exporting}
+ before={exporting ? <Spinner size="200" variant="Secondary" fill="Soft" /> : undefined}
+ >
+ <Text as="span" size="B400">
+ Export
+ </Text>
+ </Button>
+ </Box>
+ {exportState.status === AsyncStatus.Error && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{exportState.error.message}</b>
+ </Text>
+ )}
+ </Box>
+ </SettingTile>
+ );
+}
+
+function ExportKeysTile() {
+ const [expand, setExpand] = useState(false);
+
+ return (
+ <>
+ <SettingTile
+ title="Export Messages Data"
+ description="Save password protected copy of encryption data on your device to decrypt messages later."
+ after={
+ <Box>
+ <Button
+ type="button"
+ onClick={() => setExpand(!expand)}
+ size="300"
+ variant="Secondary"
+ fill="Soft"
+ outlined
+ radii="300"
+ before={
+ <Icon size="100" src={expand ? Icons.ChevronTop : Icons.ChevronBottom} filled />
+ }
+ >
+ <Text as="span" size="B300" truncate>
+ {expand ? 'Collapse' : 'Expand'}
+ </Text>
+ </Button>
+ </Box>
+ }
+ />
+ {expand && <ExportKeys />}
+ </>
+ );
+}
+
+type ImportKeysProps = {
+ file: File;
+ onDone?: () => void;
+};
+function ImportKeys({ file, onDone }: ImportKeysProps) {
+ const mx = useMatrixClient();
+ const alive = useAlive();
+
+ const [decryptState, decryptFile] = useAsyncCallback<void, Error, [string]>(
+ useCallback(
+ async (password) => {
+ const crypto = mx.getCrypto();
+ if (!crypto) throw new Error('Unexpected Error! Crypto module not found!');
+
+ const arrayBuffer = await file.arrayBuffer();
+ const keys = await decryptMegolmKeyFile(arrayBuffer, password);
+
+ await crypto.importRoomKeysAsJson(keys);
+ },
+ [file, mx]
+ )
+ );
+
+ const decrypting = decryptState.status === AsyncStatus.Loading;
+
+ useEffect(() => {
+ if (decryptState.status === AsyncStatus.Success) {
+ onDone?.();
+ }
+ }, [onDone, decryptState]);
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (decrypting) return;
+
+ const { passwordInput } = evt.target as HTMLFormElement & {
+ passwordInput: HTMLInputElement;
+ };
+
+ const password = passwordInput.value;
+
+ if (!password) return;
+ decryptFile(password).then(() => {
+ if (alive()) {
+ passwordInput.value = '';
+ }
+ });
+ };
+
+ return (
+ <SettingTile>
+ <Box as="form" onSubmit={handleSubmit} direction="Column" gap="100">
+ <Box gap="200" alignItems="End">
+ <Box grow="Yes" direction="Column" gap="100">
+ <Text size="L400">Password</Text>
+ <PasswordInput
+ name="passwordInput"
+ size="400"
+ variant="Secondary"
+ radii="300"
+ required
+ autoFocus
+ readOnly={decrypting}
+ />
+ </Box>
+ <Button
+ type="submit"
+ size="400"
+ variant="Secondary"
+ fill="Soft"
+ outlined
+ radii="300"
+ disabled={decrypting}
+ before={decrypting ? <Spinner size="200" variant="Secondary" fill="Soft" /> : undefined}
+ >
+ <Text as="span" size="B400">
+ Decrypt
+ </Text>
+ </Button>
+ </Box>
+ {decryptState.status === AsyncStatus.Error && (
+ <Text size="T200" style={{ color: color.Critical.Main }}>
+ <b>{decryptState.error.message}</b>
+ </Text>
+ )}
+ </Box>
+ </SettingTile>
+ );
+}
+
+function ImportKeysTile() {
+ const [file, setFile] = useState<File>();
+ const pickFile = useFilePicker(setFile);
+
+ const handleDone = useCallback(() => {
+ setFile(undefined);
+ }, []);
+
+ return (
+ <>
+ <SettingTile
+ title="Import Messages Data"
+ description="Load password protected copy of encryption data from device to decrypt your messages."
+ after={
+ <Box>
+ {file ? (
+ <Button
+ style={{ maxWidth: toRem(200) }}
+ type="button"
+ onClick={() => setFile(undefined)}
+ size="300"
+ variant="Warning"
+ fill="Solid"
+ radii="300"
+ before={<Icon size="100" src={Icons.File} filled />}
+ after={<Icon size="100" src={Icons.Cross} />}
+ >
+ <Text as="span" size="B300" truncate>
+ {file.name}
+ </Text>
+ </Button>
+ ) : (
+ <Button
+ type="button"
+ onClick={() => pickFile('text/plain')}
+ size="300"
+ variant="Secondary"
+ fill="Soft"
+ outlined
+ radii="300"
+ before={<Icon size="100" src={Icons.ArrowRight} />}
+ >
+ <Text as="span" size="B300">
+ Import
+ </Text>
+ </Button>
+ )}
+ </Box>
+ }
+ />
+ {file && <ImportKeys file={file} onDone={handleDone} />}
+ </>
+ );
+}
+
+export function LocalBackup() {
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Local Backup</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <ExportKeysTile />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <ImportKeysTile />
+ </SequenceCard>
+ </Box>
+ );
+}
--- /dev/null
+import React, { useCallback, useState } from 'react';
+import { Box, Button, config, Menu, Spinner, Text } from 'folds';
+import { AuthDict, IMyDevice, MatrixError } from 'matrix-js-sdk';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { ActionUIA, ActionUIAFlowsLoader } from '../../../components/ActionUIA';
+import { DeviceDeleteBtn, DeviceTile } from './DeviceTile';
+import { AsyncState, AsyncStatus, useAsync } from '../../../hooks/useAsyncCallback';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { useUIAMatrixError } from '../../../hooks/useUIAFlows';
+import { DeviceVerificationStatus } from '../../../components/DeviceVerificationStatus';
+import { VerifyOtherDeviceTile } from './Verification';
+import { VerificationStatus } from '../../../hooks/useDeviceVerificationStatus';
+
+type OtherDevicesProps = {
+ devices: IMyDevice[];
+ refreshDeviceList: () => Promise<void>;
+ showVerification?: boolean;
+};
+export function OtherDevices({ devices, refreshDeviceList, showVerification }: OtherDevicesProps) {
+ const mx = useMatrixClient();
+ const crypto = mx.getCrypto();
+ const [deleted, setDeleted] = useState<Set<string>>(new Set());
+
+ const handleToggleDelete = useCallback((deviceId: string) => {
+ setDeleted((deviceIds) => {
+ const newIds = new Set(deviceIds);
+ if (newIds.has(deviceId)) {
+ newIds.delete(deviceId);
+ } else {
+ newIds.add(deviceId);
+ }
+ return newIds;
+ });
+ }, []);
+
+ const [deleteState, setDeleteState] = useState<AsyncState<void, MatrixError>>({
+ status: AsyncStatus.Idle,
+ });
+
+ const deleteDevices = useAsync(
+ useCallback(
+ async (authDict?: AuthDict) => {
+ await mx.deleteMultipleDevices(Array.from(deleted), authDict);
+ },
+ [mx, deleted]
+ ),
+ useCallback(
+ (state: typeof deleteState) => {
+ if (state.status === AsyncStatus.Success) {
+ setDeleted(new Set());
+ refreshDeviceList();
+ }
+ setDeleteState(state);
+ },
+ [refreshDeviceList]
+ )
+ );
+ const [authData, deleteError] = useUIAMatrixError(
+ deleteState.status === AsyncStatus.Error ? deleteState.error : undefined
+ );
+ const deleting = deleteState.status === AsyncStatus.Loading || authData !== undefined;
+
+ const handleCancelDelete = () => setDeleted(new Set());
+ const handleCancelAuth = useCallback(() => {
+ setDeleteState({ status: AsyncStatus.Idle });
+ }, []);
+
+ return devices.length > 0 ? (
+ <>
+ <Box direction="Column" gap="100">
+ <Text size="L400">Others</Text>
+ {devices
+ .sort((d1, d2) => {
+ if (!d1.last_seen_ts || !d2.last_seen_ts) return 0;
+ return d1.last_seen_ts < d2.last_seen_ts ? 1 : -1;
+ })
+ .map((device) => (
+ <SequenceCard
+ key={device.device_id}
+ className={SequenceCardStyle}
+ variant={deleted.has(device.device_id) ? 'Critical' : 'SurfaceVariant'}
+ direction="Column"
+ gap="400"
+ >
+ <DeviceTile
+ device={device}
+ deleted={deleted.has(device.device_id)}
+ refreshDeviceList={refreshDeviceList}
+ disabled={deleting}
+ options={
+ <DeviceDeleteBtn
+ deviceId={device.device_id}
+ deleted={deleted.has(device.device_id)}
+ onDeleteToggle={handleToggleDelete}
+ disabled={deleting}
+ />
+ }
+ />
+ {showVerification && crypto && (
+ <DeviceVerificationStatus
+ crypto={crypto}
+ userId={mx.getSafeUserId()}
+ deviceId={device.device_id}
+ >
+ {(status) =>
+ status === VerificationStatus.Unverified && (
+ <VerifyOtherDeviceTile crypto={crypto} deviceId={device.device_id} />
+ )
+ }
+ </DeviceVerificationStatus>
+ )}
+ </SequenceCard>
+ ))}
+ </Box>
+ {deleted.size > 0 && (
+ <Menu
+ style={{
+ position: 'sticky',
+ padding: config.space.S200,
+ paddingLeft: config.space.S400,
+ bottom: config.space.S400,
+ left: config.space.S400,
+ right: 0,
+ zIndex: 1,
+ }}
+ variant="Critical"
+ >
+ <Box alignItems="Center" gap="400">
+ <Box grow="Yes" direction="Column">
+ {deleteError ? (
+ <Text size="T200">
+ <b>Failed to logout devices! Please try again. {deleteError.message}</b>
+ </Text>
+ ) : (
+ <Text size="T200">
+ <b>Logout from selected devices. ({deleted.size} selected)</b>
+ </Text>
+ )}
+ {authData && (
+ <ActionUIAFlowsLoader
+ authData={authData}
+ unsupported={() => (
+ <Text size="T200">
+ Authentication steps to perform this action are not supported by client.
+ </Text>
+ )}
+ >
+ {(ongoingFlow) => (
+ <ActionUIA
+ authData={authData}
+ ongoingFlow={ongoingFlow}
+ action={deleteDevices}
+ onCancel={handleCancelAuth}
+ />
+ )}
+ </ActionUIAFlowsLoader>
+ )}
+ </Box>
+ <Box shrink="No" gap="200">
+ <Button
+ size="300"
+ variant="Critical"
+ fill="None"
+ radii="300"
+ disabled={deleting}
+ onClick={handleCancelDelete}
+ >
+ <Text size="B300">Cancel</Text>
+ </Button>
+ <Button
+ size="300"
+ variant="Critical"
+ radii="300"
+ disabled={deleting}
+ before={deleting && <Spinner variant="Critical" fill="Solid" size="100" />}
+ onClick={() => deleteDevices()}
+ >
+ <Text size="B300">Logout</Text>
+ </Button>
+ </Box>
+ </Box>
+ </Menu>
+ )}
+ </>
+ ) : null;
+}
--- /dev/null
+import React, { MouseEventHandler, useCallback, useState } from 'react';
+import {
+ Badge,
+ Box,
+ Button,
+ Chip,
+ config,
+ Icon,
+ Icons,
+ Spinner,
+ Text,
+ Overlay,
+ OverlayBackdrop,
+ OverlayCenter,
+ IconButton,
+ RectCords,
+ PopOut,
+ Menu,
+ MenuItem,
+} from 'folds';
+import FocusTrap from 'focus-trap-react';
+import { CryptoApi, VerificationRequest } from 'matrix-js-sdk/lib/crypto-api';
+import { VerificationStatus } from '../../../hooks/useDeviceVerificationStatus';
+import { InfoCard } from '../../../components/info-card';
+import { ManualVerificationTile } from '../../../components/ManualVerification';
+import { SecretStorageKeyContent } from '../../../../types/matrix/accountData';
+import { AsyncState, AsyncStatus, useAsync } from '../../../hooks/useAsyncCallback';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { DeviceVerification } from '../../../components/DeviceVerification';
+import {
+ DeviceVerificationReset,
+ DeviceVerificationSetup,
+} from '../../../components/DeviceVerificationSetup';
+import { stopPropagation } from '../../../utils/keyboard';
+
+type VerificationStatusBadgeProps = {
+ verificationStatus: VerificationStatus;
+ otherUnverifiedCount?: number;
+};
+export function VerificationStatusBadge({
+ verificationStatus,
+ otherUnverifiedCount,
+}: VerificationStatusBadgeProps) {
+ if (
+ verificationStatus === VerificationStatus.Unknown ||
+ typeof otherUnverifiedCount !== 'number'
+ ) {
+ return <Spinner size="400" variant="Secondary" />;
+ }
+ if (verificationStatus === VerificationStatus.Unverified) {
+ return (
+ <Badge variant="Critical" fill="Solid" size="500">
+ <Text size="L400">Unverified</Text>
+ </Badge>
+ );
+ }
+
+ if (otherUnverifiedCount > 0) {
+ return (
+ <Badge variant="Warning" fill="Solid" size="500">
+ <Text size="L400">{otherUnverifiedCount} Unverified</Text>
+ </Badge>
+ );
+ }
+
+ return (
+ <Badge variant="Success" fill="Solid" size="500">
+ <Text size="L400">Verified</Text>
+ </Badge>
+ );
+}
+
+function LearnStartVerificationFromOtherDevice() {
+ return (
+ <Box direction="Column">
+ <Text size="T200">Steps to verify from other device.</Text>
+ <Text as="div" size="T200">
+ <ul style={{ margin: `${config.space.S100} 0` }}>
+ <li>Open your other verified device.</li>
+ <li>
+ Open <i>Settings</i>.
+ </li>
+ <li>
+ Find this device in <i>Devices/Sessions</i> section.
+ </li>
+ <li>Initiate verification.</li>
+ </ul>
+ </Text>
+ <Text size="T200">
+ If you do not have any verified device press the <i>"Verify Manually"</i> button.
+ </Text>
+ </Box>
+ );
+}
+
+type VerifyCurrentDeviceTileProps = {
+ secretStorageKeyId: string;
+ secretStorageKeyContent: SecretStorageKeyContent;
+};
+export function VerifyCurrentDeviceTile({
+ secretStorageKeyId,
+ secretStorageKeyContent,
+}: VerifyCurrentDeviceTileProps) {
+ const [learnMore, setLearnMore] = useState(false);
+
+ const [manualVerification, setManualVerification] = useState(false);
+ const handleCancelVerification = () => setManualVerification(false);
+
+ return (
+ <>
+ <InfoCard
+ variant="Critical"
+ title="Unverified"
+ description={
+ <>
+ Start verification from other device or verify manually.{' '}
+ <Text as="a" size="T200" onClick={() => setLearnMore(!learnMore)}>
+ <b>{learnMore ? 'View Less' : 'Learn More'}</b>
+ </Text>
+ </>
+ }
+ after={
+ !manualVerification && (
+ <Button
+ size="300"
+ variant="Critical"
+ fill="Soft"
+ radii="300"
+ outlined
+ onClick={() => setManualVerification(true)}
+ >
+ <Text as="span" size="B300">
+ Verify Manually
+ </Text>
+ </Button>
+ )
+ }
+ >
+ {learnMore && <LearnStartVerificationFromOtherDevice />}
+ </InfoCard>
+ {manualVerification && (
+ <ManualVerificationTile
+ secretStorageKeyId={secretStorageKeyId}
+ secretStorageKeyContent={secretStorageKeyContent}
+ options={
+ <Chip
+ type="button"
+ variant="Secondary"
+ fill="Soft"
+ radii="Pill"
+ onClick={handleCancelVerification}
+ >
+ <Icon size="100" src={Icons.Cross} />
+ </Chip>
+ }
+ />
+ )}
+ </>
+ );
+}
+
+type VerifyOtherDeviceTileProps = {
+ crypto: CryptoApi;
+ deviceId: string;
+};
+export function VerifyOtherDeviceTile({ crypto, deviceId }: VerifyOtherDeviceTileProps) {
+ const mx = useMatrixClient();
+ const [requestState, setRequestState] = useState<AsyncState<VerificationRequest, Error>>({
+ status: AsyncStatus.Idle,
+ });
+
+ const requestVerification = useAsync<VerificationRequest, Error, []>(
+ useCallback(() => {
+ const requestPromise = crypto.requestDeviceVerification(mx.getSafeUserId(), deviceId);
+ return requestPromise;
+ }, [mx, crypto, deviceId]),
+ setRequestState
+ );
+
+ const handleExit = useCallback(() => {
+ setRequestState({
+ status: AsyncStatus.Idle,
+ });
+ }, []);
+
+ const requesting = requestState.status === AsyncStatus.Loading;
+ return (
+ <InfoCard
+ variant="Warning"
+ title="Unverified"
+ description="Verify device identity and grant access to encrypted messages."
+ after={
+ <Button
+ size="300"
+ variant="Warning"
+ radii="300"
+ onClick={requestVerification}
+ before={requesting && <Spinner size="100" variant="Warning" fill="Solid" />}
+ disabled={requesting}
+ >
+ <Text as="span" size="B300">
+ Verify
+ </Text>
+ </Button>
+ }
+ >
+ {requestState.status === AsyncStatus.Error && (
+ <Text size="T200">{requestState.error.message}</Text>
+ )}
+ {requestState.status === AsyncStatus.Success && (
+ <DeviceVerification request={requestState.data} onExit={handleExit} />
+ )}
+ </InfoCard>
+ );
+}
+
+type EnableVerificationProps = {
+ visible: boolean;
+};
+export function EnableVerification({ visible }: EnableVerificationProps) {
+ const [open, setOpen] = useState(false);
+
+ const handleCancel = useCallback(() => setOpen(false), []);
+
+ return (
+ <>
+ {visible && (
+ <Button size="300" radii="300" onClick={() => setOpen(true)}>
+ <Text as="span" size="B300">
+ Enable
+ </Text>
+ </Button>
+ )}
+ {open && (
+ <Overlay open backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ clickOutsideDeactivates: false,
+ escapeDeactivates: false,
+ }}
+ >
+ <DeviceVerificationSetup onCancel={handleCancel} />
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ )}
+ </>
+ );
+}
+
+export function DeviceVerificationOptions() {
+ const [menuCords, setMenuCords] = useState<RectCords>();
+
+ const [reset, setReset] = useState(false);
+
+ const handleCancelReset = useCallback(() => {
+ setReset(false);
+ }, []);
+
+ const handleMenu: MouseEventHandler<HTMLButtonElement> = (event) => {
+ setMenuCords(event.currentTarget.getBoundingClientRect());
+ };
+
+ const handleReset = () => {
+ setMenuCords(undefined);
+ setReset(true);
+ };
+
+ return (
+ <>
+ <IconButton
+ aria-pressed={!!menuCords}
+ variant="SurfaceVariant"
+ size="300"
+ radii="300"
+ onClick={handleMenu}
+ >
+ <Icon size="100" src={Icons.VerticalDots} />
+ </IconButton>
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ align="Center"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu>
+ <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
+ <MenuItem
+ variant="Critical"
+ onClick={handleReset}
+ size="300"
+ radii="300"
+ fill="None"
+ >
+ <Text as="span" size="T300" truncate>
+ Reset
+ </Text>
+ </MenuItem>
+ </Box>
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ {reset && (
+ <Overlay open backdrop={<OverlayBackdrop />}>
+ <OverlayCenter>
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ clickOutsideDeactivates: false,
+ escapeDeactivates: false,
+ }}
+ >
+ <DeviceVerificationReset onCancel={handleCancelReset} />
+ </FocusTrap>
+ </OverlayCenter>
+ </Overlay>
+ )}
+ </>
+ );
+}
--- /dev/null
+export * from './Devices';
--- /dev/null
+import React, { useState } from 'react';
+import { Box, Text, IconButton, Icon, Icons, Scroll } from 'folds';
+import { Page, PageContent, PageHeader } from '../../../components/page';
+import { GlobalPacks } from './GlobalPacks';
+import { UserPack } from './UserPack';
+import { ImagePack } from '../../../plugins/custom-emoji';
+import { ImagePackView } from '../../../components/image-pack-view';
+
+type EmojisStickersProps = {
+ requestClose: () => void;
+};
+export function EmojisStickers({ requestClose }: EmojisStickersProps) {
+ const [imagePack, setImagePack] = useState<ImagePack>();
+
+ const handleImagePackViewClose = () => {
+ setImagePack(undefined);
+ };
+
+ if (imagePack) {
+ return <ImagePackView address={imagePack.address} requestClose={handleImagePackViewClose} />;
+ }
+
+ return (
+ <Page>
+ <PageHeader outlined={false}>
+ <Box grow="Yes" gap="200">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <Text size="H3" truncate>
+ Emojis & Stickers
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </PageHeader>
+ <Box grow="Yes">
+ <Scroll hideTrack visibility="Hover">
+ <PageContent>
+ <Box direction="Column" gap="700">
+ <UserPack onViewPack={setImagePack} />
+ <GlobalPacks onViewPack={setImagePack} />
+ </Box>
+ </PageContent>
+ </Scroll>
+ </Box>
+ </Page>
+ );
+}
--- /dev/null
+import React, { MouseEventHandler, useCallback, useEffect, useMemo, useState } from 'react';
+import {
+ Box,
+ Text,
+ Button,
+ Icon,
+ Icons,
+ IconButton,
+ Avatar,
+ AvatarImage,
+ AvatarFallback,
+ config,
+ Spinner,
+ Menu,
+ RectCords,
+ PopOut,
+ Checkbox,
+ toRem,
+ Scroll,
+ Header,
+ Line,
+ Chip,
+} from 'folds';
+import FocusTrap from 'focus-trap-react';
+import { useAtomValue } from 'jotai';
+import { Room } from 'matrix-js-sdk';
+import { useGlobalImagePacks, useRoomsImagePacks } from '../../../hooks/useImagePacks';
+import { SequenceCardStyle } from '../styles.css';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SettingTile } from '../../../components/setting-tile';
+import { mxcUrlToHttp } from '../../../utils/matrix';
+import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import {
+ EmoteRoomsContent,
+ ImagePack,
+ ImageUsage,
+ PackAddress,
+ packAddressEqual,
+} from '../../../plugins/custom-emoji';
+import { LineClamp2 } from '../../../styles/Text.css';
+import { allRoomsAtom } from '../../../state/room-list/roomList';
+import { AccountDataEvent } from '../../../../types/matrix/accountData';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+import { stopPropagation } from '../../../utils/keyboard';
+
+function GlobalPackSelector({
+ packs,
+ useAuthentication,
+ onSelect,
+}: {
+ packs: ImagePack[];
+ useAuthentication: boolean;
+ onSelect: (addresses: PackAddress[]) => void;
+}) {
+ const mx = useMatrixClient();
+ const roomToPacks = useMemo(() => {
+ const rToP = new Map<string, ImagePack[]>();
+ packs
+ .filter((pack) => !pack.deleted)
+ .forEach((pack) => {
+ if (!pack.address) return;
+ const pks = rToP.get(pack.address.roomId) ?? [];
+ pks.push(pack);
+ rToP.set(pack.address.roomId, pks);
+ });
+ return rToP;
+ }, [packs]);
+
+ const [selected, setSelected] = useState<PackAddress[]>([]);
+ const toggleSelect = (address: PackAddress) => {
+ setSelected((addresses) => {
+ const newAddresses = addresses.filter((addr) => !packAddressEqual(addr, address));
+ if (newAddresses.length !== addresses.length) {
+ return newAddresses;
+ }
+ newAddresses.push(address);
+ return newAddresses;
+ });
+ };
+
+ const hasSelected = selected.length > 0;
+ return (
+ <Box grow="Yes" direction="Column">
+ <Header size="400" variant="Surface" style={{ padding: `0 ${config.space.S300}` }}>
+ <Box grow="Yes">
+ <Text size="L400" truncate>
+ Room Packs
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <Chip
+ radii="Pill"
+ variant={hasSelected ? 'Success' : 'SurfaceVariant'}
+ outlined={hasSelected}
+ onClick={() => onSelect(selected)}
+ >
+ <Text size="B300">{hasSelected ? 'Save' : 'Close'}</Text>
+ </Chip>
+ </Box>
+ </Header>
+ <Line variant="Surface" size="300" />
+ <Box grow="Yes">
+ <Scroll size="300" hideTrack visibility="Hover">
+ <Box
+ direction="Column"
+ gap="400"
+ style={{
+ paddingLeft: config.space.S300,
+ paddingTop: config.space.S300,
+ paddingBottom: config.space.S300,
+ paddingRight: config.space.S100,
+ }}
+ >
+ {Array.from(roomToPacks.entries()).map(([roomId, roomPacks]) => {
+ const room = mx.getRoom(roomId);
+ if (!room) return null;
+ return (
+ <Box key={roomId} direction="Column" gap="100">
+ <Text size="L400">{room.name}</Text>
+ {roomPacks.map((pack) => {
+ const avatarMxc = pack.getAvatarUrl(ImageUsage.Emoticon);
+ const avatarUrl = avatarMxc
+ ? mxcUrlToHttp(mx, avatarMxc, useAuthentication)
+ : undefined;
+ const { address } = pack;
+ if (!address) return null;
+
+ const added = selected.find((addr) => packAddressEqual(addr, address));
+ return (
+ <SequenceCard
+ key={pack.id}
+ className={SequenceCardStyle}
+ variant={added ? 'Success' : 'SurfaceVariant'}
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title={pack.meta.name ?? 'Unknown'}
+ description={<span className={LineClamp2}>{pack.meta.attribution}</span>}
+ before={
+ <Box alignItems="Center" gap="300">
+ <Avatar size="300" radii="300">
+ {avatarUrl ? (
+ <AvatarImage style={{ objectFit: 'contain' }} src={avatarUrl} />
+ ) : (
+ <AvatarFallback>
+ <Icon size="400" src={Icons.Sticker} filled />
+ </AvatarFallback>
+ )}
+ </Avatar>
+ </Box>
+ }
+ after={
+ <Checkbox variant="Success" onClick={() => toggleSelect(address)} />
+ }
+ />
+ </SequenceCard>
+ );
+ })}
+ </Box>
+ );
+ })}
+
+ {roomToPacks.size === 0 && (
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <Box
+ justifyContent="Center"
+ direction="Column"
+ gap="200"
+ style={{
+ padding: `${config.space.S700} ${config.space.S400}`,
+ maxWidth: toRem(300),
+ margin: 'auto',
+ }}
+ >
+ <Text size="H5" align="Center">
+ No Packs
+ </Text>
+ <Text size="T200" align="Center">
+ Pack from rooms will appear here. You do not have any room with packs yet.
+ </Text>
+ </Box>
+ </SequenceCard>
+ )}
+ </Box>
+ </Scroll>
+ </Box>
+ </Box>
+ );
+}
+
+type GlobalPacksProps = {
+ onViewPack: (imagePack: ImagePack) => void;
+};
+export function GlobalPacks({ onViewPack }: GlobalPacksProps) {
+ const mx = useMatrixClient();
+ const useAuthentication = useMediaAuthentication();
+ const globalPacks = useGlobalImagePacks();
+ const [menuCords, setMenuCords] = useState<RectCords>();
+
+ const roomIds = useAtomValue(allRoomsAtom);
+ const rooms = useMemo(() => {
+ const rs: Room[] = [];
+ roomIds.forEach((rId) => {
+ const r = mx.getRoom(rId);
+ if (r) rs.push(r);
+ });
+ return rs;
+ }, [mx, roomIds]);
+ const roomsImagePack = useRoomsImagePacks(rooms);
+ const nonGlobalPacks = useMemo(
+ () =>
+ roomsImagePack.filter(
+ (pack) => !globalPacks.find((p) => packAddressEqual(pack.address, p.address))
+ ),
+ [roomsImagePack, globalPacks]
+ );
+
+ const [selectedPacks, setSelectedPacks] = useState<PackAddress[]>([]);
+ const [removedPacks, setRemovedPacks] = useState<PackAddress[]>([]);
+
+ const unselectedGlobalPacks = useMemo(
+ () =>
+ nonGlobalPacks.filter(
+ (pack) => !selectedPacks.find((addr) => packAddressEqual(pack.address, addr))
+ ),
+ [selectedPacks, nonGlobalPacks]
+ );
+
+ const handleRemove = (address: PackAddress) => {
+ setRemovedPacks((addresses) => [...addresses, address]);
+ };
+
+ const handleUndoRemove = (address: PackAddress) => {
+ setRemovedPacks((addresses) => addresses.filter((addr) => !packAddressEqual(addr, address)));
+ };
+
+ const handleSelected = (addresses: PackAddress[]) => {
+ setMenuCords(undefined);
+ if (addresses.length > 0) {
+ setSelectedPacks((a) => [...addresses, ...a]);
+ }
+ };
+
+ const [applyState, applyChanges] = useAsyncCallback(
+ useCallback(async () => {
+ const content =
+ mx.getAccountData(AccountDataEvent.PoniesEmoteRooms)?.getContent<EmoteRoomsContent>() ?? {};
+ const updatedContent: EmoteRoomsContent = JSON.parse(JSON.stringify(content));
+
+ selectedPacks.forEach((addr) => {
+ const roomsToState = updatedContent.rooms ?? {};
+ const stateKeyToObj = roomsToState[addr.roomId] ?? {};
+ stateKeyToObj[addr.stateKey] = {};
+ roomsToState[addr.roomId] = stateKeyToObj;
+ updatedContent.rooms = roomsToState;
+ });
+
+ removedPacks.forEach((addr) => {
+ if (updatedContent.rooms?.[addr.roomId]?.[addr.stateKey]) {
+ delete updatedContent.rooms?.[addr.roomId][addr.stateKey];
+ }
+ });
+
+ await mx.setAccountData(AccountDataEvent.PoniesEmoteRooms, updatedContent);
+ }, [mx, selectedPacks, removedPacks])
+ );
+
+ const resetChanges = useCallback(() => {
+ setSelectedPacks([]);
+ setRemovedPacks([]);
+ }, []);
+
+ useEffect(() => {
+ if (applyState.status === AsyncStatus.Success) {
+ resetChanges();
+ }
+ }, [applyState, resetChanges]);
+
+ const handleSelectMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setMenuCords(evt.currentTarget.getBoundingClientRect());
+ };
+
+ const applyingChanges = applyState.status === AsyncStatus.Loading;
+ const hasChanges = removedPacks.length > 0 || selectedPacks.length > 0;
+
+ const renderPack = (pack: ImagePack) => {
+ const avatarMxc = pack.getAvatarUrl(ImageUsage.Emoticon);
+ const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication) : undefined;
+ const { address } = pack;
+ if (!address) return null;
+ const removed = !!removedPacks.find((addr) => packAddressEqual(addr, address));
+
+ return (
+ <SequenceCard
+ key={pack.id}
+ className={SequenceCardStyle}
+ variant={removed ? 'Critical' : 'SurfaceVariant'}
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title={
+ <span style={{ textDecoration: removed ? 'line-through' : undefined }}>
+ {pack.meta.name ?? 'Unknown'}
+ </span>
+ }
+ description={<span className={LineClamp2}>{pack.meta.attribution}</span>}
+ before={
+ <Box alignItems="Center" gap="300">
+ {removed ? (
+ <IconButton
+ size="300"
+ radii="Pill"
+ variant="Critical"
+ onClick={() => handleUndoRemove(address)}
+ disabled={applyingChanges}
+ >
+ <Icon src={Icons.Plus} size="100" />
+ </IconButton>
+ ) : (
+ <IconButton
+ size="300"
+ radii="Pill"
+ variant="Secondary"
+ onClick={() => handleRemove(address)}
+ disabled={applyingChanges}
+ >
+ <Icon src={Icons.Cross} size="100" />
+ </IconButton>
+ )}
+ <Avatar size="300" radii="300">
+ {avatarUrl ? (
+ <AvatarImage style={{ objectFit: 'contain' }} src={avatarUrl} />
+ ) : (
+ <AvatarFallback>
+ <Icon size="400" src={Icons.Sticker} filled />
+ </AvatarFallback>
+ )}
+ </Avatar>
+ </Box>
+ }
+ after={
+ !removed && (
+ <Button
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ outlined
+ onClick={() => onViewPack(pack)}
+ >
+ <Text size="B300">View</Text>
+ </Button>
+ )
+ }
+ />
+ </SequenceCard>
+ );
+ };
+
+ return (
+ <>
+ <Box direction="Column" gap="100">
+ <Text size="L400">Favorite Packs</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Select Pack"
+ description="Pick emojis and stickers pack from rooms to use in all rooms."
+ after={
+ <>
+ <Button
+ onClick={handleSelectMenu}
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ outlined
+ >
+ <Text size="B300">Select</Text>
+ </Button>
+ <PopOut
+ anchor={menuCords}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu
+ style={{
+ display: 'flex',
+ maxWidth: toRem(400),
+ width: '100vw',
+ maxHeight: toRem(500),
+ }}
+ >
+ <GlobalPackSelector
+ packs={unselectedGlobalPacks}
+ useAuthentication={useAuthentication}
+ onSelect={handleSelected}
+ />
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ </>
+ }
+ />
+ </SequenceCard>
+ {globalPacks.map(renderPack)}
+ {nonGlobalPacks
+ .filter((pack) => !!selectedPacks.find((addr) => packAddressEqual(pack.address, addr)))
+ .map(renderPack)}
+ </Box>
+ {hasChanges && (
+ <Menu
+ style={{
+ position: 'sticky',
+ padding: config.space.S200,
+ paddingLeft: config.space.S400,
+ bottom: config.space.S400,
+ left: config.space.S400,
+ right: 0,
+ zIndex: 1,
+ }}
+ variant="Success"
+ >
+ <Box alignItems="Center" gap="400">
+ <Box grow="Yes" direction="Column">
+ {applyState.status === AsyncStatus.Error ? (
+ <Text size="T200">
+ <b>Failed to apply changes! Please try again.</b>
+ </Text>
+ ) : (
+ <Text size="T200">
+ <b>Changes saved! Apply when ready.</b>
+ </Text>
+ )}
+ </Box>
+ <Box shrink="No" gap="200">
+ <Button
+ size="300"
+ variant="Success"
+ fill="None"
+ radii="300"
+ disabled={applyingChanges}
+ onClick={resetChanges}
+ >
+ <Text size="B300">Reset</Text>
+ </Button>
+ <Button
+ size="300"
+ variant="Success"
+ radii="300"
+ disabled={applyingChanges}
+ before={applyingChanges && <Spinner variant="Success" fill="Solid" size="100" />}
+ onClick={applyChanges}
+ >
+ <Text size="B300">Apply Changes</Text>
+ </Button>
+ </Box>
+ </Box>
+ </Menu>
+ )}
+ </>
+ );
+}
--- /dev/null
+import React from 'react';
+import { Avatar, AvatarFallback, AvatarImage, Box, Button, Icon, Icons, Text } from 'folds';
+import { useUserImagePack } from '../../../hooks/useImagePacks';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { ImagePack, ImageUsage } from '../../../plugins/custom-emoji';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { mxcUrlToHttp } from '../../../utils/matrix';
+import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
+
+type UserPackProps = {
+ onViewPack: (imagePack: ImagePack) => void;
+};
+export function UserPack({ onViewPack }: UserPackProps) {
+ const mx = useMatrixClient();
+ const useAuthentication = useMediaAuthentication();
+
+ const userPack = useUserImagePack();
+ const avatarMxc = userPack?.getAvatarUrl(ImageUsage.Emoticon);
+ const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication) : undefined;
+
+ const handleView = () => {
+ if (userPack) {
+ onViewPack(userPack);
+ } else {
+ const defaultPack = new ImagePack(mx.getUserId() ?? '', {}, undefined);
+ onViewPack(defaultPack);
+ }
+ };
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Default Pack</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title={userPack?.meta.name ?? 'Unknown'}
+ description={userPack?.meta.attribution}
+ before={
+ <Avatar size="300" radii="300">
+ {avatarUrl ? (
+ <AvatarImage style={{ objectFit: 'contain' }} src={avatarUrl} />
+ ) : (
+ <AvatarFallback>
+ <Icon size="400" src={Icons.Sticker} filled />
+ </AvatarFallback>
+ )}
+ </Avatar>
+ }
+ after={
+ <Button
+ variant="Secondary"
+ fill="Soft"
+ size="300"
+ radii="300"
+ outlined
+ onClick={handleView}
+ >
+ <Text size="B300">View</Text>
+ </Button>
+ }
+ />
+ </SequenceCard>
+ </Box>
+ );
+}
--- /dev/null
+export * from './EmojisStickers';
--- /dev/null
+import React, {
+ ChangeEventHandler,
+ KeyboardEventHandler,
+ MouseEventHandler,
+ useState,
+} from 'react';
+import {
+ as,
+ Box,
+ Button,
+ Chip,
+ config,
+ Icon,
+ IconButton,
+ Icons,
+ Input,
+ Menu,
+ MenuItem,
+ PopOut,
+ RectCords,
+ Scroll,
+ Switch,
+ Text,
+ toRem,
+} from 'folds';
+import { isKeyHotkey } from 'is-hotkey';
+import FocusTrap from 'focus-trap-react';
+import { Page, PageContent, PageHeader } from '../../../components/page';
+import { SequenceCard } from '../../../components/sequence-card';
+import { useSetting } from '../../../state/hooks/settings';
+import { MessageLayout, MessageSpacing, settingsAtom } from '../../../state/settings';
+import { SettingTile } from '../../../components/setting-tile';
+import { KeySymbol } from '../../../utils/key-symbol';
+import { isMacOS } from '../../../utils/user-agent';
+import {
+ DarkTheme,
+ LightTheme,
+ Theme,
+ ThemeKind,
+ useSystemThemeKind,
+ useThemeNames,
+ useThemes,
+} from '../../../hooks/useTheme';
+import { stopPropagation } from '../../../utils/keyboard';
+import { useMessageLayoutItems } from '../../../hooks/useMessageLayout';
+import { useMessageSpacingItems } from '../../../hooks/useMessageSpacing';
+import { SequenceCardStyle } from '../styles.css';
+
+type ThemeSelectorProps = {
+ themeNames: Record<string, string>;
+ themes: Theme[];
+ selected: Theme;
+ onSelect: (theme: Theme) => void;
+};
+const ThemeSelector = as<'div', ThemeSelectorProps>(
+ ({ themeNames, themes, selected, onSelect, ...props }, ref) => (
+ <Menu {...props} ref={ref}>
+ <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
+ {themes.map((theme) => (
+ <MenuItem
+ key={theme.id}
+ size="300"
+ variant={theme.id === selected.id ? 'Primary' : 'Surface'}
+ radii="300"
+ onClick={() => onSelect(theme)}
+ >
+ <Text size="T300">{themeNames[theme.id] ?? theme.id}</Text>
+ </MenuItem>
+ ))}
+ </Box>
+ </Menu>
+ )
+);
+
+function SelectTheme({ disabled }: { disabled?: boolean }) {
+ const themes = useThemes();
+ const themeNames = useThemeNames();
+ const [themeId, setThemeId] = useSetting(settingsAtom, 'themeId');
+ const [menuCords, setMenuCords] = useState<RectCords>();
+ const selectedTheme = themes.find((theme) => theme.id === themeId) ?? LightTheme;
+
+ const handleThemeMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setMenuCords(evt.currentTarget.getBoundingClientRect());
+ };
+
+ const handleThemeSelect = (theme: Theme) => {
+ setThemeId(theme.id);
+ setMenuCords(undefined);
+ };
+
+ return (
+ <>
+ <Button
+ size="300"
+ variant="Primary"
+ outlined
+ fill="Soft"
+ radii="300"
+ after={<Icon size="300" src={Icons.ChevronBottom} />}
+ onClick={disabled ? undefined : handleThemeMenu}
+ aria-disabled={disabled}
+ >
+ <Text size="T300">{themeNames[selectedTheme.id] ?? selectedTheme.id}</Text>
+ </Button>
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <ThemeSelector
+ themeNames={themeNames}
+ themes={themes}
+ selected={selectedTheme}
+ onSelect={handleThemeSelect}
+ />
+ </FocusTrap>
+ }
+ />
+ </>
+ );
+}
+
+function SystemThemePreferences() {
+ const themeKind = useSystemThemeKind();
+ const themeNames = useThemeNames();
+ const themes = useThemes();
+ const [lightThemeId, setLightThemeId] = useSetting(settingsAtom, 'lightThemeId');
+ const [darkThemeId, setDarkThemeId] = useSetting(settingsAtom, 'darkThemeId');
+
+ const lightThemes = themes.filter((theme) => theme.kind === ThemeKind.Light);
+ const darkThemes = themes.filter((theme) => theme.kind === ThemeKind.Dark);
+
+ const selectedLightTheme = lightThemes.find((theme) => theme.id === lightThemeId) ?? LightTheme;
+ const selectedDarkTheme = darkThemes.find((theme) => theme.id === darkThemeId) ?? DarkTheme;
+
+ const [ltCords, setLTCords] = useState<RectCords>();
+ const [dtCords, setDTCords] = useState<RectCords>();
+
+ const handleLightThemeMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setLTCords(evt.currentTarget.getBoundingClientRect());
+ };
+ const handleDarkThemeMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setDTCords(evt.currentTarget.getBoundingClientRect());
+ };
+
+ const handleLightThemeSelect = (theme: Theme) => {
+ setLightThemeId(theme.id);
+ setLTCords(undefined);
+ };
+
+ const handleDarkThemeSelect = (theme: Theme) => {
+ setDarkThemeId(theme.id);
+ setDTCords(undefined);
+ };
+
+ return (
+ <Box wrap="Wrap" gap="400">
+ <SettingTile
+ title="Light Theme:"
+ after={
+ <Chip
+ variant={themeKind === ThemeKind.Light ? 'Primary' : 'Secondary'}
+ outlined={themeKind === ThemeKind.Light}
+ radii="Pill"
+ after={<Icon size="200" src={Icons.ChevronBottom} />}
+ onClick={handleLightThemeMenu}
+ >
+ <Text size="B300">{themeNames[selectedLightTheme.id] ?? selectedLightTheme.id}</Text>
+ </Chip>
+ }
+ />
+ <PopOut
+ anchor={ltCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setLTCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <ThemeSelector
+ themeNames={themeNames}
+ themes={lightThemes}
+ selected={selectedLightTheme}
+ onSelect={handleLightThemeSelect}
+ />
+ </FocusTrap>
+ }
+ />
+ <SettingTile
+ title="Dark Theme:"
+ after={
+ <Chip
+ variant={themeKind === ThemeKind.Dark ? 'Primary' : 'Secondary'}
+ outlined={themeKind === ThemeKind.Dark}
+ radii="Pill"
+ after={<Icon size="200" src={Icons.ChevronBottom} />}
+ onClick={handleDarkThemeMenu}
+ >
+ <Text size="B300">{themeNames[selectedDarkTheme.id] ?? selectedDarkTheme.id}</Text>
+ </Chip>
+ }
+ />
+ <PopOut
+ anchor={dtCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setDTCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <ThemeSelector
+ themeNames={themeNames}
+ themes={darkThemes}
+ selected={selectedDarkTheme}
+ onSelect={handleDarkThemeSelect}
+ />
+ </FocusTrap>
+ }
+ />
+ </Box>
+ );
+}
+
+function PageZoomInput() {
+ const [pageZoom, setPageZoom] = useSetting(settingsAtom, 'pageZoom');
+ const [currentZoom, setCurrentZoom] = useState(`${pageZoom}`);
+
+ const handleZoomChange: ChangeEventHandler<HTMLInputElement> = (evt) => {
+ setCurrentZoom(evt.target.value);
+ };
+
+ const handleZoomEnter: KeyboardEventHandler<HTMLInputElement> = (evt) => {
+ if (isKeyHotkey('escape', evt)) {
+ evt.stopPropagation();
+ setCurrentZoom(pageZoom.toString());
+ }
+ if (
+ isKeyHotkey('enter', evt) &&
+ 'value' in evt.target &&
+ typeof evt.target.value === 'string'
+ ) {
+ const newZoom = parseInt(evt.target.value, 10);
+ if (Number.isNaN(newZoom)) return;
+ const safeZoom = Math.max(Math.min(newZoom, 150), 75);
+ setPageZoom(safeZoom);
+ setCurrentZoom(safeZoom.toString());
+ }
+ };
+
+ return (
+ <Input
+ style={{ width: toRem(100) }}
+ variant={pageZoom === parseInt(currentZoom, 10) ? 'Secondary' : 'Success'}
+ size="300"
+ radii="300"
+ type="number"
+ min="75"
+ max="150"
+ value={currentZoom}
+ onChange={handleZoomChange}
+ onKeyDown={handleZoomEnter}
+ after={<Text size="T300">%</Text>}
+ outlined
+ />
+ );
+}
+
+function Appearance() {
+ const [systemTheme, setSystemTheme] = useSetting(settingsAtom, 'useSystemTheme');
+ const [twitterEmoji, setTwitterEmoji] = useSetting(settingsAtom, 'twitterEmoji');
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Appearance</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="System Theme"
+ description="Choose between light and dark theme based on system preference."
+ after={<Switch variant="Primary" value={systemTheme} onChange={setSystemTheme} />}
+ />
+ {systemTheme && <SystemThemePreferences />}
+ </SequenceCard>
+
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Theme"
+ description="Theme to use when system theme is not enabled."
+ after={<SelectTheme disabled={systemTheme} />}
+ />
+ </SequenceCard>
+
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Twitter Emoji"
+ after={<Switch variant="Primary" value={twitterEmoji} onChange={setTwitterEmoji} />}
+ />
+ </SequenceCard>
+
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile title="Page Zoom" after={<PageZoomInput />} />
+ </SequenceCard>
+ </Box>
+ );
+}
+
+function Editor() {
+ const [enterForNewline, setEnterForNewline] = useSetting(settingsAtom, 'enterForNewline');
+ const [isMarkdown, setIsMarkdown] = useSetting(settingsAtom, 'isMarkdown');
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Editor</Text>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="ENTER for Newline"
+ description={`Use ${
+ isMacOS() ? KeySymbol.Command : 'Ctrl'
+ } + ENTER to send message and ENTER for newline.`}
+ after={<Switch variant="Primary" value={enterForNewline} onChange={setEnterForNewline} />}
+ />
+ </SequenceCard>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Markdown Formatting"
+ after={<Switch variant="Primary" value={isMarkdown} onChange={setIsMarkdown} />}
+ />
+ </SequenceCard>
+ </Box>
+ );
+}
+
+function SelectMessageLayout() {
+ const [menuCords, setMenuCords] = useState<RectCords>();
+ const [messageLayout, setMessageLayout] = useSetting(settingsAtom, 'messageLayout');
+ const messageLayoutItems = useMessageLayoutItems();
+
+ const handleMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setMenuCords(evt.currentTarget.getBoundingClientRect());
+ };
+
+ const handleSelect = (layout: MessageLayout) => {
+ setMessageLayout(layout);
+ setMenuCords(undefined);
+ };
+
+ return (
+ <>
+ <Button
+ size="300"
+ variant="Secondary"
+ outlined
+ fill="Soft"
+ radii="300"
+ after={<Icon size="300" src={Icons.ChevronBottom} />}
+ onClick={handleMenu}
+ >
+ <Text size="T300">
+ {messageLayoutItems.find((i) => i.layout === messageLayout)?.name ?? messageLayout}
+ </Text>
+ </Button>
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu>
+ <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
+ {messageLayoutItems.map((item) => (
+ <MenuItem
+ key={item.layout}
+ size="300"
+ variant={messageLayout === item.layout ? 'Primary' : 'Surface'}
+ radii="300"
+ onClick={() => handleSelect(item.layout)}
+ >
+ <Text size="T300">{item.name}</Text>
+ </MenuItem>
+ ))}
+ </Box>
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ </>
+ );
+}
+
+function SelectMessageSpacing() {
+ const [menuCords, setMenuCords] = useState<RectCords>();
+ const [messageSpacing, setMessageSpacing] = useSetting(settingsAtom, 'messageSpacing');
+ const messageSpacingItems = useMessageSpacingItems();
+
+ const handleMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setMenuCords(evt.currentTarget.getBoundingClientRect());
+ };
+
+ const handleSelect = (layout: MessageSpacing) => {
+ setMessageSpacing(layout);
+ setMenuCords(undefined);
+ };
+
+ return (
+ <>
+ <Button
+ size="300"
+ variant="Secondary"
+ outlined
+ fill="Soft"
+ radii="300"
+ after={<Icon size="300" src={Icons.ChevronBottom} />}
+ onClick={handleMenu}
+ >
+ <Text size="T300">
+ {messageSpacingItems.find((i) => i.spacing === messageSpacing)?.name ?? messageSpacing}
+ </Text>
+ </Button>
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu>
+ <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
+ {messageSpacingItems.map((item) => (
+ <MenuItem
+ key={item.spacing}
+ size="300"
+ variant={messageSpacing === item.spacing ? 'Primary' : 'Surface'}
+ radii="300"
+ onClick={() => handleSelect(item.spacing)}
+ >
+ <Text size="T300">{item.name}</Text>
+ </MenuItem>
+ ))}
+ </Box>
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ </>
+ );
+}
+
+function Messages() {
+ const [hideMembershipEvents, setHideMembershipEvents] = useSetting(
+ settingsAtom,
+ 'hideMembershipEvents'
+ );
+ const [hideNickAvatarEvents, setHideNickAvatarEvents] = useSetting(
+ settingsAtom,
+ 'hideNickAvatarEvents'
+ );
+ const [mediaAutoLoad, setMediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad');
+ const [urlPreview, setUrlPreview] = useSetting(settingsAtom, 'urlPreview');
+ const [encUrlPreview, setEncUrlPreview] = useSetting(settingsAtom, 'encUrlPreview');
+ const [showHiddenEvents, setShowHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents');
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">Messages</Text>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile title="Message Layout" after={<SelectMessageLayout />} />
+ </SequenceCard>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile title="Message Spacing" after={<SelectMessageSpacing />} />
+ </SequenceCard>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Hide Membership Change"
+ after={
+ <Switch
+ variant="Primary"
+ value={hideMembershipEvents}
+ onChange={setHideMembershipEvents}
+ />
+ }
+ />
+ </SequenceCard>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Hide Profile Change"
+ after={
+ <Switch
+ variant="Primary"
+ value={hideNickAvatarEvents}
+ onChange={setHideNickAvatarEvents}
+ />
+ }
+ />
+ </SequenceCard>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Disable Media Auto Load"
+ after={<Switch variant="Primary" value={mediaAutoLoad} onChange={setMediaAutoLoad} />}
+ />
+ </SequenceCard>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Url Preview"
+ after={<Switch variant="Primary" value={urlPreview} onChange={setUrlPreview} />}
+ />
+ </SequenceCard>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Url Preview in Encrypted Room"
+ after={<Switch variant="Primary" value={encUrlPreview} onChange={setEncUrlPreview} />}
+ />
+ </SequenceCard>
+ <SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
+ <SettingTile
+ title="Show Hidden Events"
+ after={
+ <Switch variant="Primary" value={showHiddenEvents} onChange={setShowHiddenEvents} />
+ }
+ />
+ </SequenceCard>
+ </Box>
+ );
+}
+
+type GeneralProps = {
+ requestClose: () => void;
+};
+export function General({ requestClose }: GeneralProps) {
+ return (
+ <Page>
+ <PageHeader outlined={false}>
+ <Box grow="Yes" gap="200">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <Text size="H3" truncate>
+ General
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </PageHeader>
+ <Box grow="Yes">
+ <Scroll hideTrack visibility="Hover">
+ <PageContent>
+ <Box direction="Column" gap="700">
+ <Appearance />
+ <Editor />
+ <Messages />
+ </Box>
+ </PageContent>
+ </Scroll>
+ </Box>
+ </Page>
+ );
+}
--- /dev/null
+export * from './General';
--- /dev/null
+export * from './Settings';
--- /dev/null
+import React, { useCallback, useMemo } from 'react';
+import { Badge, Box, Text } from 'folds';
+import { ConditionKind, IPushRules, PushRuleCondition, PushRuleKind, RuleId } from 'matrix-js-sdk';
+import { useAccountData } from '../../../hooks/useAccountData';
+import { AccountDataEvent } from '../../../../types/matrix/accountData';
+import { NotificationModeSwitcher } from './NotificationModeSwitcher';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { PushRuleData, usePushRule } from '../../../hooks/usePushRule';
+import {
+ getNotificationModeActions,
+ NotificationMode,
+ useNotificationModeActions,
+} from '../../../hooks/useNotificationMode';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+
+const getAllMessageDefaultRule = (
+ ruleId: RuleId,
+ encrypted: boolean,
+ oneToOne: boolean
+): PushRuleData => {
+ const conditions: PushRuleCondition[] = [];
+ if (oneToOne)
+ conditions.push({
+ kind: ConditionKind.RoomMemberCount,
+ is: '2',
+ });
+ conditions.push({
+ kind: ConditionKind.EventMatch,
+ key: 'type',
+ pattern: encrypted ? 'm.room.encrypted' : 'm.room.message',
+ });
+
+ return {
+ kind: PushRuleKind.Underride,
+ pushRule: {
+ rule_id: ruleId,
+ default: true,
+ enabled: true,
+ conditions,
+ actions: getNotificationModeActions(NotificationMode.NotifyLoud),
+ },
+ };
+};
+
+type PushRulesProps = {
+ ruleId: RuleId.DM | RuleId.EncryptedDM | RuleId.Message | RuleId.EncryptedMessage;
+ pushRules: IPushRules;
+ encrypted?: boolean;
+ oneToOne?: boolean;
+};
+function AllMessagesModeSwitcher({
+ ruleId,
+ pushRules,
+ encrypted = false,
+ oneToOne = false,
+}: PushRulesProps) {
+ const mx = useMatrixClient();
+ const defaultPushRuleData = getAllMessageDefaultRule(ruleId, encrypted, oneToOne);
+ const { kind, pushRule } = usePushRule(pushRules, ruleId) ?? defaultPushRuleData;
+ const getModeActions = useNotificationModeActions();
+
+ const handleChange = useCallback(
+ async (mode: NotificationMode) => {
+ const actions = getModeActions(mode);
+ await mx.setPushRuleActions('global', kind, ruleId, actions);
+ },
+ [mx, getModeActions, kind, ruleId]
+ );
+
+ return <NotificationModeSwitcher pushRule={pushRule} onChange={handleChange} />;
+}
+
+export function AllMessagesNotifications() {
+ const pushRulesEvt = useAccountData(AccountDataEvent.PushRules);
+ const pushRules = useMemo(
+ () => pushRulesEvt?.getContent<IPushRules>() ?? { global: {} },
+ [pushRulesEvt]
+ );
+
+ return (
+ <Box direction="Column" gap="100">
+ <Box alignItems="Center" justifyContent="SpaceBetween" gap="200">
+ <Text size="L400">All Messages</Text>
+ <Box gap="100">
+ <Text size="T200">Badge: </Text>
+ <Badge radii="300" variant="Secondary" fill="Solid">
+ <Text size="L400">1</Text>
+ </Badge>
+ </Box>
+ </Box>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="1-to-1 Chats"
+ after={<AllMessagesModeSwitcher pushRules={pushRules} ruleId={RuleId.DM} oneToOne />}
+ />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="1-to-1 Chats (Encrypted)"
+ after={
+ <AllMessagesModeSwitcher
+ pushRules={pushRules}
+ ruleId={RuleId.EncryptedDM}
+ encrypted
+ oneToOne
+ />
+ }
+ />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Rooms"
+ after={<AllMessagesModeSwitcher pushRules={pushRules} ruleId={RuleId.Message} />}
+ />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Rooms (Encrypted)"
+ after={
+ <AllMessagesModeSwitcher
+ pushRules={pushRules}
+ ruleId={RuleId.EncryptedMessage}
+ encrypted
+ />
+ }
+ />
+ </SequenceCard>
+ </Box>
+ );
+}
--- /dev/null
+import React, { ChangeEventHandler, FormEventHandler, useCallback, useMemo, useState } from 'react';
+import { Box, Button, Chip, Icon, IconButton, Icons, Input, Spinner, Text, config } from 'folds';
+import { useAccountData } from '../../../hooks/useAccountData';
+import { AccountDataEvent } from '../../../../types/matrix/accountData';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+import { isUserId } from '../../../utils/matrix';
+
+type IgnoredUserListContent = {
+ ignored_users?: Record<string, object>;
+};
+
+function IgnoreUserInput({ userList }: { userList: string[] }) {
+ const mx = useMatrixClient();
+ const [userId, setUserId] = useState<string>('');
+
+ const [ignoreState, ignore] = useAsyncCallback(
+ useCallback(
+ async (uId: string) => {
+ mx.setIgnoredUsers([...userList, uId]);
+ setUserId('');
+ },
+ [mx, userList]
+ )
+ );
+ const ignoring = ignoreState.status === AsyncStatus.Loading;
+
+ const handleChange: ChangeEventHandler<HTMLInputElement> = (evt) => {
+ const uId = evt.currentTarget.value;
+ setUserId(uId);
+ };
+
+ const handleReset = () => {
+ setUserId('');
+ };
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (ignoring) return;
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const userIdInput = target?.userIdInput as HTMLInputElement | undefined;
+ const uId = userIdInput?.value.trim();
+ if (!uId) return;
+
+ if (!isUserId(uId)) return;
+
+ ignore(uId);
+ };
+
+ return (
+ <Box as="form" onSubmit={handleSubmit} gap="200" aria-disabled={ignoring}>
+ <Box grow="Yes" direction="Column">
+ <Input
+ required
+ name="userIdInput"
+ value={userId}
+ onChange={handleChange}
+ variant="Secondary"
+ radii="300"
+ style={{ paddingRight: config.space.S200 }}
+ readOnly={ignoring}
+ after={
+ userId &&
+ !ignoring && (
+ <IconButton
+ type="reset"
+ onClick={handleReset}
+ size="300"
+ radii="300"
+ variant="Secondary"
+ >
+ <Icon src={Icons.Cross} size="100" />
+ </IconButton>
+ )
+ }
+ />
+ </Box>
+ <Button
+ size="400"
+ variant="Secondary"
+ fill="Soft"
+ outlined
+ radii="300"
+ type="submit"
+ disabled={ignoring}
+ >
+ {ignoring && <Spinner variant="Secondary" size="300" />}
+ <Text size="B400">Block</Text>
+ </Button>
+ </Box>
+ );
+}
+
+function IgnoredUserChip({ userId, userList }: { userId: string; userList: string[] }) {
+ const mx = useMatrixClient();
+ const [unignoreState, unignore] = useAsyncCallback(
+ useCallback(
+ () => mx.setIgnoredUsers(userList.filter((uId) => uId !== userId)),
+ [mx, userId, userList]
+ )
+ );
+
+ const handleUnignore = () => unignore();
+
+ const unIgnoring = unignoreState.status === AsyncStatus.Loading;
+ return (
+ <Chip
+ variant="Secondary"
+ radii="Pill"
+ after={
+ unIgnoring ? (
+ <Spinner variant="Secondary" size="100" />
+ ) : (
+ <Icon src={Icons.Cross} size="100" />
+ )
+ }
+ onClick={handleUnignore}
+ disabled={unIgnoring}
+ >
+ <Text size="T200" truncate>
+ {userId}
+ </Text>
+ </Chip>
+ );
+}
+
+export function IgnoredUserList() {
+ const ignoredUserListEvt = useAccountData(AccountDataEvent.IgnoredUserList);
+ const ignoredUsers = useMemo(() => {
+ const ignoredUsersRecord =
+ ignoredUserListEvt?.getContent<IgnoredUserListContent>().ignored_users ?? {};
+ return Object.keys(ignoredUsersRecord);
+ }, [ignoredUserListEvt]);
+
+ return (
+ <Box direction="Column" gap="100">
+ <Box alignItems="Center" justifyContent="SpaceBetween" gap="200">
+ <Text size="L400">Block Messages</Text>
+ </Box>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Select User"
+ description="Prevent receiving message by adding userId into blocklist."
+ >
+ <Box direction="Column" gap="300">
+ <IgnoreUserInput userList={ignoredUsers} />
+ {ignoredUsers.length > 0 && (
+ <Box direction="Inherit" gap="100">
+ <Text size="L400">Blocklist</Text>
+ <Box wrap="Wrap" gap="200">
+ {ignoredUsers.map((userId) => (
+ <IgnoredUserChip key={userId} userId={userId} userList={ignoredUsers} />
+ ))}
+ </Box>
+ </Box>
+ )}
+ </Box>
+ </SettingTile>
+ </SequenceCard>
+ </Box>
+ );
+}
--- /dev/null
+import React, { ChangeEventHandler, FormEventHandler, useCallback, useMemo, useState } from 'react';
+import { IPushRule, IPushRules, PushRuleKind } from 'matrix-js-sdk';
+import { Box, Text, Badge, Button, Input, config, IconButton, Icons, Icon, Spinner } from 'folds';
+import { useAccountData } from '../../../hooks/useAccountData';
+import { AccountDataEvent } from '../../../../types/matrix/accountData';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import {
+ getNotificationModeActions,
+ NotificationMode,
+ NotificationModeOptions,
+ useNotificationModeActions,
+} from '../../../hooks/useNotificationMode';
+import { NotificationModeSwitcher } from './NotificationModeSwitcher';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+
+const NOTIFY_MODE_OPS: NotificationModeOptions = {
+ highlight: true,
+};
+
+function KeywordInput() {
+ const mx = useMatrixClient();
+ const [keyword, setKeyword] = useState<string>('');
+
+ const [keywordState, addKeyword] = useAsyncCallback(
+ useCallback(
+ async (k: string) => {
+ mx.addPushRule('global', PushRuleKind.ContentSpecific, k, {
+ actions: getNotificationModeActions(NotificationMode.Notify, NOTIFY_MODE_OPS),
+ pattern: k,
+ });
+ setKeyword('');
+ },
+ [mx]
+ )
+ );
+ const addingKeyword = keywordState.status === AsyncStatus.Loading;
+
+ const handleChange: ChangeEventHandler<HTMLInputElement> = (evt) => {
+ const k = evt.currentTarget.value;
+ setKeyword(k);
+ };
+
+ const handleReset = () => {
+ setKeyword('');
+ };
+
+ const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
+ evt.preventDefault();
+ if (addingKeyword) return;
+
+ const target = evt.target as HTMLFormElement | undefined;
+ const keywordInput = target?.keywordInput as HTMLInputElement | undefined;
+ const k = keywordInput?.value.trim();
+ if (!k) return;
+
+ addKeyword(k);
+ };
+
+ return (
+ <Box as="form" onSubmit={handleSubmit} gap="200" aria-disabled={addingKeyword}>
+ <Box grow="Yes" direction="Column">
+ <Input
+ required
+ name="keywordInput"
+ value={keyword}
+ onChange={handleChange}
+ variant="Secondary"
+ radii="300"
+ style={{ paddingRight: config.space.S200 }}
+ readOnly={addingKeyword}
+ after={
+ keyword &&
+ !addingKeyword && (
+ <IconButton
+ type="reset"
+ onClick={handleReset}
+ size="300"
+ radii="300"
+ variant="Secondary"
+ >
+ <Icon src={Icons.Cross} size="100" />
+ </IconButton>
+ )
+ }
+ />
+ </Box>
+ <Button
+ size="400"
+ variant="Secondary"
+ fill="Soft"
+ outlined
+ radii="300"
+ type="submit"
+ disabled={addingKeyword}
+ >
+ {addingKeyword && <Spinner variant="Secondary" size="300" />}
+ <Text size="B400">Save</Text>
+ </Button>
+ </Box>
+ );
+}
+
+type PushRulesProps = {
+ pushRule: IPushRule;
+};
+
+function KeywordCross({ pushRule }: PushRulesProps) {
+ const mx = useMatrixClient();
+ const [removeState, remove] = useAsyncCallback(
+ useCallback(
+ () => mx.deletePushRule('global', PushRuleKind.ContentSpecific, pushRule.rule_id),
+ [mx, pushRule]
+ )
+ );
+
+ const removing = removeState.status === AsyncStatus.Loading;
+ return (
+ <IconButton onClick={remove} size="300" radii="Pill" variant="Secondary" disabled={removing}>
+ {removing ? <Spinner size="100" /> : <Icon src={Icons.Cross} size="100" />}
+ </IconButton>
+ );
+}
+
+function KeywordModeSwitcher({ pushRule }: PushRulesProps) {
+ const mx = useMatrixClient();
+
+ const getModeActions = useNotificationModeActions(NOTIFY_MODE_OPS);
+
+ const handleChange = useCallback(
+ async (mode: NotificationMode) => {
+ const actions = getModeActions(mode);
+ await mx.setPushRuleActions(
+ 'global',
+ PushRuleKind.ContentSpecific,
+ pushRule.rule_id,
+ actions
+ );
+ },
+ [mx, getModeActions, pushRule]
+ );
+
+ return <NotificationModeSwitcher pushRule={pushRule} onChange={handleChange} />;
+}
+
+export function KeywordMessagesNotifications() {
+ const pushRulesEvt = useAccountData(AccountDataEvent.PushRules);
+ const pushRules = useMemo(
+ () => pushRulesEvt?.getContent<IPushRules>() ?? { global: {} },
+ [pushRulesEvt]
+ );
+
+ const keywordPushRules = useMemo(() => {
+ const content = pushRules.global.content ?? [];
+ return content.filter(
+ (pushRule) => pushRule.default === false && typeof pushRule.pattern === 'string'
+ );
+ }, [pushRules]);
+
+ return (
+ <Box direction="Column" gap="100">
+ <Box alignItems="Center" justifyContent="SpaceBetween" gap="200">
+ <Text size="L400">Keyword Messages</Text>
+ <Box gap="100">
+ <Text size="T200">Badge: </Text>
+ <Badge radii="300" variant="Success" fill="Solid">
+ <Text size="L400">1</Text>
+ </Badge>
+ </Box>
+ </Box>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Select Keyword"
+ description="Set a notification preference for message containing given keyword."
+ >
+ <KeywordInput />
+ </SettingTile>
+ </SequenceCard>
+ {keywordPushRules.map((pushRule) => (
+ <SequenceCard
+ key={pushRule.rule_id}
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title={`"${pushRule.pattern}"`}
+ before={<KeywordCross pushRule={pushRule} />}
+ after={<KeywordModeSwitcher pushRule={pushRule} />}
+ />
+ </SequenceCard>
+ ))}
+ </Box>
+ );
+}
--- /dev/null
+import {
+ Box,
+ Button,
+ config,
+ Icon,
+ Icons,
+ Menu,
+ MenuItem,
+ PopOut,
+ RectCords,
+ Spinner,
+ Text,
+} from 'folds';
+import { IPushRule } from 'matrix-js-sdk';
+import React, { MouseEventHandler, useMemo, useState } from 'react';
+import FocusTrap from 'focus-trap-react';
+import { NotificationMode, useNotificationActionsMode } from '../../../hooks/useNotificationMode';
+import { stopPropagation } from '../../../utils/keyboard';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+
+export const useNotificationModes = (): NotificationMode[] =>
+ useMemo(() => [NotificationMode.NotifyLoud, NotificationMode.Notify, NotificationMode.OFF], []);
+
+const useNotificationModeStr = (): Record<NotificationMode, string> =>
+ useMemo(
+ () => ({
+ [NotificationMode.OFF]: 'Disable',
+ [NotificationMode.Notify]: 'Notify Silent',
+ [NotificationMode.NotifyLoud]: 'Notify Loud',
+ }),
+ []
+ );
+
+type NotificationModeSwitcherProps = {
+ pushRule: IPushRule;
+ onChange: (mode: NotificationMode) => Promise<void>;
+};
+export function NotificationModeSwitcher({ pushRule, onChange }: NotificationModeSwitcherProps) {
+ const modes = useNotificationModes();
+ const modeToStr = useNotificationModeStr();
+ const selectedMode = useNotificationActionsMode(pushRule.actions);
+ const [changeState, change] = useAsyncCallback(onChange);
+ const changing = changeState.status === AsyncStatus.Loading;
+
+ const [menuCords, setMenuCords] = useState<RectCords>();
+
+ const handleMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
+ setMenuCords(evt.currentTarget.getBoundingClientRect());
+ };
+
+ const handleSelect = (mode: NotificationMode) => {
+ setMenuCords(undefined);
+ change(mode);
+ };
+
+ return (
+ <>
+ <Button
+ size="300"
+ variant="Secondary"
+ outlined
+ fill="Soft"
+ radii="300"
+ after={
+ changing ? (
+ <Spinner variant="Secondary" size="300" />
+ ) : (
+ <Icon size="300" src={Icons.ChevronBottom} />
+ )
+ }
+ onClick={handleMenu}
+ disabled={changing}
+ >
+ <Text size="T300">{modeToStr[selectedMode]}</Text>
+ </Button>
+ <PopOut
+ anchor={menuCords}
+ offset={5}
+ position="Bottom"
+ align="End"
+ content={
+ <FocusTrap
+ focusTrapOptions={{
+ initialFocus: false,
+ onDeactivate: () => setMenuCords(undefined),
+ clickOutsideDeactivates: true,
+ isKeyForward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
+ isKeyBackward: (evt: KeyboardEvent) =>
+ evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
+ escapeDeactivates: stopPropagation,
+ }}
+ >
+ <Menu>
+ <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
+ {modes.map((mode) => (
+ <MenuItem
+ key={mode}
+ size="300"
+ variant="Surface"
+ aria-selected={mode === selectedMode}
+ radii="300"
+ onClick={() => handleSelect(mode)}
+ >
+ <Box grow="Yes">
+ <Text size="T300">{modeToStr[mode]}</Text>
+ </Box>
+ </MenuItem>
+ ))}
+ </Box>
+ </Menu>
+ </FocusTrap>
+ }
+ />
+ </>
+ );
+}
--- /dev/null
+import React from 'react';
+import { Box, Text, IconButton, Icon, Icons, Scroll, Switch, Button, color } from 'folds';
+import { Page, PageContent, PageHeader } from '../../../components/page';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { useSetting } from '../../../state/hooks/settings';
+import { settingsAtom } from '../../../state/settings';
+import { usePermissionState } from '../../../hooks/usePermission';
+import { AllMessagesNotifications } from './AllMessages';
+import { SpecialMessagesNotifications } from './SpecialMessages';
+import { KeywordMessagesNotifications } from './KeywordMessages';
+import { IgnoredUserList } from './IgnoredUserList';
+
+function SystemNotification() {
+ const notifPermission = usePermissionState(
+ 'notifications',
+ window.Notification.permission === 'default' ? 'prompt' : window.Notification.permission
+ );
+ const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications');
+ const [isNotificationSounds, setIsNotificationSounds] = useSetting(
+ settingsAtom,
+ 'isNotificationSounds'
+ );
+
+ const requestNotificationPermission = () => {
+ window.Notification.requestPermission();
+ };
+
+ return (
+ <Box direction="Column" gap="100">
+ <Text size="L400">System</Text>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Desktop Notifications"
+ description={
+ notifPermission === 'denied' ? (
+ <Text as="span" style={{ color: color.Critical.Main }} size="T200">
+ Notification permission is blocked. Please allow notification permission from
+ browser address bar.
+ </Text>
+ ) : (
+ <span>Show desktop notifications when message arrive.</span>
+ )
+ }
+ after={
+ notifPermission === 'prompt' ? (
+ <Button size="300" radii="300" onClick={requestNotificationPermission}>
+ <Text size="B300">Enable</Text>
+ </Button>
+ ) : (
+ <Switch
+ disabled={notifPermission !== 'granted'}
+ value={showNotifications}
+ onChange={setShowNotifications}
+ />
+ )
+ }
+ />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Notification Sound"
+ description="Play sound when new message arrive."
+ after={<Switch value={isNotificationSounds} onChange={setIsNotificationSounds} />}
+ />
+ </SequenceCard>
+ </Box>
+ );
+}
+
+type NotificationsProps = {
+ requestClose: () => void;
+};
+export function Notifications({ requestClose }: NotificationsProps) {
+ return (
+ <Page>
+ <PageHeader outlined={false}>
+ <Box grow="Yes" gap="200">
+ <Box grow="Yes" alignItems="Center" gap="200">
+ <Text size="H3" truncate>
+ Notifications
+ </Text>
+ </Box>
+ <Box shrink="No">
+ <IconButton onClick={requestClose} variant="Surface">
+ <Icon src={Icons.Cross} />
+ </IconButton>
+ </Box>
+ </Box>
+ </PageHeader>
+ <Box grow="Yes">
+ <Scroll hideTrack visibility="Hover">
+ <PageContent>
+ <Box direction="Column" gap="700">
+ <SystemNotification />
+ <AllMessagesNotifications />
+ <SpecialMessagesNotifications />
+ <KeywordMessagesNotifications />
+ <IgnoredUserList />
+ </Box>
+ </PageContent>
+ </Scroll>
+ </Box>
+ </Page>
+ );
+}
--- /dev/null
+import React, { useCallback, useMemo } from 'react';
+import { ConditionKind, IPushRules, PushRuleKind, RuleId } from 'matrix-js-sdk';
+import { Box, Text, Badge } from 'folds';
+import { useAccountData } from '../../../hooks/useAccountData';
+import { AccountDataEvent } from '../../../../types/matrix/accountData';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { useUserProfile } from '../../../hooks/useUserProfile';
+import { getMxIdLocalPart } from '../../../utils/matrix';
+import { makePushRuleData, PushRuleData, usePushRule } from '../../../hooks/usePushRule';
+import {
+ getNotificationModeActions,
+ NotificationMode,
+ NotificationModeOptions,
+ useNotificationModeActions,
+} from '../../../hooks/useNotificationMode';
+import { NotificationModeSwitcher } from './NotificationModeSwitcher';
+
+const NOTIFY_MODE_OPS: NotificationModeOptions = {
+ highlight: true,
+};
+const getDefaultIsUserMention = (userId: string): PushRuleData =>
+ makePushRuleData(
+ PushRuleKind.Override,
+ RuleId.IsUserMention,
+ getNotificationModeActions(NotificationMode.NotifyLoud, { highlight: true }),
+ [
+ {
+ kind: ConditionKind.EventPropertyContains,
+ key: 'content.m\\.mentions.user_ids',
+ value: userId,
+ },
+ ]
+ );
+
+const DefaultContainsDisplayName = makePushRuleData(
+ PushRuleKind.Override,
+ RuleId.ContainsDisplayName,
+ getNotificationModeActions(NotificationMode.NotifyLoud, { highlight: true }),
+ [
+ {
+ kind: ConditionKind.ContainsDisplayName,
+ },
+ ]
+);
+
+const getDefaultContainsUsername = (username: string) =>
+ makePushRuleData(
+ PushRuleKind.ContentSpecific,
+ RuleId.ContainsUserName,
+ getNotificationModeActions(NotificationMode.NotifyLoud, { highlight: true }),
+ undefined,
+ username
+ );
+
+const DefaultIsRoomMention = makePushRuleData(
+ PushRuleKind.Override,
+ RuleId.IsRoomMention,
+ getNotificationModeActions(NotificationMode.Notify, { highlight: true }),
+ [
+ {
+ kind: ConditionKind.EventPropertyIs,
+ key: 'content.m\\.mentions.room',
+ value: true,
+ },
+ {
+ kind: ConditionKind.SenderNotificationPermission,
+ key: 'room',
+ },
+ ]
+);
+
+const DefaultAtRoomNotification = makePushRuleData(
+ PushRuleKind.Override,
+ RuleId.AtRoomNotification,
+ getNotificationModeActions(NotificationMode.Notify, { highlight: true }),
+ [
+ {
+ kind: ConditionKind.EventMatch,
+ key: 'content.body',
+ pattern: '@room',
+ },
+ {
+ kind: ConditionKind.SenderNotificationPermission,
+ key: 'room',
+ },
+ ]
+);
+
+type PushRulesProps = {
+ ruleId: RuleId;
+ pushRules: IPushRules;
+ defaultPushRuleData: PushRuleData;
+};
+function MentionModeSwitcher({ ruleId, pushRules, defaultPushRuleData }: PushRulesProps) {
+ const mx = useMatrixClient();
+
+ const { kind, pushRule } = usePushRule(pushRules, ruleId) ?? defaultPushRuleData;
+ const getModeActions = useNotificationModeActions(NOTIFY_MODE_OPS);
+
+ const handleChange = useCallback(
+ async (mode: NotificationMode) => {
+ const actions = getModeActions(mode);
+ await mx.setPushRuleActions('global', kind, ruleId, actions);
+ },
+ [mx, getModeActions, kind, ruleId]
+ );
+
+ return <NotificationModeSwitcher pushRule={pushRule} onChange={handleChange} />;
+}
+
+export function SpecialMessagesNotifications() {
+ const mx = useMatrixClient();
+ const userId = mx.getUserId()!;
+ const { displayName } = useUserProfile(userId);
+ const pushRulesEvt = useAccountData(AccountDataEvent.PushRules);
+ const pushRules = useMemo(
+ () => pushRulesEvt?.getContent<IPushRules>() ?? { global: {} },
+ [pushRulesEvt]
+ );
+
+ return (
+ <Box direction="Column" gap="100">
+ <Box alignItems="Center" justifyContent="SpaceBetween" gap="200">
+ <Text size="L400">Special Messages</Text>
+ <Box gap="100">
+ <Text size="T200">Badge: </Text>
+ <Badge radii="300" variant="Success" fill="Solid">
+ <Text size="L400">1</Text>
+ </Badge>
+ </Box>
+ </Box>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title={`Mention User ID ("${userId}")`}
+ after={
+ <MentionModeSwitcher
+ pushRules={pushRules}
+ ruleId={RuleId.IsUserMention}
+ defaultPushRuleData={getDefaultIsUserMention(userId)}
+ />
+ }
+ />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title={`Contains Displayname ${displayName ? `("${displayName}")` : ''}`}
+ after={
+ <MentionModeSwitcher
+ pushRules={pushRules}
+ ruleId={RuleId.ContainsDisplayName}
+ defaultPushRuleData={DefaultContainsDisplayName}
+ />
+ }
+ />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title={`Contains Username ("${getMxIdLocalPart(userId)}")`}
+ after={
+ <MentionModeSwitcher
+ pushRules={pushRules}
+ ruleId={RuleId.ContainsUserName}
+ defaultPushRuleData={getDefaultContainsUsername(getMxIdLocalPart(userId) ?? userId)}
+ />
+ }
+ />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Mention @room"
+ after={
+ <MentionModeSwitcher
+ pushRules={pushRules}
+ ruleId={RuleId.IsRoomMention}
+ defaultPushRuleData={DefaultIsRoomMention}
+ />
+ }
+ />
+ </SequenceCard>
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Contains @room"
+ after={
+ <MentionModeSwitcher
+ pushRules={pushRules}
+ ruleId={RuleId.AtRoomNotification}
+ defaultPushRuleData={DefaultAtRoomNotification}
+ />
+ }
+ />
+ </SequenceCard>
+ </Box>
+ );
+}
--- /dev/null
+export * from './Notifications';
--- /dev/null
+import { style } from '@vanilla-extract/css';
+import { config } from 'folds';
+
+export const SequenceCardStyle = style({
+ padding: config.space.S300,
+});
+++ /dev/null
-/* eslint-disable import/prefer-default-export */
-import { useState, useEffect } from 'react';
-import { useMatrixClient } from './useMatrixClient';
-
-export function useAccountData(eventType) {
- const mx = useMatrixClient();
- const [event, setEvent] = useState(mx.getAccountData(eventType));
-
- useEffect(() => {
- const handleChange = (mEvent) => {
- if (mEvent.getType() !== eventType) return;
- setEvent(mEvent);
- };
- mx.on('accountData', handleChange);
- return () => {
- mx.removeListener('accountData', handleChange);
- };
- }, [mx, eventType]);
-
- return event;
-}
--- /dev/null
+import { useState, useCallback } from 'react';
+import { useMatrixClient } from './useMatrixClient';
+import { useAccountDataCallback } from './useAccountDataCallback';
+
+export function useAccountData(eventType: string) {
+ const mx = useMatrixClient();
+ const [event, setEvent] = useState(() => mx.getAccountData(eventType));
+
+ useAccountDataCallback(
+ mx,
+ useCallback(
+ (evt) => {
+ if (evt.getType() === eventType) {
+ setEvent(evt);
+ }
+ },
+ [eventType, setEvent]
+ )
+ );
+
+ return event;
+}
-import { useCallback, useRef, useState } from 'react';
+import { useCallback, useEffect, useRef, useState } from 'react';
import { flushSync } from 'react-dom';
import { useAlive } from './useAlive';
export type AsyncCallback<TArgs extends unknown[], TData> = (...args: TArgs) => Promise<TData>;
-export const useAsyncCallback = <TData, TError, TArgs extends unknown[]>(
- asyncCallback: AsyncCallback<TArgs, TData>
-): [AsyncState<TData, TError>, AsyncCallback<TArgs, TData>] => {
- const [state, setState] = useState<AsyncState<TData, TError>>({
- status: AsyncStatus.Idle,
- });
+export const useAsync = <TData, TError, TArgs extends unknown[]>(
+ asyncCallback: AsyncCallback<TArgs, TData>,
+ onStateChange: (state: AsyncState<TData, TError>) => void
+): AsyncCallback<TArgs, TData> => {
const alive = useAlive();
// Tracks the request number.
flushSync(() => {
// flushSync because
// https://github.com/facebook/react/issues/26713#issuecomment-1872085134
- setState({
+ onStateChange({
status: AsyncStatus.Loading,
});
});
}
if (alive()) {
queueMicrotask(() => {
- setState({
+ onStateChange({
status: AsyncStatus.Success,
data,
});
if (alive()) {
queueMicrotask(() => {
- setState({
+ onStateChange({
status: AsyncStatus.Error,
error: e as TError,
});
throw e;
}
},
- [asyncCallback, alive]
+ [asyncCallback, alive, onStateChange]
);
+ return callback;
+};
+
+export const useAsyncCallback = <TData, TError, TArgs extends unknown[]>(
+ asyncCallback: AsyncCallback<TArgs, TData>
+): [AsyncState<TData, TError>, AsyncCallback<TArgs, TData>] => {
+ const [state, setState] = useState<AsyncState<TData, TError>>({
+ status: AsyncStatus.Idle,
+ });
+
+ const callback = useAsync(asyncCallback, setState);
+
return [state, callback];
};
+
+export const useAsyncCallbackValue = <TData, TError>(
+ asyncCallback: AsyncCallback<[], TData>
+): [AsyncState<TData, TError>, AsyncCallback<[], TData>] => {
+ const [state, load] = useAsyncCallback<TData, TError, []>(asyncCallback);
+
+ useEffect(() => {
+ load();
+ }, [load]);
+
+ return [state, load];
+};
--- /dev/null
+import { AccountDataEvent, SecretAccountData } from '../../types/matrix/accountData';
+import { useAccountData } from './useAccountData';
+
+export const useCrossSigningActive = (): boolean => {
+ const masterEvent = useAccountData(AccountDataEvent.CrossSigningMaster);
+ const content = masterEvent?.getContent<SecretAccountData>();
+
+ return !!content;
+};
+++ /dev/null
-/* eslint-disable import/prefer-default-export */
-import { useState, useEffect } from 'react';
-
-import { hasCrossSigningAccountData } from '../../util/matrixUtil';
-import { useMatrixClient } from './useMatrixClient';
-
-export function useCrossSigningStatus() {
- const mx = useMatrixClient();
- const [isCSEnabled, setIsCSEnabled] = useState(hasCrossSigningAccountData(mx));
-
- useEffect(() => {
- if (isCSEnabled) return undefined;
- const handleAccountData = (event) => {
- if (event.getType() === 'm.cross_signing.master') {
- setIsCSEnabled(true);
- }
- };
-
- mx.on('accountData', handleAccountData);
- return () => {
- mx.removeListener('accountData', handleAccountData);
- };
- }, [mx, isCSEnabled]);
- return isCSEnabled;
-}
-/* eslint-disable import/prefer-default-export */
-import { useState, useEffect } from 'react';
-import { CryptoEvent, IMyDevice } from 'matrix-js-sdk';
-import { CryptoEventHandlerMap } from 'matrix-js-sdk/lib/crypto';
+import { useEffect, useCallback, useMemo } from 'react';
+import { IMyDevice } from 'matrix-js-sdk';
+import { useQuery } from '@tanstack/react-query';
+import { CryptoEvent, CryptoEventHandlerMap } from 'matrix-js-sdk/lib/crypto';
import { useMatrixClient } from './useMatrixClient';
-export function useDeviceList() {
+export const useDeviceListChange = (
+ onChange: CryptoEventHandlerMap[CryptoEvent.DevicesUpdated]
+) => {
const mx = useMatrixClient();
- const [deviceList, setDeviceList] = useState<IMyDevice[] | null>(null);
-
useEffect(() => {
- let isMounted = true;
-
- const updateDevices = () =>
- mx.getDevices().then((data) => {
- if (!isMounted) return;
- setDeviceList(data.devices || []);
- });
- updateDevices();
-
- const handleDevicesUpdate: CryptoEventHandlerMap[CryptoEvent.DevicesUpdated] = (users) => {
- const userId = mx.getUserId();
- if (userId && users.includes(userId)) {
- updateDevices();
- }
- };
-
- mx.on(CryptoEvent.DevicesUpdated, handleDevicesUpdate);
+ mx.on(CryptoEvent.DevicesUpdated, onChange);
return () => {
- mx.removeListener(CryptoEvent.DevicesUpdated, handleDevicesUpdate);
- isMounted = false;
+ mx.removeListener(CryptoEvent.DevicesUpdated, onChange);
};
+ }, [mx, onChange]);
+};
+
+const DEVICES_QUERY_KEY = ['devices'];
+
+export function useDeviceList(): [undefined | IMyDevice[], () => Promise<void>] {
+ const mx = useMatrixClient();
+
+ const fetchDevices = useCallback(async () => {
+ const data = await mx.getDevices();
+ return data.devices ?? [];
}, [mx]);
- return deviceList;
+
+ const { data: deviceList, refetch } = useQuery({
+ queryKey: DEVICES_QUERY_KEY,
+ queryFn: fetchDevices,
+ staleTime: 0,
+ gcTime: Infinity,
+ refetchOnMount: 'always',
+ });
+
+ const refreshDeviceList = useCallback(async () => {
+ await refetch();
+ }, [refetch]);
+
+ useDeviceListChange(
+ useCallback(
+ (users) => {
+ const userId = mx.getUserId();
+ if (userId && users.includes(userId)) {
+ refreshDeviceList();
+ }
+ },
+ [mx, refreshDeviceList]
+ )
+ );
+
+ return [deviceList ?? undefined, refreshDeviceList];
}
+
+export const useDeviceIds = (devices: IMyDevice[] | undefined): string[] => {
+ const devicesId = useMemo(() => devices?.map((device) => device.device_id) ?? [], [devices]);
+
+ return devicesId;
+};
+
+export const useSplitCurrentDevice = (
+ devices: IMyDevice[] | undefined
+): [IMyDevice | undefined, IMyDevice[] | undefined] => {
+ const mx = useMatrixClient();
+ const currentDeviceId = mx.getDeviceId();
+ const currentDevice = useMemo(
+ () => devices?.find((d) => d.device_id === currentDeviceId),
+ [devices, currentDeviceId]
+ );
+ const otherDevices = useMemo(
+ () => devices?.filter((device) => device.device_id !== currentDeviceId),
+ [devices, currentDeviceId]
+ );
+
+ return [currentDevice, otherDevices];
+};
--- /dev/null
+import { useCallback, useEffect, useState } from 'react';
+import { CryptoApi } from 'matrix-js-sdk/lib/crypto-api';
+import { verifiedDevice } from '../utils/matrix-crypto';
+import { useAlive } from './useAlive';
+import { fulfilledPromiseSettledResult } from '../utils/common';
+import { useMatrixClient } from './useMatrixClient';
+import { useDeviceListChange } from './useDeviceList';
+
+export enum VerificationStatus {
+ Unknown,
+ Unverified,
+ Verified,
+ Unsupported,
+}
+
+export const useDeviceVerificationDetect = (
+ crypto: CryptoApi | undefined,
+ userId: string,
+ deviceId: string | undefined,
+ callback: (status: VerificationStatus) => void
+): void => {
+ const mx = useMatrixClient();
+
+ const updateStatus = useCallback(async () => {
+ if (crypto && deviceId) {
+ const data = await verifiedDevice(crypto, userId, deviceId);
+ if (data === null) {
+ callback(VerificationStatus.Unsupported);
+ return;
+ }
+ callback(data ? VerificationStatus.Verified : VerificationStatus.Unverified);
+ return;
+ }
+ callback(VerificationStatus.Unknown);
+ }, [crypto, deviceId, userId, callback]);
+
+ useEffect(() => {
+ updateStatus();
+ }, [mx, updateStatus, userId]);
+
+ useDeviceListChange(
+ useCallback(
+ (userIds) => {
+ if (userIds.includes(userId)) {
+ updateStatus();
+ }
+ },
+ [userId, updateStatus]
+ )
+ );
+};
+
+export const useDeviceVerificationStatus = (
+ crypto: CryptoApi | undefined,
+ userId: string,
+ deviceId: string | undefined
+): VerificationStatus => {
+ const [verificationStatus, setVerificationStatus] = useState(VerificationStatus.Unknown);
+
+ useDeviceVerificationDetect(crypto, userId, deviceId, setVerificationStatus);
+
+ return verificationStatus;
+};
+
+export const useUnverifiedDeviceCount = (
+ crypto: CryptoApi | undefined,
+ userId: string,
+ devices: string[]
+): number | undefined => {
+ const [unverifiedCount, setUnverifiedCount] = useState<number>();
+ const alive = useAlive();
+
+ const updateCount = useCallback(async () => {
+ let count = 0;
+ if (crypto) {
+ const promises = devices.map((deviceId) => verifiedDevice(crypto, userId, deviceId));
+ const result = await Promise.allSettled(promises);
+ const settledResult = fulfilledPromiseSettledResult(result);
+ settledResult.forEach((status) => {
+ if (status === false) {
+ count += 1;
+ }
+ });
+ }
+ if (alive()) {
+ setUnverifiedCount(count);
+ }
+ }, [crypto, userId, devices, alive]);
+
+ useDeviceListChange(
+ useCallback(
+ (userIds) => {
+ if (userIds.includes(userId)) {
+ updateCount();
+ }
+ },
+ [userId, updateCount]
+ )
+ );
+
+ useEffect(() => {
+ updateCount();
+ }, [updateCount]);
+
+ return unverifiedCount;
+};
-import { ClientEvent, MatrixClient, MatrixEvent, Room, RoomStateEvent } from 'matrix-js-sdk';
-import { useEffect, useMemo } from 'react';
-import { getRelevantPacks, ImagePack, PackUsage } from '../plugins/custom-emoji';
+import { Room } from 'matrix-js-sdk';
+import { useCallback, useMemo, useState } from 'react';
import { AccountDataEvent } from '../../types/matrix/accountData';
import { StateEvent } from '../../types/matrix/room';
-import { useForceUpdate } from './useForceUpdate';
-
-export const useRelevantImagePacks = (
- mx: MatrixClient,
- usage: PackUsage,
- rooms: Room[]
-): ImagePack[] => {
- const [forceCount, forceUpdate] = useForceUpdate();
-
- const relevantPacks = useMemo(
- () => getRelevantPacks(mx, rooms).filter((pack) => pack.getImagesFor(usage).length > 0),
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [mx, usage, rooms, forceCount]
+import {
+ getGlobalImagePacks,
+ getRoomImagePack,
+ getRoomImagePacks,
+ getUserImagePack,
+ ImagePack,
+ ImageUsage,
+} from '../plugins/custom-emoji';
+import { useMatrixClient } from './useMatrixClient';
+import { useAccountDataCallback } from './useAccountDataCallback';
+import { useStateEventCallback } from './useStateEventCallback';
+
+export const useUserImagePack = (): ImagePack | undefined => {
+ const mx = useMatrixClient();
+ const [userPack, setUserPack] = useState(() => getUserImagePack(mx));
+
+ useAccountDataCallback(
+ mx,
+ useCallback(
+ (mEvent) => {
+ if (mEvent.getType() === AccountDataEvent.PoniesUserEmotes) {
+ setUserPack(getUserImagePack(mx));
+ }
+ },
+ [mx]
+ )
+ );
+
+ return userPack;
+};
+
+export const useGlobalImagePacks = (): ImagePack[] => {
+ const mx = useMatrixClient();
+ const [globalPacks, setGlobalPacks] = useState(() => getGlobalImagePacks(mx));
+
+ useAccountDataCallback(
+ mx,
+ useCallback(
+ (mEvent) => {
+ if (mEvent.getType() === AccountDataEvent.PoniesEmoteRooms) {
+ setGlobalPacks(getGlobalImagePacks(mx));
+ }
+ },
+ [mx]
+ )
);
- useEffect(() => {
- const handleUpdate = (event: MatrixEvent) => {
- if (
- event.getType() === AccountDataEvent.PoniesEmoteRooms ||
- event.getType() === AccountDataEvent.PoniesUserEmotes
- ) {
- forceUpdate();
- }
- const eventRoomId = event.getRoomId();
- if (
- eventRoomId &&
- event.getType() === StateEvent.PoniesRoomEmotes &&
- rooms.find((room) => room.roomId === eventRoomId)
- ) {
- forceUpdate();
- }
- };
-
- mx.on(ClientEvent.AccountData, handleUpdate);
- mx.on(RoomStateEvent.Events, handleUpdate);
- return () => {
- mx.removeListener(ClientEvent.AccountData, handleUpdate);
- mx.removeListener(RoomStateEvent.Events, handleUpdate);
- };
- }, [mx, rooms, forceUpdate]);
+ useStateEventCallback(
+ mx,
+ useCallback(
+ (mEvent) => {
+ const eventType = mEvent.getType();
+ const roomId = mEvent.getRoomId();
+ const stateKey = mEvent.getStateKey();
+ if (eventType === StateEvent.PoniesRoomEmotes && roomId && typeof stateKey === 'string') {
+ const global = !!globalPacks.find(
+ (pack) =>
+ pack.address && pack.address.roomId === roomId && pack.address.stateKey === stateKey
+ );
+ if (global) {
+ setGlobalPacks(getGlobalImagePacks(mx));
+ }
+ }
+ },
+ [mx, globalPacks]
+ )
+ );
+
+ return globalPacks;
+};
+
+export const useRoomImagePack = (room: Room, stateKey: string): ImagePack | undefined => {
+ const mx = useMatrixClient();
+ const [roomPack, setRoomPack] = useState(() => getRoomImagePack(room, stateKey));
+
+ useStateEventCallback(
+ mx,
+ useCallback(
+ (mEvent) => {
+ if (
+ mEvent.getRoomId() === room.roomId &&
+ mEvent.getType() === StateEvent.PoniesRoomEmotes &&
+ mEvent.getStateKey() === stateKey
+ ) {
+ setRoomPack(getRoomImagePack(room, stateKey));
+ }
+ },
+ [room, stateKey]
+ )
+ );
+
+ return roomPack;
+};
+
+export const useRoomImagePacks = (room: Room): ImagePack[] => {
+ const mx = useMatrixClient();
+ const [roomPacks, setRoomPacks] = useState(() => getRoomImagePacks(room));
+
+ useStateEventCallback(
+ mx,
+ useCallback(
+ (mEvent) => {
+ if (
+ mEvent.getRoomId() === room.roomId &&
+ mEvent.getType() === StateEvent.PoniesRoomEmotes
+ ) {
+ setRoomPacks(getRoomImagePacks(room));
+ }
+ },
+ [room]
+ )
+ );
+
+ return roomPacks;
+};
+
+export const useRoomsImagePacks = (rooms: Room[]) => {
+ const mx = useMatrixClient();
+ const [roomPacks, setRoomPacks] = useState(() => rooms.flatMap(getRoomImagePacks));
+
+ useStateEventCallback(
+ mx,
+ useCallback(
+ (mEvent) => {
+ if (
+ rooms.find((room) => room.roomId === mEvent.getRoomId()) &&
+ mEvent.getType() === StateEvent.PoniesRoomEmotes
+ ) {
+ setRoomPacks(rooms.flatMap(getRoomImagePacks));
+ }
+ },
+ [rooms]
+ )
+ );
+
+ return roomPacks;
+};
+
+export const useRelevantImagePacks = (usage: ImageUsage, rooms: Room[]): ImagePack[] => {
+ const userPack = useUserImagePack();
+ const globalPacks = useGlobalImagePacks();
+ const roomsPacks = useRoomsImagePacks(rooms);
+
+ const relevantPacks = useMemo(() => {
+ const packs = userPack ? [userPack] : [];
+ const globalPackIds = new Set(globalPacks.map((pack) => pack.id));
+
+ const relPacks = packs.concat(
+ globalPacks,
+ roomsPacks.filter((pack) => !globalPackIds.has(pack.id))
+ );
+
+ return relPacks.filter((pack) => pack.getImages(usage).length > 0);
+ }, [userPack, globalPacks, roomsPacks, usage]);
return relevantPacks;
};
--- /dev/null
+import {
+ BackupTrustInfo,
+ CryptoApi,
+ CryptoEvent,
+ CryptoEventHandlerMap,
+ KeyBackupInfo,
+} from 'matrix-js-sdk/lib/crypto-api';
+import { useCallback, useEffect, useState } from 'react';
+import { useMatrixClient } from './useMatrixClient';
+import { useAlive } from './useAlive';
+
+export const useKeyBackupStatusChange = (
+ onChange: CryptoEventHandlerMap[CryptoEvent.KeyBackupStatus]
+) => {
+ const mx = useMatrixClient();
+
+ useEffect(() => {
+ mx.on(CryptoEvent.KeyBackupStatus, onChange);
+ return () => {
+ mx.removeListener(CryptoEvent.KeyBackupStatus, onChange);
+ };
+ }, [mx, onChange]);
+};
+
+export const useKeyBackupStatus = (crypto: CryptoApi): boolean => {
+ const alive = useAlive();
+ const [status, setStatus] = useState(false);
+
+ useEffect(() => {
+ crypto.getActiveSessionBackupVersion().then((v) => {
+ if (alive()) {
+ setStatus(typeof v === 'string');
+ }
+ });
+ }, [crypto, alive]);
+
+ useKeyBackupStatusChange(setStatus);
+
+ return status;
+};
+
+export const useKeyBackupSessionsRemainingChange = (
+ onChange: CryptoEventHandlerMap[CryptoEvent.KeyBackupSessionsRemaining]
+) => {
+ const mx = useMatrixClient();
+
+ useEffect(() => {
+ mx.on(CryptoEvent.KeyBackupSessionsRemaining, onChange);
+ return () => {
+ mx.removeListener(CryptoEvent.KeyBackupSessionsRemaining, onChange);
+ };
+ }, [mx, onChange]);
+};
+
+export const useKeyBackupFailedChange = (
+ onChange: CryptoEventHandlerMap[CryptoEvent.KeyBackupFailed]
+) => {
+ const mx = useMatrixClient();
+
+ useEffect(() => {
+ mx.on(CryptoEvent.KeyBackupFailed, onChange);
+ return () => {
+ mx.removeListener(CryptoEvent.KeyBackupFailed, onChange);
+ };
+ }, [mx, onChange]);
+};
+
+export const useKeyBackupDecryptionKeyCached = (
+ onChange: CryptoEventHandlerMap[CryptoEvent.KeyBackupDecryptionKeyCached]
+) => {
+ const mx = useMatrixClient();
+
+ useEffect(() => {
+ mx.on(CryptoEvent.KeyBackupDecryptionKeyCached, onChange);
+ return () => {
+ mx.removeListener(CryptoEvent.KeyBackupDecryptionKeyCached, onChange);
+ };
+ }, [mx, onChange]);
+};
+
+export const useKeyBackupSync = (): [number, string | undefined] => {
+ const [remaining, setRemaining] = useState(0);
+ const [failure, setFailure] = useState<string>();
+
+ useKeyBackupSessionsRemainingChange(
+ useCallback((count) => {
+ setRemaining(count);
+ setFailure(undefined);
+ }, [])
+ );
+
+ useKeyBackupFailedChange(
+ useCallback((f) => {
+ if (typeof f === 'string') {
+ setFailure(f);
+ setRemaining(0);
+ }
+ }, [])
+ );
+
+ return [remaining, failure];
+};
+
+export const useKeyBackupInfo = (crypto: CryptoApi): KeyBackupInfo | undefined | null => {
+ const alive = useAlive();
+ const [info, setInfo] = useState<KeyBackupInfo | null>();
+
+ const fetchInfo = useCallback(() => {
+ crypto.getKeyBackupInfo().then((i) => {
+ if (alive()) {
+ setInfo(i);
+ }
+ });
+ }, [crypto, alive]);
+
+ useEffect(() => {
+ fetchInfo();
+ }, [fetchInfo]);
+
+ useKeyBackupStatusChange(fetchInfo);
+
+ useKeyBackupSessionsRemainingChange(
+ useCallback(
+ (remainingCount) => {
+ if (remainingCount === 0) {
+ fetchInfo();
+ }
+ },
+ [fetchInfo]
+ )
+ );
+
+ return info;
+};
+
+export const useKeyBackupTrust = (
+ crypto: CryptoApi,
+ backupInfo: KeyBackupInfo
+): BackupTrustInfo | undefined => {
+ const alive = useAlive();
+ const [trust, setTrust] = useState<BackupTrustInfo>();
+
+ const fetchTrust = useCallback(() => {
+ crypto.isKeyBackupTrusted(backupInfo).then((t) => {
+ if (alive()) {
+ setTrust(t);
+ }
+ });
+ }, [crypto, alive, backupInfo]);
+
+ useEffect(() => {
+ fetchTrust();
+ }, [fetchTrust]);
+
+ useKeyBackupStatusChange(fetchTrust);
+
+ useKeyBackupDecryptionKeyCached(fetchTrust);
+
+ return trust;
+};
--- /dev/null
+import { useMemo } from 'react';
+import { MessageLayout } from '../state/settings';
+
+export type MessageLayoutItem = {
+ name: string;
+ layout: MessageLayout;
+};
+
+export const useMessageLayoutItems = (): MessageLayoutItem[] =>
+ useMemo(
+ () => [
+ {
+ layout: MessageLayout.Modern,
+ name: 'Modern',
+ },
+ {
+ layout: MessageLayout.Compact,
+ name: 'Compact',
+ },
+ {
+ layout: MessageLayout.Bubble,
+ name: 'Bubble',
+ },
+ ],
+ []
+ );
--- /dev/null
+import { useMemo } from 'react';
+import { MessageSpacing } from '../state/settings';
+
+export type MessageSpacingItem = {
+ name: string;
+ spacing: MessageSpacing;
+};
+
+export const useMessageSpacingItems = (): MessageSpacingItem[] =>
+ useMemo(
+ () => [
+ {
+ spacing: '0',
+ name: 'None',
+ },
+ {
+ spacing: '100',
+ name: 'Ultra Small',
+ },
+ {
+ spacing: '200',
+ name: 'Extra Small',
+ },
+ {
+ spacing: '300',
+ name: 'Small',
+ },
+ {
+ spacing: '400',
+ name: 'Normal',
+ },
+ {
+ spacing: '500',
+ name: 'Large',
+ },
+ ],
+ []
+ );
--- /dev/null
+import { PushRuleAction, PushRuleActionName, TweakName } from 'matrix-js-sdk';
+import { useCallback, useMemo } from 'react';
+
+export enum NotificationMode {
+ OFF = 'OFF',
+ Notify = 'Notify',
+ NotifyLoud = 'NotifyLoud',
+}
+
+export type NotificationModeOptions = {
+ soundValue?: string;
+ highlight?: boolean;
+};
+export const getNotificationModeActions = (
+ mode: NotificationMode,
+ options?: NotificationModeOptions
+): PushRuleAction[] => {
+ if (mode === NotificationMode.OFF) return [];
+
+ const actions: PushRuleAction[] = [PushRuleActionName.Notify];
+
+ if (mode === NotificationMode.NotifyLoud) {
+ actions.push({
+ set_tweak: TweakName.Sound,
+ value: options?.soundValue ?? 'default',
+ });
+ }
+
+ if (options?.highlight) {
+ actions.push({
+ set_tweak: TweakName.Highlight,
+ value: true,
+ });
+ }
+
+ return actions;
+};
+
+export type GetNotificationModeCallback = (mode: NotificationMode) => PushRuleAction[];
+export const useNotificationModeActions = (
+ options?: NotificationModeOptions
+): GetNotificationModeCallback => {
+ const getAction: GetNotificationModeCallback = useCallback(
+ (mode) => getNotificationModeActions(mode, options),
+ [options]
+ );
+
+ return getAction;
+};
+
+export const useNotificationActionsMode = (actions: PushRuleAction[]): NotificationMode => {
+ const mode: NotificationMode = useMemo(() => {
+ const soundTweak = actions.find(
+ (action) => typeof action === 'object' && action.set_tweak === TweakName.Sound
+ );
+ const notify = actions.find(
+ (action) => typeof action === 'string' && action === PushRuleActionName.Notify
+ );
+
+ if (notify && soundTweak) return NotificationMode.NotifyLoud;
+ if (notify) return NotificationMode.Notify;
+ return NotificationMode.OFF;
+ }, [actions]);
+
+ return mode;
+};
--- /dev/null
+import { useEffect, useMemo } from 'react';
+
+export const useObjectURL = (object?: Blob): string | undefined => {
+ const url = useMemo(() => {
+ if (object) return URL.createObjectURL(object);
+ return undefined;
+ }, [object]);
+
+ useEffect(
+ () => () => {
+ if (url) URL.revokeObjectURL(url);
+ },
+ [url]
+ );
+
+ return url;
+};
--- /dev/null
+import {
+ IPushRule,
+ IPushRules,
+ PushRuleAction,
+ PushRuleCondition,
+ PushRuleKind,
+ RuleId,
+} from 'matrix-js-sdk';
+import { useMemo } from 'react';
+
+export type PushRuleData = {
+ kind: PushRuleKind;
+ pushRule: IPushRule;
+};
+
+export const makePushRuleData = (
+ kind: PushRuleKind,
+ ruleId: RuleId,
+ actions: PushRuleAction[],
+ conditions?: PushRuleCondition[],
+ pattern?: string,
+ enabled?: boolean,
+ _default?: boolean
+): PushRuleData => ({
+ kind,
+ pushRule: {
+ rule_id: ruleId,
+ default: _default ?? true,
+ enabled: enabled ?? true,
+ pattern,
+ conditions,
+ actions,
+ },
+});
+
+export const orderedPushRuleKinds: PushRuleKind[] = [
+ PushRuleKind.Override,
+ PushRuleKind.ContentSpecific,
+ PushRuleKind.RoomSpecific,
+ PushRuleKind.SenderSpecific,
+ PushRuleKind.Underride,
+];
+
+export const getPushRule = (
+ pushRules: IPushRules,
+ ruleId: RuleId | string
+): PushRuleData | undefined => {
+ const { global } = pushRules;
+
+ let ruleData: PushRuleData | undefined;
+
+ orderedPushRuleKinds.some((kind) => {
+ const rules = global[kind];
+ const pushRule = rules?.find((r) => r.rule_id === ruleId);
+ if (pushRule) {
+ ruleData = {
+ kind,
+ pushRule,
+ };
+ return true;
+ }
+ return false;
+ });
+
+ return ruleData;
+};
+
+export const usePushRule = (
+ pushRules: IPushRules,
+ ruleId: RuleId | string
+): PushRuleData | undefined => useMemo(() => getPushRule(pushRules, ruleId), [pushRules, ruleId]);
--- /dev/null
+import { useSetAtom } from 'jotai';
+import { useCallback } from 'react';
+import { backupRestoreProgressAtom } from '../state/backupRestore';
+import { useMatrixClient } from './useMatrixClient';
+import { useKeyBackupDecryptionKeyCached } from './useKeyBackup';
+
+export const useRestoreBackupOnVerification = () => {
+ const setRestoreProgress = useSetAtom(backupRestoreProgressAtom);
+
+ const mx = useMatrixClient();
+
+ useKeyBackupDecryptionKeyCached(
+ useCallback(() => {
+ const crypto = mx.getCrypto();
+ if (!crypto) return;
+
+ crypto.restoreKeyBackup({
+ progressCallback(progress) {
+ setRestoreProgress(progress);
+ },
+ });
+ }, [mx, setRestoreProgress])
+ );
+};
--- /dev/null
+import {
+ AccountDataEvent,
+ SecretStorageDefaultKeyContent,
+ SecretStorageKeyContent,
+} from '../../types/matrix/accountData';
+import { useAccountData } from './useAccountData';
+
+export const getSecretStorageKeyEventType = (key: string): string => `m.secret_storage.key.${key}`;
+
+export const useSecretStorageDefaultKeyId = (): string | undefined => {
+ const defaultKeyEvent = useAccountData(AccountDataEvent.SecretStorageDefaultKey);
+ const defaultKeyId = defaultKeyEvent?.getContent<SecretStorageDefaultKeyContent>().key;
+
+ return defaultKeyId;
+};
+
+export const useSecretStorageKeyContent = (keyId: string): SecretStorageKeyContent | undefined => {
+ const keyEvent = useAccountData(getSecretStorageKeyEventType(keyId));
+ const secretStorageKey = keyEvent?.getContent<SecretStorageKeyContent>();
+
+ return secretStorageKey;
+};
--- /dev/null
+import { isKeyHotkey } from 'is-hotkey';
+import { KeyboardEventHandler, useCallback } from 'react';
+import { Cursor, Intent, Operations, TextArea } from '../plugins/text-area';
+
+export const useTextAreaIntentHandler = (
+ textArea: TextArea,
+ operations: Operations,
+ intent: Intent
+) => {
+ const handler: KeyboardEventHandler<HTMLTextAreaElement> = useCallback(
+ (evt) => {
+ const target = evt.currentTarget;
+
+ if (isKeyHotkey('tab', evt)) {
+ evt.preventDefault();
+
+ const cursor = Cursor.fromTextAreaElement(target);
+ if (textArea.selection(cursor)) {
+ operations.select(intent.moveForward(cursor));
+ } else {
+ operations.deselect(operations.insert(cursor, intent.str));
+ }
+
+ target.focus();
+ }
+ if (isKeyHotkey('shift+tab', evt)) {
+ evt.preventDefault();
+ const cursor = Cursor.fromTextAreaElement(target);
+ const intentCursor = intent.moveBackward(cursor);
+ if (textArea.selection(cursor)) {
+ operations.select(intentCursor);
+ } else {
+ operations.deselect(intentCursor);
+ }
+
+ target.focus();
+ }
+ if (isKeyHotkey('enter', evt) || isKeyHotkey('shift+enter', evt)) {
+ evt.preventDefault();
+ const cursor = Cursor.fromTextAreaElement(target);
+ operations.select(intent.addNewLine(cursor));
+ }
+ if (isKeyHotkey('mod+enter', evt)) {
+ evt.preventDefault();
+ const cursor = Cursor.fromTextAreaElement(target);
+ operations.select(intent.addNextLine(cursor));
+ }
+ if (isKeyHotkey('mod+shift+enter', evt)) {
+ evt.preventDefault();
+ const cursor = Cursor.fromTextAreaElement(target);
+ operations.select(intent.addPreviousLine(cursor));
+ }
+ },
+ [textArea, operations, intent]
+ );
+
+ return handler;
+};
--- /dev/null
+import { lightTheme } from 'folds';
+import { useEffect, useMemo, useState } from 'react';
+import { onDarkFontWeight, onLightFontWeight } from '../../config.css';
+import { butterTheme, darkTheme, silverTheme } from '../../colors.css';
+
+export enum ThemeKind {
+ Light = 'light',
+ Dark = 'dark',
+}
+
+export type Theme = {
+ id: string;
+ kind: ThemeKind;
+ classNames: string[];
+};
+
+export const LightTheme: Theme = {
+ id: 'light-theme',
+ kind: ThemeKind.Light,
+ classNames: [lightTheme, onLightFontWeight, 'prism-light'],
+};
+
+export const SilverTheme: Theme = {
+ id: 'silver-theme',
+ kind: ThemeKind.Light,
+ classNames: ['silver-theme', silverTheme, onLightFontWeight, 'prism-light'],
+};
+export const DarkTheme: Theme = {
+ id: 'dark-theme',
+ kind: ThemeKind.Dark,
+ classNames: ['dark-theme', darkTheme, onDarkFontWeight, 'prism-dark'],
+};
+export const ButterTheme: Theme = {
+ id: 'butter-theme',
+ kind: ThemeKind.Dark,
+ classNames: ['butter-theme', butterTheme, onDarkFontWeight, 'prism-dark'],
+};
+
+export const useThemes = (): Theme[] => {
+ const themes: Theme[] = useMemo(() => [LightTheme, SilverTheme, DarkTheme, ButterTheme], []);
+
+ return themes;
+};
+
+export const useThemeNames = (): Record<string, string> =>
+ useMemo(
+ () => ({
+ [LightTheme.id]: 'Light',
+ [SilverTheme.id]: 'Silver',
+ [DarkTheme.id]: 'Dark',
+ [ButterTheme.id]: 'Butter',
+ }),
+ []
+ );
+
+export const useSystemThemeKind = (): ThemeKind => {
+ const darkModeQueryList = useMemo(() => window.matchMedia('(prefers-color-scheme: dark)'), []);
+ const [themeKind, setThemeKind] = useState<ThemeKind>(
+ darkModeQueryList.matches ? ThemeKind.Dark : ThemeKind.Light
+ );
+
+ useEffect(() => {
+ const handleMediaQueryChange = () => {
+ setThemeKind(darkModeQueryList.matches ? ThemeKind.Dark : ThemeKind.Light);
+ };
+
+ darkModeQueryList.addEventListener('change', handleMediaQueryChange);
+ return () => {
+ darkModeQueryList.removeEventListener('change', handleMediaQueryChange);
+ };
+ }, [darkModeQueryList, setThemeKind]);
+
+ return themeKind;
+};
-import { AuthType, IAuthData, UIAFlow } from 'matrix-js-sdk';
+import { AuthType, IAuthData, MatrixError, UIAFlow } from 'matrix-js-sdk';
import { useCallback, useMemo } from 'react';
import {
getSupportedUIAFlows,
getStageInfo,
};
};
+
+export const useUIAMatrixError = (
+ error?: MatrixError
+): [undefined, undefined] | [IAuthData, undefined] | [undefined, MatrixError] => {
+ if (!error) return [undefined, undefined];
+ if (error.httpStatus === 401) return [error.data as IAuthData, undefined];
+
+ return [undefined, error];
+};
--- /dev/null
+import { useEffect, useState } from 'react';
+import { UserEvent, UserEventHandlerMap } from 'matrix-js-sdk';
+import { useMatrixClient } from './useMatrixClient';
+
+export type UserProfile = {
+ avatarUrl?: string;
+ displayName?: string;
+};
+export const useUserProfile = (userId: string): UserProfile => {
+ const mx = useMatrixClient();
+
+ const [profile, setProfile] = useState<UserProfile>(() => {
+ const user = mx.getUser(userId);
+ return {
+ avatarUrl: user?.avatarUrl,
+ displayName: user?.displayName,
+ };
+ });
+
+ useEffect(() => {
+ const user = mx.getUser(userId);
+ const onAvatarChange: UserEventHandlerMap[UserEvent.AvatarUrl] = (event, myUser) => {
+ setProfile((cp) => ({
+ ...cp,
+ avatarUrl: myUser.avatarUrl,
+ }));
+ };
+ const onDisplayNameChange: UserEventHandlerMap[UserEvent.DisplayName] = (event, myUser) => {
+ setProfile((cp) => ({
+ ...cp,
+ displayName: myUser.displayName,
+ }));
+ };
+
+ mx.getProfileInfo(userId).then((info) =>
+ setProfile({
+ avatarUrl: info.avatar_url,
+ displayName: info.displayname,
+ })
+ );
+
+ user?.on(UserEvent.AvatarUrl, onAvatarChange);
+ user?.on(UserEvent.DisplayName, onDisplayNameChange);
+ return () => {
+ user?.removeListener(UserEvent.AvatarUrl, onAvatarChange);
+ user?.removeListener(UserEvent.DisplayName, onDisplayNameChange);
+ };
+ }, [mx, userId]);
+
+ return profile;
+};
--- /dev/null
+import { CryptoEvent, CryptoEventHandlerMap } from 'matrix-js-sdk/lib/crypto-api';
+import { useEffect } from 'react';
+import { useMatrixClient } from './useMatrixClient';
+
+export const useUserTrustStatusChange = (
+ onChange: CryptoEventHandlerMap[CryptoEvent.UserTrustStatusChanged]
+) => {
+ const mx = useMatrixClient();
+
+ useEffect(() => {
+ mx.on(CryptoEvent.UserTrustStatusChanged, onChange);
+ return () => {
+ mx.removeListener(CryptoEvent.UserTrustStatusChanged, onChange);
+ };
+ }, [mx, onChange]);
+};
--- /dev/null
+import { useCallback, useEffect, useState } from 'react';
+import {
+ CryptoEvent,
+ CryptoEventHandlerMap,
+ VerificationPhase,
+ VerificationRequest,
+ VerificationRequestEvent,
+ VerificationRequestEventHandlerMap,
+ Verifier,
+ VerifierEvent,
+ VerifierEventHandlerMap,
+} from 'matrix-js-sdk/lib/crypto-api';
+import { useMatrixClient } from './useMatrixClient';
+
+export const useVerificationRequestReceived = (
+ onRequest: CryptoEventHandlerMap[CryptoEvent.VerificationRequestReceived]
+) => {
+ const mx = useMatrixClient();
+
+ useEffect(() => {
+ mx.on(CryptoEvent.VerificationRequestReceived, onRequest);
+ return () => {
+ mx.removeListener(CryptoEvent.VerificationRequestReceived, onRequest);
+ };
+ }, [mx, onRequest]);
+};
+
+export const useVerificationRequestChange = (
+ request: VerificationRequest,
+ onChange: VerificationRequestEventHandlerMap[VerificationRequestEvent.Change]
+) => {
+ useEffect(() => {
+ request.on(VerificationRequestEvent.Change, onChange);
+ return () => {
+ request.removeListener(VerificationRequestEvent.Change, onChange);
+ };
+ }, [request, onChange]);
+};
+
+export const useVerificationRequestPhase = (request: VerificationRequest): VerificationPhase => {
+ const [phase, setPhase] = useState(() => request.phase);
+
+ useVerificationRequestChange(
+ request,
+ useCallback(() => {
+ setPhase(request.phase);
+ }, [request])
+ );
+
+ return phase;
+};
+
+export const useVerifierCancel = (
+ verifier: Verifier,
+ onCallback: VerifierEventHandlerMap[VerifierEvent.Cancel]
+) => {
+ useEffect(() => {
+ verifier.on(VerifierEvent.Cancel, onCallback);
+ return () => {
+ verifier.removeListener(VerifierEvent.Cancel, onCallback);
+ };
+ }, [verifier, onCallback]);
+};
+
+export const useVerifierShowSas = (
+ verifier: Verifier,
+ onCallback: VerifierEventHandlerMap[VerifierEvent.ShowSas]
+) => {
+ useEffect(() => {
+ verifier.on(VerifierEvent.ShowSas, onCallback);
+ return () => {
+ verifier.removeListener(VerifierEvent.ShowSas, onCallback);
+ };
+ }, [verifier, onCallback]);
+};
+
+export const useVerifierShowReciprocateQr = (
+ verifier: Verifier,
+ onCallback: VerifierEventHandlerMap[VerifierEvent.ShowReciprocateQr]
+) => {
+ useEffect(() => {
+ verifier.on(VerifierEvent.ShowReciprocateQr, onCallback);
+ return () => {
+ verifier.removeListener(VerifierEvent.ShowReciprocateQr, onCallback);
+ };
+ }, [verifier, onCallback]);
+};
+++ /dev/null
-import React from 'react';
-
-import { openReusableContextMenu } from '../../../client/action/navigation';
-import { getEventCords } from '../../../util/common';
-
-import Text from '../../atoms/text/Text';
-import Button from '../../atoms/button/Button';
-import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
-import SettingTile from '../setting-tile/SettingTile';
-
-import NotificationSelector from './NotificationSelector';
-
-import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
-
-import { useAccountData } from '../../hooks/useAccountData';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-export const notifType = {
- ON: 'on',
- OFF: 'off',
- NOISY: 'noisy',
-};
-export const typeToLabel = {
- [notifType.ON]: 'On',
- [notifType.OFF]: 'Off',
- [notifType.NOISY]: 'Noisy',
-};
-Object.freeze(notifType);
-
-const DM = '.m.rule.room_one_to_one';
-const ENC_DM = '.m.rule.encrypted_room_one_to_one';
-const ROOM = '.m.rule.message';
-const ENC_ROOM = '.m.rule.encrypted';
-
-export function getActionType(rule) {
- const { actions } = rule;
- if (actions.find((action) => action?.set_tweak === 'sound')) return notifType.NOISY;
- if (actions.find((action) => action?.set_tweak === 'highlight')) return notifType.ON;
- if (actions.find((action) => action === 'dont_notify')) return notifType.OFF;
- return notifType.OFF;
-}
-
-export function getTypeActions(type, highlightValue = false) {
- if (type === notifType.OFF) return ['dont_notify'];
-
- const highlight = { set_tweak: 'highlight' };
- if (typeof highlightValue === 'boolean') highlight.value = highlightValue;
- if (type === notifType.ON) return ['notify', highlight];
-
- const sound = { set_tweak: 'sound', value: 'default' };
- return ['notify', sound, highlight];
-}
-
-function useGlobalNotif() {
- const mx = useMatrixClient();
- const pushRules = useAccountData('m.push_rules')?.getContent();
- const underride = pushRules?.global?.underride ?? [];
- const rulesToType = {
- [DM]: notifType.ON,
- [ENC_DM]: notifType.ON,
- [ROOM]: notifType.NOISY,
- [ENC_ROOM]: notifType.NOISY,
- };
-
- const getRuleCondition = (rule) => {
- const condition = [];
- if (rule === DM || rule === ENC_DM) {
- condition.push({ kind: 'room_member_count', is: '2' });
- }
- condition.push({
- kind: 'event_match',
- key: 'type',
- pattern: [ENC_DM, ENC_ROOM].includes(rule) ? 'm.room.encrypted' : 'm.room.message',
- });
- return condition;
- };
-
- const setRule = (rule, type) => {
- const content = pushRules ?? {};
- if (!content.global) content.global = {};
- if (!content.global.underride) content.global.underride = [];
- const ur = content.global.underride;
- let ruleContent = ur.find((action) => action?.rule_id === rule);
- if (!ruleContent) {
- ruleContent = {
- conditions: getRuleCondition(type),
- actions: [],
- rule_id: rule,
- default: true,
- enabled: true,
- };
- ur.push(ruleContent);
- }
- ruleContent.actions = getTypeActions(type);
-
- mx.setAccountData('m.push_rules', content);
- };
-
- const dmRule = underride.find((rule) => rule.rule_id === DM);
- const encDmRule = underride.find((rule) => rule.rule_id === ENC_DM);
- const roomRule = underride.find((rule) => rule.rule_id === ROOM);
- const encRoomRule = underride.find((rule) => rule.rule_id === ENC_ROOM);
-
- if (dmRule) rulesToType[DM] = getActionType(dmRule);
- if (encDmRule) rulesToType[ENC_DM] = getActionType(encDmRule);
- if (roomRule) rulesToType[ROOM] = getActionType(roomRule);
- if (encRoomRule) rulesToType[ENC_ROOM] = getActionType(encRoomRule);
-
- return [rulesToType, setRule];
-}
-
-function GlobalNotification() {
- const [rulesToType, setRule] = useGlobalNotif();
-
- const onSelect = (evt, rule) => {
- openReusableContextMenu(
- 'bottom',
- getEventCords(evt, '.btn-surface'),
- (requestClose) => (
- <NotificationSelector
- value={rulesToType[rule]}
- onSelect={(value) => {
- if (rulesToType[rule] !== value) setRule(rule, value);
- requestClose();
- }}
- />
- ),
- );
- };
-
- return (
- <div className="global-notification">
- <MenuHeader>Global Notifications</MenuHeader>
- <SettingTile
- title="Direct messages"
- options={(
- <Button onClick={(evt) => onSelect(evt, DM)} iconSrc={ChevronBottomIC}>
- { typeToLabel[rulesToType[DM]] }
- </Button>
- )}
- content={<Text variant="b3">Default notification settings for all direct message.</Text>}
- />
- <SettingTile
- title="Encrypted direct messages"
- options={(
- <Button onClick={(evt) => onSelect(evt, ENC_DM)} iconSrc={ChevronBottomIC}>
- {typeToLabel[rulesToType[ENC_DM]]}
- </Button>
- )}
- content={<Text variant="b3">Default notification settings for all encrypted direct message.</Text>}
- />
- <SettingTile
- title="Rooms messages"
- options={(
- <Button onClick={(evt) => onSelect(evt, ROOM)} iconSrc={ChevronBottomIC}>
- {typeToLabel[rulesToType[ROOM]]}
- </Button>
- )}
- content={<Text variant="b3">Default notification settings for all room message.</Text>}
- />
- <SettingTile
- title="Encrypted rooms messages"
- options={(
- <Button onClick={(evt) => onSelect(evt, ENC_ROOM)} iconSrc={ChevronBottomIC}>
- {typeToLabel[rulesToType[ENC_ROOM]]}
- </Button>
- )}
- content={<Text variant="b3">Default notification settings for all encrypted room message.</Text>}
- />
- </div>
- );
-}
-
-export default GlobalNotification;
+++ /dev/null
-import React from 'react';
-import './IgnoreUserList.scss';
-
-import * as roomActions from '../../../client/action/room';
-
-import Text from '../../atoms/text/Text';
-import Chip from '../../atoms/chip/Chip';
-import Input from '../../atoms/input/Input';
-import Button from '../../atoms/button/Button';
-import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
-import SettingTile from '../setting-tile/SettingTile';
-
-import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
-
-import { useAccountData } from '../../hooks/useAccountData';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-function IgnoreUserList() {
- useAccountData('m.ignored_user_list');
- const mx = useMatrixClient();
- const ignoredUsers = mx.getIgnoredUsers();
-
- const handleSubmit = (evt) => {
- evt.preventDefault();
- const { ignoreInput } = evt.target.elements;
- const value = ignoreInput.value.trim();
- const userIds = value.split(' ').filter((v) => v.match(/^@\S+:\S+$/));
- if (userIds.length === 0) return;
- ignoreInput.value = '';
- roomActions.ignore(mx, userIds);
- };
-
- return (
- <div className="ignore-user-list">
- <MenuHeader>Ignored users</MenuHeader>
- <SettingTile
- title="Ignore user"
- content={(
- <div className="ignore-user-list__users">
- <Text variant="b3">Ignore userId if you do not want to receive their messages or invites.</Text>
- <form onSubmit={handleSubmit}>
- <Input name="ignoreInput" required />
- <Button variant="primary" type="submit">Ignore</Button>
- </form>
- {ignoredUsers.length > 0 && (
- <div>
- {ignoredUsers.map((uId) => (
- <Chip
- iconSrc={CrossIC}
- key={uId}
- text={uId}
- iconColor={CrossIC}
- onClick={() => roomActions.unignore(mx, [uId])}
- />
- ))}
- </div>
- )}
- </div>
- )}
- />
- </div>
- );
-}
-
-export default IgnoreUserList;
+++ /dev/null
-.ignore-user-list {
- &__users {
- & form,
- & > div:last-child {
- display: flex;
- flex-wrap: wrap;
- gap: var(--sp-tight);
- }
-
- & form {
- margin: var(--sp-extra-tight) 0 var(--sp-normal);
- .input-container {
- flex-grow: 1;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-import React from 'react';
-import './KeywordNotification.scss';
-
-import { openReusableContextMenu } from '../../../client/action/navigation';
-import { getEventCords } from '../../../util/common';
-
-import Text from '../../atoms/text/Text';
-import Chip from '../../atoms/chip/Chip';
-import Input from '../../atoms/input/Input';
-import Button from '../../atoms/button/Button';
-import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
-import SettingTile from '../setting-tile/SettingTile';
-
-import NotificationSelector from './NotificationSelector';
-
-import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
-import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
-
-import { useAccountData } from '../../hooks/useAccountData';
-import {
- notifType, typeToLabel, getActionType, getTypeActions,
-} from './GlobalNotification';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-const DISPLAY_NAME = '.m.rule.contains_display_name';
-const ROOM_PING = '.m.rule.roomnotif';
-const USERNAME = '.m.rule.contains_user_name';
-const KEYWORD = 'keyword';
-
-function useKeywordNotif() {
- const mx = useMatrixClient();
- const pushRules = useAccountData('m.push_rules')?.getContent();
- const override = pushRules?.global?.override ?? [];
- const content = pushRules?.global?.content ?? [];
-
- const rulesToType = {
- [DISPLAY_NAME]: notifType.NOISY,
- [ROOM_PING]: notifType.NOISY,
- [USERNAME]: notifType.NOISY,
- };
-
- const setRule = (rule, type) => {
- const evtContent = pushRules ?? {};
- if (!evtContent.global) evtContent.global = {};
- if (!evtContent.global.override) evtContent.global.override = [];
- if (!evtContent.global.content) evtContent.global.content = [];
- const or = evtContent.global.override;
- const ct = evtContent.global.content;
-
- if (rule === DISPLAY_NAME || rule === ROOM_PING) {
- let orRule = or.find((r) => r?.rule_id === rule);
- if (!orRule) {
- orRule = {
- conditions: [],
- actions: [],
- rule_id: rule,
- default: true,
- enabled: true,
- };
- or.push(orRule);
- }
- if (rule === DISPLAY_NAME) {
- orRule.conditions = [{ kind: 'contains_display_name' }];
- orRule.actions = getTypeActions(type, true);
- } else {
- orRule.conditions = [
- { kind: 'event_match', key: 'content.body', pattern: '@room' },
- { kind: 'sender_notification_permission', key: 'room' },
- ];
- orRule.actions = getTypeActions(type, true);
- }
- } else if (rule === USERNAME) {
- let usernameRule = ct.find((r) => r?.rule_id === rule);
- if (!usernameRule) {
- const userId = mx.getUserId();
- const username = userId.match(/^@?(\S+):(\S+)$/)?.[1] ?? userId;
- usernameRule = {
- actions: [],
- default: true,
- enabled: true,
- pattern: username,
- rule_id: rule,
- };
- ct.push(usernameRule);
- }
- usernameRule.actions = getTypeActions(type, true);
- } else {
- const keyRules = ct.filter((r) => r.rule_id !== USERNAME);
- keyRules.forEach((r) => {
- // eslint-disable-next-line no-param-reassign
- r.actions = getTypeActions(type, true);
- });
- }
-
- mx.setAccountData('m.push_rules', evtContent);
- };
-
- const addKeyword = (keyword) => {
- if (content.find((r) => r.rule_id === keyword)) return;
- content.push({
- rule_id: keyword,
- pattern: keyword,
- enabled: true,
- default: false,
- actions: getTypeActions(rulesToType[KEYWORD] ?? notifType.NOISY, true),
- });
- mx.setAccountData('m.push_rules', pushRules);
- };
- const removeKeyword = (rule) => {
- pushRules.global.content = content.filter((r) => r.rule_id !== rule.rule_id);
- mx.setAccountData('m.push_rules', pushRules);
- };
-
- const dsRule = override.find((rule) => rule.rule_id === DISPLAY_NAME);
- const roomRule = override.find((rule) => rule.rule_id === ROOM_PING);
- const usernameRule = content.find((rule) => rule.rule_id === USERNAME);
- const keywordRule = content.find((rule) => rule.rule_id !== USERNAME);
-
- if (dsRule) rulesToType[DISPLAY_NAME] = getActionType(dsRule);
- if (roomRule) rulesToType[ROOM_PING] = getActionType(roomRule);
- if (usernameRule) rulesToType[USERNAME] = getActionType(usernameRule);
- if (keywordRule) rulesToType[KEYWORD] = getActionType(keywordRule);
-
- return {
- rulesToType,
- pushRules,
- setRule,
- addKeyword,
- removeKeyword,
- };
-}
-
-function GlobalNotification() {
- const {
- rulesToType,
- pushRules,
- setRule,
- addKeyword,
- removeKeyword,
- } = useKeywordNotif();
-
- const keywordRules = pushRules?.global?.content.filter((r) => r.rule_id !== USERNAME) ?? [];
-
- const onSelect = (evt, rule) => {
- openReusableContextMenu(
- 'bottom',
- getEventCords(evt, '.btn-surface'),
- (requestClose) => (
- <NotificationSelector
- value={rulesToType[rule]}
- onSelect={(value) => {
- if (rulesToType[rule] !== value) setRule(rule, value);
- requestClose();
- }}
- />
- ),
- );
- };
-
- const handleSubmit = (evt) => {
- evt.preventDefault();
- const { keywordInput } = evt.target.elements;
- const value = keywordInput.value.trim();
- if (value === '') return;
- addKeyword(value);
- keywordInput.value = '';
- };
-
- return (
- <div className="keyword-notification">
- <MenuHeader>Mentions & keywords</MenuHeader>
- <SettingTile
- title="Message containing my display name"
- options={(
- <Button onClick={(evt) => onSelect(evt, DISPLAY_NAME)} iconSrc={ChevronBottomIC}>
- { typeToLabel[rulesToType[DISPLAY_NAME]] }
- </Button>
- )}
- content={<Text variant="b3">Default notification settings for all message containing your display name.</Text>}
- />
- <SettingTile
- title="Message containing my username"
- options={(
- <Button onClick={(evt) => onSelect(evt, USERNAME)} iconSrc={ChevronBottomIC}>
- { typeToLabel[rulesToType[USERNAME]] }
- </Button>
- )}
- content={<Text variant="b3">Default notification settings for all message containing your username.</Text>}
- />
- <SettingTile
- title="Message containing @room"
- options={(
- <Button onClick={(evt) => onSelect(evt, ROOM_PING)} iconSrc={ChevronBottomIC}>
- {typeToLabel[rulesToType[ROOM_PING]]}
- </Button>
- )}
- content={<Text variant="b3">Default notification settings for all messages containing @room.</Text>}
- />
- { rulesToType[KEYWORD] && (
- <SettingTile
- title="Message containing keywords"
- options={(
- <Button onClick={(evt) => onSelect(evt, KEYWORD)} iconSrc={ChevronBottomIC}>
- {typeToLabel[rulesToType[KEYWORD]]}
- </Button>
- )}
- content={<Text variant="b3">Default notification settings for all message containing keywords.</Text>}
- />
- )}
- <SettingTile
- title="Keywords"
- content={(
- <div className="keyword-notification__keyword">
- <Text variant="b3">Get notification when a message contains keyword.</Text>
- <form onSubmit={handleSubmit}>
- <Input name="keywordInput" required />
- <Button variant="primary" type="submit">Add</Button>
- </form>
- {keywordRules.length > 0 && (
- <div>
- {keywordRules.map((rule) => (
- <Chip
- iconSrc={CrossIC}
- key={rule.rule_id}
- text={rule.pattern}
- iconColor={CrossIC}
- onClick={() => removeKeyword(rule)}
- />
- ))}
- </div>
- )}
- </div>
- )}
- />
- </div>
- );
-}
-
-export default GlobalNotification;
+++ /dev/null
-.keyword-notification {
- &__keyword {
- & form,
- & > div:last-child {
- display: flex;
- flex-wrap: wrap;
- gap: var(--sp-tight);
- }
-
- & form {
- margin: var(--sp-extra-tight) 0 var(--sp-normal);
- .input-container {
- flex-grow: 1;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu';
-
-import CheckIC from '../../../../public/res/ic/outlined/check.svg';
-
-function NotificationSelector({
- value, onSelect,
-}) {
- return (
- <div>
- <MenuHeader>Notification</MenuHeader>
- <MenuItem iconSrc={value === 'off' ? CheckIC : null} variant={value === 'off' ? 'positive' : 'surface'} onClick={() => onSelect('off')}>Off</MenuItem>
- <MenuItem iconSrc={value === 'on' ? CheckIC : null} variant={value === 'on' ? 'positive' : 'surface'} onClick={() => onSelect('on')}>On</MenuItem>
- <MenuItem iconSrc={value === 'noisy' ? CheckIC : null} variant={value === 'noisy' ? 'positive' : 'surface'} onClick={() => onSelect('noisy')}>Noisy</MenuItem>
- </div>
- );
-}
-
-NotificationSelector.propTypes = {
- value: PropTypes.oneOf(['off', 'on', 'noisy']).isRequired,
- onSelect: PropTypes.func.isRequired,
-};
-
-export default NotificationSelector;
import React, { useState, useMemo, useReducer, useEffect } from 'react';
import PropTypes from 'prop-types';
+import { EventTimeline } from 'matrix-js-sdk';
import './ImagePack.scss';
import { openReusableDialog } from '../../../client/action/navigation';
import ImagePackUpload from './ImagePackUpload';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
+import { getStateEvent } from '../../utils/room';
const renameImagePackItem = (shortcode) =>
new Promise((resolve) => {
const room = mx.getRoom(roomId);
const pack = useMemo(() => {
- const packEvent = room.currentState.getStateEvents('im.ponies.room_emotes', stateKey);
+ const packEvent = getStateEvent(room, 'im.ponies.room_emotes', stateKey);
return ImagePackBuilder.parsePack(packEvent.getId(), packEvent.getContent());
}, [room, stateKey]);
};
const myPowerlevel = room.getMember(mx.getUserId())?.powerLevel || 0;
- const canChange = room.currentState.hasSufficientPowerLevelFor('state_default', myPowerlevel);
+ const canChange = room
+ .getLiveTimeline()
+ .getState(EventTimeline.FORWARDS)
+ ?.hasSufficientPowerLevelFor('state_default', myPowerlevel);
const handleDeletePack = async () => {
const isConfirmed = await confirmDialog(
[...roomIdToStateKeys].map(([roomId, stateKeys]) => {
const room = mx.getRoom(roomId);
return stateKeys.map((stateKey) => {
- const data = room.currentState.getStateEvents('im.ponies.room_emotes', stateKey);
+ const data = getStateEvent(room, 'im.ponies.room_emotes', stateKey);
const pack = ImagePackBuilder.parsePack(data?.getId(), data?.getContent());
if (!pack) return null;
return (
+++ /dev/null
-import React, { useState, useEffect, useRef } from 'react';
-import './ExportE2ERoomKeys.scss';
-
-import FileSaver from 'file-saver';
-
-import cons from '../../../client/state/cons';
-import { encryptMegolmKeyFile } from '../../../util/cryptE2ERoomKeys';
-
-import Text from '../../atoms/text/Text';
-import Button from '../../atoms/button/Button';
-import Input from '../../atoms/input/Input';
-import Spinner from '../../atoms/spinner/Spinner';
-
-import { useStore } from '../../hooks/useStore';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-function ExportE2ERoomKeys() {
- const mx = useMatrixClient();
- const isMountStore = useStore();
- const [status, setStatus] = useState({
- isOngoing: false,
- msg: null,
- type: cons.status.PRE_FLIGHT,
- });
- const passwordRef = useRef(null);
- const confirmPasswordRef = useRef(null);
-
- const exportE2ERoomKeys = async () => {
- const password = passwordRef.current.value;
- if (password !== confirmPasswordRef.current.value) {
- setStatus({
- isOngoing: false,
- msg: 'Password does not match.',
- type: cons.status.ERROR,
- });
- return;
- }
- setStatus({
- isOngoing: true,
- msg: 'Getting keys...',
- type: cons.status.IN_FLIGHT,
- });
- try {
- const keys = await mx.exportRoomKeys();
- if (isMountStore.getItem()) {
- setStatus({
- isOngoing: true,
- msg: 'Encrypting keys...',
- type: cons.status.IN_FLIGHT,
- });
- }
- const encKeys = await encryptMegolmKeyFile(JSON.stringify(keys), password);
- const blob = new Blob([encKeys], {
- type: 'text/plain;charset=us-ascii',
- });
- FileSaver.saveAs(blob, 'cinny-keys.txt');
- if (isMountStore.getItem()) {
- setStatus({
- isOngoing: false,
- msg: 'Successfully exported all keys.',
- type: cons.status.SUCCESS,
- });
- }
- } catch (e) {
- if (isMountStore.getItem()) {
- setStatus({
- isOngoing: false,
- msg: e.friendlyText || 'Failed to export keys. Please try again.',
- type: cons.status.ERROR,
- });
- }
- }
- };
-
- useEffect(() => {
- isMountStore.setItem(true);
- return () => {
- isMountStore.setItem(false);
- };
- }, []);
-
- return (
- <div className="export-e2e-room-keys">
- <form className="export-e2e-room-keys__form" onSubmit={(e) => { e.preventDefault(); exportE2ERoomKeys(); }}>
- <Input forwardRef={passwordRef} type="password" placeholder="Password" required />
- <Input forwardRef={confirmPasswordRef} type="password" placeholder="Confirm password" required />
- <Button disabled={status.isOngoing} variant="primary" type="submit">Export</Button>
- </form>
- { status.type === cons.status.IN_FLIGHT && (
- <div className="import-e2e-room-keys__process">
- <Spinner size="small" />
- <Text variant="b2">{status.msg}</Text>
- </div>
- )}
- {status.type === cons.status.SUCCESS && <Text className="import-e2e-room-keys__success" variant="b2">{status.msg}</Text>}
- {status.type === cons.status.ERROR && <Text className="import-e2e-room-keys__error" variant="b2">{status.msg}</Text>}
- </div>
- );
-}
-
-export default ExportE2ERoomKeys;
+++ /dev/null
-.export-e2e-room-keys {
- margin-top: var(--sp-extra-tight);
- &__form {
- display: flex;
- & > .input-container {
- flex: 1;
- min-width: 0;
- }
- & > *:nth-child(2) {
- margin: 0 var(--sp-tight);
- }
- }
-
- &__process {
- margin-top: var(--sp-tight);
- display: flex;
- justify-content: center;
- align-items: center;
- & .text {
- margin: 0 var(--sp-tight);
- }
- }
- &__error {
- margin-top: var(--sp-tight);
- color: var(--tc-danger-high);
- }
-
-}
\ No newline at end of file
+++ /dev/null
-import React, { useState, useEffect, useRef } from 'react';
-import './ImportE2ERoomKeys.scss';
-
-import cons from '../../../client/state/cons';
-import { decryptMegolmKeyFile } from '../../../util/cryptE2ERoomKeys';
-
-import Text from '../../atoms/text/Text';
-import IconButton from '../../atoms/button/IconButton';
-import Button from '../../atoms/button/Button';
-import Input from '../../atoms/input/Input';
-import Spinner from '../../atoms/spinner/Spinner';
-
-import CirclePlusIC from '../../../../public/res/ic/outlined/circle-plus.svg';
-
-import { useStore } from '../../hooks/useStore';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-function ImportE2ERoomKeys() {
- const mx = useMatrixClient();
- const isMountStore = useStore();
- const [keyFile, setKeyFile] = useState(null);
- const [status, setStatus] = useState({
- isOngoing: false,
- msg: null,
- type: cons.status.PRE_FLIGHT,
- });
- const inputRef = useRef(null);
- const passwordRef = useRef(null);
-
- async function tryDecrypt(file, password) {
- try {
- const arrayBuffer = await file.arrayBuffer();
- if (isMountStore.getItem()) {
- setStatus({
- isOngoing: true,
- msg: 'Decrypting file...',
- type: cons.status.IN_FLIGHT,
- });
- }
-
- const keys = await decryptMegolmKeyFile(arrayBuffer, password);
- if (isMountStore.getItem()) {
- setStatus({
- isOngoing: true,
- msg: 'Decrypting messages...',
- type: cons.status.IN_FLIGHT,
- });
- }
- await mx.importRoomKeys(JSON.parse(keys));
- if (isMountStore.getItem()) {
- setStatus({
- isOngoing: false,
- msg: 'Successfully imported all keys.',
- type: cons.status.SUCCESS,
- });
- inputRef.current.value = null;
- passwordRef.current.value = null;
- }
- } catch (e) {
- if (isMountStore.getItem()) {
- setStatus({
- isOngoing: false,
- msg: e.friendlyText || 'Failed to decrypt keys. Please try again.',
- type: cons.status.ERROR,
- });
- }
- }
- }
-
- const importE2ERoomKeys = () => {
- const password = passwordRef.current.value;
- if (password === '' || keyFile === null) return;
- if (status.isOngoing) return;
-
- tryDecrypt(keyFile, password);
- };
-
- const handleFileChange = (e) => {
- const file = e.target.files.item(0);
- passwordRef.current.value = '';
- setKeyFile(file);
- setStatus({
- isOngoing: false,
- msg: null,
- type: cons.status.PRE_FLIGHT,
- });
- };
- const removeImportKeysFile = () => {
- if (status.isOngoing) return;
- inputRef.current.value = null;
- passwordRef.current.value = null;
- setKeyFile(null);
- setStatus({
- isOngoing: false,
- msg: null,
- type: cons.status.PRE_FLIGHT,
- });
- };
-
- useEffect(() => {
- isMountStore.setItem(true);
- return () => {
- isMountStore.setItem(false);
- };
- }, []);
-
- return (
- <div className="import-e2e-room-keys">
- <input ref={inputRef} onChange={handleFileChange} style={{ display: 'none' }} type="file" />
-
- <form className="import-e2e-room-keys__form" onSubmit={(e) => { e.preventDefault(); importE2ERoomKeys(); }}>
- { keyFile !== null && (
- <div className="import-e2e-room-keys__file">
- <IconButton onClick={removeImportKeysFile} src={CirclePlusIC} tooltip="Remove file" />
- <Text>{keyFile.name}</Text>
- </div>
- )}
- {keyFile === null && <Button onClick={() => inputRef.current.click()}>Import keys</Button>}
- <Input forwardRef={passwordRef} type="password" placeholder="Password" required />
- <Button disabled={status.isOngoing} variant="primary" type="submit">Decrypt</Button>
- </form>
- { status.type === cons.status.IN_FLIGHT && (
- <div className="import-e2e-room-keys__process">
- <Spinner size="small" />
- <Text variant="b2">{status.msg}</Text>
- </div>
- )}
- {status.type === cons.status.SUCCESS && <Text className="import-e2e-room-keys__success" variant="b2">{status.msg}</Text>}
- {status.type === cons.status.ERROR && <Text className="import-e2e-room-keys__error" variant="b2">{status.msg}</Text>}
- </div>
- );
-}
-
-export default ImportE2ERoomKeys;
+++ /dev/null
-@use '../../partials/text';
-@use '../../partials/dir';
-
-.import-e2e-room-keys {
- &__file {
- display: inline-flex;
- align-items: center;
- background: var(--bg-surface-low);
- border-radius: var(--bo-radius);
- box-shadow: var(--bs-surface-border);
-
- & button {
- --parent-height: 46px;
- width: var(--parent-height);
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- }
-
- & .ic-raw {
- background-color: var(--bg-caution);
- transform: rotate(45deg);
- }
-
- & .text {
- @extend .cp-txt__ellipsis;
- @include dir.side(margin, var(--sp-tight), var(--sp-loose));
- max-width: 86px;
- }
- }
-
- &__form {
- display: flex;
- margin-top: var(--sp-extra-tight);
-
-
- & .input-container {
- flex: 1;
- margin: 0 var(--sp-tight);
- }
- }
-
- &__process {
- margin-top: var(--sp-tight);
- display: flex;
- justify-content: center;
- align-items: center;
- & .text {
- margin: 0 var(--sp-tight);
- }
- }
- &__error {
- margin-top: var(--sp-tight);
- color: var(--tc-danger-high);
- }
- &__success {
- margin-top: var(--sp-tight);
- color: var(--tc-positive-high);
- }
-}
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import './RoomAliases.scss';
+import { EventTimeline } from 'matrix-js-sdk';
import cons from '../../../client/state/cons';
import { Debounce } from '../../../util/common';
const [deleteAlias, setDeleteAlias] = useState(null);
const [validate, setValidateToDefault, handleAliasChange] = useValidate(hsString);
- const canPublishAlias = room.currentState.maySendStateEvent('m.room.canonical_alias', userId);
+ const canPublishAlias = room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.maySendStateEvent('m.room.canonical_alias', userId);
useEffect(() => {
isMountedStore.setItem(true)
import React, { useReducer, useEffect } from 'react';
import PropTypes from 'prop-types';
import './RoomEmojis.scss';
+import { EventTimeline } from 'matrix-js-sdk';
import { suffixRename } from '../../../util/common';
import Button from '../../atoms/button/Button';
import ImagePack from '../image-pack/ImagePack';
import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { getStateEvent, getStateEvents } from '../../utils/room';
function useRoomPacks(room) {
const mx = useMatrixClient();
const [, forceUpdate] = useReducer((count) => count + 1, 0);
- const packEvents = room.currentState.getStateEvents('im.ponies.room_emotes');
+ const packEvents = getStateEvents(room, 'im.ponies.room_emotes');
const unUsablePacks = [];
const usablePacks = packEvents.filter((mEvent) => {
if (typeof mEvent.getContent()?.images !== 'object') {
};
}, [room, mx]);
- const isStateKeyAvailable = (key) => !room.currentState.getStateEvents('im.ponies.room_emotes', key);
+ const isStateKeyAvailable = (key) => !getStateEvent(room, 'im.ponies.room_emotes', key);
const createPack = async (name) => {
const packContent = {
const { usablePacks, createPack, deletePack } = useRoomPacks(room);
- const canChange = room.currentState.maySendStateEvent('im.ponies.room_emote', mx.getUserId());
+ const canChange = room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.maySendStateEvent('im.ponies.room_emote', mx.getUserId());
const handlePackCreate = (e) => {
e.preventDefault();
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import './RoomEncryption.scss';
-
+import { EventTimeline } from 'matrix-js-sdk';
import Text from '../../atoms/text/Text';
import Toggle from '../../atoms/button/Toggle';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { getStateEvents } from '../../utils/room';
function RoomEncryption({ roomId }) {
const mx = useMatrixClient();
const room = mx.getRoom(roomId);
- const encryptionEvents = room.currentState.getStateEvents('m.room.encryption');
+ const encryptionEvents = getStateEvents(room, 'm.room.encryption');
const [isEncrypted, setIsEncrypted] = useState(encryptionEvents.length > 0);
- const canEnableEncryption = room.currentState.maySendStateEvent('m.room.encryption', mx.getUserId());
+ const canEnableEncryption = room.getLiveTimeline().getState(EventTimeline.FORWARDS).maySendStateEvent('m.room.encryption', mx.getUserId());
const handleEncryptionEnable = async () => {
const joinRule = room.getJoinRule();
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import './RoomPermissions.scss';
+import { EventTimeline } from 'matrix-js-sdk';
import { getPowerLabel } from '../../../util/matrixUtil';
import { openReusableContextMenu } from '../../../client/action/navigation';
import { useForceUpdate } from '../../hooks/useForceUpdate';
import { useMatrixClient } from '../../hooks/useMatrixClient';
+import { getStateEvent } from '../../utils/room';
const permissionsInfo = {
users_default: {
useRoomStateUpdate(roomId);
const mx = useMatrixClient();
const room = mx.getRoom(roomId);
- const pLEvent = room.currentState.getStateEvents('m.room.power_levels')[0];
+ const pLEvent = getStateEvent(room, 'm.room.power_levels');
const permissions = pLEvent.getContent();
- const canChangePermission = room.currentState.maySendStateEvent('m.room.power_levels', mx.getUserId());
+ const canChangePermission = room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.maySendStateEvent('m.room.power_levels', mx.getUserId());
const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel ?? 100;
const handlePowerSelector = (e, permKey, parentKey, powerLevel) => {
import React, { useState, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';
import './RoomVisibility.scss';
-
+import { EventTimeline } from 'matrix-js-sdk';
import Text from '../../atoms/text/Text';
import RadioButton from '../../atoms/button/RadioButton';
const roomVersion = Number(mCreate?.room_version ?? 0);
const myPowerlevel = room.getMember(mx.getUserId())?.powerLevel || 0;
- const canChange = room.currentState.hasSufficientPowerLevelFor('state_default', myPowerlevel);
+ const canChange = room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.hasSufficientPowerLevelFor('state_default', myPowerlevel);
const items = [{
iconSrc: isSpace ? SpaceLockIC : HashLockIC,
+++ /dev/null
-/* eslint-disable react/prop-types */
-import React, { useState, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import './EmojiVerification.scss';
-
-import cons from '../../../client/state/cons';
-import navigation from '../../../client/state/navigation';
-import { hasPrivateKey } from '../../../client/state/secretStorageKeys';
-import { getDefaultSSKey, isCrossVerified } from '../../../util/matrixUtil';
-
-import Text from '../../atoms/text/Text';
-import IconButton from '../../atoms/button/IconButton';
-import Button from '../../atoms/button/Button';
-import Spinner from '../../atoms/spinner/Spinner';
-import Dialog from '../../molecules/dialog/Dialog';
-
-import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
-import { useStore } from '../../hooks/useStore';
-import { accessSecretStorage } from '../settings/SecretStorageAccess';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-function EmojiVerificationContent({ data, requestClose }) {
- const [sas, setSas] = useState(null);
- const [process, setProcess] = useState(false);
- const { request, targetDevice } = data;
- const mx = useMatrixClient();
- const mountStore = useStore();
- const beginStore = useStore();
-
- const beginVerification = async () => {
- if (
- isCrossVerified(mx, mx.deviceId) &&
- (mx.getCrossSigningId() === null ||
- (await mx.crypto.crossSigningInfo.isStoredInKeyCache('self_signing')) === false)
- ) {
- if (!hasPrivateKey(getDefaultSSKey(mx))) {
- const keyData = await accessSecretStorage(mx, 'Emoji verification');
- if (!keyData) {
- request.cancel();
- return;
- }
- }
- await mx.checkOwnCrossSigningTrust();
- }
- setProcess(true);
- await request.accept();
-
- const verifier = request.beginKeyVerification('m.sas.v1', targetDevice);
-
- const handleVerifier = (sasData) => {
- verifier.off('show_sas', handleVerifier);
- if (!mountStore.getItem()) return;
- setSas(sasData);
- setProcess(false);
- };
- verifier.on('show_sas', handleVerifier);
- await verifier.verify();
- };
-
- const sasMismatch = () => {
- sas.mismatch();
- setProcess(true);
- };
-
- const sasConfirm = () => {
- sas.confirm();
- setProcess(true);
- };
-
- useEffect(() => {
- mountStore.setItem(true);
- const handleChange = () => {
- if (request.done || request.cancelled) {
- requestClose();
- return;
- }
- if (targetDevice && !beginStore.getItem()) {
- beginStore.setItem(true);
- beginVerification();
- }
- };
-
- if (request === null) return undefined;
- const req = request;
- req.on('change', handleChange);
- return () => {
- req.off('change', handleChange);
- if (req.cancelled === false && req.done === false) {
- req.cancel();
- }
- };
- }, [request]);
-
- const renderWait = () => (
- <>
- <Spinner size="small" />
- <Text>Waiting for response from other device...</Text>
- </>
- );
-
- if (sas !== null) {
- return (
- <div className="emoji-verification__content">
- <Text>Confirm the emoji below are displayed on both devices, in the same order:</Text>
- <div className="emoji-verification__emojis">
- {sas.sas.emoji.map((emoji, i) => (
- // eslint-disable-next-line react/no-array-index-key
- <div className="emoji-verification__emoji-block" key={`${emoji[1]}-${i}`}>
- <Text variant="h1">{emoji[0]}</Text>
- <Text>{emoji[1]}</Text>
- </div>
- ))}
- </div>
- <div className="emoji-verification__buttons">
- {process ? (
- renderWait()
- ) : (
- <>
- <Button variant="primary" onClick={sasConfirm}>
- They match
- </Button>
- <Button onClick={sasMismatch}>No match</Button>
- </>
- )}
- </div>
- </div>
- );
- }
-
- if (targetDevice) {
- return (
- <div className="emoji-verification__content">
- <Text>Please accept the request from other device.</Text>
- <div className="emoji-verification__buttons">{renderWait()}</div>
- </div>
- );
- }
-
- return (
- <div className="emoji-verification__content">
- <Text>Click accept to start the verification process.</Text>
- <div className="emoji-verification__buttons">
- {process ? (
- renderWait()
- ) : (
- <Button variant="primary" onClick={beginVerification}>
- Accept
- </Button>
- )}
- </div>
- </div>
- );
-}
-EmojiVerificationContent.propTypes = {
- data: PropTypes.shape({}).isRequired,
- requestClose: PropTypes.func.isRequired,
-};
-
-function useVisibilityToggle() {
- const [data, setData] = useState(null);
- const mx = useMatrixClient();
-
- useEffect(() => {
- const handleOpen = (request, targetDevice) => {
- setData({ request, targetDevice });
- };
- navigation.on(cons.events.navigation.EMOJI_VERIFICATION_OPENED, handleOpen);
- mx.on('crypto.verification.request', handleOpen);
- return () => {
- navigation.removeListener(cons.events.navigation.EMOJI_VERIFICATION_OPENED, handleOpen);
- mx.removeListener('crypto.verification.request', handleOpen);
- };
- }, [mx]);
-
- const requestClose = () => setData(null);
-
- return [data, requestClose];
-}
-
-function EmojiVerification() {
- const [data, requestClose] = useVisibilityToggle();
-
- return (
- <Dialog
- isOpen={data !== null}
- className="emoji-verification"
- title={
- <Text variant="s1" weight="medium" primary>
- Emoji verification
- </Text>
- }
- contentOptions={<IconButton src={CrossIC} onClick={requestClose} tooltip="Close" />}
- onRequestClose={requestClose}
- >
- {data !== null ? (
- <EmojiVerificationContent data={data} requestClose={requestClose} />
- ) : (
- <div />
- )}
- </Dialog>
- );
-}
-
-export default EmojiVerification;
+++ /dev/null
-@use '../../partials/flex';
-@use '../../partials/dir';
-
-.emoji-verification {
- &__content {
- padding: var(--sp-normal);
- @include dir.side(padding, var(--sp-normal), var(--sp-extra-tight));
- display: flex;
- flex-direction: column;
- gap: var(--sp-normal);
- }
-
- &__emojis {
- margin: var(--sp-loose) 0;
- display: flex;
- align-items: center;
- justify-content: space-around;
- gap: var(--sp-extra-tight);
- flex-wrap: wrap;
- }
-
- &__emoji-block {
- @extend .cp-fx__column;
- flex: 1;
- align-items: center;
- gap: var(--sp-extra-tight);
- white-space: nowrap;
- text-transform: capitalize;
- }
-
- &__buttons {
- display: flex;
- gap: var(--sp-normal);
- }
-}
+++ /dev/null
-import React, { useState, useEffect, useRef } from 'react';
-import PropTypes from 'prop-types';
-
-import colorMXID from '../../../util/colorMXID';
-
-import Text from '../../atoms/text/Text';
-import IconButton from '../../atoms/button/IconButton';
-import Button from '../../atoms/button/Button';
-import ImageUpload from '../../molecules/image-upload/ImageUpload';
-import Input from '../../atoms/input/Input';
-
-import PencilIC from '../../../../public/res/ic/outlined/pencil.svg';
-import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
-
-import './ProfileEditor.scss';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
-
-function ProfileEditor({ userId }) {
- const [isEditing, setIsEditing] = useState(false);
- const mx = useMatrixClient();
- const user = mx.getUser(mx.getUserId());
- const useAuthentication = useMediaAuthentication();
-
- const displayNameRef = useRef(null);
- const [avatarSrc, setAvatarSrc] = useState(
- user.avatarUrl
- ? mx.mxcUrlToHttp(user.avatarUrl, 80, 80, 'crop', undefined, undefined, useAuthentication)
- : null
- );
- const [username, setUsername] = useState(user.displayName);
- const [disabled, setDisabled] = useState(true);
-
- useEffect(() => {
- let isMounted = true;
- mx.getProfileInfo(mx.getUserId()).then((info) => {
- if (!isMounted) return;
- setAvatarSrc(
- info.avatar_url
- ? mx.mxcUrlToHttp(
- info.avatar_url,
- 80,
- 80,
- 'crop',
- undefined,
- undefined,
- useAuthentication
- )
- : null
- );
- setUsername(info.displayname);
- });
- return () => {
- isMounted = false;
- };
- }, [mx, userId, useAuthentication]);
-
- const handleAvatarUpload = async (url) => {
- if (url === null) {
- const isConfirmed = await confirmDialog(
- 'Remove avatar',
- 'Are you sure that you want to remove avatar?',
- 'Remove',
- 'caution'
- );
- if (isConfirmed) {
- mx.setAvatarUrl('');
- setAvatarSrc(null);
- }
- return;
- }
- mx.setAvatarUrl(url);
- setAvatarSrc(mx.mxcUrlToHttp(url, 80, 80, 'crop', undefined, undefined, useAuthentication));
- };
-
- const saveDisplayName = () => {
- const newDisplayName = displayNameRef.current.value;
- if (newDisplayName !== null && newDisplayName !== username) {
- mx.setDisplayName(newDisplayName);
- setUsername(newDisplayName);
- setDisabled(true);
- setIsEditing(false);
- }
- };
-
- const onDisplayNameInputChange = () => {
- setDisabled(username === displayNameRef.current.value || displayNameRef.current.value == null);
- };
- const cancelDisplayNameChanges = () => {
- displayNameRef.current.value = username;
- onDisplayNameInputChange();
- setIsEditing(false);
- };
-
- const renderForm = () => (
- <form
- className="profile-editor__form"
- style={{ marginBottom: avatarSrc ? '24px' : '0' }}
- onSubmit={(e) => {
- e.preventDefault();
- saveDisplayName();
- }}
- >
- <Input
- label={`Display name of ${mx.getUserId()}`}
- onChange={onDisplayNameInputChange}
- value={mx.getUser(mx.getUserId()).displayName}
- forwardRef={displayNameRef}
- />
- <Button variant="primary" type="submit" disabled={disabled}>
- Save
- </Button>
- <Button onClick={cancelDisplayNameChanges}>Cancel</Button>
- </form>
- );
-
- const renderInfo = () => (
- <div className="profile-editor__info" style={{ marginBottom: avatarSrc ? '24px' : '0' }}>
- <div>
- <Text variant="h2" primary weight="medium">
- {username ?? userId}
- </Text>
- <IconButton
- src={PencilIC}
- size="extra-small"
- tooltip="Edit"
- onClick={() => setIsEditing(true)}
- />
- </div>
- <Text variant="b2">{mx.getUserId()}</Text>
- </div>
- );
-
- return (
- <div className="profile-editor">
- <ImageUpload
- text={username ?? userId}
- bgColor={colorMXID(userId)}
- imageSrc={avatarSrc}
- onUpload={handleAvatarUpload}
- onRequestRemove={() => handleAvatarUpload(null)}
- />
- {isEditing ? renderForm() : renderInfo()}
- </div>
- );
-}
-
-ProfileEditor.defaultProps = {
- userId: null,
-};
-
-ProfileEditor.propTypes = {
- userId: PropTypes.string,
-};
-
-export default ProfileEditor;
+++ /dev/null
-@use '../../partials/dir';
-@use '../../partials/flex';
-
-.profile-editor {
- display: flex;
- align-items: flex-end;
-}
-
-.profile-editor__info,
-.profile-editor__form {
- @extend .cp-fx__item-one;
- @include dir.side(margin, var(--sp-loose), 0);
- display: flex;
-}
-
-.profile-editor__info {
- flex-direction: column;
- & > div:first-child {
- display: flex;
- align-items: center;
- }
- .ic-btn {
- margin: 0 var(--sp-extra-tight);
- }
-}
-
-.profile-editor__form {
- margin-top: 10px;
- flex-wrap: wrap;
- align-items: flex-end;
-
- & > .input-container {
- @extend .cp-fx__item-one;
- }
- & > button {
- height: 46px;
- margin-top: var(--sp-normal);
- @include dir.side(margin, var(--sp-normal), 0);
- }
-
-}
\ No newline at end of file
import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import './ProfileViewer.scss';
+import { EventTimeline } from 'matrix-js-sdk';
import cons from '../../../client/state/cons';
import navigation from '../../../client/state/navigation';
const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel || 0;
const powerLevel = roomMember?.powerLevel || 0;
+ const roomState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);
const canIKick =
roomMember?.membership === 'join' &&
- room.currentState.hasSufficientPowerLevelFor('kick', myPowerLevel) &&
+ roomState?.hasSufficientPowerLevelFor('kick', myPowerLevel) &&
powerLevel < myPowerLevel;
const canIBan =
['join', 'leave'].includes(roomMember?.membership) &&
- room.currentState.hasSufficientPowerLevelFor('ban', myPowerLevel) &&
+ roomState?.hasSufficientPowerLevelFor('ban', myPowerLevel) &&
powerLevel < myPowerLevel;
const handleKick = (e) => {
async function loadDevices() {
try {
- await mx.downloadKeys([userId], true);
- const myDevices = mx.getStoredDevicesForUser(userId);
+ const crypto = mx.getCrypto();
+ const userToDevices = await crypto.getUserDeviceInfo([userId], true);
+ const myDevices = Array.from(userToDevices.get(userId).values());
if (isUnmounted) return;
setDevices(myDevices);
<Chip
key={device.deviceId}
iconSrc={ShieldEmptyIC}
- text={device.getDisplayName() || device.deviceId}
+ text={device.displayName || device.deviceId}
/>
))}
</div>
const myPowerlevel = room.getMember(mx.getUserId())?.powerLevel || 0;
const userPL = room.getMember(userId)?.powerLevel || 0;
+ const roomState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);
+
const canIKick =
- room.currentState.hasSufficientPowerLevelFor('kick', myPowerlevel) && userPL < myPowerlevel;
+ roomState?.hasSufficientPowerLevelFor('kick', myPowerlevel) && userPL < myPowerlevel;
const isBanned = member?.membership === 'ban';
const powerLevel = roomMember?.powerLevel || 0;
const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel || 0;
+ const roomState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);
const canChangeRole =
- room.currentState.maySendEvent('m.room.power_levels', mx.getUserId()) &&
+ roomState?.maySendEvent('m.room.power_levels', mx.getUserId()) &&
(powerLevel < myPowerLevel || userId === mx.getUserId());
const handleChangePowerLevel = async (newPowerLevel) => {
import Search from '../search/Search';
import CreateRoom from '../create-room/CreateRoom';
import JoinAlias from '../join-alias/JoinAlias';
-import EmojiVerification from '../emoji-verification/EmojiVerification';
import ReusableDialog from '../../molecules/dialog/ReusableDialog';
<JoinAlias />
<SpaceAddExisting />
<Search />
- <EmojiVerification />
<ReusableDialog />
</>
import navigation from '../../../client/state/navigation';
import InviteUser from '../invite-user/InviteUser';
-import Settings from '../settings/Settings';
import SpaceSettings from '../space-settings/SpaceSettings';
import RoomSettings from '../room/RoomSettings';
searchTerm={inviteUser.searchTerm}
onRequestClose={() => changeInviteUser({ isOpen: false, roomId: undefined })}
/>
- <Settings />
<SpaceSettings />
<RoomSettings />
</>
+++ /dev/null
-import React, { useState } from 'react';
-import PropTypes from 'prop-types';
-import './AuthRequest.scss';
-
-import { openReusableDialog } from '../../../client/action/navigation';
-
-import Text from '../../atoms/text/Text';
-import Button from '../../atoms/button/Button';
-import Input from '../../atoms/input/Input';
-import Spinner from '../../atoms/spinner/Spinner';
-
-import { useStore } from '../../hooks/useStore';
-import { getSecret } from '../../../client/state/auth';
-
-let lastUsedPassword;
-const getAuthId = (password) => ({
- type: 'm.login.password',
- password,
- identifier: {
- type: 'm.id.user',
- user: getSecret().userId,
- },
-});
-
-function AuthRequest({ onComplete, makeRequest }) {
- const [status, setStatus] = useState(false);
- const mountStore = useStore();
-
- const handleForm = async (e) => {
- mountStore.setItem(true);
- e.preventDefault();
- const password = e.target.password.value;
- if (password.trim() === '') return;
- try {
- setStatus({ ongoing: true });
- await makeRequest(getAuthId(password));
- lastUsedPassword = password;
- if (!mountStore.getItem()) return;
- onComplete(true);
- } catch (err) {
- lastUsedPassword = undefined;
- if (!mountStore.getItem()) return;
- if (err.errcode === 'M_FORBIDDEN') {
- setStatus({ error: 'Wrong password. Please enter correct password.' });
- return;
- }
- setStatus({ error: 'Request failed!' });
- }
- };
-
- const handleChange = () => {
- setStatus(false);
- };
-
- return (
- <div className="auth-request">
- <form onSubmit={handleForm}>
- <Input
- name="password"
- label="Account password"
- type="password"
- onChange={handleChange}
- required
- />
- {status.ongoing && <Spinner size="small" />}
- {status.error && <Text variant="b3">{status.error}</Text>}
- {(status === false || status.error) && <Button variant="primary" type="submit" disabled={!!status.error}>Continue</Button>}
- </form>
- </div>
- );
-}
-AuthRequest.propTypes = {
- onComplete: PropTypes.func.isRequired,
- makeRequest: PropTypes.func.isRequired,
-};
-
-/**
- * @param {string} title Title of dialog
- * @param {(auth) => void} makeRequest request to make
- * @returns {Promise<boolean>} whether the request succeed or not.
- */
-export const authRequest = async (title, makeRequest) => {
- try {
- const auth = lastUsedPassword ? getAuthId(lastUsedPassword) : undefined;
- await makeRequest(auth);
- return true;
- } catch (e) {
- lastUsedPassword = undefined;
- if (e.httpStatus !== 401 || e.data?.flows === undefined) return false;
-
- const { flows } = e.data;
- const canUsePassword = flows.find((f) => f.stages.includes('m.login.password'));
- if (!canUsePassword) return false;
-
- return new Promise((resolve) => {
- let isCompleted = false;
- openReusableDialog(
- <Text variant="s1" weight="medium">{title}</Text>,
- (requestClose) => (
- <AuthRequest
- onComplete={(done) => {
- isCompleted = true;
- resolve(done);
- requestClose();
- }}
- makeRequest={makeRequest}
- />
- ),
- () => {
- if (!isCompleted) resolve(false);
- },
- );
- });
- }
-};
-
-export default AuthRequest;
+++ /dev/null
-.auth-request {
- padding: var(--sp-normal);
-
- & form > *:not(:first-child) {
- margin-top: var(--sp-normal);
- }
-
- & .text-b3 {
- color: var(--tc-danger-high);
- margin-top: var(--sp-ultra-tight) !important;
- }
-}
\ No newline at end of file
+++ /dev/null
-/* eslint-disable react/jsx-one-expression-per-line */
-import React, { useState } from 'react';
-import './CrossSigning.scss';
-import FileSaver from 'file-saver';
-import { Formik } from 'formik';
-
-import { openReusableDialog } from '../../../client/action/navigation';
-import { copyToClipboard } from '../../../util/common';
-import { clearSecretStorageKeys } from '../../../client/state/secretStorageKeys';
-
-import Text from '../../atoms/text/Text';
-import Button from '../../atoms/button/Button';
-import Input from '../../atoms/input/Input';
-import Spinner from '../../atoms/spinner/Spinner';
-import SettingTile from '../../molecules/setting-tile/SettingTile';
-
-import { authRequest } from './AuthRequest';
-import { useCrossSigningStatus } from '../../hooks/useCrossSigningStatus';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-const failedDialog = () => {
- const renderFailure = (requestClose) => (
- <div className="cross-signing__failure">
- <Text variant="h1">❌</Text>
- <Text weight="medium">Failed to setup cross signing. Please try again.</Text>
- <Button onClick={requestClose}>Close</Button>
- </div>
- );
-
- openReusableDialog(
- <Text variant="s1" weight="medium">
- Setup cross signing
- </Text>,
- renderFailure
- );
-};
-
-const securityKeyDialog = (key) => {
- const downloadKey = () => {
- const blob = new Blob([key.encodedPrivateKey], {
- type: 'text/plain;charset=us-ascii',
- });
- FileSaver.saveAs(blob, 'security-key.txt');
- };
- const copyKey = () => {
- copyToClipboard(key.encodedPrivateKey);
- };
-
- const renderSecurityKey = () => (
- <div className="cross-signing__key">
- <Text weight="medium">Please save this security key somewhere safe.</Text>
- <Text className="cross-signing__key-text">{key.encodedPrivateKey}</Text>
- <div className="cross-signing__key-btn">
- <Button variant="primary" onClick={() => copyKey(key)}>
- Copy
- </Button>
- <Button onClick={() => downloadKey(key)}>Download</Button>
- </div>
- </div>
- );
-
- // Download automatically.
- downloadKey();
-
- openReusableDialog(
- <Text variant="s1" weight="medium">
- Security Key
- </Text>,
- () => renderSecurityKey()
- );
-};
-
-function CrossSigningSetup() {
- const initialValues = { phrase: '', confirmPhrase: '' };
- const [genWithPhrase, setGenWithPhrase] = useState(undefined);
- const mx = useMatrixClient();
-
- const setup = async (securityPhrase = undefined) => {
- setGenWithPhrase(typeof securityPhrase === 'string');
- const recoveryKey = await mx.createRecoveryKeyFromPassphrase(securityPhrase);
- clearSecretStorageKeys();
-
- await mx.bootstrapSecretStorage({
- createSecretStorageKey: async () => recoveryKey,
- setupNewKeyBackup: true,
- setupNewSecretStorage: true,
- });
-
- const authUploadDeviceSigningKeys = async (makeRequest) => {
- const isDone = await authRequest('Setup cross signing', async (auth) => {
- await makeRequest(auth);
- });
- setTimeout(() => {
- if (isDone) securityKeyDialog(recoveryKey);
- else failedDialog();
- });
- };
-
- await mx.bootstrapCrossSigning({
- authUploadDeviceSigningKeys,
- setupNewCrossSigning: true,
- });
- };
-
- const validator = (values) => {
- const errors = {};
- if (values.phrase === '12345678') {
- errors.phrase = 'How about 87654321 ?';
- }
- if (values.phrase === '87654321') {
- errors.phrase = 'Your are playing with 🔥';
- }
- const PHRASE_REGEX = /^([^\s]){8,127}$/;
- if (values.phrase.length > 0 && !PHRASE_REGEX.test(values.phrase)) {
- errors.phrase = 'Phrase must contain 8-127 characters with no space.';
- }
- if (values.confirmPhrase.length > 0 && values.confirmPhrase !== values.phrase) {
- errors.confirmPhrase = "Phrase don't match.";
- }
- return errors;
- };
-
- return (
- <div className="cross-signing__setup">
- <div className="cross-signing__setup-entry">
- <Text>
- We will generate a <b>Security Key</b>, which you can use to manage messages backup and
- session verification.
- </Text>
- {genWithPhrase !== false && (
- <Button variant="primary" onClick={() => setup()} disabled={genWithPhrase !== undefined}>
- Generate Key
- </Button>
- )}
- {genWithPhrase === false && <Spinner size="small" />}
- </div>
- <Text className="cross-signing__setup-divider">OR</Text>
- <Formik
- initialValues={initialValues}
- onSubmit={(values) => setup(values.phrase)}
- validate={validator}
- >
- {({ values, errors, handleChange, handleSubmit }) => (
- <form
- className="cross-signing__setup-entry"
- onSubmit={handleSubmit}
- disabled={genWithPhrase !== undefined}
- >
- <Text>
- Alternatively you can also set a <b>Security Phrase </b>
- so you don't have to remember long Security Key, and optionally save the Key as
- backup.
- </Text>
- <Input
- name="phrase"
- value={values.phrase}
- onChange={handleChange}
- label="Security Phrase"
- type="password"
- required
- disabled={genWithPhrase !== undefined}
- />
- {errors.phrase && (
- <Text variant="b3" className="cross-signing__error">
- {errors.phrase}
- </Text>
- )}
- <Input
- name="confirmPhrase"
- value={values.confirmPhrase}
- onChange={handleChange}
- label="Confirm Security Phrase"
- type="password"
- required
- disabled={genWithPhrase !== undefined}
- />
- {errors.confirmPhrase && (
- <Text variant="b3" className="cross-signing__error">
- {errors.confirmPhrase}
- </Text>
- )}
- {genWithPhrase !== true && (
- <Button variant="primary" type="submit" disabled={genWithPhrase !== undefined}>
- Set Phrase & Generate Key
- </Button>
- )}
- {genWithPhrase === true && <Spinner size="small" />}
- </form>
- )}
- </Formik>
- </div>
- );
-}
-
-const setupDialog = () => {
- openReusableDialog(
- <Text variant="s1" weight="medium">
- Setup cross signing
- </Text>,
- () => <CrossSigningSetup />
- );
-};
-
-function CrossSigningReset() {
- return (
- <div className="cross-signing__reset">
- <Text variant="h1">✋🧑🚒🤚</Text>
- <Text weight="medium">Resetting cross-signing keys is permanent.</Text>
- <Text>
- Anyone you have verified with will see security alerts and your message backup will be lost.
- You almost certainly do not want to do this, unless you have lost <b>Security Key</b> or{' '}
- <b>Phrase</b> and every session you can cross-sign from.
- </Text>
- <Button variant="danger" onClick={setupDialog}>
- Reset
- </Button>
- </div>
- );
-}
-
-const resetDialog = () => {
- openReusableDialog(
- <Text variant="s1" weight="medium">
- Reset cross signing
- </Text>,
- () => <CrossSigningReset />
- );
-};
-
-function CrossSignin() {
- const isCSEnabled = useCrossSigningStatus();
- return (
- <SettingTile
- title="Cross signing"
- content={
- <Text variant="b3">
- Setup to verify and keep track of all your sessions. Also required to backup encrypted
- message.
- </Text>
- }
- options={
- isCSEnabled ? (
- <Button variant="danger" onClick={resetDialog}>
- Reset
- </Button>
- ) : (
- <Button variant="primary" onClick={setupDialog}>
- Setup
- </Button>
- )
- }
- />
- );
-}
-
-export default CrossSignin;
+++ /dev/null
-.cross-signing {
- &__setup {
- padding: var(--sp-normal);
- }
- &__setup-entry {
- & > *:not(:first-child) {
- margin-top: var(--sp-normal);
- }
- }
-
- &__error {
- color: var(--tc-danger-high);
- margin-top: var(--sp-ultra-tight) !important;
- }
-
- &__setup-divider {
- margin: var(--sp-tight) 0;
- display: flex;
- align-items: center;
-
- &::before,
- &::after {
- flex: 1;
- content: '';
- margin: var(--sp-tight) 0;
- border-bottom: 1px solid var(--bg-surface-border);
- }
- }
-}
-
-.cross-signing__key {
- padding: var(--sp-normal);
-
- &-text {
- margin: var(--sp-normal) 0;
- padding: var(--sp-extra-tight);
- background-color: var(--bg-surface-low);
- border-radius: var(--bo-radius);
- }
- &-btn {
- display: flex;
- & > button:last-child {
- margin: 0 var(--sp-normal);
- }
- }
-}
-
-.cross-signing__failure,
-.cross-signing__reset {
- padding: var(--sp-normal);
- padding-top: var(--sp-extra-loose);
- & > .text {
- padding-bottom: var(--sp-normal);
- }
-}
\ No newline at end of file
+++ /dev/null
-import React, { useState, useEffect } from 'react';
-import './DeviceManage.scss';
-import dateFormat from 'dateformat';
-
-import { isCrossVerified } from '../../../util/matrixUtil';
-import { openReusableDialog, openEmojiVerification } from '../../../client/action/navigation';
-
-import Text from '../../atoms/text/Text';
-import Button from '../../atoms/button/Button';
-import IconButton from '../../atoms/button/IconButton';
-import Input from '../../atoms/input/Input';
-import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
-import InfoCard from '../../atoms/card/InfoCard';
-import Spinner from '../../atoms/spinner/Spinner';
-import SettingTile from '../../molecules/setting-tile/SettingTile';
-
-import PencilIC from '../../../../public/res/ic/outlined/pencil.svg';
-import BinIC from '../../../../public/res/ic/outlined/bin.svg';
-import InfoIC from '../../../../public/res/ic/outlined/info.svg';
-
-import { authRequest } from './AuthRequest';
-import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
-
-import { useStore } from '../../hooks/useStore';
-import { useDeviceList } from '../../hooks/useDeviceList';
-import { useCrossSigningStatus } from '../../hooks/useCrossSigningStatus';
-import { accessSecretStorage } from './SecretStorageAccess';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-const promptDeviceName = async (deviceName) => new Promise((resolve) => {
- let isCompleted = false;
-
- const renderContent = (onComplete) => {
- const handleSubmit = (e) => {
- e.preventDefault();
- const name = e.target.session.value;
- if (typeof name !== 'string') onComplete(null);
- onComplete(name);
- };
- return (
- <form className="device-manage__rename" onSubmit={handleSubmit}>
- <Input value={deviceName} label="Session name" name="session" />
- <div className="device-manage__rename-btn">
- <Button variant="primary" type="submit">Save</Button>
- <Button onClick={() => onComplete(null)}>Cancel</Button>
- </div>
- </form>
- );
- };
-
- openReusableDialog(
- <Text variant="s1" weight="medium">Edit session name</Text>,
- (requestClose) => renderContent((name) => {
- isCompleted = true;
- resolve(name);
- requestClose();
- }),
- () => {
- if (!isCompleted) resolve(null);
- },
- );
-});
-
-function DeviceManage() {
- const TRUNCATED_COUNT = 4;
- const mx = useMatrixClient();
- const isCSEnabled = useCrossSigningStatus();
- const deviceList = useDeviceList();
- const [processing, setProcessing] = useState([]);
- const [truncated, setTruncated] = useState(true);
- const mountStore = useStore();
- mountStore.setItem(true);
- const isMeVerified = isCrossVerified(mx, mx.deviceId);
-
- useEffect(() => {
- setProcessing([]);
- }, [deviceList]);
-
- const addToProcessing = (device) => {
- const old = [...processing];
- old.push(device.device_id);
- setProcessing(old);
- };
-
- const removeFromProcessing = () => {
- setProcessing([]);
- };
-
- if (deviceList === null) {
- return (
- <div className="device-manage">
- <div className="device-manage__loading">
- <Spinner size="small" />
- <Text>Loading sessions...</Text>
- </div>
- </div>
- );
- }
-
- const handleRename = async (device) => {
- const newName = await promptDeviceName(device.display_name);
- if (newName === null || newName.trim() === '') return;
- if (newName.trim() === device.display_name) return;
- addToProcessing(device);
- try {
- await mx.setDeviceDetails(device.device_id, {
- display_name: newName,
- });
- } catch {
- if (!mountStore.getItem()) return;
- removeFromProcessing(device);
- }
- };
-
- const handleRemove = async (device) => {
- const isConfirmed = await confirmDialog(
- `Logout ${device.display_name}`,
- `You are about to logout "${device.display_name}" session.`,
- 'Logout',
- 'danger',
- );
- if (!isConfirmed) return;
- addToProcessing(device);
- await authRequest(`Logout "${device.display_name}"`, async (auth) => {
- await mx.deleteDevice(device.device_id, auth);
- });
-
- if (!mountStore.getItem()) return;
- removeFromProcessing(device);
- };
-
- const verifyWithKey = async (device) => {
- const keyData = await accessSecretStorage(mx, 'Session verification');
- if (!keyData) return;
- addToProcessing(device);
- await mx.checkOwnCrossSigningTrust();
- };
-
- const verifyWithEmojis = async (deviceId) => {
- const req = await mx.requestVerification(mx.getUserId(), [deviceId]);
- openEmojiVerification(req, { userId: mx.getUserId(), deviceId });
- };
-
- const verify = (deviceId, isCurrentDevice) => {
- if (isCurrentDevice) {
- verifyWithKey(deviceId);
- return;
- }
- verifyWithEmojis(deviceId);
- };
-
- const renderDevice = (device, isVerified) => {
- const deviceId = device.device_id;
- const displayName = device.display_name;
- const lastIP = device.last_seen_ip;
- const lastTS = device.last_seen_ts;
- const isCurrentDevice = mx.deviceId === deviceId;
- const canVerify = isVerified === false && (isMeVerified || isCurrentDevice);
-
- return (
- <SettingTile
- key={deviceId}
- title={(
- <Text style={{ color: isVerified !== false ? '' : 'var(--tc-danger-high)' }}>
- {displayName}
- <Text variant="b3" span>{`${displayName ? ' — ' : ''}${deviceId}`}</Text>
- {isCurrentDevice && <Text span className="device-manage__current-label" variant="b3">Current</Text>}
- </Text>
- )}
- options={
- processing.includes(deviceId)
- ? <Spinner size="small" />
- : (
- <>
- {(isCSEnabled && canVerify) && <Button onClick={() => verify(deviceId, isCurrentDevice)} variant="positive">Verify</Button>}
- <IconButton size="small" onClick={() => handleRename(device)} src={PencilIC} tooltip="Rename" />
- <IconButton size="small" onClick={() => handleRemove(device)} src={BinIC} tooltip="Remove session" />
- </>
- )
- }
- content={(
- <>
- {lastTS && (
- <Text variant="b3">
- Last activity
- <span style={{ color: 'var(--tc-surface-normal)' }}>
- {dateFormat(new Date(lastTS), ' hh:MM TT, dd/mm/yyyy')}
- </span>
- {lastIP ? ` at ${lastIP}` : ''}
- </Text>
- )}
- {isCurrentDevice && (
- <Text style={{ marginTop: 'var(--sp-ultra-tight)' }} variant="b3">
- {`Session Key: ${mx.getDeviceEd25519Key().match(/.{1,4}/g).join(' ')}`}
- </Text>
- )}
- </>
- )}
- />
- );
- };
-
- const unverified = [];
- const verified = [];
- const noEncryption = [];
- deviceList.sort((a, b) => b.last_seen_ts - a.last_seen_ts).forEach((device) => {
- const isVerified = isCrossVerified(mx, device.device_id);
- if (isVerified === true) {
- verified.push(device);
- } else if (isVerified === false) {
- unverified.push(device);
- } else {
- noEncryption.push(device);
- }
- });
- return (
- <div className="device-manage">
- <div>
- <MenuHeader>Unverified sessions</MenuHeader>
- {!isMeVerified && isCSEnabled && (
- <div style={{ padding: 'var(--sp-extra-tight) var(--sp-normal)' }}>
- <InfoCard
- rounded
- variant="primary"
- iconSrc={InfoIC}
- title="Verify this session either with your Security Key/Phrase here or by initiating emoji verification from a verified session."
- />
- </div>
- )}
- {isMeVerified && unverified.length > 0 && (
- <div style={{ padding: 'var(--sp-extra-tight) var(--sp-normal)' }}>
- <InfoCard
- rounded
- variant="surface"
- iconSrc={InfoIC}
- title="Verify other sessions by emoji verification or remove unfamiliar ones."
- />
- </div>
- )}
- {!isCSEnabled && (
- <div style={{ padding: 'var(--sp-extra-tight) var(--sp-normal)' }}>
- <InfoCard
- rounded
- variant="caution"
- iconSrc={InfoIC}
- title="Setup cross signing in case you lose all your sessions."
- />
- </div>
- )}
- {
- unverified.length > 0
- ? unverified.map((device) => renderDevice(device, false))
- : <Text className="device-manage__info">No unverified sessions</Text>
- }
- </div>
- {noEncryption.length > 0 && (
- <div>
- <MenuHeader>Sessions without encryption support</MenuHeader>
- {noEncryption.map((device) => renderDevice(device, null))}
- </div>
- )}
- <div>
- <MenuHeader>Verified sessions</MenuHeader>
- {
- verified.length > 0
- ? verified.map((device, index) => {
- if (truncated && index >= TRUNCATED_COUNT) return null;
- return renderDevice(device, true);
- })
- : <Text className="device-manage__info">No verified sessions</Text>
- }
- { verified.length > TRUNCATED_COUNT && (
- <Button className="device-manage__info" onClick={() => setTruncated(!truncated)}>
- {truncated ? `View ${verified.length - 4} more` : 'View less'}
- </Button>
- )}
- { deviceList.length > 0 && (
- <Text className="device-manage__info" variant="b3">Session names are visible to everyone, so do not put any private info here.</Text>
- )}
- </div>
- </div>
- );
-}
-
-export default DeviceManage;
+++ /dev/null
-@use '../../partials/flex';
-
-.device-manage {
- &__loading {
- @extend .cp-fx__row--c-c;
- padding: var(--sp-extra-loose) var(--sp-normal);
-
- .text {
- margin: 0 var(--sp-normal);
- }
- }
- &__info {
- margin: var(--sp-normal);
- }
- & .setting-tile:last-of-type {
- border-bottom: none;
- }
- & .setting-tile__options {
- display: flex;
- align-items: center;
- gap: var(--sp-ultra-tight);
- & .btn-positive {
- padding: 6px var(--sp-tight);
- min-width: 0;
- }
- }
-
- &__current-label {
- margin: 0 var(--sp-extra-tight);
- padding: 2px var(--sp-ultra-tight);
- color: var(--bg-surface);
- background-color: var(--tc-surface-low);
- border-radius: 4px;
- }
-
- &__rename {
- padding: var(--sp-normal);
- & > *:not(:last-child) {
- margin-bottom: var(--sp-normal);
- }
- &-btn {
- display: flex;
- gap: var(--sp-normal);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/* eslint-disable react/prop-types */
-import React, { useState, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import './KeyBackup.scss';
-
-import { openReusableDialog } from '../../../client/action/navigation';
-import { deletePrivateKey } from '../../../client/state/secretStorageKeys';
-
-import Text from '../../atoms/text/Text';
-import Button from '../../atoms/button/Button';
-import IconButton from '../../atoms/button/IconButton';
-import Spinner from '../../atoms/spinner/Spinner';
-import InfoCard from '../../atoms/card/InfoCard';
-import SettingTile from '../../molecules/setting-tile/SettingTile';
-
-import { accessSecretStorage } from './SecretStorageAccess';
-
-import InfoIC from '../../../../public/res/ic/outlined/info.svg';
-import BinIC from '../../../../public/res/ic/outlined/bin.svg';
-import DownloadIC from '../../../../public/res/ic/outlined/download.svg';
-
-import { useStore } from '../../hooks/useStore';
-import { useCrossSigningStatus } from '../../hooks/useCrossSigningStatus';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-function CreateKeyBackupDialog({ keyData }) {
- const [done, setDone] = useState(false);
- const mx = useMatrixClient();
- const mountStore = useStore();
-
- const doBackup = async () => {
- setDone(false);
- let info;
-
- try {
- info = await mx.prepareKeyBackupVersion(null, { secureSecretStorage: true });
- info = await mx.createKeyBackupVersion(info);
- await mx.scheduleAllGroupSessionsForBackup();
- if (!mountStore.getItem()) return;
- setDone(true);
- } catch (e) {
- deletePrivateKey(keyData.keyId);
- await mx.deleteKeyBackupVersion(info.version);
- if (!mountStore.getItem()) return;
- setDone(null);
- }
- };
-
- useEffect(() => {
- mountStore.setItem(true);
- doBackup();
- }, []);
-
- return (
- <div className="key-backup__create">
- {done === false && (
- <div>
- <Spinner size="small" />
- <Text>Creating backup...</Text>
- </div>
- )}
- {done === true && (
- <>
- <Text variant="h1">✅</Text>
- <Text>Successfully created backup</Text>
- </>
- )}
- {done === null && (
- <>
- <Text>Failed to create backup</Text>
- <Button onClick={doBackup}>Retry</Button>
- </>
- )}
- </div>
- );
-}
-CreateKeyBackupDialog.propTypes = {
- keyData: PropTypes.shape({}).isRequired,
-};
-
-function RestoreKeyBackupDialog({ keyData }) {
- const [status, setStatus] = useState(false);
- const mx = useMatrixClient();
- const mountStore = useStore();
-
- const restoreBackup = async () => {
- setStatus(false);
-
- let meBreath = true;
- const progressCallback = (progress) => {
- if (!progress.successes) return;
- if (meBreath === false) return;
- meBreath = false;
- setTimeout(() => {
- meBreath = true;
- }, 200);
-
- setStatus({ message: `Restoring backup keys... (${progress.successes}/${progress.total})` });
- };
-
- try {
- const backupInfo = await mx.getKeyBackupVersion();
- const info = await mx.restoreKeyBackupWithSecretStorage(backupInfo, undefined, undefined, {
- progressCallback,
- });
- if (!mountStore.getItem()) return;
- setStatus({ done: `Successfully restored backup keys (${info.imported}/${info.total}).` });
- } catch (e) {
- if (!mountStore.getItem()) return;
- if (e.errcode === 'RESTORE_BACKUP_ERROR_BAD_KEY') {
- deletePrivateKey(keyData.keyId);
- setStatus({ error: 'Failed to restore backup. Key is invalid!', errorCode: 'BAD_KEY' });
- } else {
- setStatus({ error: 'Failed to restore backup.', errCode: 'UNKNOWN' });
- }
- }
- };
-
- useEffect(() => {
- mountStore.setItem(true);
- restoreBackup();
- }, []);
-
- return (
- <div className="key-backup__restore">
- {(status === false || status.message) && (
- <div>
- <Spinner size="small" />
- <Text>{status.message ?? 'Restoring backup keys...'}</Text>
- </div>
- )}
- {status.done && (
- <>
- <Text variant="h1">✅</Text>
- <Text>{status.done}</Text>
- </>
- )}
- {status.error && (
- <>
- <Text>{status.error}</Text>
- <Button onClick={restoreBackup}>Retry</Button>
- </>
- )}
- </div>
- );
-}
-RestoreKeyBackupDialog.propTypes = {
- keyData: PropTypes.shape({}).isRequired,
-};
-
-function DeleteKeyBackupDialog({ requestClose }) {
- const [isDeleting, setIsDeleting] = useState(false);
- const mx = useMatrixClient();
- const mountStore = useStore();
-
- const deleteBackup = async () => {
- mountStore.setItem(true);
- setIsDeleting(true);
- try {
- const backupInfo = await mx.getKeyBackupVersion();
- if (backupInfo) await mx.deleteKeyBackupVersion(backupInfo.version);
- if (!mountStore.getItem()) return;
- requestClose(true);
- } catch {
- if (!mountStore.getItem()) return;
- setIsDeleting(false);
- }
- };
-
- return (
- <div className="key-backup__delete">
- <Text variant="h1">🗑</Text>
- <Text weight="medium">Deleting key backup is permanent.</Text>
- <Text>All encrypted messages keys stored on server will be deleted.</Text>
- {isDeleting ? (
- <Spinner size="small" />
- ) : (
- <Button variant="danger" onClick={deleteBackup}>
- Delete
- </Button>
- )}
- </div>
- );
-}
-DeleteKeyBackupDialog.propTypes = {
- requestClose: PropTypes.func.isRequired,
-};
-
-function KeyBackup() {
- const mx = useMatrixClient();
- const isCSEnabled = useCrossSigningStatus();
- const [keyBackup, setKeyBackup] = useState(undefined);
- const mountStore = useStore();
-
- const fetchKeyBackupVersion = async () => {
- const info = await mx.getKeyBackupVersion();
- if (!mountStore.getItem()) return;
- setKeyBackup(info);
- };
-
- useEffect(() => {
- mountStore.setItem(true);
- fetchKeyBackupVersion();
-
- const handleAccountData = (event) => {
- if (event.getType() === 'm.megolm_backup.v1') {
- fetchKeyBackupVersion();
- }
- };
-
- mx.on('accountData', handleAccountData);
- return () => {
- mx.removeListener('accountData', handleAccountData);
- };
- }, [isCSEnabled]);
-
- const openCreateKeyBackup = async () => {
- const keyData = await accessSecretStorage(mx, 'Create Key Backup');
- if (keyData === null) return;
-
- openReusableDialog(
- <Text variant="s1" weight="medium">
- Create Key Backup
- </Text>,
- () => <CreateKeyBackupDialog keyData={keyData} />,
- () => fetchKeyBackupVersion()
- );
- };
-
- const openRestoreKeyBackup = async () => {
- const keyData = await accessSecretStorage(mx, 'Restore Key Backup');
- if (keyData === null) return;
-
- openReusableDialog(
- <Text variant="s1" weight="medium">
- Restore Key Backup
- </Text>,
- () => <RestoreKeyBackupDialog keyData={keyData} />
- );
- };
-
- const openDeleteKeyBackup = () =>
- openReusableDialog(
- <Text variant="s1" weight="medium">
- Delete Key Backup
- </Text>,
- (requestClose) => (
- <DeleteKeyBackupDialog
- requestClose={(isDone) => {
- if (isDone) setKeyBackup(null);
- requestClose();
- }}
- />
- )
- );
-
- const renderOptions = () => {
- if (keyBackup === undefined) return <Spinner size="small" />;
- if (keyBackup === null)
- return (
- <Button variant="primary" onClick={openCreateKeyBackup}>
- Create Backup
- </Button>
- );
- return (
- <>
- <IconButton
- src={DownloadIC}
- variant="positive"
- onClick={openRestoreKeyBackup}
- tooltip="Restore backup"
- />
- <IconButton src={BinIC} onClick={openDeleteKeyBackup} tooltip="Delete backup" />
- </>
- );
- };
-
- return (
- <SettingTile
- title="Encrypted messages backup"
- content={
- <>
- <Text variant="b3">
- Online backup your encrypted messages keys with your account data in case you lose
- access to your sessions. Your keys will be secured with a unique Security Key.
- </Text>
- {!isCSEnabled && (
- <InfoCard
- style={{ marginTop: 'var(--sp-ultra-tight)' }}
- rounded
- variant="caution"
- iconSrc={InfoIC}
- title="Setup cross signing to backup your encrypted messages."
- />
- )}
- </>
- }
- options={isCSEnabled ? renderOptions() : null}
- />
- );
-}
-
-export default KeyBackup;
+++ /dev/null
-.key-backup__create,
-.key-backup__restore {
- padding: var(--sp-normal);
-
- & > div {
- padding: var(--sp-normal) 0;
- display: flex;
- align-items: center;
-
- & > .text {
- margin: 0 var(--sp-normal);
- }
- }
-
- & > .text {
- margin-bottom: var(--sp-normal);
- }
-}
-
-.key-backup__delete {
- padding: var(--sp-normal);
- padding-top: var(--sp-extra-loose);
-
- & > .text {
- padding-bottom: var(--sp-normal);
- }
-}
\ No newline at end of file
+++ /dev/null
-import React, { useState } from 'react';
-import PropTypes from 'prop-types';
-import './SecretStorageAccess.scss';
-import { deriveKey } from 'matrix-js-sdk/lib/crypto/key_passphrase';
-
-import { openReusableDialog } from '../../../client/action/navigation';
-import { getDefaultSSKey, getSSKeyInfo } from '../../../util/matrixUtil';
-import { storePrivateKey, hasPrivateKey, getPrivateKey } from '../../../client/state/secretStorageKeys';
-
-import Text from '../../atoms/text/Text';
-import Button from '../../atoms/button/Button';
-import Input from '../../atoms/input/Input';
-import Spinner from '../../atoms/spinner/Spinner';
-
-import { useStore } from '../../hooks/useStore';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-function SecretStorageAccess({ onComplete }) {
- const mx = useMatrixClient();
- const sSKeyId = getDefaultSSKey(mx);
- const sSKeyInfo = getSSKeyInfo(mx, sSKeyId);
- const isPassphrase = !!sSKeyInfo.passphrase;
- const [withPhrase, setWithPhrase] = useState(isPassphrase);
- const [process, setProcess] = useState(false);
- const [error, setError] = useState(null);
- const mountStore = useStore();
-
- const toggleWithPhrase = () => setWithPhrase(!withPhrase);
-
- const processInput = async ({ key, phrase }) => {
- mountStore.setItem(true);
- setProcess(true);
- try {
- const { salt, iterations } = sSKeyInfo.passphrase || {};
- const privateKey = key
- ? mx.keyBackupKeyFromRecoveryKey(key)
- : await deriveKey(phrase, salt, iterations);
- const isCorrect = await mx.checkSecretStorageKey(privateKey, sSKeyInfo);
-
- if (!mountStore.getItem()) return;
- if (!isCorrect) {
- setError(`Incorrect Security ${key ? 'Key' : 'Phrase'}`);
- setProcess(false);
- return;
- }
- onComplete({
- keyId: sSKeyId,
- key,
- phrase,
- privateKey,
- });
- } catch (e) {
- if (!mountStore.getItem()) return;
- setError(`Incorrect Security ${key ? 'Key' : 'Phrase'}`);
- setProcess(false);
- }
- };
-
- const handleForm = async (e) => {
- e.preventDefault();
- const password = e.target.password.value;
- if (password.trim() === '') return;
- const data = {};
- if (withPhrase) data.phrase = password;
- else data.key = password;
- processInput(data);
- };
-
- const handleChange = () => {
- setError(null);
- setProcess(false);
- };
-
- return (
- <div className="secret-storage-access">
- <form onSubmit={handleForm}>
- <Input
- name="password"
- label={`Security ${withPhrase ? 'Phrase' : 'Key'}`}
- type="password"
- onChange={handleChange}
- required
- />
- {error && <Text variant="b3">{error}</Text>}
- {!process && (
- <div className="secret-storage-access__btn">
- <Button variant="primary" type="submit">Continue</Button>
- {isPassphrase && <Button onClick={toggleWithPhrase}>{`Use Security ${withPhrase ? 'Key' : 'Phrase'}`}</Button>}
- </div>
- )}
- </form>
- {process && <Spinner size="small" />}
- </div>
- );
-}
-SecretStorageAccess.propTypes = {
- onComplete: PropTypes.func.isRequired,
-};
-
-/**
- * @param {MatrixClient} mx Matrix client
- * @param {string} title Title of secret storage access dialog
- * @returns {Promise<keyData | null>} resolve to keyData or null
- */
-export const accessSecretStorage = (mx, title) => new Promise((resolve) => {
- let isCompleted = false;
- const defaultSSKey = getDefaultSSKey(mx);
- if (hasPrivateKey(defaultSSKey)) {
- resolve({ keyId: defaultSSKey, privateKey: getPrivateKey(defaultSSKey) });
- return;
- }
- const handleComplete = (keyData) => {
- isCompleted = true;
- storePrivateKey(keyData.keyId, keyData.privateKey);
- resolve(keyData);
- };
-
- openReusableDialog(
- <Text variant="s1" weight="medium">{title}</Text>,
- (requestClose) => (
- <SecretStorageAccess
- onComplete={(keyData) => {
- handleComplete(keyData);
- requestClose(requestClose);
- }}
- />
- ),
- () => {
- if (!isCompleted) resolve(null);
- },
- );
-});
-
-export default SecretStorageAccess;
+++ /dev/null
-.secret-storage-access {
- padding: var(--sp-normal);
-
- & form > *:not(:first-child) {
- margin-top: var(--sp-normal);
- }
-
- & .text-b3 {
- color: var(--tc-danger-high);
- margin-top: var(--sp-ultra-tight) !important;
- }
-
- &__btn {
- display: flex;
- justify-content: space-between;
- }
- & .donut-spinner {
- margin-top: var(--sp-normal);
- }
-}
\ No newline at end of file
+++ /dev/null
-import React, { useState, useEffect } from 'react';
-import { Input, toRem } from 'folds';
-import { isKeyHotkey } from 'is-hotkey';
-import './Settings.scss';
-
-import { clearCacheAndReload, logoutClient } from '../../../client/initMatrix';
-import cons from '../../../client/state/cons';
-import settings from '../../../client/state/settings';
-import navigation from '../../../client/state/navigation';
-import { toggleSystemTheme } from '../../../client/action/settings';
-import { usePermissionState } from '../../hooks/usePermission';
-
-import Text from '../../atoms/text/Text';
-import IconButton from '../../atoms/button/IconButton';
-import Button from '../../atoms/button/Button';
-import Toggle from '../../atoms/button/Toggle';
-import Tabs from '../../atoms/tabs/Tabs';
-import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
-import SegmentedControls from '../../atoms/segmented-controls/SegmentedControls';
-
-import PopupWindow from '../../molecules/popup-window/PopupWindow';
-import SettingTile from '../../molecules/setting-tile/SettingTile';
-import ImportE2ERoomKeys from '../../molecules/import-export-e2e-room-keys/ImportE2ERoomKeys';
-import ExportE2ERoomKeys from '../../molecules/import-export-e2e-room-keys/ExportE2ERoomKeys';
-import { ImagePackUser, ImagePackGlobal } from '../../molecules/image-pack/ImagePack';
-import GlobalNotification from '../../molecules/global-notification/GlobalNotification';
-import KeywordNotification from '../../molecules/global-notification/KeywordNotification';
-import IgnoreUserList from '../../molecules/global-notification/IgnoreUserList';
-
-import ProfileEditor from '../profile-editor/ProfileEditor';
-import CrossSigning from './CrossSigning';
-import KeyBackup from './KeyBackup';
-import DeviceManage from './DeviceManage';
-
-import SunIC from '../../../../public/res/ic/outlined/sun.svg';
-import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg';
-import LockIC from '../../../../public/res/ic/outlined/lock.svg';
-import BellIC from '../../../../public/res/ic/outlined/bell.svg';
-import InfoIC from '../../../../public/res/ic/outlined/info.svg';
-import PowerIC from '../../../../public/res/ic/outlined/power.svg';
-import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
-
-import CinnySVG from '../../../../public/res/svg/cinny.svg';
-import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
-import { useSetting } from '../../state/hooks/settings';
-import { settingsAtom } from '../../state/settings';
-import { isMacOS } from '../../utils/user-agent';
-import { KeySymbol } from '../../utils/key-symbol';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-
-function AppearanceSection() {
- const [, updateState] = useState({});
-
- const [enterForNewline, setEnterForNewline] = useSetting(settingsAtom, 'enterForNewline');
- const [messageLayout, setMessageLayout] = useSetting(settingsAtom, 'messageLayout');
- const [messageSpacing, setMessageSpacing] = useSetting(settingsAtom, 'messageSpacing');
- const [twitterEmoji, setTwitterEmoji] = useSetting(settingsAtom, 'twitterEmoji');
- const [pageZoom, setPageZoom] = useSetting(settingsAtom, 'pageZoom');
- const [isMarkdown, setIsMarkdown] = useSetting(settingsAtom, 'isMarkdown');
- const [hideMembershipEvents, setHideMembershipEvents] = useSetting(
- settingsAtom,
- 'hideMembershipEvents'
- );
- const [hideNickAvatarEvents, setHideNickAvatarEvents] = useSetting(
- settingsAtom,
- 'hideNickAvatarEvents'
- );
- const [mediaAutoLoad, setMediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad');
- const [urlPreview, setUrlPreview] = useSetting(settingsAtom, 'urlPreview');
- const [encUrlPreview, setEncUrlPreview] = useSetting(settingsAtom, 'encUrlPreview');
- const [showHiddenEvents, setShowHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents');
- const spacings = ['0', '100', '200', '300', '400', '500'];
-
- const [currentZoom, setCurrentZoom] = useState(`${pageZoom}`);
-
- const handleZoomChange = (evt) => {
- setCurrentZoom(evt.target.value);
- };
-
- const handleZoomEnter = (evt) => {
- if (isKeyHotkey('escape', evt)) {
- evt.stopPropagation();
- setCurrentZoom(pageZoom);
- }
- if (isKeyHotkey('enter', evt)) {
- const newZoom = parseInt(evt.target.value, 10);
- if (Number.isNaN(newZoom)) return;
- const safeZoom = Math.max(Math.min(newZoom, 150), 75);
- setPageZoom(safeZoom);
- setCurrentZoom(safeZoom);
- }
- };
-
- return (
- <div className="settings-appearance">
- <div className="settings-appearance__card">
- <MenuHeader>Theme</MenuHeader>
- <SettingTile
- title="Follow system theme"
- options={
- <Toggle
- isActive={settings.useSystemTheme}
- onToggle={() => {
- toggleSystemTheme();
- updateState({});
- }}
- />
- }
- content={<Text variant="b3">Use light or dark mode based on the system settings.</Text>}
- />
- <SettingTile
- title="Theme"
- content={
- <SegmentedControls
- selected={settings.useSystemTheme ? -1 : settings.getThemeIndex()}
- segments={[
- { text: 'Light' },
- { text: 'Silver' },
- { text: 'Dark' },
- { text: 'Butter' },
- ]}
- onSelect={(index) => {
- if (settings.useSystemTheme) toggleSystemTheme();
- settings.setTheme(index);
- updateState({});
- }}
- />
- }
- />
- <SettingTile
- title="Use Twitter Emoji"
- options={
- <Toggle isActive={twitterEmoji} onToggle={() => setTwitterEmoji(!twitterEmoji)} />
- }
- content={<Text variant="b3">Use Twitter emoji instead of system emoji.</Text>}
- />
- <SettingTile
- title="Page Zoom"
- options={
- <Input
- style={{ width: toRem(150) }}
- variant={pageZoom === parseInt(currentZoom, 10) ? 'Background' : 'Primary'}
- size="400"
- type="number"
- min="75"
- max="150"
- value={currentZoom}
- onChange={handleZoomChange}
- onKeyDown={handleZoomEnter}
- outlined
- after={<Text variant="b2">%</Text>}
- />
- }
- content={
- <Text variant="b3">
- Change page zoom to scale user interface between 75% to 150%. Default: 100%
- </Text>
- }
- />
- </div>
- <div className="settings-appearance__card">
- <MenuHeader>Room messages</MenuHeader>
- <SettingTile
- title="Message Layout"
- content={
- <SegmentedControls
- selected={messageLayout}
- segments={[{ text: 'Modern' }, { text: 'Compact' }, { text: 'Bubble' }]}
- onSelect={(index) => setMessageLayout(index)}
- />
- }
- />
- <SettingTile
- title="Message Spacing"
- content={
- <SegmentedControls
- selected={spacings.findIndex((s) => s === messageSpacing)}
- segments={[
- { text: 'No' },
- { text: 'XXS' },
- { text: 'XS' },
- { text: 'S' },
- { text: 'M' },
- { text: 'L' },
- ]}
- onSelect={(index) => {
- setMessageSpacing(spacings[index]);
- }}
- />
- }
- />
- <SettingTile
- title="Use ENTER for Newline"
- options={
- <Toggle
- isActive={enterForNewline}
- onToggle={() => setEnterForNewline(!enterForNewline)}
- />
- }
- content={
- <Text variant="b3">{`Use ${
- isMacOS() ? KeySymbol.Command : 'Ctrl'
- } + ENTER to send message and ENTER for newline.`}</Text>
- }
- />
- <SettingTile
- title="Markdown formatting"
- options={<Toggle isActive={isMarkdown} onToggle={() => setIsMarkdown(!isMarkdown)} />}
- content={<Text variant="b3">Format messages with markdown syntax before sending.</Text>}
- />
- <SettingTile
- title="Hide membership events"
- options={
- <Toggle
- isActive={hideMembershipEvents}
- onToggle={() => setHideMembershipEvents(!hideMembershipEvents)}
- />
- }
- content={
- <Text variant="b3">
- Hide membership change messages from room timeline. (Join, Leave, Invite, Kick and
- Ban)
- </Text>
- }
- />
- <SettingTile
- title="Hide nick/avatar events"
- options={
- <Toggle
- isActive={hideNickAvatarEvents}
- onToggle={() => setHideNickAvatarEvents(!hideNickAvatarEvents)}
- />
- }
- content={
- <Text variant="b3">Hide nick and avatar change messages from room timeline.</Text>
- }
- />
- <SettingTile
- title="Disable media auto load"
- options={
- <Toggle isActive={!mediaAutoLoad} onToggle={() => setMediaAutoLoad(!mediaAutoLoad)} />
- }
- content={
- <Text variant="b3">Prevent images and videos from auto loading to save bandwidth.</Text>
- }
- />
- <SettingTile
- title="Url Preview"
- options={<Toggle isActive={urlPreview} onToggle={() => setUrlPreview(!urlPreview)} />}
- content={<Text variant="b3">Show url preview for link in messages.</Text>}
- />
- <SettingTile
- title="Url Preview in Encrypted Room"
- options={
- <Toggle isActive={encUrlPreview} onToggle={() => setEncUrlPreview(!encUrlPreview)} />
- }
- content={<Text variant="b3">Show url preview for link in encrypted messages.</Text>}
- />
- <SettingTile
- title="Show hidden events"
- options={
- <Toggle
- isActive={showHiddenEvents}
- onToggle={() => setShowHiddenEvents(!showHiddenEvents)}
- />
- }
- content={<Text variant="b3">Show hidden state and message events.</Text>}
- />
- </div>
- </div>
- );
-}
-
-function NotificationsSection() {
- const notifPermission = usePermissionState(
- 'notifications',
- window.Notification?.permission ?? 'denied'
- );
- const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications');
- const [isNotificationSounds, setIsNotificationSounds] = useSetting(
- settingsAtom,
- 'isNotificationSounds'
- );
-
- const renderOptions = () => {
- if (window.Notification === undefined) {
- return (
- <Text className="settings-notifications__not-supported">
- Not supported in this browser.
- </Text>
- );
- }
-
- if (notifPermission === 'denied') {
- return <Text>Permission Denied</Text>;
- }
-
- if (notifPermission === 'granted') {
- return (
- <Toggle
- isActive={showNotifications}
- onToggle={() => {
- setShowNotifications(!showNotifications);
- }}
- />
- );
- }
-
- return (
- <Button
- variant="primary"
- onClick={() =>
- window.Notification.requestPermission().then(() => {
- setShowNotifications(window.Notification?.permission === 'granted');
- })
- }
- >
- Request permission
- </Button>
- );
- };
-
- return (
- <>
- <div className="settings-notifications">
- <MenuHeader>Notification & Sound</MenuHeader>
- <SettingTile
- title="Desktop notification"
- options={renderOptions()}
- content={<Text variant="b3">Show desktop notification when new messages arrive.</Text>}
- />
- <SettingTile
- title="Notification Sound"
- options={
- <Toggle
- isActive={isNotificationSounds}
- onToggle={() => setIsNotificationSounds(!isNotificationSounds)}
- />
- }
- content={<Text variant="b3">Play sound when new messages arrive.</Text>}
- />
- </div>
- <GlobalNotification />
- <KeywordNotification />
- <IgnoreUserList />
- </>
- );
-}
-
-function EmojiSection() {
- return (
- <>
- <div className="settings-emoji__card">
- <ImagePackUser />
- </div>
- <div className="settings-emoji__card">
- <ImagePackGlobal />
- </div>
- </>
- );
-}
-
-function SecuritySection() {
- return (
- <div className="settings-security">
- <div className="settings-security__card">
- <MenuHeader>Cross signing and backup</MenuHeader>
- <CrossSigning />
- <KeyBackup />
- </div>
- <DeviceManage />
- <div className="settings-security__card">
- <MenuHeader>Export/Import encryption keys</MenuHeader>
- <SettingTile
- title="Export E2E room keys"
- content={
- <>
- <Text variant="b3">
- Export end-to-end encryption room keys to decrypt old messages in other session. In
- order to encrypt keys you need to set a password, which will be used while
- importing.
- </Text>
- <ExportE2ERoomKeys />
- </>
- }
- />
- <SettingTile
- title="Import E2E room keys"
- content={
- <>
- <Text variant="b3">
- {
- "To decrypt older messages, Export E2EE room keys from Element (Settings > Security & Privacy > Encryption > Cryptography) and import them here. Imported keys are encrypted so you'll have to enter the password you set in order to decrypt it."
- }
- </Text>
- <ImportE2ERoomKeys />
- </>
- }
- />
- </div>
- </div>
- );
-}
-
-function AboutSection() {
- const mx = useMatrixClient();
-
- return (
- <div className="settings-about">
- <div className="settings-about__card">
- <MenuHeader>Application</MenuHeader>
- <div className="settings-about__branding">
- <img width="60" height="60" src={CinnySVG} alt="Cinny logo" />
- <div>
- <Text variant="h2" weight="medium">
- Cinny
- <span
- className="text text-b3"
- style={{ margin: '0 var(--sp-extra-tight)' }}
- >{`v${cons.version}`}</span>
- </Text>
- <Text>Yet another matrix client</Text>
-
- <div className="settings-about__btns">
- <Button onClick={() => window.open('https://github.com/ajbura/cinny')}>
- Source code
- </Button>
- <Button onClick={() => window.open('https://cinny.in/#sponsor')}>Support</Button>
- <Button onClick={() => clearCacheAndReload(mx)} variant="danger">
- Clear cache & reload
- </Button>
- </div>
- </div>
- </div>
- </div>
- <div className="settings-about__card">
- <MenuHeader>Credits</MenuHeader>
- <div className="settings-about__credits">
- <ul>
- <li>
- {/* eslint-disable-next-line react/jsx-one-expression-per-line */}
- <Text>
- The{' '}
- <a
- href="https://github.com/matrix-org/matrix-js-sdk"
- rel="noreferrer noopener"
- target="_blank"
- >
- matrix-js-sdk
- </a>{' '}
- is ©{' '}
- <a href="https://matrix.org/foundation" rel="noreferrer noopener" target="_blank">
- The Matrix.org Foundation C.I.C
- </a>{' '}
- used under the terms of{' '}
- <a
- href="http://www.apache.org/licenses/LICENSE-2.0"
- rel="noreferrer noopener"
- target="_blank"
- >
- Apache 2.0
- </a>
- .
- </Text>
- </li>
- <li>
- {/* eslint-disable-next-line react/jsx-one-expression-per-line */}
- <Text>
- The{' '}
- <a
- href="https://github.com/mozilla/twemoji-colr"
- target="_blank"
- rel="noreferrer noopener"
- >
- twemoji-colr
- </a>{' '}
- font is ©{' '}
- <a href="https://mozilla.org/" target="_blank" rel="noreferrer noopener">
- Mozilla Foundation
- </a>{' '}
- used under the terms of{' '}
- <a
- href="http://www.apache.org/licenses/LICENSE-2.0"
- target="_blank"
- rel="noreferrer noopener"
- >
- Apache 2.0
- </a>
- .
- </Text>
- </li>
- <li>
- {/* eslint-disable-next-line react/jsx-one-expression-per-line */}
- <Text>
- The{' '}
- <a href="https://twemoji.twitter.com" target="_blank" rel="noreferrer noopener">
- Twemoji
- </a>{' '}
- emoji art is ©{' '}
- <a href="https://twemoji.twitter.com" target="_blank" rel="noreferrer noopener">
- Twitter, Inc and other contributors
- </a>{' '}
- used under the terms of{' '}
- <a
- href="https://creativecommons.org/licenses/by/4.0/"
- target="_blank"
- rel="noreferrer noopener"
- >
- CC-BY 4.0
- </a>
- .
- </Text>
- </li>
- <li>
- {/* eslint-disable-next-line react/jsx-one-expression-per-line */}
- <Text>
- The{' '}
- <a
- href="https://material.io/design/sound/sound-resources.html"
- target="_blank"
- rel="noreferrer noopener"
- >
- Material sound resources
- </a>{' '}
- are ©{' '}
- <a href="https://google.com" target="_blank" rel="noreferrer noopener">
- Google
- </a>{' '}
- used under the terms of{' '}
- <a
- href="https://creativecommons.org/licenses/by/4.0/"
- target="_blank"
- rel="noreferrer noopener"
- >
- CC-BY 4.0
- </a>
- .
- </Text>
- </li>
- </ul>
- </div>
- </div>
- </div>
- );
-}
-
-export const tabText = {
- APPEARANCE: 'Appearance',
- NOTIFICATIONS: 'Notifications',
- EMOJI: 'Emoji',
- SECURITY: 'Security',
- ABOUT: 'About',
-};
-const tabItems = [
- {
- text: tabText.APPEARANCE,
- iconSrc: SunIC,
- disabled: false,
- render: () => <AppearanceSection />,
- },
- {
- text: tabText.NOTIFICATIONS,
- iconSrc: BellIC,
- disabled: false,
- render: () => <NotificationsSection />,
- },
- {
- text: tabText.EMOJI,
- iconSrc: EmojiIC,
- disabled: false,
- render: () => <EmojiSection />,
- },
- {
- text: tabText.SECURITY,
- iconSrc: LockIC,
- disabled: false,
- render: () => <SecuritySection />,
- },
- {
- text: tabText.ABOUT,
- iconSrc: InfoIC,
- disabled: false,
- render: () => <AboutSection />,
- },
-];
-
-function useWindowToggle(setSelectedTab) {
- const [isOpen, setIsOpen] = useState(false);
-
- useEffect(() => {
- const openSettings = (tab) => {
- const tabItem = tabItems.find((item) => item.text === tab);
- if (tabItem) setSelectedTab(tabItem);
- setIsOpen(true);
- };
- navigation.on(cons.events.navigation.SETTINGS_OPENED, openSettings);
- return () => {
- navigation.removeListener(cons.events.navigation.SETTINGS_OPENED, openSettings);
- };
- }, []);
-
- const requestClose = () => setIsOpen(false);
-
- return [isOpen, requestClose];
-}
-
-function Settings() {
- const [selectedTab, setSelectedTab] = useState(tabItems[0]);
- const [isOpen, requestClose] = useWindowToggle(setSelectedTab);
- const mx = useMatrixClient();
-
- const handleTabChange = (tabItem) => setSelectedTab(tabItem);
- const handleLogout = async () => {
- if (
- await confirmDialog(
- 'Logout',
- 'Are you sure that you want to logout your session?',
- 'Logout',
- 'danger'
- )
- ) {
- logoutClient(mx);
- }
- };
-
- return (
- <PopupWindow
- isOpen={isOpen}
- className="settings-window"
- title={
- <Text variant="s1" weight="medium" primary>
- Settings
- </Text>
- }
- contentOptions={
- <>
- <Button variant="danger" iconSrc={PowerIC} onClick={handleLogout}>
- Logout
- </Button>
- <IconButton src={CrossIC} onClick={requestClose} tooltip="Close" />
- </>
- }
- onRequestClose={requestClose}
- >
- {isOpen && (
- <div className="settings-window__content">
- <ProfileEditor userId={mx.getUserId()} />
- <Tabs
- items={tabItems}
- defaultSelected={tabItems.findIndex((tab) => tab.text === selectedTab.text)}
- onSelect={handleTabChange}
- />
- <div className="settings-window__cards-wrapper">{selectedTab.render()}</div>
- </div>
- )}
- </PopupWindow>
- );
-}
-
-export default Settings;
+++ /dev/null
-@use '../../partials/flex';
-@use '../../partials/dir';
-@use '../../partials/screen';
-
-.settings-window {
- & .pw {
- background-color: var(--bg-surface-low);
- }
-
- .header .btn-danger {
- margin: 0 var(--sp-tight);
- box-shadow: none;
- }
-
- & .profile-editor {
- padding: var(--sp-loose) var(--sp-extra-loose);
- }
-
- & .tabs__content {
- padding: 0 var(--sp-normal);
- }
-
- &__cards-wrapper {
- padding: 0 var(--sp-normal);
- @include dir.side(padding, var(--sp-normal), var(--sp-extra-tight));
- }
-}
-.settings-window__card {
- margin: var(--sp-normal) 0;
- background-color: var(--bg-surface);
- border-radius: var(--bo-radius);
- box-shadow: var(--bs-surface-border);
- overflow: hidden;
-
- & > .context-menu__header:first-child {
- margin-top: 2px;
- }
-}
-.settings-appearance__card,
-.settings-notifications,
-.global-notification,
-.keyword-notification,
-.ignore-user-list,
-.settings-security__card,
-.settings-security .device-manage,
-.settings-about__card,
-.settings-emoji__card {
- @extend .settings-window__card;
-}
-
-.settings-window__cards-wrapper{
- & .setting-tile {
- margin: 0 var(--sp-normal);
- margin-top: var(--sp-normal);
- padding-bottom: 16px;
- border-bottom: 1px solid var(--bg-surface-border);
- &:last-child {
- border-bottom: none;
- }
- }
-}
-
-.settings-notifications {
- &__not-supported {
- padding: 0 var(--sp-ultra-tight);
- }
-}
-
-.settings-about {
- &__branding {
- padding: var(--sp-normal);
- display: flex;
-
- & > div {
- margin: 0 var(--sp-loose);
- }
-
- }
- &__btns {
- & button {
- margin-top: var(--sp-tight);
- @include dir.side(margin, 0, var(--sp-tight));
- }
- }
-
- &__credits {
- padding: 0 var(--sp-normal);
- & ul {
- color: var(--tc-surface-low);
- padding: var(--sp-normal);
- margin: var(--sp-extra-tight) 0;
- }
- }
-}
import { MobileFriendlyPageNav, MobileFriendlyClientNav } from './MobileFriendly';
import { ClientInitStorageAtom } from './client/ClientInitStorageAtom';
import { ClientNonUIFeatures } from './client/ClientNonUIFeatures';
+import { AuthRouteThemeManager, UnAuthRouteThemeManager } from './ThemeManager';
+import { ReceiveSelfDeviceVerification } from '../components/DeviceVerification';
+import { AutoRestoreBackupOnVerification } from '../components/BackupRestore';
export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize) => {
const { hashRouter } = clientConfig;
return null;
}}
- element={<AuthLayout />}
+ element={
+ <>
+ <AuthLayout />
+ <UnAuthRouteThemeManager />
+ </>
+ }
>
<Route path={LOGIN_PATH} element={<Login />} />
<Route path={REGISTER_PATH} element={<Register />} />
return null;
}}
element={
- <ClientRoot>
- <ClientInitStorageAtom>
- <ClientBindAtoms>
- <ClientNonUIFeatures>
- <ClientLayout
- nav={
- <MobileFriendlyClientNav>
- <SidebarNav />
- </MobileFriendlyClientNav>
- }
- >
- <Outlet />
- </ClientLayout>
- </ClientNonUIFeatures>
- </ClientBindAtoms>
- </ClientInitStorageAtom>
- </ClientRoot>
+ <>
+ <ClientRoot>
+ <ClientInitStorageAtom>
+ <ClientBindAtoms>
+ <ClientNonUIFeatures>
+ <ClientLayout
+ nav={
+ <MobileFriendlyClientNav>
+ <SidebarNav />
+ </MobileFriendlyClientNav>
+ }
+ >
+ <Outlet />
+ </ClientLayout>
+ <ReceiveSelfDeviceVerification />
+ <AutoRestoreBackupOnVerification />
+ </ClientNonUIFeatures>
+ </ClientBindAtoms>
+ </ClientInitStorageAtom>
+ </ClientRoot>
+ <AuthRouteThemeManager />
+ </>
}
>
<Route
--- /dev/null
+import { useEffect } from 'react';
+import { configClass, varsClass } from 'folds';
+import { DarkTheme, LightTheme, ThemeKind, useSystemThemeKind, useThemes } from '../hooks/useTheme';
+import { useSetting } from '../state/hooks/settings';
+import { settingsAtom } from '../state/settings';
+
+export function UnAuthRouteThemeManager() {
+ const systemThemeKind = useSystemThemeKind();
+
+ useEffect(() => {
+ document.body.className = '';
+ document.body.classList.add(configClass, varsClass);
+ if (systemThemeKind === ThemeKind.Dark) {
+ document.body.classList.add(...DarkTheme.classNames);
+ }
+ if (systemThemeKind === ThemeKind.Light) {
+ document.body.classList.add(...LightTheme.classNames);
+ }
+ }, [systemThemeKind]);
+
+ return null;
+}
+
+export function AuthRouteThemeManager() {
+ const systemThemeKind = useSystemThemeKind();
+ const themes = useThemes();
+ const [systemTheme] = useSetting(settingsAtom, 'useSystemTheme');
+ const [themeId] = useSetting(settingsAtom, 'themeId');
+ const [lightThemeId] = useSetting(settingsAtom, 'lightThemeId');
+ const [darkThemeId] = useSetting(settingsAtom, 'darkThemeId');
+
+ // apply normal theme if system theme is disabled
+ useEffect(() => {
+ if (!systemTheme) {
+ document.body.className = '';
+ document.body.classList.add(configClass, varsClass);
+ const selectedTheme = themes.find((theme) => theme.id === themeId) ?? LightTheme;
+
+ document.body.classList.add(...selectedTheme.classNames);
+ }
+ }, [systemTheme, themes, themeId]);
+
+ // apply preferred system theme if system theme is enabled
+ useEffect(() => {
+ if (systemTheme) {
+ document.body.className = '';
+ document.body.classList.add(configClass, varsClass);
+ const selectedTheme =
+ systemThemeKind === ThemeKind.Dark
+ ? themes.find((theme) => theme.id === darkThemeId) ?? DarkTheme
+ : themes.find((theme) => theme.id === lightThemeId) ?? LightTheme;
+
+ document.body.classList.add(...selectedTheme.classNames);
+ }
+ }, [systemTheme, systemThemeKind, themes, lightThemeId, darkThemeId]);
+
+ return null;
+}
login,
useLoginComplete,
} from './loginUtil';
-import { PasswordInput } from '../../../components/password-input/PasswordInput';
+import { PasswordInput } from '../../../components/password-input';
import { FieldError } from '../FiledError';
import { getResetPasswordPath } from '../../pathUtils';
import { stopPropagation } from '../../../utils/keyboard';
UIAFlow,
createClient,
} from 'matrix-js-sdk';
-import { PasswordInput } from '../../../components/password-input/PasswordInput';
+import { PasswordInput } from '../../../components/password-input';
import {
getLoginTermUrl,
getUIAFlowForStages,
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useAuthServer } from '../../../hooks/useAuthServer';
import { usePasswordEmail } from '../../../hooks/usePasswordEmail';
-import { PasswordInput } from '../../../components/password-input/PasswordInput';
+import { PasswordInput } from '../../../components/password-input';
import { ConfirmPasswordMatch } from '../../../components/ConfirmPasswordMatch';
import { FieldError } from '../FiledError';
import { UIAFlowOverlay } from '../../../components/UIAFlowOverlay';
import React, { MouseEventHandler, ReactNode, useCallback, useEffect, useState } from 'react';
import {
clearCacheAndReload,
+ clearLoginData,
initClient,
logoutClient,
startClient,
);
}
-function ClientRootOptions({ mx }: { mx: MatrixClient }) {
+function ClientRootOptions({ mx }: { mx?: MatrixClient }) {
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
const handleToggle: MouseEventHandler<HTMLButtonElement> = (evt) => {
>
<Menu>
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
- <MenuItem onClick={() => clearCacheAndReload(mx)} size="300" radii="300">
- <Text as="span" size="T300" truncate>
- Clear Cache and Reload
- </Text>
- </MenuItem>
+ {mx && (
+ <MenuItem onClick={() => clearCacheAndReload(mx)} size="300" radii="300">
+ <Text as="span" size="T300" truncate>
+ Clear Cache and Reload
+ </Text>
+ </MenuItem>
+ )}
<MenuItem
- onClick={() => logoutClient(mx)}
+ onClick={() => {
+ if (mx) {
+ logoutClient(mx);
+ return;
+ }
+ clearLoginData();
+ }}
size="300"
radii="300"
variant="Critical"
return (
<SpecVersions baseUrl={baseUrl!}>
{mx && <SyncStatus mx={mx} />}
- {loading && mx && <ClientRootOptions mx={mx} />}
+ {loading && <ClientRootOptions mx={mx} />}
{(loadState.status === AsyncStatus.Error || startState.status === AsyncStatus.Error) && (
<SplashScreen>
<Box direction="Column" grow="Yes" alignItems="Center" justifyContent="Center" gap="400">
<Text>{`Failed to load. ${loadState.error.message}`}</Text>
)}
{startState.status === AsyncStatus.Error && (
- <Text>{`Failed to load. ${startState.error.message}`}</Text>
+ <Text>{`Failed to start. ${startState.error.message}`}</Text>
)}
<Button variant="Critical" onClick={mx ? () => startMatrix(mx) : loadMatrix}>
<Text as="span" size="B400">
SpaceTabs,
InboxTab,
ExploreTab,
- UserTab,
+ SettingsTab,
UnverifiedTab,
} from './sidebar';
import { openCreateRoom, openSearch } from '../../../client/action/navigation';
<UnverifiedTab />
<InboxTab />
- <UserTab />
+ <SettingsTab />
</SidebarStack>
</>
}
--- /dev/null
+import React, { useState } from 'react';
+import { Text } from 'folds';
+import { SidebarItem, SidebarItemTooltip, SidebarAvatar } from '../../../components/sidebar';
+import { UserAvatar } from '../../../components/user-avatar';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix';
+import { nameInitials } from '../../../utils/common';
+import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
+import { Settings } from '../../../features/settings';
+import { useUserProfile } from '../../../hooks/useUserProfile';
+import { Modal500 } from '../../../components/Modal500';
+
+export function SettingsTab() {
+ const mx = useMatrixClient();
+ const useAuthentication = useMediaAuthentication();
+ const userId = mx.getUserId()!;
+ const profile = useUserProfile(userId);
+
+ const [settings, setSettings] = useState(false);
+
+ const displayName = profile.displayName ?? getMxIdLocalPart(userId) ?? userId;
+ const avatarUrl = profile.avatarUrl
+ ? mxcUrlToHttp(mx, profile.avatarUrl, useAuthentication, 96, 96, 'crop') ?? undefined
+ : undefined;
+
+ const openSettings = () => setSettings(true);
+ const closeSettings = () => setSettings(false);
+
+ return (
+ <SidebarItem active={settings}>
+ <SidebarItemTooltip tooltip={displayName}>
+ {(triggerRef) => (
+ <SidebarAvatar as="button" ref={triggerRef} onClick={openSettings}>
+ <UserAvatar
+ userId={userId}
+ src={avatarUrl}
+ renderFallback={() => <Text size="H4">{nameInitials(displayName)}</Text>}
+ />
+ </SidebarAvatar>
+ )}
+ </SidebarItemTooltip>
+ {settings && (
+ <Modal500 requestClose={closeSettings}>
+ <Settings requestClose={closeSettings} />
+ </Modal500>
+ )}
+ </SidebarItem>
+ );
+}
color: color.Critical.OnContainer,
borderColor: color.Critical.ContainerLine,
});
+
+export const UnverifiedOtherAvatar = style({
+ backgroundColor: color.Warning.Container,
+ color: color.Warning.OnContainer,
+ borderColor: color.Warning.ContainerLine,
+});
-import React from 'react';
+import React, { useState } from 'react';
import { Badge, color, Icon, Icons, Text } from 'folds';
-import { openSettings } from '../../../../client/action/navigation';
-import { isCrossVerified } from '../../../../util/matrixUtil';
import {
SidebarAvatar,
SidebarItem,
SidebarItemBadge,
SidebarItemTooltip,
} from '../../../components/sidebar';
-import { useDeviceList } from '../../../hooks/useDeviceList';
-import { tabText } from '../../../organisms/settings/Settings';
+import { useDeviceIds, useDeviceList, useSplitCurrentDevice } from '../../../hooks/useDeviceList';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import * as css from './UnverifiedTab.css';
+import {
+ useDeviceVerificationStatus,
+ useUnverifiedDeviceCount,
+ VerificationStatus,
+} from '../../../hooks/useDeviceVerificationStatus';
+import { useCrossSigningActive } from '../../../hooks/useCrossSigning';
+import { Modal500 } from '../../../components/Modal500';
+import { Settings, SettingsPages } from '../../../features/settings';
-export function UnverifiedTab() {
+function UnverifiedIndicator() {
const mx = useMatrixClient();
- const deviceList = useDeviceList();
- const unverified = deviceList?.filter(
- (device) => isCrossVerified(mx, device.device_id) === false
+
+ const crypto = mx.getCrypto();
+ const [devices] = useDeviceList();
+
+ const [currentDevice, otherDevices] = useSplitCurrentDevice(devices);
+
+ const verificationStatus = useDeviceVerificationStatus(
+ crypto,
+ mx.getSafeUserId(),
+ currentDevice?.device_id
+ );
+ const unverified = verificationStatus === VerificationStatus.Unverified;
+
+ const otherDevicesId = useDeviceIds(otherDevices);
+ const unverifiedDeviceCount = useUnverifiedDeviceCount(
+ crypto,
+ mx.getSafeUserId(),
+ otherDevicesId
);
- if (!unverified?.length) return null;
+ const [settings, setSettings] = useState(false);
+ const closeSettings = () => setSettings(false);
+ const hasUnverified =
+ unverified || (unverifiedDeviceCount !== undefined && unverifiedDeviceCount > 0);
return (
- <SidebarItem className={css.UnverifiedTab}>
- <SidebarItemTooltip tooltip="Unverified Sessions">
- {(triggerRef) => (
- <SidebarAvatar
- className={css.UnverifiedAvatar}
- as="button"
- ref={triggerRef}
- outlined
- onClick={() => openSettings(tabText.SECURITY)}
- >
- <Icon style={{ color: color.Critical.Main }} src={Icons.ShieldUser} />
- </SidebarAvatar>
- )}
- </SidebarItemTooltip>
- <SidebarItemBadge hasCount>
- <Badge variant="Critical" size="400" fill="Solid" radii="Pill" outlined={false}>
- <Text as="span" size="L400">
- {unverified.length}
- </Text>
- </Badge>
- </SidebarItemBadge>
- </SidebarItem>
+ <>
+ {hasUnverified && (
+ <SidebarItem active={settings} className={css.UnverifiedTab}>
+ <SidebarItemTooltip tooltip={unverified ? 'Unverified Device' : 'Unverified Devices'}>
+ {(triggerRef) => (
+ <SidebarAvatar
+ className={unverified ? css.UnverifiedAvatar : css.UnverifiedOtherAvatar}
+ as="button"
+ ref={triggerRef}
+ outlined
+ onClick={() => setSettings(true)}
+ >
+ <Icon
+ style={{ color: unverified ? color.Critical.Main : color.Warning.Main }}
+ src={Icons.ShieldUser}
+ />
+ </SidebarAvatar>
+ )}
+ </SidebarItemTooltip>
+ {!unverified && unverifiedDeviceCount && unverifiedDeviceCount > 0 && (
+ <SidebarItemBadge hasCount>
+ <Badge variant="Warning" size="400" fill="Solid" radii="Pill" outlined={false}>
+ <Text as="span" size="L400">
+ {unverifiedDeviceCount}
+ </Text>
+ </Badge>
+ </SidebarItemBadge>
+ )}
+ </SidebarItem>
+ )}
+ {settings && (
+ <Modal500 requestClose={closeSettings}>
+ <Settings initialPage={SettingsPages.DevicesPage} requestClose={closeSettings} />
+ </Modal500>
+ )}
+ </>
);
}
+
+export function UnverifiedTab() {
+ const crossSigningActive = useCrossSigningActive();
+
+ if (!crossSigningActive) return null;
+
+ return <UnverifiedIndicator />;
+}
+++ /dev/null
-import React, { useEffect, useState } from 'react';
-import { Text } from 'folds';
-import { UserEvent, UserEventHandlerMap } from 'matrix-js-sdk';
-import { SidebarItem, SidebarItemTooltip, SidebarAvatar } from '../../../components/sidebar';
-import { openSettings } from '../../../../client/action/navigation';
-import { UserAvatar } from '../../../components/user-avatar';
-import { useMatrixClient } from '../../../hooks/useMatrixClient';
-import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix';
-import { nameInitials } from '../../../utils/common';
-import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
-
-type UserProfile = {
- avatar_url?: string;
- displayname?: string;
-};
-export function UserTab() {
- const mx = useMatrixClient();
- const useAuthentication = useMediaAuthentication();
- const userId = mx.getUserId()!;
-
- const [profile, setProfile] = useState<UserProfile>({});
- const displayName = profile.displayname ?? getMxIdLocalPart(userId) ?? userId;
- const avatarUrl = profile.avatar_url
- ? mxcUrlToHttp(mx, profile.avatar_url, useAuthentication, 96, 96, 'crop') ?? undefined
- : undefined;
-
- useEffect(() => {
- const user = mx.getUser(userId);
- const onAvatarChange: UserEventHandlerMap[UserEvent.AvatarUrl] = (event, myUser) => {
- setProfile((cp) => ({
- ...cp,
- avatar_url: myUser.avatarUrl,
- }));
- };
- const onDisplayNameChange: UserEventHandlerMap[UserEvent.DisplayName] = (event, myUser) => {
- setProfile((cp) => ({
- ...cp,
- avatar_url: myUser.displayName,
- }));
- };
- mx.getProfileInfo(userId).then((info) => setProfile(() => ({ ...info })));
- user?.on(UserEvent.AvatarUrl, onAvatarChange);
- user?.on(UserEvent.DisplayName, onDisplayNameChange);
- return () => {
- user?.removeListener(UserEvent.AvatarUrl, onAvatarChange);
- user?.removeListener(UserEvent.DisplayName, onDisplayNameChange);
- };
- }, [mx, userId]);
-
- return (
- <SidebarItem>
- <SidebarItemTooltip tooltip="User Settings">
- {(triggerRef) => (
- <SidebarAvatar as="button" ref={triggerRef} onClick={() => openSettings()}>
- <UserAvatar
- userId={userId}
- src={avatarUrl}
- renderFallback={() => <Text size="H4">{nameInitials(displayName)}</Text>}
- />
- </SidebarAvatar>
- )}
- </SidebarItemTooltip>
- </SidebarItem>
- );
-}
export * from './SpaceTabs';
export * from './InboxTab';
export * from './ExploreTab';
-export * from './UserTab';
+export * from './SettingsTab';
export * from './UnverifiedTab';
toRem,
} from 'folds';
import { useVirtualizer } from '@tanstack/react-virtual';
-import { IJoinRuleEventContent, JoinRule, Room } from 'matrix-js-sdk';
+import { JoinRule, Room } from 'matrix-js-sdk';
+import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
import FocusTrap from 'focus-trap-react';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { mDirectAtom } from '../../../state/mDirectList';
const joinRules = useStateEvent(
space,
StateEvent.RoomJoinRules
- )?.getContent<IJoinRuleEventContent>();
+ )?.getContent<RoomJoinRulesEventContent>();
const handleOpenMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
const cords = evt.currentTarget.getBoundingClientRect();
export const INBOX_NOTIFICATIONS_PATH = `/inbox/${_NOTIFICATIONS_PATH}`;
export const INBOX_INVITES_PATH = `/inbox/${_INVITES_PATH}`;
-export const USER_SETTINGS_PATH = '/user-settings/';
-
export const SPACE_SETTINGS_PATH = '/space-settings/';
export const ROOM_SETTINGS_PATH = '/room-settings/';
+++ /dev/null
-import { IImageInfo, MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk';
-import { AccountDataEvent } from '../../types/matrix/accountData';
-import { getAccountData, getStateEvents } from '../utils/room';
-import { StateEvent } from '../../types/matrix/room';
-
-// https://github.com/Sorunome/matrix-doc/blob/soru/emotes/proposals/2545-emotes.md
-
-export type PackEventIdToUnknown = Record<string, unknown>;
-export type EmoteRoomIdToPackEvents = Record<string, PackEventIdToUnknown>;
-export type EmoteRoomsContent = {
- rooms?: EmoteRoomIdToPackEvents;
-};
-
-export enum PackUsage {
- Emoticon = 'emoticon',
- Sticker = 'sticker',
-}
-
-export type PackImage = {
- url: string;
- body?: string;
- usage?: PackUsage[];
- info?: IImageInfo;
-};
-
-export type PackImages = Record<string, PackImage>;
-
-export type PackMeta = {
- display_name?: string;
- avatar_url?: string;
- attribution?: string;
- usage?: PackUsage[];
-};
-
-export type ExtendedPackImage = PackImage & {
- shortcode: string;
-};
-
-export type PackContent = {
- pack?: PackMeta;
- images?: PackImages;
-};
-
-export class ImagePack {
- public id: string;
-
- public content: PackContent;
-
- public displayName?: string;
-
- public avatarUrl?: string;
-
- public usage?: PackUsage[];
-
- public attribution?: string;
-
- public images: Map<string, ExtendedPackImage>;
-
- public emoticons: ExtendedPackImage[];
-
- public stickers: ExtendedPackImage[];
-
- static parsePack(eventId: string, packContent: PackContent) {
- if (!eventId || typeof packContent?.images !== 'object') {
- return undefined;
- }
-
- return new ImagePack(eventId, packContent);
- }
-
- constructor(eventId: string, content: PackContent) {
- this.id = eventId;
- this.content = JSON.parse(JSON.stringify(content));
-
- this.images = new Map();
- this.emoticons = [];
- this.stickers = [];
-
- this.applyPackMeta(content);
- this.applyImages(content);
- }
-
- applyPackMeta(content: PackContent) {
- const pack = content.pack ?? {};
-
- this.displayName = pack.display_name;
- this.avatarUrl = pack.avatar_url;
- this.usage = pack.usage ?? [PackUsage.Emoticon, PackUsage.Sticker];
- this.attribution = pack.attribution;
- }
-
- applyImages(content: PackContent) {
- this.images = new Map();
- this.emoticons = [];
- this.stickers = [];
- if (!content.images) return;
-
- Object.entries(content.images).forEach(([shortcode, data]) => {
- const { url } = data;
- const body = data.body ?? shortcode;
- const usage = data.usage ?? this.usage;
- const { info } = data;
-
- if (!url) return;
- const image: ExtendedPackImage = {
- shortcode,
- url,
- body,
- usage,
- info,
- };
-
- this.images.set(shortcode, image);
- if (usage && usage.includes(PackUsage.Emoticon)) {
- this.emoticons.push(image);
- }
- if (usage && usage.includes(PackUsage.Sticker)) {
- this.stickers.push(image);
- }
- });
- }
-
- getImages() {
- return this.images;
- }
-
- getEmojis() {
- return this.emoticons;
- }
-
- getStickers() {
- return this.stickers;
- }
-
- getImagesFor(usage: PackUsage) {
- if (usage === PackUsage.Emoticon) return this.getEmojis();
- if (usage === PackUsage.Sticker) return this.getStickers();
- return this.getEmojis();
- }
-
- getContent() {
- return this.content;
- }
-
- getPackAvatarUrl(usage: PackUsage): string | undefined {
- return this.avatarUrl || this.getImagesFor(usage)[0].url;
- }
-
- private updatePackProperty<K extends keyof PackMeta>(property: K, value: PackMeta[K]) {
- if (this.content.pack === undefined) {
- this.content.pack = {};
- }
- this.content.pack[property] = value;
- this.applyPackMeta(this.content);
- }
-
- setAvatarUrl(avatarUrl?: string) {
- this.updatePackProperty('avatar_url', avatarUrl);
- }
-
- setDisplayName(displayName?: string) {
- this.updatePackProperty('display_name', displayName);
- }
-
- setAttribution(attribution?: string) {
- this.updatePackProperty('attribution', attribution);
- }
-
- setUsage(usage?: PackUsage[]) {
- this.updatePackProperty('usage', usage);
- }
-
- addImage(key: string, imgContent: PackImage) {
- this.content.images = {
- [key]: imgContent,
- ...this.content.images,
- };
- this.applyImages(this.content);
- }
-
- removeImage(key: string) {
- if (!this.content.images) return;
- if (this.content.images[key] === undefined) return;
- delete this.content.images[key];
- this.applyImages(this.content);
- }
-
- updateImageKey(key: string, newKey: string) {
- const { images } = this.content;
- if (!images) return;
- if (images[key] === undefined) return;
- const copyImages: PackImages = {};
- Object.keys(images).forEach((imgKey) => {
- copyImages[imgKey === key ? newKey : imgKey] = images[imgKey];
- });
- this.content.images = copyImages;
- this.applyImages(this.content);
- }
-
- private updateImageProperty<K extends keyof PackImage>(
- key: string,
- property: K,
- value: PackImage[K]
- ) {
- if (!this.content.images) return;
- if (this.content.images[key] === undefined) return;
- this.content.images[key][property] = value;
- this.applyImages(this.content);
- }
-
- setImageUrl(key: string, url: string) {
- this.updateImageProperty(key, 'url', url);
- }
-
- setImageBody(key: string, body?: string) {
- this.updateImageProperty(key, 'body', body);
- }
-
- setImageInfo(key: string, info?: IImageInfo) {
- this.updateImageProperty(key, 'info', info);
- }
-
- setImageUsage(key: string, usage?: PackUsage[]) {
- this.updateImageProperty(key, 'usage', usage);
- }
-}
-
-export function packEventsToImagePacks(packEvents: MatrixEvent[]): ImagePack[] {
- return packEvents.reduce<ImagePack[]>((imagePacks, packEvent) => {
- const packId = packEvent?.getId();
- const content = packEvent?.getContent() as PackContent | undefined;
- if (!packId || !content) return imagePacks;
- const pack = ImagePack.parsePack(packId, content);
- if (pack) {
- imagePacks.push(pack);
- }
- return imagePacks;
- }, []);
-}
-
-export function getRoomImagePacks(room: Room): ImagePack[] {
- const dataEvents = getStateEvents(room, StateEvent.PoniesRoomEmotes);
- return packEventsToImagePacks(dataEvents);
-}
-
-export function getGlobalImagePacks(mx: MatrixClient): ImagePack[] {
- const emoteRoomsContent = getAccountData(mx, AccountDataEvent.PoniesEmoteRooms)?.getContent() as
- | EmoteRoomsContent
- | undefined;
- if (typeof emoteRoomsContent !== 'object') return [];
-
- const { rooms } = emoteRoomsContent;
- if (typeof rooms !== 'object') return [];
-
- const roomIds = Object.keys(rooms);
-
- const packs = roomIds.flatMap((roomId) => {
- if (typeof rooms[roomId] !== 'object') return [];
- const room = mx.getRoom(roomId);
- if (!room) return [];
- const packEventIdToUnknown = rooms[roomId];
- const roomPacks = getStateEvents(room, StateEvent.PoniesRoomEmotes);
- const globalPacks = roomPacks.filter((mE) => {
- const packKey = mE.getStateKey();
- if (typeof packKey === 'string') return !!packEventIdToUnknown[packKey];
- return false;
- });
- return packEventsToImagePacks(globalPacks);
- });
-
- return packs;
-}
-
-export function getUserImagePack(mx: MatrixClient): ImagePack | undefined {
- const userPackContent = getAccountData(mx, AccountDataEvent.PoniesUserEmotes)?.getContent() as
- | PackContent
- | undefined;
- const userId = mx.getUserId();
- if (!userPackContent || !userId) {
- return undefined;
- }
-
- const userImagePack = ImagePack.parsePack(userId, userPackContent);
- return userImagePack;
-}
-
-/**
- * @param {MatrixClient} mx Provide if you want to include user personal/global pack
- * @param {Room[]} rooms Provide rooms if you want to include rooms pack
- * @returns {ImagePack[]} packs
- */
-export function getRelevantPacks(mx?: MatrixClient, rooms?: Room[]): ImagePack[] {
- const userPack = mx && getUserImagePack(mx);
- const userPacks = userPack ? [userPack] : [];
- const globalPacks = mx ? getGlobalImagePacks(mx) : [];
- const globalPackIds = new Set(globalPacks.map((pack) => pack.id));
- const roomsPack = rooms?.flatMap(getRoomImagePacks) ?? [];
-
- return userPacks.concat(
- globalPacks,
- roomsPack.filter((pack) => !globalPackIds.has(pack.id))
- );
-}
--- /dev/null
+import { MatrixEvent } from 'matrix-js-sdk';
+import { PackAddress } from './PackAddress';
+import { PackImageReader } from './PackImageReader';
+import { PackImagesReader } from './PackImagesReader';
+import { PackMetaReader } from './PackMetaReader';
+import { ImageUsage, PackContent } from './types';
+
+export class ImagePack {
+ public readonly id: string;
+
+ public readonly deleted: boolean;
+
+ public readonly address: PackAddress | undefined;
+
+ public readonly meta: PackMetaReader;
+
+ public readonly images: PackImagesReader;
+
+ private emoticonMemo: PackImageReader[] | undefined;
+
+ private stickerMemo: PackImageReader[] | undefined;
+
+ constructor(id: string, content: PackContent, address: PackAddress | undefined) {
+ this.id = id;
+
+ this.address = address;
+
+ this.deleted = content.pack === undefined && content.images === undefined;
+
+ this.meta = new PackMetaReader(content.pack ?? {});
+ this.images = new PackImagesReader(content.images ?? {});
+ }
+
+ static fromMatrixEvent(id: string, matrixEvent: MatrixEvent) {
+ const roomId = matrixEvent.getRoomId();
+ const stateKey = matrixEvent.getStateKey();
+
+ const address =
+ roomId && typeof stateKey === 'string' ? new PackAddress(roomId, stateKey) : undefined;
+
+ const content = matrixEvent.getContent<PackContent>();
+
+ const imagePack: ImagePack = new ImagePack(id, content, address);
+
+ return imagePack;
+ }
+
+ public getImages(usage: ImageUsage): PackImageReader[] {
+ if (usage === ImageUsage.Emoticon && this.emoticonMemo) {
+ return this.emoticonMemo;
+ }
+ if (usage === ImageUsage.Sticker && this.stickerMemo) {
+ return this.stickerMemo;
+ }
+
+ const images = Array.from(this.images.collection.values()).filter((image) => {
+ const usg = image.usage ?? this.meta.usage;
+ return usg.includes(usage);
+ });
+
+ if (usage === ImageUsage.Emoticon) {
+ this.emoticonMemo = images;
+ }
+ if (usage === ImageUsage.Sticker) {
+ this.stickerMemo = images;
+ }
+
+ return images;
+ }
+
+ public getAvatarUrl(usage: ImageUsage): string | undefined {
+ if (this.meta.avatar) return this.meta.avatar;
+ const images = this.getImages(usage);
+ const firstImage = images[0];
+ if (firstImage) return firstImage.url;
+ return undefined;
+ }
+}
--- /dev/null
+export class PackAddress {
+ public readonly roomId: string;
+
+ public readonly stateKey: string;
+
+ constructor(roomId: string, stateKey: string) {
+ this.roomId = roomId;
+ this.stateKey = stateKey;
+ }
+}
--- /dev/null
+import { IImageInfo } from '../../../types/matrix/common';
+import { ImageUsage, PackImage } from './types';
+
+export class PackImageReader {
+ public readonly shortcode: string;
+
+ public readonly url: string;
+
+ private readonly image: Omit<PackImage, 'url'>;
+
+ constructor(shortcode: string, url: string, image: Omit<PackImage, 'url'>) {
+ this.shortcode = shortcode;
+ this.url = url;
+
+ this.image = image;
+ }
+
+ static fromPackImage(shortcode: string, image: PackImage): PackImageReader | undefined {
+ const { url } = image;
+
+ if (typeof url !== 'string') return undefined;
+
+ return new PackImageReader(shortcode, url, image);
+ }
+
+ get body(): string | undefined {
+ const { body } = this.image;
+ return typeof body === 'string' ? body : undefined;
+ }
+
+ get info(): IImageInfo | undefined {
+ return this.image.info;
+ }
+
+ get usage(): ImageUsage[] | undefined {
+ const usg = this.image.usage;
+ if (!Array.isArray(usg)) return undefined;
+
+ const knownUsage = usg.filter((u) => u === ImageUsage.Emoticon || u === ImageUsage.Sticker);
+
+ return knownUsage.length > 0 ? knownUsage : undefined;
+ }
+
+ get content(): PackImage {
+ return {
+ url: this.url,
+ body: this.image.body,
+ usage: this.image.usage,
+ info: this.image.info,
+ };
+ }
+}
--- /dev/null
+import { PackImageReader } from './PackImageReader';
+import { PackImages } from './types';
+
+export class PackImagesReader {
+ private readonly rawImages: PackImages;
+
+ private shortcodeToImages: Map<string, PackImageReader> | undefined;
+
+ constructor(images: PackImages) {
+ this.rawImages = images;
+ }
+
+ get collection(): Map<string, PackImageReader> {
+ if (this.shortcodeToImages) return this.shortcodeToImages;
+
+ const shortcodeToImages: Map<string, PackImageReader> = new Map();
+
+ Object.entries(this.rawImages).forEach(([shortcode, image]) => {
+ const imageReader = PackImageReader.fromPackImage(shortcode, image);
+ if (imageReader) {
+ shortcodeToImages.set(shortcode, imageReader);
+ }
+ });
+
+ this.shortcodeToImages = shortcodeToImages;
+ return this.shortcodeToImages;
+ }
+}
--- /dev/null
+import { PackMeta, ImageUsage } from './types';
+
+export class PackMetaReader {
+ private readonly meta: PackMeta;
+
+ public readonly fallbackUsage: ImageUsage[] = [ImageUsage.Emoticon, ImageUsage.Sticker];
+
+ constructor(meta: PackMeta) {
+ this.meta = meta;
+ }
+
+ get name(): string | undefined {
+ const displayName = this.meta.display_name;
+ if (typeof displayName === 'string') return displayName;
+ return undefined;
+ }
+
+ get avatar(): string | undefined {
+ const avatarURL = this.meta.avatar_url;
+ if (typeof avatarURL === 'string') return avatarURL;
+ return undefined;
+ }
+
+ get attribution(): string | undefined {
+ const { attribution } = this.meta;
+ if (typeof this.meta.attribution === 'string') return attribution;
+ return undefined;
+ }
+
+ get usage(): ImageUsage[] {
+ if (!Array.isArray(this.meta.usage)) return this.fallbackUsage;
+
+ const knownUsage = this.meta.usage.filter(
+ (u) => u === ImageUsage.Emoticon || u === ImageUsage.Sticker
+ );
+
+ if (knownUsage.length === 0) return this.fallbackUsage;
+
+ return knownUsage;
+ }
+
+ get content(): PackMeta {
+ return this.meta;
+ }
+}
--- /dev/null
+export * from './PackAddress';
+export * from './PackMetaReader';
+export * from './PackImageReader';
+export * from './PackImagesReader';
+export * from './ImagePack';
+export * from './types';
+export * from './utils';
--- /dev/null
+import { IImageInfo } from '../../../types/matrix/common';
+
+// https://github.com/Sorunome/matrix-doc/blob/soru/emotes/proposals/2545-emotes.md
+
+/**
+ * im.ponies.emote_rooms content
+ */
+export type PackStateKeyToObject = Record<string, object>;
+export type RoomIdToStateKey = Record<string, PackStateKeyToObject>;
+export type EmoteRoomsContent = {
+ rooms?: RoomIdToStateKey;
+};
+
+/**
+ * Pack
+ */
+export enum ImageUsage {
+ Emoticon = 'emoticon',
+ Sticker = 'sticker',
+}
+
+export type PackImage = {
+ url: string;
+ body?: string;
+ usage?: ImageUsage[];
+ info?: IImageInfo;
+};
+
+export type PackImages = Record<string, PackImage>;
+
+export type PackMeta = {
+ display_name?: string;
+ avatar_url?: string;
+ attribution?: string;
+ usage?: ImageUsage[];
+};
+
+export type PackContent = {
+ pack?: PackMeta;
+ images?: PackImages;
+};
--- /dev/null
+import { MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk';
+import { ImagePack } from './ImagePack';
+import { EmoteRoomsContent, ImageUsage } from './types';
+import { StateEvent } from '../../../types/matrix/room';
+import { getAccountData, getStateEvent, getStateEvents } from '../../utils/room';
+import { AccountDataEvent } from '../../../types/matrix/accountData';
+import { PackMetaReader } from './PackMetaReader';
+import { PackAddress } from './PackAddress';
+
+export function packAddressEqual(a1?: PackAddress, a2?: PackAddress): boolean {
+ if (!a1 && !a2) return true;
+ if (!a1 || !a2) return false;
+ return a1.roomId === a2.roomId && a1.stateKey === a2.stateKey;
+}
+
+export function imageUsageEqual(u1: ImageUsage[], u2: ImageUsage[]) {
+ return u1.length === u2.length && u1.every((u) => u2.includes(u));
+}
+
+export function packMetaEqual(a: PackMetaReader, b: PackMetaReader): boolean {
+ return (
+ a.name === b.name &&
+ a.avatar === b.avatar &&
+ a.attribution === b.attribution &&
+ imageUsageEqual(a.usage, b.usage)
+ );
+}
+
+export function makeImagePacks(packEvents: MatrixEvent[]): ImagePack[] {
+ return packEvents.reduce<ImagePack[]>((imagePacks, packEvent) => {
+ const packId = packEvent.getId();
+ if (!packId) return imagePacks;
+ imagePacks.push(ImagePack.fromMatrixEvent(packId, packEvent));
+ return imagePacks;
+ }, []);
+}
+
+export function getRoomImagePack(room: Room, stateKey: string): ImagePack | undefined {
+ const packEvent = getStateEvent(room, StateEvent.PoniesRoomEmotes, stateKey);
+ if (!packEvent) return undefined;
+ const packId = packEvent.getId();
+ if (!packId) return undefined;
+ return ImagePack.fromMatrixEvent(packId, packEvent);
+}
+
+export function getRoomImagePacks(room: Room): ImagePack[] {
+ const packEvents = getStateEvents(room, StateEvent.PoniesRoomEmotes);
+ return makeImagePacks(packEvents);
+}
+
+export function getGlobalImagePacks(mx: MatrixClient): ImagePack[] {
+ const emoteRoomsContent = getAccountData(mx, AccountDataEvent.PoniesEmoteRooms)?.getContent() as
+ | EmoteRoomsContent
+ | undefined;
+ if (typeof emoteRoomsContent !== 'object') return [];
+
+ const { rooms: roomIdToPackInfo } = emoteRoomsContent;
+ if (typeof roomIdToPackInfo !== 'object') return [];
+
+ const roomIds = Object.keys(roomIdToPackInfo);
+
+ const packs = roomIds.flatMap((roomId) => {
+ if (typeof roomIdToPackInfo[roomId] !== 'object') return [];
+ const room = mx.getRoom(roomId);
+ if (!room) return [];
+ const packStateKeyToUnknown = roomIdToPackInfo[roomId];
+ const packEvents = getStateEvents(room, StateEvent.PoniesRoomEmotes);
+ const globalPackEvents = packEvents.filter((mE) => {
+ const stateKey = mE.getStateKey();
+ if (typeof stateKey === 'string') return !!packStateKeyToUnknown[stateKey];
+ return false;
+ });
+ return makeImagePacks(globalPackEvents);
+ });
+
+ return packs;
+}
+
+export function getUserImagePack(mx: MatrixClient): ImagePack | undefined {
+ const packEvent = getAccountData(mx, AccountDataEvent.PoniesUserEmotes);
+ const userId = mx.getUserId();
+ if (!packEvent || !userId) {
+ return undefined;
+ }
+
+ const userImagePack = ImagePack.fromMatrixEvent(userId, packEvent);
+ return userImagePack;
+}
import 'prismjs/components/prism-python';
import './ReactPrism.css';
-// we apply theme in client/state/settings.js
// using classNames .prism-dark .prism-light from ReactPrism.css
export default function ReactPrism({
--- /dev/null
+export type CursorDirection = 'forward' | 'backward' | 'none';
+
+export class Cursor {
+ public readonly start: number;
+
+ public readonly end: number;
+
+ public readonly direction: CursorDirection;
+
+ constructor(start: number, end: number, direction: CursorDirection) {
+ this.start = start;
+ this.end = end;
+ this.direction = direction;
+ }
+
+ static fromTextAreaElement(element: HTMLTextAreaElement) {
+ return new Cursor(element.selectionStart, element.selectionEnd, element.selectionDirection);
+ }
+
+ public get selection() {
+ return this.start !== this.end;
+ }
+
+ public get length() {
+ return this.end - this.start;
+ }
+}
--- /dev/null
+import { Cursor } from './Cursor';
+
+export interface Operations {
+ select(cursor: Cursor): void;
+ deselect(cursor: Cursor): void;
+ insert(cursor: Cursor, text: string): Cursor;
+}
--- /dev/null
+import { Cursor } from './Cursor';
+import { GetTarget } from './type';
+
+export class TextArea {
+ private readonly getTarget: GetTarget;
+
+ constructor(getTarget: GetTarget) {
+ this.getTarget = getTarget;
+ }
+
+ get target() {
+ return this.getTarget();
+ }
+
+ public selection(cursor: Cursor): string {
+ return this.target.value.substring(cursor.start, cursor.end);
+ }
+
+ public lineBeginIndex(cursor: Cursor): number {
+ const beforeValue = this.target.value.substring(0, cursor.start);
+ const lineEndIndex = beforeValue.lastIndexOf('\n');
+ return lineEndIndex + 1;
+ }
+
+ public lineEndIndex(cursor: Cursor): number {
+ const afterValue = this.target.value.substring(cursor.end);
+ const lineEndIndex = afterValue.indexOf('\n');
+ return cursor.end + (lineEndIndex === -1 ? afterValue.length : lineEndIndex);
+ }
+
+ public cursorLines(cursor: Cursor): Cursor {
+ const lineBeginIndex = this.lineBeginIndex(cursor);
+ const lineEndIndex = this.lineEndIndex(cursor);
+
+ const linesCursor = new Cursor(lineBeginIndex, lineEndIndex, 'none');
+ return linesCursor;
+ }
+
+ public prevLine(cursor: Cursor): Cursor | undefined {
+ const currentLineIndex = this.lineBeginIndex(cursor);
+ const prevIndex = currentLineIndex - 1;
+
+ if (prevIndex < 0) return undefined;
+
+ const lineCursor = this.cursorLines(new Cursor(prevIndex, prevIndex, 'none'));
+ return lineCursor;
+ }
+
+ public nextLine(cursor: Cursor): Cursor | undefined {
+ const currentLineIndex = this.lineEndIndex(cursor);
+ const nextIndex = currentLineIndex + 1;
+
+ if (nextIndex > this.target.value.length) return undefined;
+
+ const lineCursor = this.cursorLines(new Cursor(nextIndex, nextIndex, 'none'));
+ return lineCursor;
+ }
+}
--- /dev/null
+import { Cursor } from './Cursor';
+import { Operations } from './Operations';
+import { GetTarget } from './type';
+
+export class TextAreaOperations implements Operations {
+ private readonly getTarget: GetTarget;
+
+ constructor(getTarget: GetTarget) {
+ this.getTarget = getTarget;
+ }
+
+ get target() {
+ return this.getTarget();
+ }
+
+ public select(cursor: Cursor) {
+ this.target.setSelectionRange(cursor.start, cursor.end, cursor.direction);
+ }
+
+ public deselect(cursor: Cursor) {
+ if (cursor.direction === 'backward') {
+ this.target.setSelectionRange(cursor.start, cursor.start, 'none');
+ return;
+ }
+ this.target.setSelectionRange(cursor.end, cursor.end, 'none');
+ }
+
+ public insert(cursor: Cursor, text: string): Cursor {
+ const { value } = this.target;
+ this.target.value = `${value.substring(0, cursor.start)}${text}${value.substring(cursor.end)}`;
+
+ return new Cursor(cursor.start, cursor.start + text.length, cursor.direction);
+ }
+}
--- /dev/null
+export class TextUtils {
+ static multiline(str: string) {
+ return str.indexOf('\n') !== -1;
+ }
+}
--- /dev/null
+export * from './Cursor';
+export * from './mods';
+export * from './Operations';
+export * from './TextArea';
+export * from './TextAreaOperations';
+export * from './TextUtils';
--- /dev/null
+import { Cursor } from '../Cursor';
+import { Operations } from '../Operations';
+import { TextArea } from '../TextArea';
+
+export class Intent {
+ public readonly textArea: TextArea;
+
+ public readonly operations: Operations;
+
+ public readonly size: number;
+
+ public readonly str: string;
+
+ private intentReg: RegExp;
+
+ constructor(size: number, textArea: TextArea, operations: Operations) {
+ this.textArea = textArea;
+ this.operations = operations;
+ this.size = size;
+ this.intentReg = /^\s*/;
+
+ this.str = '';
+ for (let i = 0; i < size; i += 1) this.str += ' ';
+ }
+
+ private lineIntent(cursor: Cursor): string {
+ const lines = this.textArea.cursorLines(cursor);
+ const selection = this.textArea.selection(lines);
+ const match = selection.match(this.intentReg);
+ if (!match) return '';
+ return match[0];
+ }
+
+ public moveForward(cursor: Cursor): Cursor {
+ const linesCursor = this.textArea.cursorLines(cursor);
+
+ const selection = this.textArea.selection(linesCursor);
+ const lines = selection.split('\n');
+
+ const intentLines = lines.map((line) => `${this.str}${line}`);
+ this.operations.insert(linesCursor, intentLines.join('\n'));
+
+ const addedIntentLength = lines.length * this.str.length;
+ return new Cursor(
+ cursor.start === linesCursor.start ? cursor.start : cursor.start + this.str.length,
+ cursor.end + addedIntentLength,
+ cursor.direction
+ );
+ }
+
+ public moveBackward(cursor: Cursor): Cursor {
+ const linesCursor = this.textArea.cursorLines(cursor);
+
+ const selection = this.textArea.selection(linesCursor);
+ const lines = selection.split('\n');
+
+ const intentLines = lines.map((line) => {
+ if (line.startsWith(this.str)) return line.substring(this.str.length);
+ return line.replace(this.intentReg, '');
+ });
+ const intentCursor = this.operations.insert(linesCursor, intentLines.join('\n'));
+
+ const firstLineTrimLength = lines[0].length - intentLines[0].length;
+ const lastLine = this.textArea.cursorLines(
+ new Cursor(intentCursor.end, intentCursor.end, 'none')
+ );
+
+ const start = Math.max(cursor.start - firstLineTrimLength, linesCursor.start);
+ const trimmedContentLength = linesCursor.length - intentCursor.length;
+ const end = Math.max(lastLine.start, cursor.end - trimmedContentLength);
+ return new Cursor(start, end, cursor.direction);
+ }
+
+ public addNewLine(cursor: Cursor): Cursor {
+ const lineIntent = this.lineIntent(cursor);
+ const line = `\n${lineIntent}`;
+
+ const insertCursor = this.operations.insert(cursor, line);
+ return new Cursor(insertCursor.end, insertCursor.end, 'none');
+ }
+
+ public addNextLine(cursor: Cursor): Cursor {
+ const lineIntent = this.lineIntent(cursor);
+ const line = `\n${lineIntent}`;
+
+ const currentLine = this.textArea.cursorLines(cursor);
+ const lineCursor = new Cursor(currentLine.end, currentLine.end, 'none');
+ const insertCursor = this.operations.insert(lineCursor, line);
+ return new Cursor(insertCursor.end, insertCursor.end, 'none');
+ }
+
+ public addPreviousLine(cursor: Cursor): Cursor {
+ const lineIntent = this.lineIntent(cursor);
+ const line = `\n${lineIntent}`;
+
+ const prevLine = this.textArea.prevLine(cursor);
+ const insertIndex = prevLine?.end ?? 0;
+ const lineCursor = new Cursor(insertIndex, insertIndex, 'none');
+ const insertCursor = this.operations.insert(lineCursor, line);
+ return new Cursor(insertCursor.end, insertCursor.end, 'none');
+ }
+}
--- /dev/null
+export * from './Intent';
--- /dev/null
+export type GetTarget = () => HTMLTextAreaElement;
--- /dev/null
+import { atom } from 'jotai';
+import { ImportRoomKeyProgressData } from 'matrix-js-sdk/lib/crypto-api';
+
+export enum BackupProgressStatus {
+ Idle,
+ Fetching,
+ Loading,
+ Done,
+}
+export type ProgressData = {
+ downloaded: number;
+ successes: number;
+ failures: number;
+ total: number;
+};
+export type IBackupProgress =
+ | {
+ status: BackupProgressStatus.Idle;
+ }
+ | {
+ status: BackupProgressStatus.Fetching;
+ }
+ | {
+ status: BackupProgressStatus.Loading;
+ data: ProgressData;
+ }
+ | {
+ status: BackupProgressStatus.Done;
+ };
+
+const baseBackupRestoreProgressAtom = atom<IBackupProgress>({
+ status: BackupProgressStatus.Idle,
+});
+
+export const backupRestoreProgressAtom = atom<
+ IBackupProgress,
+ [ImportRoomKeyProgressData],
+ undefined
+>(
+ (get) => get(baseBackupRestoreProgressAtom),
+ (get, set, progress) => {
+ if (progress.stage === 'fetch') {
+ set(baseBackupRestoreProgressAtom, {
+ status: BackupProgressStatus.Fetching,
+ });
+ return;
+ }
+
+ if (progress.stage === 'load_keys') {
+ const { total, successes, failures } = progress;
+ if (total === undefined || successes === undefined || failures === undefined) {
+ // Setting to idle as https://github.com/matrix-org/matrix-js-sdk/issues/4703
+ set(baseBackupRestoreProgressAtom, {
+ status: BackupProgressStatus.Idle,
+ });
+ return;
+ }
+ const downloaded = successes + failures;
+ if (downloaded === total) {
+ set(baseBackupRestoreProgressAtom, {
+ status: BackupProgressStatus.Done,
+ });
+ return;
+ }
+ set(baseBackupRestoreProgressAtom, {
+ status: BackupProgressStatus.Loading,
+ data: {
+ downloaded,
+ successes,
+ failures,
+ total,
+ },
+ });
+ }
+ }
+);
const STORAGE_KEY = 'settings';
export type MessageSpacing = '0' | '100' | '200' | '300' | '400' | '500';
-export type MessageLayout = 0 | 1 | 2;
+export enum MessageLayout {
+ Modern = 0,
+ Compact = 1,
+ Bubble = 2,
+}
export interface Settings {
- themeIndex: number;
+ themeId?: string;
useSystemTheme: boolean;
+ lightThemeId?: string;
+ darkThemeId?: string;
isMarkdown: boolean;
editorToolbar: boolean;
twitterEmoji: boolean;
showNotifications: boolean;
isNotificationSounds: boolean;
+
+ developerTools: boolean;
}
const defaultSettings: Settings = {
- themeIndex: 0,
+ themeId: undefined,
useSystemTheme: true,
+ lightThemeId: undefined,
+ darkThemeId: undefined,
isMarkdown: true,
editorToolbar: false,
twitterEmoji: false,
showNotifications: true,
isNotificationSounds: true,
+
+ developerTools: false,
};
export const getSettings = () => {
export const useBindUploadAtom = (
mx: MatrixClient,
- file: TUploadContent,
uploadAtom: TUploadAtom,
hideFilename?: boolean
) => {
const [upload, setUpload] = useAtom(uploadAtom);
+ const { file } = upload;
const handleProgress = useThrottle(
useCallback((progress: UploadProgress) => setUpload({ progress }), [setUpload]),
--- /dev/null
+import { style } from '@vanilla-extract/css';
+
+export const ModalWide = style({
+ minWidth: '85vw',
+ minHeight: '90vh',
+});
--- /dev/null
+import { style } from '@vanilla-extract/css';
+
+export const BreakWord = style({
+ wordBreak: 'break-word',
+});
+
+export const LineClamp2 = style({
+ display: '-webkit-box',
+ WebkitLineClamp: 2,
+ WebkitBoxOrient: 'vertical',
+ overflow: 'hidden',
+});
+
+export const LineClamp3 = style({
+ display: '-webkit-box',
+ WebkitLineClamp: 3,
+ WebkitBoxOrient: 'vertical',
+ overflow: 'hidden',
+});
}
return str;
};
+
+export const suffixRename = (name: string, validator: (newName: string) => boolean): string => {
+ let suffix = 1;
+ let newName = name;
+ do {
+ newName = name + suffix;
+ suffix += 1;
+ } while (validator(newName));
+
+ return newName;
+};
+
+export const replaceSpaceWithDash = (str: string): string => str.replace(/ /g, '-');
export const editableActiveElement = (): boolean =>
!!document.activeElement &&
(document.activeElement.nodeName.toLowerCase() === 'input' ||
- document.activeElement.nodeName.toLowerCase() === 'textbox' ||
+ document.activeElement.nodeName.toLowerCase() === 'textarea' ||
document.activeElement.getAttribute('contenteditable') === 'true' ||
document.activeElement.getAttribute('role') === 'input' ||
- document.activeElement.getAttribute('role') === 'textbox');
+ document.activeElement.getAttribute('role') === 'textarea');
export const isIntersectingScrollView = (
scrollElement: HTMLElement,
return files;
};
+export const renameFile = (file: File, name: string): File =>
+ new File([file], name, { type: file.type });
+
export const getImageUrlBlob = async (url: string) => {
const res = await fetch(url);
const blob = await res.blob();
return encodedURIComponent;
}
};
+
+export const syntaxErrorPosition = (error: SyntaxError): number | undefined => {
+ const match = error.message.match(/position\s(\d+)\s/);
+ if (!match) return undefined;
+
+ const posStr = match[1];
+ const position = parseInt(posStr, 10);
+ if (Number.isNaN(position)) return undefined;
+ return position;
+};
};
export const stopPropagation = (evt: KeyboardEvent): boolean => {
+ const ae = document.activeElement;
+ const editableActiveElement = ae
+ ? ae.nodeName.toLowerCase() === 'input' ||
+ ae.nodeName.toLowerCase() === 'textarea' ||
+ ae.getAttribute('contenteditable') === 'true'
+ : false;
+
+ if (editableActiveElement) return false;
+
evt.stopPropagation();
return true;
};
--- /dev/null
+import { CryptoApi } from 'matrix-js-sdk/lib/crypto-api';
+
+export const verifiedDevice = async (
+ api: CryptoApi,
+ userId: string,
+ deviceId: string
+): Promise<boolean | null> => {
+ const status = await api.getDeviceVerificationStatus(userId, deviceId);
+
+ if (!status) return null;
+
+ const verified = status.crossSigningVerified;
+ return verified;
+};
encryptAttachment,
} from 'browser-encrypt-attachment';
import {
+ EventTimeline,
MatrixClient,
MatrixError,
MatrixEvent,
export const getDMRoomFor = (mx: MatrixClient, userId: string): Room | undefined => {
const dmLikeRooms = mx
.getRooms()
- .filter((room) => mx.isRoomEncrypted(room.roomId) && room.getMembers().length <= 2);
+ .filter((room) => room.hasEncryptionStateEvent() && room.getMembers().length <= 2);
return dmLikeRooms.find((room) => room.getMember(userId));
};
if (member) return member.userId;
// if there are no joined members other than us, use the oldest member
- const member1 = getOldestMember(room.currentState.getMembers());
+ const member1 = getOldestMember(
+ room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.getMembers() ?? []
+ );
return member1?.userId ?? myUserId;
};
const extStart = fileName.lastIndexOf('.') + 1;
return fileName.slice(extStart);
};
+export const getFileNameWithoutExt = (fileName: string): string => {
+ const extStart = fileName.lastIndexOf('.');
+ if (extStart === 0 || extStart === -1) return fileName;
+ return fileName.slice(0, extStart);
+};
room: Room,
eventType: StateEvent,
stateKey = ''
-): MatrixEvent | undefined => room.currentState.getStateEvents(eventType, stateKey) ?? undefined;
+): MatrixEvent | undefined =>
+ room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.getStateEvents(eventType, stateKey) ??
+ undefined;
export const getStateEvents = (room: Room, eventType: StateEvent): MatrixEvent[] =>
- room.currentState.getStateEvents(eventType);
+ room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.getStateEvents(eventType) ?? [];
export const getAccountData = (
mx: MatrixClient,
});
}
-export function openSettings(tabText) {
- appDispatcher.dispatch({
- type: cons.actions.navigation.OPEN_SETTINGS,
- tabText,
- });
-}
-
export function openSearch(term) {
appDispatcher.dispatch({
type: cons.actions.navigation.OPEN_SEARCH,
});
}
-export function openEmojiVerification(request, targetDevice) {
- appDispatcher.dispatch({
- type: cons.actions.navigation.OPEN_EMOJI_VERIFICATION,
- request,
- targetDevice,
- });
-}
+import { EventTimeline } from 'matrix-js-sdk';
import { getIdServer } from '../../util/matrixUtil';
/**
if (oldestMember) return oldestMember.userId;
// if there are no joined members other than us, use the oldest member
- room.currentState.getMembers().forEach((member) => {
+ room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.getMembers().forEach((member) => {
if (member.userId === myUserId) return;
if (typeof oldestMemberTs === 'undefined' || (member.events.member && member.events.member.getTs() < oldestMemberTs)) {
async function setMyRoomNick(mx, roomId, nick) {
const room = mx.getRoom(roomId);
- const mEvent = room.currentState.getStateEvents('m.room.member', mx.getUserId());
+ const mEvent = room.getLiveTimeline().getState(EventTimeline.FORWARDS).getStateEvents('m.room.member', mx.getUserId());
const content = mEvent?.getContent();
if (!content) return;
await mx.sendStateEvent(roomId, 'm.room.member', {
async function setMyRoomAvatar(mx, roomId, mxc) {
const room = mx.getRoom(roomId);
- const mEvent = room.currentState.getStateEvents('m.room.member', mx.getUserId());
+ const mEvent = room.getLiveTimeline().getState(EventTimeline.FORWARDS).getStateEvents('m.room.member', mx.getUserId());
const content = mEvent?.getContent();
if (!content) return;
await mx.sendStateEvent(roomId, 'm.room.member', {
+++ /dev/null
-import appDispatcher from '../dispatcher';
-import cons from '../state/cons';
-
-export function toggleSystemTheme() {
- appDispatcher.dispatch({
- type: cons.actions.settings.TOGGLE_SYSTEM_THEME,
- });
-}
-
-export function toggleMarkdown() {
- appDispatcher.dispatch({
- type: cons.actions.settings.TOGGLE_MARKDOWN,
- });
-}
-
-export function togglePeopleDrawer() {
- appDispatcher.dispatch({
- type: cons.actions.settings.TOGGLE_PEOPLE_DRAWER,
- });
-}
-
-export function toggleMembershipEvents() {
- appDispatcher.dispatch({
- type: cons.actions.settings.TOGGLE_MEMBERSHIP_EVENT,
- });
-}
-
-export function toggleNickAvatarEvents() {
- appDispatcher.dispatch({
- type: cons.actions.settings.TOGGLE_NICKAVATAR_EVENT,
- });
-}
import { createClient, MatrixClient, IndexedDBStore, IndexedDBCryptoStore } from 'matrix-js-sdk';
-import Olm from '@matrix-org/olm';
import { logger } from 'matrix-js-sdk/lib/logger';
import { cryptoCallbacks } from './state/secretStorageKeys';
-global.Olm = Olm;
-
if (import.meta.env.PROD) {
logger.disableAll();
}
dbName: 'web-sync-store',
});
+ const legacyCryptoStore = new IndexedDBCryptoStore(global.indexedDB, 'crypto-store');
+
const mx = createClient({
baseUrl: session.baseUrl,
accessToken: session.accessToken,
userId: session.userId,
store: indexedDBStore,
- cryptoStore: new IndexedDBCryptoStore(global.indexedDB, 'crypto-store'),
+ cryptoStore: legacyCryptoStore,
deviceId: session.deviceId,
timelineSupport: true,
cryptoCallbacks: cryptoCallbacks as any,
verificationMethods: ['m.sas.v1'],
});
- await mx.initCrypto();
await indexedDBStore.startup();
+ await mx.initRustCrypto();
mx.setGlobalErrorOnUnknownDevices(false);
mx.setMaxListeners(50);
window.localStorage.clear();
window.location.reload();
};
+
+export const clearLoginData = async () => {
+ const dbs = await window.indexedDB.databases();
+
+ dbs.forEach((idbInfo) => {
+ const { name } = idbInfo;
+ if (name) {
+ window.indexedDB.deleteDatabase(name);
+ }
+ });
+
+ window.localStorage.clear();
+ window.location.reload();
+};
OPEN_JOIN_ALIAS: 'OPEN_JOIN_ALIAS',
OPEN_INVITE_USER: 'OPEN_INVITE_USER',
OPEN_PROFILE_VIEWER: 'OPEN_PROFILE_VIEWER',
- OPEN_SETTINGS: 'OPEN_SETTINGS',
OPEN_SEARCH: 'OPEN_SEARCH',
OPEN_REUSABLE_CONTEXT_MENU: 'OPEN_REUSABLE_CONTEXT_MENU',
OPEN_REUSABLE_DIALOG: 'OPEN_REUSABLE_DIALOG',
- OPEN_EMOJI_VERIFICATION: 'OPEN_EMOJI_VERIFICATION',
- },
- settings: {
- TOGGLE_SYSTEM_THEME: 'TOGGLE_SYSTEM_THEME',
- TOGGLE_MARKDOWN: 'TOGGLE_MARKDOWN',
- TOGGLE_PEOPLE_DRAWER: 'TOGGLE_PEOPLE_DRAWER',
- TOGGLE_MEMBERSHIP_EVENT: 'TOGGLE_MEMBERSHIP_EVENT',
- TOGGLE_NICKAVATAR_EVENT: 'TOGGLE_NICKAVATAR_EVENT',
},
},
events: {
CREATE_ROOM_OPENED: 'CREATE_ROOM_OPENED',
JOIN_ALIAS_OPENED: 'JOIN_ALIAS_OPENED',
INVITE_USER_OPENED: 'INVITE_USER_OPENED',
- SETTINGS_OPENED: 'SETTINGS_OPENED',
SEARCH_OPENED: 'SEARCH_OPENED',
REUSABLE_CONTEXT_MENU_OPENED: 'REUSABLE_CONTEXT_MENU_OPENED',
REUSABLE_DIALOG_OPENED: 'REUSABLE_DIALOG_OPENED',
- EMOJI_VERIFICATION_OPENED: 'EMOJI_VERIFICATION_OPENED',
- },
- notifications: {
- NOTI_CHANGED: 'NOTI_CHANGED',
- FULL_READ: 'FULL_READ',
- MUTE_TOGGLED: 'MUTE_TOGGLED',
- },
- settings: {
- SYSTEM_THEME_TOGGLED: 'SYSTEM_THEME_TOGGLED',
- MARKDOWN_TOGGLED: 'MARKDOWN_TOGGLED',
- PEOPLE_DRAWER_TOGGLED: 'PEOPLE_DRAWER_TOGGLED',
- MEMBERSHIP_EVENTS_TOGGLED: 'MEMBERSHIP_EVENTS_TOGGLED',
- NICKAVATAR_EVENTS_TOGGLED: 'NICKAVATAR_EVENTS_TOGGLED',
},
},
};
[cons.actions.navigation.OPEN_PROFILE_VIEWER]: () => {
this.emit(cons.events.navigation.PROFILE_VIEWER_OPENED, action.userId, action.roomId);
},
- [cons.actions.navigation.OPEN_SETTINGS]: () => {
- this.emit(cons.events.navigation.SETTINGS_OPENED, action.tabText);
- },
[cons.actions.navigation.OPEN_SEARCH]: () => {
this.emit(
cons.events.navigation.SEARCH_OPENED,
action.afterClose,
);
},
- [cons.actions.navigation.OPEN_EMOJI_VERIFICATION]: () => {
- this.emit(
- cons.events.navigation.EMOJI_VERIFICATION_OPENED,
- action.request,
- action.targetDevice,
- );
- },
};
actions[action.type]?.();
}
+++ /dev/null
-import { lightTheme } from 'folds';
-import EventEmitter from 'events';
-import appDispatcher from '../dispatcher';
-
-import cons from './cons';
-import { darkTheme, butterTheme, silverTheme } from '../../colors.css';
-import { onLightFontWeight, onDarkFontWeight } from '../../config.css';
-
-function getSettings() {
- const settings = localStorage.getItem('settings');
- if (settings === null) return null;
- return JSON.parse(settings);
-}
-
-function setSettings(key, value) {
- let settings = getSettings();
- if (settings === null) settings = {};
- settings[key] = value;
- localStorage.setItem('settings', JSON.stringify(settings));
-}
-
-class Settings extends EventEmitter {
- constructor() {
- super();
-
- this.themeClasses = [lightTheme, silverTheme, darkTheme, butterTheme];
- this.fontWeightClasses = [onLightFontWeight, onLightFontWeight, onDarkFontWeight, onDarkFontWeight]
- this.themes = ['', 'silver-theme', 'dark-theme', 'butter-theme'];
- this.themeIndex = this.getThemeIndex();
-
- this.useSystemTheme = this.getUseSystemTheme();
- this.isMarkdown = this.getIsMarkdown();
- this.isPeopleDrawer = this.getIsPeopleDrawer();
- this.hideMembershipEvents = this.getHideMembershipEvents();
- this.hideNickAvatarEvents = this.getHideNickAvatarEvents();
-
- this.darkModeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
-
- this.darkModeQueryList.addEventListener('change', () => this.applyTheme())
-
- this.isTouchScreenDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0);
- }
-
- getThemeIndex() {
- if (typeof this.themeIndex === 'number') return this.themeIndex;
-
- const settings = getSettings();
- if (settings === null) return 0;
- if (typeof settings.themeIndex === 'undefined') return 0;
- // eslint-disable-next-line radix
- return parseInt(settings.themeIndex);
- }
-
- getThemeName() {
- return this.themes[this.themeIndex];
- }
-
- _clearTheme() {
- this.themes.forEach((themeName, index) => {
- if (themeName !== '') document.body.classList.remove(themeName);
- document.body.classList.remove(this.themeClasses[index]);
- document.body.classList.remove(this.fontWeightClasses[index]);
- document.body.classList.remove('prism-light')
- document.body.classList.remove('prism-dark')
- });
- }
-
- applyTheme() {
- this._clearTheme();
- const autoThemeIndex = this.darkModeQueryList.matches ? 2 : 0;
- const themeIndex = this.useSystemTheme ? autoThemeIndex : this.themeIndex;
- if (this.themes[themeIndex] === undefined) return
- if (this.themes[themeIndex]) document.body.classList.add(this.themes[themeIndex]);
- document.body.classList.add(this.themeClasses[themeIndex]);
- document.body.classList.add(this.fontWeightClasses[themeIndex]);
- document.body.classList.add(themeIndex < 2 ? 'prism-light' : 'prism-dark');
- }
-
- setTheme(themeIndex) {
- this.themeIndex = themeIndex;
- setSettings('themeIndex', this.themeIndex);
- this.applyTheme();
- }
-
- toggleUseSystemTheme() {
- this.useSystemTheme = !this.useSystemTheme;
- setSettings('useSystemTheme', this.useSystemTheme);
- this.applyTheme();
-
- this.emit(cons.events.settings.SYSTEM_THEME_TOGGLED, this.useSystemTheme);
- }
-
- getUseSystemTheme() {
- if (typeof this.useSystemTheme === 'boolean') return this.useSystemTheme;
-
- const settings = getSettings();
- if (settings === null) return true;
- if (typeof settings.useSystemTheme === 'undefined') return true;
- return settings.useSystemTheme;
- }
-
- getIsMarkdown() {
- if (typeof this.isMarkdown === 'boolean') return this.isMarkdown;
-
- const settings = getSettings();
- if (settings === null) return true;
- if (typeof settings.isMarkdown === 'undefined') return true;
- return settings.isMarkdown;
- }
-
- getHideMembershipEvents() {
- if (typeof this.hideMembershipEvents === 'boolean') return this.hideMembershipEvents;
-
- const settings = getSettings();
- if (settings === null) return false;
- if (typeof settings.hideMembershipEvents === 'undefined') return false;
- return settings.hideMembershipEvents;
- }
-
- getHideNickAvatarEvents() {
- if (typeof this.hideNickAvatarEvents === 'boolean') return this.hideNickAvatarEvents;
-
- const settings = getSettings();
- if (settings === null) return true;
- if (typeof settings.hideNickAvatarEvents === 'undefined') return true;
- return settings.hideNickAvatarEvents;
- }
-
- getIsPeopleDrawer() {
- if (typeof this.isPeopleDrawer === 'boolean') return this.isPeopleDrawer;
-
- const settings = getSettings();
- if (settings === null) return true;
- if (typeof settings.isPeopleDrawer === 'undefined') return true;
- return settings.isPeopleDrawer;
- }
-
- setter(action) {
- const actions = {
- [cons.actions.settings.TOGGLE_SYSTEM_THEME]: () => {
- this.toggleUseSystemTheme();
- },
- [cons.actions.settings.TOGGLE_MARKDOWN]: () => {
- this.isMarkdown = !this.isMarkdown;
- setSettings('isMarkdown', this.isMarkdown);
- this.emit(cons.events.settings.MARKDOWN_TOGGLED, this.isMarkdown);
- },
- [cons.actions.settings.TOGGLE_PEOPLE_DRAWER]: () => {
- this.isPeopleDrawer = !this.isPeopleDrawer;
- setSettings('isPeopleDrawer', this.isPeopleDrawer);
- this.emit(cons.events.settings.PEOPLE_DRAWER_TOGGLED, this.isPeopleDrawer);
- },
- [cons.actions.settings.TOGGLE_MEMBERSHIP_EVENT]: () => {
- this.hideMembershipEvents = !this.hideMembershipEvents;
- setSettings('hideMembershipEvents', this.hideMembershipEvents);
- this.emit(cons.events.settings.MEMBERSHIP_EVENTS_TOGGLED, this.hideMembershipEvents);
- },
- [cons.actions.settings.TOGGLE_NICKAVATAR_EVENT]: () => {
- this.hideNickAvatarEvents = !this.hideNickAvatarEvents;
- setSettings('hideNickAvatarEvents', this.hideNickAvatarEvents);
- this.emit(cons.events.settings.NICKAVATAR_EVENTS_TOGGLED, this.hideNickAvatarEvents);
- },
- };
-
- actions[action.type]?.();
- }
-}
-
-const settings = new Settings();
-appDispatcher.register(settings.setter.bind(settings));
-
-export default settings;
Other: {
FocusRing: 'rgba(255, 255, 255, 0.5)',
Shadow: 'rgba(0, 0, 0, 1)',
- Overlay: 'rgba(0, 0, 0, 0.6)',
+ Overlay: 'rgba(0, 0, 0, 0.8)',
},
};
import './index.scss';
-import settings from './client/state/settings';
-
import { trimTrailingSlash } from './app/utils/common';
import App from './app/pages/App';
import './app/i18n';
document.body.classList.add(configClass, varsClass);
-settings.applyTheme();
// Register Service Worker
if ('serviceWorker' in navigator) {
PoniesUserEmotes = 'im.ponies.user_emotes',
PoniesEmoteRooms = 'im.ponies.emote_rooms',
+
+ SecretStorageDefaultKey = 'm.secret_storage.default_key',
+
+ CrossSigningMaster = 'm.cross_signing.master',
+ CrossSigningSelf = 'm.cross_signing.self',
+ CrossSigningUser = 'm.cross_signing.user',
+ MegolmBackupV1 = 'm.megolm_backup.v1',
}
+
+export type SecretStorageDefaultKeyContent = {
+ key: string;
+};
+
+export type SecretStoragePassphraseContent = {
+ algorithm: string;
+ salt: string;
+ iterations: number;
+ bits?: number;
+};
+
+export type SecretStorageKeyContent = {
+ name?: string;
+ algorithm: string;
+ iv?: string;
+ mac?: string;
+ passphrase?: SecretStoragePassphraseContent;
+};
+
+export type SecretContent = {
+ iv: string;
+ ciphertext: string;
+ mac: string;
+};
+
+export type SecretAccountData = {
+ encrypted: Record<string, SecretContent>;
+};
return idParts[1];
}
-export function isCrossVerified(mx, deviceId) {
- try {
- const crossSignInfo = mx.getStoredCrossSigningForUser(mx.getUserId());
- const deviceInfo = mx.getStoredDevice(mx.getUserId(), deviceId);
- const deviceTrust = crossSignInfo.checkDeviceTrust(crossSignInfo, deviceInfo, false, true);
- return deviceTrust.isCrossSigningVerified();
- } catch (e) {
- // device does not support encryption
- return null;
- }
-}
-
-export function hasCrossSigningAccountData(mx) {
- const masterKeyData = mx.getAccountData('m.cross_signing.master');
- return !!masterKeyData;
-}
-
-export function getDefaultSSKey(mx) {
- try {
- return mx.getAccountData('m.secret_storage.default_key').getContent().key;
- } catch {
- return undefined;
- }
-}
-
-export function getSSKeyInfo(mx, key) {
- try {
- return mx.getAccountData(`m.secret_storage.key.${key}`).getContent();
- } catch {
- return undefined;
- }
-}
-
export async function hasDevices(mx, userId) {
try {
- const usersDeviceMap = await mx.downloadKeys([userId, mx.getUserId()]);
+ const usersDeviceMap = await mx.getUserDeviceInfo([userId, mx.getUserId()]);
return Object.values(usersDeviceMap)
- .every((userDevices) => (Object.keys(userDevices).length > 0));
+ .every((deviceIdToDevices) => deviceIdToDevices.size > 0);
} catch (e) {
console.error("Error determining if it's possible to encrypt to all users: ", e);
return false;