Major housekeeping.
This commit is contained in:
parent
f4d422cb69
commit
14f9eab077
36 changed files with 847 additions and 1448 deletions
package-lock.json
src/mami.js
animate.jsargs.jsarray.js
audio
awaitable.jscolpick
conman.jscontrols
easings.jseeprom
emotes
flashii.jshash.jsmain.jsmobile.jsnotices
proto/sockchat
sidebar
sockchat
sound
srle.jstimedp.jstitle.jsui
uniqstr.jsurib64.jsurl.jsxhr.js
519
package-lock.json
generated
519
package-lock.json
generated
|
@ -80,9 +80,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.11.21.tgz",
|
||||
"integrity": "sha512-/Y3BJLcwd40pExmdar8MH2UGGvCBrqNN7hauOMckrEX2Ivcbv3IMhrbGX4od1dnF880Ed8y/E9aStZCIQi0EGw==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.11.24.tgz",
|
||||
"integrity": "sha512-MaQEIpfcEMzx3VWWopbofKJvaraqmL6HbLlw2bFZ7qYqYw3rkhM0cQVEgyzbHtTWwCwPMFZSC2DUbhlZgrMfLg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
|
@ -97,16 +97,16 @@
|
|||
"url": "https://opencollective.com/swc"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@swc/core-darwin-arm64": "1.11.21",
|
||||
"@swc/core-darwin-x64": "1.11.21",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.11.21",
|
||||
"@swc/core-linux-arm64-gnu": "1.11.21",
|
||||
"@swc/core-linux-arm64-musl": "1.11.21",
|
||||
"@swc/core-linux-x64-gnu": "1.11.21",
|
||||
"@swc/core-linux-x64-musl": "1.11.21",
|
||||
"@swc/core-win32-arm64-msvc": "1.11.21",
|
||||
"@swc/core-win32-ia32-msvc": "1.11.21",
|
||||
"@swc/core-win32-x64-msvc": "1.11.21"
|
||||
"@swc/core-darwin-arm64": "1.11.24",
|
||||
"@swc/core-darwin-x64": "1.11.24",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.11.24",
|
||||
"@swc/core-linux-arm64-gnu": "1.11.24",
|
||||
"@swc/core-linux-arm64-musl": "1.11.24",
|
||||
"@swc/core-linux-x64-gnu": "1.11.24",
|
||||
"@swc/core-linux-x64-musl": "1.11.24",
|
||||
"@swc/core-win32-arm64-msvc": "1.11.24",
|
||||
"@swc/core-win32-ia32-msvc": "1.11.24",
|
||||
"@swc/core-win32-x64-msvc": "1.11.24"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/helpers": ">=0.5.17"
|
||||
|
@ -118,9 +118,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-arm64": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.21.tgz",
|
||||
"integrity": "sha512-v6gjw9YFWvKulCw3ZA1dY+LGMafYzJksm1mD4UZFZ9b36CyHFowYVYug1ajYRIRqEvvfIhHUNV660zTLoVFR8g==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.24.tgz",
|
||||
"integrity": "sha512-dhtVj0PC1APOF4fl5qT2neGjRLgHAAYfiVP8poJelhzhB/318bO+QCFWAiimcDoyMgpCXOhTp757gnoJJrheWA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -134,9 +134,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-x64": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.21.tgz",
|
||||
"integrity": "sha512-CUiTiqKlzskwswrx9Ve5NhNoab30L1/ScOfQwr1duvNlFvarC8fvQSgdtpw2Zh3MfnfNPpyLZnYg7ah4kbT9JQ==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.24.tgz",
|
||||
"integrity": "sha512-H/3cPs8uxcj2Fe3SoLlofN5JG6Ny5bl8DuZ6Yc2wr7gQFBmyBkbZEz+sPVgsID7IXuz7vTP95kMm1VL74SO5AQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -150,9 +150,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.21.tgz",
|
||||
"integrity": "sha512-YyBTAFM/QPqt1PscD8hDmCLnqPGKmUZpqeE25HXY8OLjl2MUs8+O4KjwPZZ+OGxpdTbwuWFyMoxjcLy80JODvg==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.24.tgz",
|
||||
"integrity": "sha512-PHJgWEpCsLo/NGj+A2lXZ2mgGjsr96ULNW3+T3Bj2KTc8XtMUkE8tmY2Da20ItZOvPNC/69KroU7edyo1Flfbw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
@ -166,9 +166,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-gnu": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.21.tgz",
|
||||
"integrity": "sha512-DQD+ooJmwpNsh4acrftdkuwl5LNxxg8U4+C/RJNDd7m5FP9Wo4c0URi5U0a9Vk/6sQNh9aSGcYChDpqCDWEcBw==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.24.tgz",
|
||||
"integrity": "sha512-C2FJb08+n5SD4CYWCTZx1uR88BN41ZieoHvI8A55hfVf2woT8+6ZiBzt74qW2g+ntZ535Jts5VwXAKdu41HpBg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -182,9 +182,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-musl": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.21.tgz",
|
||||
"integrity": "sha512-y1L49+snt1a1gLTYPY641slqy55QotPdtRK9Y6jMi4JBQyZwxC8swWYlQWb+MyILwxA614fi62SCNZNznB3XSA==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.24.tgz",
|
||||
"integrity": "sha512-ypXLIdszRo0re7PNNaXN0+2lD454G8l9LPK/rbfRXnhLWDBPURxzKlLlU/YGd2zP98wPcVooMmegRSNOKfvErw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -198,9 +198,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-gnu": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.21.tgz",
|
||||
"integrity": "sha512-NesdBXv4CvVEaFUlqKj+GA4jJMNUzK2NtKOrUNEtTbXaVyNiXjFCSaDajMTedEB0jTAd9ybB0aBvwhgkJUWkWA==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.24.tgz",
|
||||
"integrity": "sha512-IM7d+STVZD48zxcgo69L0yYptfhaaE9cMZ+9OoMxirNafhKKXwoZuufol1+alEFKc+Wbwp+aUPe/DeWC/Lh3dg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -214,9 +214,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-musl": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.21.tgz",
|
||||
"integrity": "sha512-qFV60pwpKVOdmX67wqQzgtSrUGWX9Cibnp1CXyqZ9Mmt8UyYGvmGu7p6PMbTyX7vdpVUvWVRf8DzrW2//wmVHg==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.24.tgz",
|
||||
"integrity": "sha512-DZByJaMVzSfjQKKQn3cqSeqwy6lpMaQDQQ4HPlch9FWtDx/dLcpdIhxssqZXcR2rhaQVIaRQsCqwV6orSDGAGw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -230,9 +230,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-arm64-msvc": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.21.tgz",
|
||||
"integrity": "sha512-DJJe9k6gXR/15ZZVLv1SKhXkFst8lYCeZRNHH99SlBodvu4slhh/MKQ6YCixINRhCwliHrpXPym8/5fOq8b7Ig==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.24.tgz",
|
||||
"integrity": "sha512-Q64Ytn23y9aVDKN5iryFi8mRgyHw3/kyjTjT4qFCa8AEb5sGUuSj//AUZ6c0J7hQKMHlg9do5Etvoe61V98/JQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -246,9 +246,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-ia32-msvc": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.21.tgz",
|
||||
"integrity": "sha512-TqEXuy6wedId7bMwLIr9byds+mKsaXVHctTN88R1UIBPwJA92Pdk0uxDgip0pEFzHB/ugU27g6d8cwUH3h2eIw==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.24.tgz",
|
||||
"integrity": "sha512-9pKLIisE/Hh2vJhGIPvSoTK4uBSPxNVyXHmOrtdDot4E1FUUI74Vi8tFdlwNbaj8/vusVnb8xPXsxF1uB0VgiQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
@ -262,9 +262,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-x64-msvc": {
|
||||
"version": "1.11.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.21.tgz",
|
||||
"integrity": "sha512-BT9BNNbMxdpUM1PPAkYtviaV0A8QcXttjs2MDtOeSqqvSJaPtyM+Fof2/+xSwQDmDEFzbGCcn75M5+xy3lGqpA==",
|
||||
"version": "1.11.24",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.24.tgz",
|
||||
"integrity": "sha512-sybnXtOsdB+XvzVFlBVGgRHLqp3yRpHK7CrmpuDKszhj/QhmsaZzY/GHSeALlMtLup13M0gqbcQvsTNlAHTg3w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -357,9 +357,9 @@
|
|||
"license": "ISC"
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.24.4",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
|
||||
"integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
|
||||
"version": "4.24.5",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz",
|
||||
"integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
@ -376,10 +376,10 @@
|
|||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001688",
|
||||
"electron-to-chromium": "^1.5.73",
|
||||
"caniuse-lite": "^1.0.30001716",
|
||||
"electron-to-chromium": "^1.5.149",
|
||||
"node-releases": "^2.0.19",
|
||||
"update-browserslist-db": "^1.1.1"
|
||||
"update-browserslist-db": "^1.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"browserslist": "cli.js"
|
||||
|
@ -417,9 +417,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001715",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz",
|
||||
"integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==",
|
||||
"version": "1.0.30001718",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz",
|
||||
"integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
@ -529,13 +529,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/cssnano": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.6.tgz",
|
||||
"integrity": "sha512-54woqx8SCbp8HwvNZYn68ZFAepuouZW4lTwiMVnBErM3VkO7/Sd4oTOt3Zz3bPx3kxQ36aISppyXj2Md4lg8bw==",
|
||||
"version": "7.0.7",
|
||||
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.7.tgz",
|
||||
"integrity": "sha512-evKu7yiDIF7oS+EIpwFlMF730ijRyLFaM2o5cTxRGJR9OKHKkc+qP443ZEVR9kZG0syaAJJCPJyfv5pbrxlSng==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssnano-preset-default": "^7.0.6",
|
||||
"lilconfig": "^3.1.2"
|
||||
"cssnano-preset-default": "^7.0.7",
|
||||
"lilconfig": "^3.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
|
@ -545,63 +545,63 @@
|
|||
"url": "https://opencollective.com/cssnano"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/cssnano-preset-default": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.6.tgz",
|
||||
"integrity": "sha512-ZzrgYupYxEvdGGuqL+JKOY70s7+saoNlHSCK/OGn1vB2pQK8KSET8jvenzItcY+kA7NoWvfbb/YhlzuzNKjOhQ==",
|
||||
"version": "7.0.7",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.7.tgz",
|
||||
"integrity": "sha512-jW6CG/7PNB6MufOrlovs1TvBTEVmhY45yz+bd0h6nw3h6d+1e+/TX+0fflZ+LzvZombbT5f+KC063w9VoHeHow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"browserslist": "^4.24.5",
|
||||
"css-declaration-sorter": "^7.2.0",
|
||||
"cssnano-utils": "^5.0.0",
|
||||
"postcss-calc": "^10.0.2",
|
||||
"postcss-colormin": "^7.0.2",
|
||||
"postcss-convert-values": "^7.0.4",
|
||||
"postcss-discard-comments": "^7.0.3",
|
||||
"postcss-discard-duplicates": "^7.0.1",
|
||||
"postcss-discard-empty": "^7.0.0",
|
||||
"postcss-discard-overridden": "^7.0.0",
|
||||
"postcss-merge-longhand": "^7.0.4",
|
||||
"postcss-merge-rules": "^7.0.4",
|
||||
"postcss-minify-font-values": "^7.0.0",
|
||||
"postcss-minify-gradients": "^7.0.0",
|
||||
"postcss-minify-params": "^7.0.2",
|
||||
"postcss-minify-selectors": "^7.0.4",
|
||||
"postcss-normalize-charset": "^7.0.0",
|
||||
"postcss-normalize-display-values": "^7.0.0",
|
||||
"postcss-normalize-positions": "^7.0.0",
|
||||
"postcss-normalize-repeat-style": "^7.0.0",
|
||||
"postcss-normalize-string": "^7.0.0",
|
||||
"postcss-normalize-timing-functions": "^7.0.0",
|
||||
"postcss-normalize-unicode": "^7.0.2",
|
||||
"postcss-normalize-url": "^7.0.0",
|
||||
"postcss-normalize-whitespace": "^7.0.0",
|
||||
"postcss-ordered-values": "^7.0.1",
|
||||
"postcss-reduce-initial": "^7.0.2",
|
||||
"postcss-reduce-transforms": "^7.0.0",
|
||||
"postcss-svgo": "^7.0.1",
|
||||
"postcss-unique-selectors": "^7.0.3"
|
||||
"cssnano-utils": "^5.0.1",
|
||||
"postcss-calc": "^10.1.1",
|
||||
"postcss-colormin": "^7.0.3",
|
||||
"postcss-convert-values": "^7.0.5",
|
||||
"postcss-discard-comments": "^7.0.4",
|
||||
"postcss-discard-duplicates": "^7.0.2",
|
||||
"postcss-discard-empty": "^7.0.1",
|
||||
"postcss-discard-overridden": "^7.0.1",
|
||||
"postcss-merge-longhand": "^7.0.5",
|
||||
"postcss-merge-rules": "^7.0.5",
|
||||
"postcss-minify-font-values": "^7.0.1",
|
||||
"postcss-minify-gradients": "^7.0.1",
|
||||
"postcss-minify-params": "^7.0.3",
|
||||
"postcss-minify-selectors": "^7.0.5",
|
||||
"postcss-normalize-charset": "^7.0.1",
|
||||
"postcss-normalize-display-values": "^7.0.1",
|
||||
"postcss-normalize-positions": "^7.0.1",
|
||||
"postcss-normalize-repeat-style": "^7.0.1",
|
||||
"postcss-normalize-string": "^7.0.1",
|
||||
"postcss-normalize-timing-functions": "^7.0.1",
|
||||
"postcss-normalize-unicode": "^7.0.3",
|
||||
"postcss-normalize-url": "^7.0.1",
|
||||
"postcss-normalize-whitespace": "^7.0.1",
|
||||
"postcss-ordered-values": "^7.0.2",
|
||||
"postcss-reduce-initial": "^7.0.3",
|
||||
"postcss-reduce-transforms": "^7.0.1",
|
||||
"postcss-svgo": "^7.0.2",
|
||||
"postcss-unique-selectors": "^7.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/cssnano-utils": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.0.tgz",
|
||||
"integrity": "sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.1.tgz",
|
||||
"integrity": "sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/csso": {
|
||||
|
@ -703,9 +703,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.139",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.139.tgz",
|
||||
"integrity": "sha512-GGnRYOTdN5LYpwbIr0rwP/ZHOQSvAF6TG0LSzp28uCBb9JiXHJGmaaKw29qjNJc5bGnnp6kXJqRnGMQoELwi5w==",
|
||||
"version": "1.5.155",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.155.tgz",
|
||||
"integrity": "sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/entities": {
|
||||
|
@ -928,12 +928,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/postcss-colormin": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.2.tgz",
|
||||
"integrity": "sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA==",
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.3.tgz",
|
||||
"integrity": "sha512-xZxQcSyIVZbSsl1vjoqZAcMYYdnJsIyG8OvqShuuqf12S88qQboxxEy0ohNCOLwVPXTU+hFHvJPACRL2B5ohTA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"browserslist": "^4.24.5",
|
||||
"caniuse-api": "^3.0.0",
|
||||
"colord": "^2.9.3",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -942,140 +942,114 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-convert-values": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.4.tgz",
|
||||
"integrity": "sha512-e2LSXPqEHVW6aoGbjV9RsSSNDO3A0rZLCBxN24zvxF25WknMPpX8Dm9UxxThyEbaytzggRuZxaGXqaOhxQ514Q==",
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.5.tgz",
|
||||
"integrity": "sha512-0VFhH8nElpIs3uXKnVtotDJJNX0OGYSZmdt4XfSfvOMrFw1jKfpwpZxfC4iN73CTM/MWakDEmsHQXkISYj4BXw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"browserslist": "^4.24.5",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-discard-comments": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.3.tgz",
|
||||
"integrity": "sha512-q6fjd4WU4afNhWOA2WltHgCbkRhZPgQe7cXF74fuVB/ge4QbM9HEaOIzGSiMvM+g/cOsNAUGdf2JDzqA2F8iLA==",
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.4.tgz",
|
||||
"integrity": "sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-selector-parser": "^6.1.2"
|
||||
"postcss-selector-parser": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-discard-comments/node_modules/postcss-selector-parser": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-discard-duplicates": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.1.tgz",
|
||||
"integrity": "sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ==",
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.2.tgz",
|
||||
"integrity": "sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-discard-empty": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.0.tgz",
|
||||
"integrity": "sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.1.tgz",
|
||||
"integrity": "sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-discard-overridden": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.0.tgz",
|
||||
"integrity": "sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.1.tgz",
|
||||
"integrity": "sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-merge-longhand": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.4.tgz",
|
||||
"integrity": "sha512-zer1KoZA54Q8RVHKOY5vMke0cCdNxMP3KBfDerjH/BYHh4nCIh+1Yy0t1pAEQF18ac/4z3OFclO+ZVH8azjR4A==",
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.5.tgz",
|
||||
"integrity": "sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0",
|
||||
"stylehacks": "^7.0.4"
|
||||
"stylehacks": "^7.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-merge-rules": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.4.tgz",
|
||||
"integrity": "sha512-ZsaamiMVu7uBYsIdGtKJ64PkcQt6Pcpep/uO90EpLS3dxJi6OXamIobTYcImyXGoW0Wpugh7DSD3XzxZS9JCPg==",
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.5.tgz",
|
||||
"integrity": "sha512-ZonhuSwEaWA3+xYbOdJoEReKIBs5eDiBVLAGpYZpNFPzXZcEE5VKR7/qBEQvTZpiwjqhhqEQ+ax5O3VShBj9Wg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"browserslist": "^4.24.5",
|
||||
"caniuse-api": "^3.0.0",
|
||||
"cssnano-utils": "^5.0.0",
|
||||
"postcss-selector-parser": "^6.1.2"
|
||||
"cssnano-utils": "^5.0.1",
|
||||
"postcss-selector-parser": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-minify-font-values": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.0.tgz",
|
||||
"integrity": "sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.1.tgz",
|
||||
"integrity": "sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1084,88 +1058,75 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-minify-gradients": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.0.tgz",
|
||||
"integrity": "sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.1.tgz",
|
||||
"integrity": "sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"colord": "^2.9.3",
|
||||
"cssnano-utils": "^5.0.0",
|
||||
"cssnano-utils": "^5.0.1",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-minify-params": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.2.tgz",
|
||||
"integrity": "sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ==",
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.3.tgz",
|
||||
"integrity": "sha512-vUKV2+f5mtjewYieanLX0xemxIp1t0W0H/D11u+kQV/MWdygOO7xPMkbK+r9P6Lhms8MgzKARF/g5OPXhb8tgg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"cssnano-utils": "^5.0.0",
|
||||
"browserslist": "^4.24.5",
|
||||
"cssnano-utils": "^5.0.1",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-minify-selectors": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.0.4.tgz",
|
||||
"integrity": "sha512-JG55VADcNb4xFCf75hXkzc1rNeURhlo7ugf6JjiiKRfMsKlDzN9CXHZDyiG6x/zGchpjQS+UAgb1d4nqXqOpmA==",
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.0.5.tgz",
|
||||
"integrity": "sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"postcss-selector-parser": "^6.1.2"
|
||||
"postcss-selector-parser": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-charset": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.0.tgz",
|
||||
"integrity": "sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.1.tgz",
|
||||
"integrity": "sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-display-values": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.0.tgz",
|
||||
"integrity": "sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.1.tgz",
|
||||
"integrity": "sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1174,13 +1135,13 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-positions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.0.tgz",
|
||||
"integrity": "sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.1.tgz",
|
||||
"integrity": "sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1189,13 +1150,13 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-repeat-style": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.0.tgz",
|
||||
"integrity": "sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.1.tgz",
|
||||
"integrity": "sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1204,13 +1165,13 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-string": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.0.tgz",
|
||||
"integrity": "sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.1.tgz",
|
||||
"integrity": "sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1219,13 +1180,13 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-timing-functions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.0.tgz",
|
||||
"integrity": "sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.1.tgz",
|
||||
"integrity": "sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1234,29 +1195,29 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-unicode": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.2.tgz",
|
||||
"integrity": "sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg==",
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.3.tgz",
|
||||
"integrity": "sha512-EcoA29LvG3F+EpOh03iqu+tJY3uYYKzArqKJHxDhUYLa2u58aqGq16K6/AOsXD9yqLN8O6y9mmePKN5cx6krOw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"browserslist": "^4.24.5",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-url": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.0.tgz",
|
||||
"integrity": "sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.1.tgz",
|
||||
"integrity": "sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1265,13 +1226,13 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-normalize-whitespace": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.0.tgz",
|
||||
"integrity": "sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.1.tgz",
|
||||
"integrity": "sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1280,45 +1241,45 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-ordered-values": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.1.tgz",
|
||||
"integrity": "sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw==",
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.2.tgz",
|
||||
"integrity": "sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssnano-utils": "^5.0.0",
|
||||
"cssnano-utils": "^5.0.1",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-reduce-initial": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.2.tgz",
|
||||
"integrity": "sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA==",
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.3.tgz",
|
||||
"integrity": "sha512-RFvkZaqiWtGMlVjlUHpaxGqEL27lgt+Q2Ixjf83CRAzqdo+TsDyGPtJUbPx2MuYIJ+sCQc2TrOvRnhcXQfgIVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"browserslist": "^4.24.5",
|
||||
"caniuse-api": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-reduce-transforms": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.0.tgz",
|
||||
"integrity": "sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.1.tgz",
|
||||
"integrity": "sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -1327,7 +1288,7 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-selector-parser": {
|
||||
|
@ -1344,9 +1305,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/postcss-svgo": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.0.1.tgz",
|
||||
"integrity": "sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==",
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.0.2.tgz",
|
||||
"integrity": "sha512-5Dzy66JlnRM6pkdOTF8+cGsB1fnERTE8Nc+Eed++fOWo1hdsBptCsbG8UuJkgtZt75bRtMJIrPeZmtfANixdFA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0",
|
||||
|
@ -1356,35 +1317,22 @@
|
|||
"node": "^18.12.0 || ^20.9.0 || >= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-unique-selectors": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.3.tgz",
|
||||
"integrity": "sha512-J+58u5Ic5T1QjP/LDV9g3Cx4CNOgB5vz+kM6+OxHHhFACdcDeKhBXjQmB7fnIZM12YSTvsL0Opwco83DmacW2g==",
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.4.tgz",
|
||||
"integrity": "sha512-pmlZjsmEAG7cHd7uK3ZiNSW6otSZ13RHuZ/4cDN/bVglS5EpF2r2oxY99SuOHa8m7AWoBCelTS3JPpzsIs8skQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-selector-parser": "^6.1.2"
|
||||
"postcss-selector-parser": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-unique-selectors/node_modules/postcss-selector-parser": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-value-parser": {
|
||||
|
@ -1431,32 +1379,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/stylehacks": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.4.tgz",
|
||||
"integrity": "sha512-i4zfNrGMt9SB4xRK9L83rlsFCgdGANfeDAYacO1pkqcE7cRHPdWHwnKZVz7WY17Veq/FvyYsRAU++Ga+qDFIww==",
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.5.tgz",
|
||||
"integrity": "sha512-5kNb7V37BNf0Q3w+1pxfa+oiNPS++/b4Jil9e/kPDgrk1zjEd6uR7SZeJiYaLYH6RRSC1XX2/37OTeU/4FvuIA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"postcss-selector-parser": "^6.1.2"
|
||||
"browserslist": "^4.24.5",
|
||||
"postcss-selector-parser": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || ^20.9.0 || >=22.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/stylehacks/node_modules/postcss-selector-parser": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/svgo": {
|
||||
|
@ -1494,13 +1429,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.39.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
|
||||
"integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
|
||||
"version": "5.39.2",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.39.2.tgz",
|
||||
"integrity": "sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
"acorn": "^8.8.2",
|
||||
"acorn": "^8.14.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map-support": "~0.5.20"
|
||||
},
|
||||
|
|
|
@ -1,138 +1,41 @@
|
|||
#include easings.js
|
||||
|
||||
// This probably need a bit of a rewrite at some point to allow starting for arbitrary time points
|
||||
const MamiAnimate = info => {
|
||||
if(typeof info !== 'object')
|
||||
throw 'info must be an object';
|
||||
|
||||
let onUpdate;
|
||||
if('update' in info && typeof info.update === 'function')
|
||||
onUpdate = info.update;
|
||||
if(onUpdate === undefined)
|
||||
throw 'update is a required parameter for info';
|
||||
|
||||
let duration;
|
||||
if('duration' in info)
|
||||
duration = parseFloat(info.duration);
|
||||
if(duration <= 0)
|
||||
throw 'duration is a required parameter for info and must be greater than 0';
|
||||
|
||||
let onStart;
|
||||
if('start' in info && typeof info.start === 'function')
|
||||
onStart = info.start;
|
||||
|
||||
let onEnd;
|
||||
if('end' in info && typeof info.end === 'function')
|
||||
onEnd = info.end;
|
||||
|
||||
let onCancel;
|
||||
if('cancel' in info && typeof info.cancel === 'function')
|
||||
onCancel = info.cancel;
|
||||
|
||||
let easing;
|
||||
if('easing' in info)
|
||||
easing = info.easing;
|
||||
|
||||
let delayed;
|
||||
if('delayed' in info)
|
||||
delayed = !!info.delayed;
|
||||
|
||||
let async;
|
||||
if('async' in info)
|
||||
async = !!info.async;
|
||||
|
||||
const easingType = typeof easing;
|
||||
if(easingType !== 'function') {
|
||||
if(easingType === 'string' && easing in MamiEasings)
|
||||
const MamiAnimate = ({ update, duration, easing='linear', signal=null }) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(typeof update !== 'function')
|
||||
throw new Error('update argument must be a function');
|
||||
if(typeof duration !== 'number' || duration < 0)
|
||||
throw new Error('duration argument must be a positive number');
|
||||
if(typeof easing === 'string' && easing in MamiEasings)
|
||||
easing = MamiEasings[easing];
|
||||
else
|
||||
easing = MamiEasings.linear;
|
||||
}
|
||||
else if(typeof easing !== 'function')
|
||||
throw new Error('easing argument was must be an acceptable easing name or an easing function');
|
||||
if(signal !== null && !(signal instanceof AbortSignal))
|
||||
throw new Error('signal must be null or an instance of AbortSignal');
|
||||
|
||||
if(typeof window.mami?.settings?.get === 'function')
|
||||
duration *= mami.settings.get('dbgAnimDurationMulti');
|
||||
let start = null;
|
||||
|
||||
let tStart, tLast,
|
||||
cancel = false,
|
||||
tRawCompletion = 0,
|
||||
tCompletion = 0,
|
||||
started = !delayed;
|
||||
|
||||
const update = tCurrent => {
|
||||
if(tStart === undefined) {
|
||||
tStart = tCurrent;
|
||||
if(onStart !== undefined)
|
||||
onStart();
|
||||
}
|
||||
|
||||
const tElapsed = tCurrent - tStart;
|
||||
|
||||
tRawCompletion = Math.min(1, Math.max(0, tElapsed / duration));
|
||||
tCompletion = easing(tRawCompletion);
|
||||
|
||||
onUpdate(tCompletion, tRawCompletion);
|
||||
|
||||
if(tElapsed < duration) {
|
||||
if(cancel) {
|
||||
if(onCancel !== undefined)
|
||||
onCancel(tCompletion, tRawCompletion);
|
||||
const frame = time => {
|
||||
if(signal?.aborted) {
|
||||
reject(signal.reason);
|
||||
return;
|
||||
}
|
||||
|
||||
tLast = tCurrent;
|
||||
requestAnimationFrame(update);
|
||||
} else if(onEnd !== undefined)
|
||||
onEnd();
|
||||
};
|
||||
start ??= time;
|
||||
|
||||
let promise;
|
||||
if(async)
|
||||
promise = new Promise((resolve, reject) => {
|
||||
if(onCancel === undefined) {
|
||||
onCancel = reject;
|
||||
} else {
|
||||
const realOnCancel = onCancel;
|
||||
onCancel = (...args) => {
|
||||
realOnCancel(...args);
|
||||
reject(...args);
|
||||
};
|
||||
const elapsed = time - start;
|
||||
const completion = Math.min(1, Math.max(0, elapsed / duration));
|
||||
|
||||
update(easing(completion), completion);
|
||||
|
||||
if(elapsed < duration) {
|
||||
requestAnimationFrame(frame);
|
||||
return;
|
||||
}
|
||||
|
||||
if(onEnd === undefined) {
|
||||
onEnd = resolve;
|
||||
} else {
|
||||
const realOnEnd = onEnd;
|
||||
onEnd = (...args) => {
|
||||
realOnEnd(...args);
|
||||
resolve(...args);
|
||||
};
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
|
||||
if(!delayed)
|
||||
requestAnimationFrame(update);
|
||||
});
|
||||
|
||||
if(!delayed) {
|
||||
if(promise !== undefined)
|
||||
return promise;
|
||||
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
return {
|
||||
get completion() { return tCompletion; },
|
||||
get rawCompletion() { return tRawCompletion; },
|
||||
start: () => {
|
||||
if(!started) {
|
||||
started = true;
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
if(promise !== undefined)
|
||||
return promise;
|
||||
},
|
||||
cancel: () => {
|
||||
cancel = true;
|
||||
},
|
||||
};
|
||||
requestAnimationFrame(frame);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
const MamiArgs = (argName, input, builder) => {
|
||||
if(input !== undefined && typeof input !== 'object')
|
||||
throw `${argName} must be an object or undefined`;
|
||||
if(typeof builder !== 'function')
|
||||
throw 'builder must be a function';
|
||||
|
||||
const args = new Map;
|
||||
|
||||
builder(name => {
|
||||
if(typeof name !== 'string')
|
||||
throw 'name must be a string';
|
||||
|
||||
const checkDefined = () => {
|
||||
if(args.has(name))
|
||||
throw `${name} has already been defined`;
|
||||
};
|
||||
checkDefined();
|
||||
|
||||
let created = false;
|
||||
const checkCreated = () => {
|
||||
if(created)
|
||||
throw 'argument has already been defined';
|
||||
};
|
||||
|
||||
const info = {
|
||||
name: name,
|
||||
type: undefined,
|
||||
filter: undefined,
|
||||
constraint: undefined,
|
||||
fallback: undefined,
|
||||
throw: undefined,
|
||||
required: undefined,
|
||||
min: undefined,
|
||||
max: undefined,
|
||||
};
|
||||
|
||||
const blueprint = {
|
||||
type: value => {
|
||||
if(typeof value !== 'string' && !Array.isArray(value))
|
||||
throw 'type must be a javascript type or array of valid string values';
|
||||
|
||||
checkCreated();
|
||||
|
||||
info.type = value;
|
||||
return blueprint;
|
||||
},
|
||||
default: value => {
|
||||
checkCreated();
|
||||
info.fallback = value;
|
||||
|
||||
if(info.type === undefined && info.constraint === undefined)
|
||||
info.type = typeof info.fallback;
|
||||
|
||||
return blueprint;
|
||||
},
|
||||
filter: value => {
|
||||
if(typeof value !== 'function')
|
||||
throw 'filter must be a function';
|
||||
|
||||
checkCreated();
|
||||
|
||||
info.filter = value;
|
||||
return blueprint;
|
||||
},
|
||||
constraint: value => {
|
||||
if(typeof value !== 'function')
|
||||
throw 'constraint must be a function';
|
||||
|
||||
checkCreated();
|
||||
|
||||
info.constraint = value;
|
||||
return blueprint;
|
||||
},
|
||||
throw: value => {
|
||||
checkCreated();
|
||||
info.throw = value === undefined || value === true;
|
||||
return blueprint;
|
||||
},
|
||||
required: value => {
|
||||
checkCreated();
|
||||
info.required = value === undefined || value === true;
|
||||
|
||||
if(info.required && info.throw === undefined)
|
||||
info.throw = true;
|
||||
|
||||
return blueprint;
|
||||
},
|
||||
min: value => {
|
||||
checkCreated();
|
||||
if(typeof value !== 'number')
|
||||
throw 'value must be a number';
|
||||
|
||||
info.min = value;
|
||||
return blueprint;
|
||||
},
|
||||
max: value => {
|
||||
checkCreated();
|
||||
if(typeof value !== 'number')
|
||||
throw 'value must be a number';
|
||||
|
||||
info.max = value;
|
||||
return blueprint;
|
||||
},
|
||||
done: () => {
|
||||
checkCreated();
|
||||
checkDefined();
|
||||
|
||||
args.set(name, info);
|
||||
},
|
||||
};
|
||||
|
||||
return blueprint;
|
||||
});
|
||||
|
||||
const inputIsNull = input === undefined || input === null;
|
||||
if(inputIsNull)
|
||||
input = {};
|
||||
|
||||
const output = {};
|
||||
|
||||
for(const [name, info] of args) {
|
||||
let value = info.fallback;
|
||||
|
||||
if(info.name in input) {
|
||||
const defaultOrThrow = ex => {
|
||||
if(info.throw)
|
||||
throw ex;
|
||||
value = info.fallback;
|
||||
};
|
||||
|
||||
value = input[info.name];
|
||||
|
||||
if(info.type !== undefined) {
|
||||
if(Array.isArray(info.type)) {
|
||||
if(!info.type.includes(value))
|
||||
defaultOrThrow(`${info.name} must match an enum value`);
|
||||
} else {
|
||||
const type = typeof value;
|
||||
let resolved = false;
|
||||
|
||||
if(type !== info.type) {
|
||||
if(type === 'string') {
|
||||
if(info.type === 'number') {
|
||||
value = parseFloat(value);
|
||||
resolved = true;
|
||||
|
||||
if(info.min !== undefined && value < info.min)
|
||||
value = info.min;
|
||||
else if(info.max !== undefined && value > info.max)
|
||||
value = info.max;
|
||||
} else if(info.type === 'boolean') {
|
||||
value = !!value;
|
||||
resolved = true;
|
||||
}
|
||||
} else if(info.type === 'string') {
|
||||
value = value.toString();
|
||||
resolved = true;
|
||||
}
|
||||
} else resolved = true;
|
||||
|
||||
if(!resolved)
|
||||
defaultOrThrow(`${info.name} must be of type ${info.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
if(info.constraint !== undefined && !info.constraint(value))
|
||||
defaultOrThrow(`${info.name} did not fit within constraints`);
|
||||
|
||||
// you could have a devious streak with this one cuz the checks aren't rerun
|
||||
// but surely you wouldn't fuck yourself over like that
|
||||
if(info.filter !== undefined)
|
||||
value = info.filter(value);
|
||||
} else if(info.required) {
|
||||
if(inputIsNull)
|
||||
throw `${argName} must be a non-null object`;
|
||||
|
||||
throw `${argName} is missing required key ${info.name}`;
|
||||
}
|
||||
|
||||
output[info.name] = value;
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
const $arrayRemoveAt = function(array, index) {
|
||||
array.splice(index, 1);
|
||||
};
|
||||
|
||||
const $arrayRemoveValue = function(array, item) {
|
||||
let index;
|
||||
while(array.length > 0 && (index = array.indexOf(item)) >= 0)
|
||||
$arrayRemoveAt(array, index);
|
||||
};
|
||||
|
||||
const $arrayRemoveAny = function(array, predicate) {
|
||||
let index;
|
||||
while(array.length > 0 && (index = array.findIndex(predicate)) >= 0)
|
||||
$arrayRemoveAt(array, index);
|
||||
};
|
||||
|
||||
const $arrayShuffle = function(array) {
|
||||
if(array.length < 2)
|
||||
return;
|
||||
|
||||
for(let i = array.length - 1; i > 0; --i) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
const tmp = array[i];
|
||||
array[i] = array[j];
|
||||
array[j] = tmp;
|
||||
}
|
||||
};
|
|
@ -1,10 +1,7 @@
|
|||
#include srle.js
|
||||
|
||||
const MamiDetectAutoPlaySource = '/+NIxA!!FhpbmcA#PA$wA@fgAV$#q$#/$#A#OUxBTUUzLjEwMAIeA!)UCCQC8CIA@gA@H49wpKWgA!%&/+MYxA$NIA$ExBTUUzLjEwMFV^%/+MYxDsA@NIA$FV&&/+MYxHYA@NIA$FV&&';
|
||||
|
||||
const MamiDetectAutoPlaySource = 'data:audio/mpeg;base64,/+NIxAAAAAAAAAAAAFhpbmcAAAAPAAAAAwAAAfgAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq////////////////////////////////////////////AAAAOUxBTUUzLjEwMAIeAAAAAAAAAAAUCCQC8CIAAAgAAAH49wpKWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+MYxAAAAANIAAAAAExBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxDsAAANIAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxHYAAANIAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV';
|
||||
const MamiDetectAutoPlay = async () => {
|
||||
try {
|
||||
await $element('audio', { src: 'data:audio/mpeg;base64,' + MamiSRLE.decode(MamiDetectAutoPlaySource) }).play();
|
||||
await $element('audio', { src: MamiDetectAutoPlaySource }).play();
|
||||
} catch(ex) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,2 @@
|
|||
const MamiSleep = durationMs => new Promise(resolve => { setTimeout(resolve, durationMs); });
|
||||
|
||||
const MamiWaitVisible = () => {
|
||||
return new Promise(resolve => {
|
||||
if(document.visibilityState === 'visible') {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
const handler = () => {
|
||||
if(document.visibilityState === 'visible') {
|
||||
window.removeEventListener('visibilitychange', handler);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('visibilitychange', handler);
|
||||
});
|
||||
};
|
||||
const MamiTimeout = (promise, time) => Promise.race([promise, new Promise((resolve, reject) => setTimeout(reject, time))]);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include args.js
|
||||
#include colour.js
|
||||
#include controls/tabs.js
|
||||
#include colpick/tgrid.jsx
|
||||
|
@ -7,22 +6,32 @@
|
|||
#include colpick/vhex.jsx
|
||||
#include colpick/vraw.jsx
|
||||
|
||||
const MamiColourPicker = function(options) {
|
||||
options = MamiArgs('options', options, define => {
|
||||
define('colour').default(0).filter(value => Math.min(0xFFFFFF, Math.max(0, value))).done();
|
||||
define('posX').default(-1).done();
|
||||
define('posY').default(-1).done();
|
||||
define('flashii').type('object').default(null).done();
|
||||
define('presets').default([]).constraint(value => Array.isArray(value)).done();
|
||||
define('showPresetsTab').default(true).done();
|
||||
define('showGridTab').default(true).done();
|
||||
define('showSlidersTab').default(true).done();
|
||||
define('showHexValue').default(true).done();
|
||||
define('showRawValue').default(true).done();
|
||||
define('showDialogButtons').default(true).done();
|
||||
});
|
||||
const MamiColourPicker = function({
|
||||
colour=0,
|
||||
posX=-1,
|
||||
posY=-1,
|
||||
flashii=null,
|
||||
presets=[],
|
||||
showPresetsTab=true,
|
||||
showGridTab=true,
|
||||
showSlidersTab=true,
|
||||
showHexValue=true,
|
||||
showRawValue=true,
|
||||
showDialogButtons=true,
|
||||
}={}) {
|
||||
if(typeof colour !== 'number')
|
||||
throw new Error('colour argument must be a number');
|
||||
if(typeof posX !== 'number')
|
||||
throw new Error('posX argument must be a number');
|
||||
if(typeof posY !== 'number')
|
||||
throw new Error('posY argument must be a number');
|
||||
if(typeof flashii !== 'object')
|
||||
throw new Error('flashii argument must be an object or null');
|
||||
if(!Array.isArray(presets))
|
||||
throw new Error('presets argument must be an array');
|
||||
|
||||
colour = Math.min(0xFFFFFF, Math.max(0, colour | 0));
|
||||
|
||||
let colour;
|
||||
const needsColour = [];
|
||||
|
||||
let promiseResolve;
|
||||
|
@ -115,11 +124,11 @@ const MamiColourPicker = function(options) {
|
|||
},
|
||||
});
|
||||
|
||||
if(options.showPresetsTab && (options.flashii !== null || options.presets.length > 0))
|
||||
tabs.add(new MamiColourPickerPresetsTab(options.flashii ?? options.presets));
|
||||
if(options.showGridTab)
|
||||
if(showPresetsTab && (flashii !== null || presets.length > 0))
|
||||
tabs.add(new MamiColourPickerPresetsTab(flashii ?? presets));
|
||||
if(showGridTab)
|
||||
tabs.add(new MamiColourPickerGridTab);
|
||||
if(options.showSlidersTab)
|
||||
if(showSlidersTab)
|
||||
tabs.add(new MamiColourPickerSlidersTab);
|
||||
|
||||
if(tabs.count < 1)
|
||||
|
@ -134,9 +143,9 @@ const MamiColourPicker = function(options) {
|
|||
</label>);
|
||||
};
|
||||
|
||||
if(options.showHexValue)
|
||||
if(showHexValue)
|
||||
addValue('hex', 'Hex', new MamiColourPickerValueHex);
|
||||
if(options.showRawValue)
|
||||
if(showRawValue)
|
||||
addValue('raw', 'Raw', new MamiColourPickerValueRaw);
|
||||
|
||||
const addButton = (id, name, action) => {
|
||||
|
@ -153,13 +162,13 @@ const MamiColourPicker = function(options) {
|
|||
buttons.appendChild(button);
|
||||
};
|
||||
|
||||
if(options.showDialogButtons) {
|
||||
if(showDialogButtons) {
|
||||
addButton('cancel', 'Cancel', runReject);
|
||||
addButton('apply', 'Apply');
|
||||
}
|
||||
|
||||
setPosition({ x: options.posX, y: options.posY });
|
||||
setColour(options.colour);
|
||||
setPosition({ x: posX, y: posY });
|
||||
setColour(colour);
|
||||
|
||||
return {
|
||||
get element() { return html; },
|
||||
|
|
|
@ -47,9 +47,6 @@ const MamiConnectionManager = function(client, settings, flashii, eventTarget) {
|
|||
resetTimeout();
|
||||
|
||||
(async () => {
|
||||
if(settings.get('onlyConnectWhenVisible2'))
|
||||
await MamiWaitVisible();
|
||||
|
||||
eventTarget.dispatch('attempt', {
|
||||
url: url,
|
||||
started: started,
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#include animate.js
|
||||
#include args.js
|
||||
|
||||
const MamiMessageBoxContainer = function() {
|
||||
const container = <div class="msgbox-container"/>;
|
||||
let raised = false;
|
||||
let currAnim;
|
||||
let animeAbort;
|
||||
|
||||
return {
|
||||
raise: async parent => {
|
||||
async raise(parent) {
|
||||
if(raised) return;
|
||||
raised = true;
|
||||
container.style.pointerEvents = null;
|
||||
|
@ -15,41 +14,46 @@ const MamiMessageBoxContainer = function() {
|
|||
if(!parent.contains(container))
|
||||
parent.appendChild(container);
|
||||
|
||||
currAnim?.cancel();
|
||||
animeAbort?.abort();
|
||||
animeAbort = new AbortController;
|
||||
const signal = animeAbort.signal;
|
||||
|
||||
container.style.opacity = '0';
|
||||
|
||||
currAnim = MamiAnimate({
|
||||
async: true,
|
||||
delayed: true,
|
||||
duration: 300,
|
||||
easing: 'outExpo',
|
||||
start: () => { container.style.opacity = '0'; },
|
||||
update: t => { container.style.opacity = t; },
|
||||
end: () => { container.style.opacity = null; },
|
||||
});
|
||||
try {
|
||||
await currAnim.start();
|
||||
await MamiAnimate({
|
||||
duration: 300,
|
||||
easing: 'outExpo',
|
||||
signal,
|
||||
update(t) {
|
||||
container.style.opacity = t;
|
||||
},
|
||||
});
|
||||
container.style.opacity = null;
|
||||
} catch(ex) {}
|
||||
},
|
||||
dismiss: async parent => {
|
||||
async dismiss(parent) {
|
||||
if(!raised) return;
|
||||
raised = false;
|
||||
container.style.pointerEvents = 'none';
|
||||
|
||||
currAnim?.cancel();
|
||||
animeAbort?.abort();
|
||||
animeAbort = new AbortController;
|
||||
const signal = animeAbort.signal;
|
||||
|
||||
currAnim = MamiAnimate({
|
||||
async: true,
|
||||
delayed: true,
|
||||
duration: 300,
|
||||
easing: 'outExpo',
|
||||
update: t => { container.style.opacity = 1 - t; },
|
||||
end: t => { parent.removeChild(container); },
|
||||
});
|
||||
try {
|
||||
await currAnim.start();
|
||||
await MamiAnimate({
|
||||
duration: 300,
|
||||
easing: 'outExpo',
|
||||
signal,
|
||||
update(t) {
|
||||
container.style.opacity = 1 - t;
|
||||
},
|
||||
});
|
||||
parent.removeChild(container);
|
||||
} catch(ex) {}
|
||||
},
|
||||
show: async dialog => {
|
||||
async show(dialog) {
|
||||
if(typeof dialog !== 'object' || dialog === null)
|
||||
throw 'dialog must be a non-null object';
|
||||
|
||||
|
@ -167,6 +171,8 @@ const MamiMessageBoxDialog = function(info) {
|
|||
if(buttons.childElementCount > 2)
|
||||
buttons.classList.add('msgbox-dialog-buttons-many');
|
||||
|
||||
const showAnimAbort = new AbortController;
|
||||
|
||||
return {
|
||||
get buttonCount() {
|
||||
return buttons.childElementCount;
|
||||
|
@ -204,31 +210,36 @@ const MamiMessageBoxDialog = function(info) {
|
|||
if(primaryButton instanceof HTMLButtonElement)
|
||||
primaryButton.focus();
|
||||
|
||||
dialog.style.pointerEvents = null;
|
||||
|
||||
MamiAnimate({
|
||||
async: true,
|
||||
duration: 500,
|
||||
easing: 'outElasticHalf',
|
||||
signal: showAnimAbort.signal,
|
||||
update: t => {
|
||||
dialog.style.transform = `scale(${t})`;
|
||||
},
|
||||
end: () => {
|
||||
dialog.style.transform = null;
|
||||
},
|
||||
});
|
||||
}).then(() => {
|
||||
dialog.style.transform = null;
|
||||
}).catch(ex => { });
|
||||
});
|
||||
},
|
||||
dismiss: async () => {
|
||||
dismiss: () => {
|
||||
showAnimAbort.abort();
|
||||
|
||||
dialog.style.pointerEvents = 'none';
|
||||
|
||||
await MamiAnimate({
|
||||
async: true,
|
||||
MamiAnimate({
|
||||
duration: 600,
|
||||
easing: 'outExpo',
|
||||
update: t => { dialog.style.opacity = 1 - t; },
|
||||
end: () => { dialog.style.opacity = '0'; },
|
||||
update(t) {
|
||||
dialog.style.opacity = 1 - t;
|
||||
},
|
||||
}).catch(ex => { }).then(() => {
|
||||
dialog.style.opacity = '0';
|
||||
}).finally(() => {
|
||||
dialog.remove();
|
||||
});
|
||||
|
||||
dialog.remove();
|
||||
},
|
||||
cancel: () => {
|
||||
doReject();
|
||||
|
@ -236,12 +247,10 @@ const MamiMessageBoxDialog = function(info) {
|
|||
};
|
||||
};
|
||||
|
||||
const MamiMessageBoxControl = function(options) {
|
||||
options = MamiArgs('options', options, define => {
|
||||
define('parent').required().constraint(value => value instanceof Element).done();
|
||||
});
|
||||
const MamiMessageBoxControl = function({ parent }) {
|
||||
if(!(parent instanceof HTMLElement))
|
||||
throw new Error('parent argument must be an instance of HTMLElement');
|
||||
|
||||
const parent = options.parent;
|
||||
const container = new MamiMessageBoxContainer;
|
||||
const queue = [];
|
||||
let currentDialog;
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
#include args.js
|
||||
|
||||
const MamiTabsControl = function(options) {
|
||||
options = MamiArgs('options', options, define => {
|
||||
define('onAdd').required().type('function').done();
|
||||
define('onRemove').required().type('function').done();
|
||||
define('onSwitch').required().type('function').done();
|
||||
});
|
||||
|
||||
const onAdd = options.onAdd;
|
||||
const onRemove = options.onRemove;
|
||||
const onSwitch = options.onSwitch;
|
||||
const MamiTabsControl = function({ onAdd, onRemove, onSwitch }) {
|
||||
if(typeof onAdd !== 'function')
|
||||
throw new Error('onAdd argument must be a function');
|
||||
if(typeof onRemove !== 'function')
|
||||
throw new Error('onRemove argument must be a function');
|
||||
if(typeof onSwitch !== 'function')
|
||||
throw new Error('onSwitch argument must be a function');
|
||||
|
||||
const tabs = new Map;
|
||||
let tabIdCounter = 0;
|
||||
let currentTab;
|
||||
|
||||
const extractElement = elementInfo => {
|
||||
|
@ -123,7 +119,7 @@ const MamiTabsControl = function(options) {
|
|||
if(tabId !== undefined)
|
||||
throw 'tabInfo has already been added';
|
||||
|
||||
tabId = $rngs(8);
|
||||
tabId = 't' + (++tabIdCounter).toString(16);
|
||||
tabs.set(tabId, tabInfo);
|
||||
|
||||
if(title !== 'string' && 'title' in tabInfo)
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
#include args.js
|
||||
const MamiViewsControl = function({ body }) {
|
||||
if(!(body instanceof HTMLElement))
|
||||
throw new Error('body argument must be an instance of HTMLElement');
|
||||
|
||||
const MamiViewsControl = function(options) {
|
||||
options = MamiArgs('options', options, define => {
|
||||
define('body').required().constraint(value => value instanceof Element).done();
|
||||
});
|
||||
|
||||
const targetBody = options.body;
|
||||
targetBody.classList.toggle('views', true);
|
||||
body.classList.toggle('views', true);
|
||||
|
||||
const views = [];
|
||||
|
||||
|
@ -20,8 +16,8 @@ const MamiViewsControl = function(options) {
|
|||
|
||||
if(!(element instanceof Element))
|
||||
throw 'element is not an instance of Element';
|
||||
if(element === targetBody)
|
||||
throw 'element may not be the same as targetBody';
|
||||
if(element === body)
|
||||
throw 'element may not be the same as the body argument';
|
||||
|
||||
return element;
|
||||
};
|
||||
|
@ -46,8 +42,8 @@ const MamiViewsControl = function(options) {
|
|||
element.classList.toggle('views-background', false);
|
||||
element.classList.toggle('hidden', false);
|
||||
|
||||
if(!targetBody.contains(element))
|
||||
targetBody.appendChild(element);
|
||||
if(!body.contains(element))
|
||||
body.appendChild(element);
|
||||
|
||||
if(typeof elementInfo.onViewForeground === 'function')
|
||||
await elementInfo.onViewForeground();
|
||||
|
@ -118,8 +114,8 @@ const MamiViewsControl = function(options) {
|
|||
if(typeof elementInfo.onViewBackground === 'function')
|
||||
await elementInfo.onViewBackground();
|
||||
|
||||
if(targetBody.contains(element))
|
||||
targetBody.removeChild(element);
|
||||
if(body.contains(element))
|
||||
body.removeChild(element);
|
||||
|
||||
if(typeof elementInfo.onViewPop === 'function')
|
||||
await elementInfo.onViewPop();
|
||||
|
@ -181,8 +177,8 @@ const MamiViewsControl = function(options) {
|
|||
element.classList.toggle('views-background', true);
|
||||
element.classList.toggle('hidden', true);
|
||||
|
||||
if(!targetBody.contains(element))
|
||||
targetBody.appendChild(element);
|
||||
if(!body.contains(element))
|
||||
body.appendChild(element);
|
||||
|
||||
updateZIncides();
|
||||
},
|
||||
|
@ -193,8 +189,8 @@ const MamiViewsControl = function(options) {
|
|||
const elementInfo = views.shift();
|
||||
const element = extractElement(elementInfo);
|
||||
|
||||
if(targetBody.contains(element))
|
||||
targetBody.removeChild(element);
|
||||
if(body.contains(element))
|
||||
body.removeChild(element);
|
||||
|
||||
if(typeof elementInfo.onViewPop === 'function')
|
||||
await elementInfo.onViewPop();
|
||||
|
|
|
@ -14,82 +14,124 @@ const MamiEasings = (() => {
|
|||
const elasticOffsetQuarter = Math.pow(2, -10) * Math.sin((.25 - elasticConst2) * elasticConst);
|
||||
const inOutElasticOffset = Math.pow(2, -10) * Math.sin((1 - elasticConst2 * 1.5) * elasticConst / 1.5);
|
||||
|
||||
let outBounce;
|
||||
|
||||
return {
|
||||
linear: t => t,
|
||||
linear(t) {
|
||||
return t;
|
||||
},
|
||||
|
||||
inQuad: t => t * t,
|
||||
outQuad: t => t * (2 - t),
|
||||
inOutQuad: t => {
|
||||
inQuad(t) {
|
||||
return t * t;
|
||||
},
|
||||
outQuad(t) {
|
||||
return t * (2 - t);
|
||||
},
|
||||
inOutQuad(t) {
|
||||
if(t < .5)
|
||||
return t * t * 2;
|
||||
return --t * t * -2 + 1;
|
||||
},
|
||||
|
||||
inCubic: t => t * t * t,
|
||||
outCubic: t => --t * t * t + 1,
|
||||
inOutCubic: t => {
|
||||
inCubic(t) {
|
||||
return t * t * t;
|
||||
},
|
||||
outCubic(t) {
|
||||
return --t * t * t + 1;
|
||||
},
|
||||
inOutCubic(t) {
|
||||
if(t < .5)
|
||||
return t * t * t * 4;
|
||||
return --t * t * t * 4 + 1;
|
||||
},
|
||||
|
||||
inQuart: t => t * t * t * t,
|
||||
outQuart: t => 1 - --t * t * t * t,
|
||||
inOutQuart: t => {
|
||||
inQuart(t) {
|
||||
return t * t * t * t;
|
||||
},
|
||||
outQuart(t) {
|
||||
return 1 - --t * t * t * t;
|
||||
},
|
||||
inOutQuart(t) {
|
||||
if(t < .5)
|
||||
return t * t * t * t * 8;
|
||||
return --t * t * t * t * -8 + 1;
|
||||
},
|
||||
|
||||
inQuint: t => t * t * t * t * t,
|
||||
outQuint: t => --t * t * t * t * t + 1,
|
||||
inOutQuint: t => {
|
||||
inQuint(t) {
|
||||
return t * t * t * t * t;
|
||||
},
|
||||
outQuint(t) {
|
||||
return --t * t * t * t * t + 1;
|
||||
},
|
||||
inOutQuint(t) {
|
||||
if(t < .5)
|
||||
return t * t * t * t * t * 16;
|
||||
return --t * t * t * t * t * 16 + 1;
|
||||
},
|
||||
|
||||
inSine: t => 1 - Math.cos(t * Math.PI * .5),
|
||||
outSine: t => Math.sin(t * Math.PI * .5),
|
||||
inOutSine: t => .5 - .5 * Math.cos(Math.PI * t),
|
||||
inSine(t) {
|
||||
return 1 - Math.cos(t * Math.PI * .5);
|
||||
},
|
||||
outSine(t) {
|
||||
return Math.sin(t * Math.PI * .5);
|
||||
},
|
||||
inOutSine(t) {
|
||||
return .5 - .5 * Math.cos(Math.PI * t);
|
||||
},
|
||||
|
||||
inCirc: t => 1 - Math.sqrt(1 - t * t),
|
||||
outCirc: t => Math.sqrt(1 - --t * t),
|
||||
inOutCirc: t => {
|
||||
inCirc(t) {
|
||||
return 1 - Math.sqrt(1 - t * t);
|
||||
},
|
||||
outCirc(t) {
|
||||
return Math.sqrt(1 - --t * t);
|
||||
},
|
||||
inOutCirc(t) {
|
||||
if((t *= 2) < 1)
|
||||
return .5 - .5 * Math.sqrt(1 - t * t);
|
||||
return .5 * Math.sqrt(1 - (t -= 2) * t) + .5;
|
||||
},
|
||||
|
||||
inElastic: t => -Math.pow(2, -10 + 10 * t) * Math.sin((1 - elasticConst2 - t) * elasticConst) + elasticOffsetFull * (1 - t),
|
||||
outElastic: t => Math.pow(2, -10 * t) * Math.sin((t - elasticConst2) * elasticConst) + 1 - elasticOffsetFull * t,
|
||||
outElasticHalf: t => Math.pow(2, -10 * t) * Math.sin((.5 * t - elasticConst2) * elasticConst) + 1 - elasticOffsetHalf * t,
|
||||
outElasticQuarter: t => Math.pow(2, -10 * t) * Math.sin((.25 * t - elasticConst2) * elasticConst) + 1 - elasticOffsetQuarter * t,
|
||||
inOutElastic: t => {
|
||||
inElastic(t) {
|
||||
return -Math.pow(2, -10 + 10 * t) * Math.sin((1 - elasticConst2 - t) * elasticConst) + elasticOffsetFull * (1 - t);
|
||||
},
|
||||
outElastic(t) {
|
||||
return Math.pow(2, -10 * t) * Math.sin((t - elasticConst2) * elasticConst) + 1 - elasticOffsetFull * t;
|
||||
},
|
||||
outElasticHalf(t) {
|
||||
return Math.pow(2, -10 * t) * Math.sin((.5 * t - elasticConst2) * elasticConst) + 1 - elasticOffsetHalf * t;
|
||||
},
|
||||
outElasticQuarter(t) {
|
||||
return Math.pow(2, -10 * t) * Math.sin((.25 * t - elasticConst2) * elasticConst) + 1 - elasticOffsetQuarter * t;
|
||||
},
|
||||
inOutElastic(t) {
|
||||
if((t *= 2) < 1)
|
||||
return -.5 * (Math.pow(2, -10 + 10 * t) * Math.sin((1 - elasticConst2 * 1.5 - t) * elasticConst / 1.5) - inOutElasticOffset * (1 - t));
|
||||
return .5 * (Math.pow(2, -10 * --t) * Math.sin((t - elasticConst2 * 1.5) * elasticConst / 1.5) - inOutElasticOffset * t) + 1;
|
||||
},
|
||||
|
||||
inExpo: t => Math.pow(2, 10 * (t - 1)) + expoOffset * (t - 1),
|
||||
outExpo: t => -Math.pow(2, -10 * t) + 1 + expoOffset * t,
|
||||
inOutExpo: t => {
|
||||
inExpo(t) {
|
||||
return Math.pow(2, 10 * (t - 1)) + expoOffset * (t - 1);
|
||||
},
|
||||
outExpo(t) {
|
||||
return -Math.pow(2, -10 * t) + 1 + expoOffset * t;
|
||||
},
|
||||
inOutExpo(t) {
|
||||
if(t < .5)
|
||||
return .5 * (Math.pow(2, 20 * t - 10)) + expoOffset * (2 * t - 1);
|
||||
return 1 - .5 * (Math.pow(2, -20 * t + 10)) + expoOffset * (-2 * t + 1);
|
||||
},
|
||||
|
||||
inBack: t => t * t * ((backConst + 1) * t - backConst),
|
||||
outBack: t => --t * t * ((backConst + 1) * t + backConst) + 1,
|
||||
inOutBack: t => {
|
||||
inBack(t) {
|
||||
return t * t * ((backConst + 1) * t - backConst);
|
||||
},
|
||||
outBack(t) {
|
||||
return --t * t * ((backConst + 1) * t + backConst) + 1;
|
||||
},
|
||||
inOutBack(t) {
|
||||
if((t *= 2) < 1)
|
||||
return .5 * t * t * ((backConst2 + 1) * t - backConst2);
|
||||
return .5 * ((t -= 2) * t * ((backConst2 + 1) * t + backConst2) + 2);
|
||||
},
|
||||
|
||||
inBounce: t => {
|
||||
inBounce(t) {
|
||||
t = 1 - t;
|
||||
if(t < bounceConst)
|
||||
return 1 - 7.5625 * t * t;
|
||||
|
@ -99,23 +141,23 @@ const MamiEasings = (() => {
|
|||
return 1 - (7.5625 * (t -= 2.25 * bounceConst) * t + .9375);
|
||||
return 1 - (7.5625 * (t -= 2.625 * bounceConst) * t + .984375);
|
||||
},
|
||||
outBounce: (() => {
|
||||
return outBounce = t => {
|
||||
if(t < bounceConst)
|
||||
return 7.5625 * t * t;
|
||||
if(t < 2 * bounceConst)
|
||||
return 7.5625 * (t -= 1.5 * bounceConst) * t + .75;
|
||||
if(t < 2.5 * bounceConst)
|
||||
return 7.5625 * (t -= 2.25 * bounceConst) * t + .9375;
|
||||
return 7.5625 * (t -= 2.625 * bounceConst) * t + .984375;
|
||||
};
|
||||
})(),
|
||||
inOutBounce: t => {
|
||||
outBounce(t) {
|
||||
if(t < bounceConst)
|
||||
return 7.5625 * t * t;
|
||||
if(t < 2 * bounceConst)
|
||||
return 7.5625 * (t -= 1.5 * bounceConst) * t + .75;
|
||||
if(t < 2.5 * bounceConst)
|
||||
return 7.5625 * (t -= 2.25 * bounceConst) * t + .9375;
|
||||
return 7.5625 * (t -= 2.625 * bounceConst) * t + .984375;
|
||||
},
|
||||
inOutBounce(t) {
|
||||
if(t < .5)
|
||||
return .5 - .5 * outBounce(1 - t * 2);
|
||||
return outBounce((t - .5) * 2) * .5 + .5;
|
||||
},
|
||||
|
||||
outPow10: t => --t * Math.pow(t, 10) + 1,
|
||||
outPow10(t) {
|
||||
return --t * Math.pow(t, 10) + 1;
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -6,21 +6,16 @@ const MamiEEPROM = function(endPoint) {
|
|||
const appId = '1';
|
||||
|
||||
return {
|
||||
create: fileInput => {
|
||||
create(fileInput) {
|
||||
if(!(fileInput instanceof File))
|
||||
throw 'fileInput must be an instance of window.File';
|
||||
|
||||
let userAborted = false;
|
||||
let abortHandler;
|
||||
const abort = new AbortController;
|
||||
|
||||
return {
|
||||
abort: () => {
|
||||
userAborted = true;
|
||||
if(typeof abortHandler === 'function')
|
||||
abortHandler();
|
||||
},
|
||||
start: async progress => {
|
||||
if(userAborted)
|
||||
abort() { abort.abort(); },
|
||||
async start(progress) {
|
||||
if(abort.signal.aborted)
|
||||
throw 'File upload was cancelled by the user, it cannot be restarted.';
|
||||
|
||||
const reportProgress = typeof progress !== 'function' ? undefined : ev => {
|
||||
|
@ -40,7 +35,7 @@ const MamiEEPROM = function(endPoint) {
|
|||
type: 'json',
|
||||
authed: true,
|
||||
upload: reportProgress,
|
||||
abort: handler => abortHandler = handler,
|
||||
signal: abort.signal,
|
||||
}, formData);
|
||||
if(body === null)
|
||||
throw "The upload server didn't return the metadata for some reason.";
|
||||
|
@ -55,7 +50,7 @@ const MamiEEPROM = function(endPoint) {
|
|||
|
||||
return Object.freeze(body);
|
||||
} catch(ex) {
|
||||
if(userAborted)
|
||||
if(ex.aborted || abort.signal.aborted)
|
||||
throw '';
|
||||
|
||||
console.error(ex);
|
||||
|
@ -65,7 +60,7 @@ const MamiEEPROM = function(endPoint) {
|
|||
};
|
||||
},
|
||||
|
||||
delete: async fileInfo => {
|
||||
async delete(fileInfo) {
|
||||
if(typeof fileInfo !== 'object')
|
||||
throw 'fileInfo must be an object';
|
||||
if(typeof fileInfo.urlf !== 'string')
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
#include args.js
|
||||
|
||||
const MamiEmotePicker = function(args) {
|
||||
args = MamiArgs('args', args, define => {
|
||||
define('getEmotes').type('function').done();
|
||||
define('setKeepOpenOnPick').type('function').done();
|
||||
define('onPick').type('function').done();
|
||||
define('onClose').type('function').done();
|
||||
});
|
||||
const MamiEmotePicker = function({ getEmotes, onPick, onClose=null, setKeepOpenOnPick=null }) {
|
||||
if(typeof getEmotes !== 'function')
|
||||
throw new Error('getEmotes must be a function');
|
||||
if(typeof onPick !== 'function')
|
||||
throw new Error('onPick must be a function');
|
||||
|
||||
let emotes;
|
||||
|
||||
let listElem, searchElem, keepOpenToggleElem;
|
||||
const html = <div class="emopick" style="z-index: 9001;" onfocusout={ev => {
|
||||
if(!keepOpenToggleElem.checked && !html.contains(ev.relatedTarget))
|
||||
|
@ -24,8 +19,8 @@ const MamiEmotePicker = function(args) {
|
|||
<div class="emopick-actions" tabindex="0">
|
||||
<label class="emopick-action-toggle" tabindex="0">
|
||||
{keepOpenToggleElem = <input type="checkbox" class="emopick-action-toggle-box" onchange={() => {
|
||||
if(args.setKeepOpenOnPick !== undefined)
|
||||
args.setKeepOpenOnPick(keepOpenToggleElem.checked);
|
||||
if(typeof setKeepOpenOnPick === 'function')
|
||||
setKeepOpenOnPick(keepOpenToggleElem.checked);
|
||||
}} />}
|
||||
<span class="emopick-action-toggle-label">Keep picker open</span>
|
||||
</label>
|
||||
|
@ -38,7 +33,7 @@ const MamiEmotePicker = function(args) {
|
|||
|
||||
for(const emote of emotes)
|
||||
listElem.appendChild(<button class="emopick-emote" type="button" title={`:${emote.strings[0]}:`} data-strings={emote.strings.join(' ')} onclick={() => {
|
||||
args.onPick(emote);
|
||||
onPick(emote);
|
||||
if(!keepOpenToggleElem.checked)
|
||||
close();
|
||||
}}>
|
||||
|
@ -89,8 +84,8 @@ const MamiEmotePicker = function(args) {
|
|||
promiseResolve = undefined;
|
||||
}
|
||||
|
||||
if(args.onClose !== undefined)
|
||||
args.onClose();
|
||||
if(typeof onClose === 'function')
|
||||
onClose();
|
||||
|
||||
html.classList.add('hidden');
|
||||
};
|
||||
|
@ -110,7 +105,7 @@ const MamiEmotePicker = function(args) {
|
|||
setPosition: setPosition,
|
||||
close: close,
|
||||
dialog: pos => {
|
||||
emotes = args.getEmotes();
|
||||
emotes = getEmotes();
|
||||
buildList();
|
||||
|
||||
html.classList.remove('hidden');
|
||||
|
|
|
@ -59,9 +59,7 @@ const Flashii = function(baseUrl) {
|
|||
headers ??= {};
|
||||
if(fresh) headers['Cache-Control'] = 'no-cache';
|
||||
|
||||
const options = { type, headers, authed };
|
||||
|
||||
return await $xhr.send(method, url, options, body);
|
||||
return await $xhr.send(method, url, { type, headers, authed }, body);
|
||||
};
|
||||
|
||||
const fii = {};
|
||||
|
@ -77,7 +75,7 @@ const Flashii = function(baseUrl) {
|
|||
};
|
||||
|
||||
fii.v1.chat = {};
|
||||
fii.v1.chat.login = function({ redirect=null, assign=true }) {
|
||||
fii.v1.chat.login = function({ redirect=null, assign=true }={}) {
|
||||
return new Promise(resolve => {
|
||||
redirect ??= `${location.protocol}//${location.host}`;
|
||||
if(typeof redirect !== 'string')
|
||||
|
@ -93,7 +91,7 @@ const Flashii = function(baseUrl) {
|
|||
resolve(url);
|
||||
});
|
||||
};
|
||||
fii.v1.chat.servers = async function({ proto=null, secure=null, fields=null, fresh=false }) {
|
||||
fii.v1.chat.servers = async function({ proto=null, secure=null, fields=null, fresh=false }={}) {
|
||||
const params = {};
|
||||
|
||||
if(proto !== null && typeof proto !== 'string')
|
||||
|
@ -163,7 +161,7 @@ const Flashii = function(baseUrl) {
|
|||
};
|
||||
|
||||
fii.v1.colours = {};
|
||||
fii.v1.colours.presets = async function({ fields=null, fresh=false }) {
|
||||
fii.v1.colours.presets = async function({ fields=null, fresh=false }={}) {
|
||||
const { status, body } = await send({ method: 'GET', path: '/v1/colours/presets', fields, fresh });
|
||||
|
||||
if(status === 400)
|
||||
|
@ -196,7 +194,7 @@ const Flashii = function(baseUrl) {
|
|||
return id;
|
||||
};
|
||||
|
||||
fii.v1.emotes = async function({ fields=null, fresh=false }) {
|
||||
fii.v1.emotes = async function({ fields=null, fresh=false }={}) {
|
||||
const { status, body } = await send({ method: 'GET', path: '/v1/emotes', fields, fresh });
|
||||
|
||||
if(status === 400)
|
||||
|
@ -243,7 +241,7 @@ const Flashii = function(baseUrl) {
|
|||
return id;
|
||||
};
|
||||
|
||||
fii.v1.kaomoji = async function({ as=null, fields=null, fresh=false }) {
|
||||
fii.v1.kaomoji = async function({ as=null, fields=null, fresh=false }={}) {
|
||||
const { status, body } = await send({ method: 'GET', path: '/v1/kaomoji', params: { as }, fields, fresh });
|
||||
|
||||
if(status === 400)
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#include urib64.js
|
||||
|
||||
const MamiHash = (() => {
|
||||
const textEncoder = new TextEncoder('utf-8');
|
||||
|
||||
return async (data, method='SHA-256', asString=true) => {
|
||||
if(typeof data === 'string')
|
||||
data = textEncoder.encode(data);
|
||||
|
||||
const hash = new Uint8Array(await crypto.subtle.digest(method, data));
|
||||
return asString ? MamiUriBase64.encode(hash) : hash;
|
||||
};
|
||||
})();
|
|
@ -1,12 +1,9 @@
|
|||
window.Umi = { UI: {} };
|
||||
|
||||
#include array.js
|
||||
#include html.js
|
||||
#include uniqstr.js
|
||||
#include xhr.js
|
||||
|
||||
#include animate.js
|
||||
#include args.js
|
||||
#include auth.js
|
||||
#include awaitable.js
|
||||
#include common.js
|
||||
|
@ -16,7 +13,6 @@ window.Umi = { UI: {} };
|
|||
#include emotes.js
|
||||
#include events.js
|
||||
#include flashii.js
|
||||
#include mobile.js
|
||||
#include parsing.js
|
||||
#include themes.js
|
||||
#include txtrigs.js
|
||||
|
@ -53,31 +49,37 @@ window.Umi = { UI: {} };
|
|||
#include ui/emotes.js
|
||||
#include ui/loading-overlay.jsx
|
||||
|
||||
const MamiInit = async args => {
|
||||
args = MamiArgs('args', args, define => {
|
||||
define('parent').default(document.body).constraint(value => value instanceof Element).done();
|
||||
define('eventTarget').required().constraint(MamiIsEventTarget).done();
|
||||
define('settingsPrefix').default('umi-').done();
|
||||
define('auth').default(null).constraint(MamiIsAuth).done();
|
||||
});
|
||||
const MamiInit = async ({ auth=null, eventTarget, parent=null, settingsPrefix='umi-' }={}) => {
|
||||
if(auth !== null && !MamiIsAuth(auth))
|
||||
throw new Error('auth argument must be a compatible auth object');
|
||||
|
||||
if(!MamiIsEventTarget(eventTarget))
|
||||
throw new Error('eventTarget must be a compatible event target object');
|
||||
|
||||
if(parent === null)
|
||||
parent = document.body;
|
||||
else if(!(parent instanceof HTMLElement))
|
||||
throw new Error('parent argument must be an instance of HTMLElement');
|
||||
|
||||
if(typeof settingsPrefix !== 'string')
|
||||
throw new Error('settingsPrefix must be a string');
|
||||
|
||||
const flashii = new Flashii(`${window.FII_URL}/api`);
|
||||
|
||||
let auth = args.auth;
|
||||
if(!auth) {
|
||||
auth = new MamiFlashiiAuth(flashii);
|
||||
await auth.refresh();
|
||||
setInterval(() => { auth.refresh(); }, 600000);
|
||||
}
|
||||
|
||||
const ctx = new MamiContext(args.eventTarget, null, auth, flashii);
|
||||
const ctx = new MamiContext(eventTarget, null, auth, flashii);
|
||||
|
||||
// remove this later and replace with the one commented out way below
|
||||
if(!('mami' in window))
|
||||
Object.defineProperty(window, 'mami', { enumerable: true, value: ctx });
|
||||
|
||||
ctx.views = new MamiViewsControl({ body: args.parent });
|
||||
ctx.msgbox = new MamiMessageBoxControl({ parent: args.parent });
|
||||
ctx.views = new MamiViewsControl({ body: parent });
|
||||
ctx.msgbox = new MamiMessageBoxControl({ parent });
|
||||
|
||||
const loadingOverlay = new Umi.UI.LoadingOverlay('spinner', 'Loading...');
|
||||
await ctx.views.push(loadingOverlay);
|
||||
|
@ -94,7 +96,7 @@ const MamiInit = async args => {
|
|||
}
|
||||
|
||||
|
||||
const settings = new MamiSettings(args.settingsPrefix, ctx.events.scopeTo('settings'));
|
||||
const settings = new MamiSettings(settingsPrefix, ctx.events.scopeTo('settings'));
|
||||
ctx.settings = settings;
|
||||
|
||||
settings.define('style').default('dark').create();
|
||||
|
@ -123,7 +125,6 @@ const MamiInit = async args => {
|
|||
settings.define('windowsLiveMessenger').default(false).create();
|
||||
settings.define('seinfeld').default(false).create();
|
||||
settings.define('flashTitle').default(true).create();
|
||||
settings.define('onlyConnectWhenVisible2').default(MamiIsMobileDevice()).create();
|
||||
settings.define('playJokeSounds').default(true).create();
|
||||
settings.define('weeaboo').default(false).create();
|
||||
settings.define('motivationalImages').default(false).create();
|
||||
|
@ -134,7 +135,6 @@ const MamiInit = async args => {
|
|||
settings.define('dumpPackets').default(window.DEBUG).create();
|
||||
settings.define('dumpEvents').default(window.DEBUG).create();
|
||||
settings.define('marqueeAllNames').default(false).create();
|
||||
settings.define('dbgAnimDurationMulti').default(1).min(0).max(10).create();
|
||||
settings.define('newLineOnEnter').default(false).create();
|
||||
settings.define('keepEmotePickerOpen').default(true).create();
|
||||
settings.define('doNotMarkLinksAsVisited').default(false).create();
|
||||
|
@ -329,7 +329,7 @@ const MamiInit = async args => {
|
|||
layout.element.classList.toggle('chat--compact', ev.detail.value);
|
||||
layout.interface.messageList.element.classList.toggle('chat--compact', ev.detail.value);
|
||||
});
|
||||
settings.watch('preventOverflow', ev => { args.parent.classList.toggle('prevent-overflow', ev.detail.value); });
|
||||
settings.watch('preventOverflow', ev => { parent.classList.toggle('prevent-overflow', ev.detail.value); });
|
||||
settings.watch('doNotMarkLinksAsVisited', ev => { layout.interface.messageList.element.classList.toggle('mami-do-not-mark-links-as-visited', ev.detail.value); });
|
||||
settings.watch('newLineOnEnter', ev => { chatForm.input.newLineOnEnter = ev.detail.value; });
|
||||
settings.watch('expandTextBox', ev => { chatForm.input.growInputField = ev.detail.value; });
|
||||
|
@ -509,10 +509,6 @@ const MamiInit = async args => {
|
|||
});
|
||||
sbSettings.category(category => {
|
||||
category.header('Misc');
|
||||
category.setting('onlyConnectWhenVisible2').title('Only connect when the tab is in the foreground').confirm([
|
||||
'Please only disable this setting if you are using a desktop or laptop computer, this should always remain on on a phone, tablet or other device of that sort.',
|
||||
'Are you sure you want to change this setting? Ignoring this warning may carry consequences.',
|
||||
]).done();
|
||||
category.setting('playJokeSounds').title('Run joke triggers').done();
|
||||
category.setting('weeaboo').title('Weeaboo').done();
|
||||
category.setting('motivationalImages').title('Make images motivational').done();
|
||||
|
@ -596,7 +592,7 @@ const MamiInit = async args => {
|
|||
sbSettings.category(category => {
|
||||
category.header('Settings');
|
||||
category.button('Import settings', () => {
|
||||
(new MamiSettingsBackup(settings)).importUpload(args.parent);
|
||||
(new MamiSettingsBackup(settings)).importUpload(parent);
|
||||
}, ['Your current settings will be replaced with the ones in the export.', 'Are you sure you want to continue?']);
|
||||
category.button('Export settings', () => {
|
||||
const user = Umi.User.getCurrentUser();
|
||||
|
@ -604,7 +600,7 @@ const MamiInit = async args => {
|
|||
if(user !== null)
|
||||
fileName = `${user.name}'s settings.mami`;
|
||||
|
||||
(new MamiSettingsBackup(settings)).exportDownload(args.parent, fileName);
|
||||
(new MamiSettingsBackup(settings)).exportDownload(parent, fileName);
|
||||
});
|
||||
category.button('Reset settings', () => {
|
||||
settings.clear();
|
||||
|
@ -617,7 +613,6 @@ const MamiInit = async args => {
|
|||
category.setting('dumpPackets').title('Dump packets to console').done();
|
||||
category.setting('dumpEvents').title('Dump events to console').done();
|
||||
category.setting('marqueeAllNames').title('Apply marquee on everyone (requires reload)').done();
|
||||
category.setting('dbgAnimDurationMulti').title('Animation multiplier').type('range').done();
|
||||
category.button('Test kick/ban notice', async button => {
|
||||
button.disabled = true;
|
||||
await ctx.views.push(new MamiForceDisconnectNotice({ perma: true, type: 'ban' }));
|
||||
|
@ -775,7 +770,7 @@ const MamiInit = async args => {
|
|||
doUpload(file);
|
||||
},
|
||||
});
|
||||
args.parent.appendChild(uploadForm);
|
||||
parent.appendChild(uploadForm);
|
||||
|
||||
chatForm.input.createButton({
|
||||
title: 'Upload',
|
||||
|
@ -790,10 +785,10 @@ const MamiInit = async args => {
|
|||
});
|
||||
|
||||
// figure out how to display a UI for this someday
|
||||
//args.parent.addEventListener('dragenter', ev => { console.info('dragenter', ev); });
|
||||
//args.parent.addEventListener('dragleave', ev => { console.info('dragleave', ev); });
|
||||
args.parent.addEventListener('dragover', ev => { ev.preventDefault(); });
|
||||
args.parent.addEventListener('drop', ev => {
|
||||
//parent.addEventListener('dragenter', ev => { console.info('dragenter', ev); });
|
||||
//parent.addEventListener('dragleave', ev => { console.info('dragleave', ev); });
|
||||
parent.addEventListener('dragover', ev => { ev.preventDefault(); });
|
||||
parent.addEventListener('drop', ev => {
|
||||
if(ev.dataTransfer === undefined || ev.dataTransfer === null || ev.dataTransfer.files.length < 1)
|
||||
return;
|
||||
|
||||
|
@ -901,8 +896,8 @@ const MamiInit = async args => {
|
|||
ctx, sockChat, setLoadingOverlay, sockChatReconnect, pingIndicator,
|
||||
sbActPing, sbChannels, sbUsers
|
||||
);
|
||||
settings.watch('dumpEvents', ev => sockChatHandlers.setDumpEvents(ev.detail.value));
|
||||
settings.watch('dumpPackets', ev => sockChat.setDumpPackets(ev.detail.value));
|
||||
settings.watch('dumpEvents', ev => { sockChatHandlers.setDumpEvents(ev.detail.value); });
|
||||
settings.watch('dumpPackets', ev => { sockChat.dumpPackets = ev.detail.value; });
|
||||
sockChatHandlers.register();
|
||||
|
||||
const conManAttempt = ev => {
|
||||
|
@ -932,35 +927,7 @@ const MamiInit = async args => {
|
|||
const eventTarget = new MamiEventTargetWindow;
|
||||
Object.defineProperty(window, 'mamiEventTarget', { enumerable: true, value: eventTarget });
|
||||
|
||||
MamiInit({
|
||||
eventTarget: eventTarget,
|
||||
}).then(mami => {
|
||||
MamiInit({ eventTarget }).then(mami => {
|
||||
//Object.defineProperty(window, 'mami', { enumerable: true, value: mami });
|
||||
});
|
||||
})();
|
||||
|
||||
const MamiDbgCreateFloatingInstance = async () => {
|
||||
if(!window.DEBUG)
|
||||
return;
|
||||
|
||||
const prefix = $rngs(8);
|
||||
const parent = $element('div', {
|
||||
style: {
|
||||
position: 'absolute',
|
||||
bottom: '100px',
|
||||
right: '100px',
|
||||
zIndex: '9001',
|
||||
width: '640px',
|
||||
height: '480px',
|
||||
background: '#0f0',
|
||||
},
|
||||
});
|
||||
|
||||
document.body.appendChild(parent);
|
||||
|
||||
return await MamiInit({
|
||||
parent: parent,
|
||||
settingsPrefix: `dbg:${prefix}:`,
|
||||
eventTarget: mamiEventTarget.scopeTo(prefix),
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
const MamiIsMobileDevice = () => {
|
||||
if('userAgentData' in navigator)
|
||||
return navigator.userAgentData.mobile;
|
||||
|
||||
if('matchMedia' in window)
|
||||
return !window.matchMedia("(any-pointer:fine)").matches;
|
||||
|
||||
if('maxTouchPoints' in navigator)
|
||||
return navigator.maxTouchPoints > 1;
|
||||
|
||||
return false;
|
||||
};
|
|
@ -52,59 +52,58 @@ const MamiForceDisconnectNotice = function(banInfo) {
|
|||
} catch(ex) {}
|
||||
bgmSrc = sfxBuf = undefined;
|
||||
},
|
||||
getViewTransition: mode => {
|
||||
getViewTransition(mode) {
|
||||
if(mode === 'push')
|
||||
return ctx => MamiAnimate({
|
||||
async: true,
|
||||
duration: (sfxBuf?.duration ?? 1.4) * 1000,
|
||||
start: () => {
|
||||
if(sfxBuf !== undefined)
|
||||
mami.sound.audio.createSource(sfxBuf).play();
|
||||
return async ({ fromElem, toElem }) => {
|
||||
if(sfxBuf !== undefined)
|
||||
mami.sound.audio.createSource(sfxBuf).play();
|
||||
|
||||
ctx.toElem.style.top = '-100%';
|
||||
},
|
||||
update: t => {
|
||||
const tOutBounce = MamiEasings.outBounce(t);
|
||||
ctx.toElem.style.top = `${-100 + (tOutBounce * 100)}%`;
|
||||
toElem.style.top = '-100%';
|
||||
|
||||
const tOutExpo = MamiEasings.outExpo(t);
|
||||
ctx.fromElem.style.transform = `scale(${1 - (1 * tOutExpo)}) rotate(${rotate * tOutExpo}deg)`;
|
||||
ctx.fromElem.style.filter = `grayscale(${tOutExpo * 100}%)`;
|
||||
},
|
||||
end: () => {
|
||||
bgmSrc?.play();
|
||||
ctx.toElem.style.top = null;
|
||||
ctx.fromElem.style.transform = null;
|
||||
ctx.fromElem.style.filter = null;
|
||||
},
|
||||
});
|
||||
await MamiAnimate({
|
||||
duration: (sfxBuf?.duration ?? 1.4) * 1000,
|
||||
update(t) {
|
||||
const tOutBounce = MamiEasings.outBounce(t);
|
||||
toElem.style.top = `${-100 + (tOutBounce * 100)}%`;
|
||||
|
||||
const tOutExpo = MamiEasings.outExpo(t);
|
||||
fromElem.style.transform = `scale(${1 - (1 * tOutExpo)}) rotate(${rotate * tOutExpo}deg)`;
|
||||
fromElem.style.filter = `grayscale(${tOutExpo * 100}%)`;
|
||||
},
|
||||
});
|
||||
|
||||
bgmSrc?.play();
|
||||
|
||||
toElem.style.top = null;
|
||||
fromElem.style.transform = null;
|
||||
fromElem.style.filter = null;
|
||||
};
|
||||
|
||||
if(mode === 'pop')
|
||||
return ctx => MamiAnimate({
|
||||
async: true,
|
||||
duration: (sfxBuf?.duration ?? 1.4) * 1000,
|
||||
start: () => {
|
||||
bgmSrc?.stop();
|
||||
if(sfxBuf !== undefined)
|
||||
mami.sound.audio.createSource(sfxBuf, true).play();
|
||||
return async ({ fromElem, toElem }) => {
|
||||
bgmSrc?.stop();
|
||||
if(sfxBuf !== undefined)
|
||||
mami.sound.audio.createSource(sfxBuf, true).play();
|
||||
|
||||
ctx.toElem.style.transform = `scale(1) rotate(${rotate}deg)`;
|
||||
ctx.toElem.style.filter = 'grayscale(100%)';
|
||||
},
|
||||
update: t => {
|
||||
const tOutBounce = MamiEasings.inBounce(t);
|
||||
ctx.fromElem.style.top = `${tOutBounce * -100}%`;
|
||||
toElem.style.transform = `scale(1) rotate(${rotate}deg)`;
|
||||
toElem.style.filter = 'grayscale(100%)';
|
||||
|
||||
const tOutExpo = MamiEasings.inExpo(t);
|
||||
ctx.toElem.style.transform = `scale(${1 * tOutExpo}) rotate(${rotate - (rotate * tOutExpo)}deg)`;
|
||||
ctx.toElem.style.filter = `grayscale(${100 - (tOutExpo * 100)}%)`;
|
||||
},
|
||||
end: () => {
|
||||
ctx.fromElem.style.top = null;
|
||||
ctx.toElem.style.transform = null;
|
||||
ctx.toElem.style.filter = null;
|
||||
},
|
||||
});
|
||||
await MamiAnimate({
|
||||
duration: (sfxBuf?.duration ?? 1.4) * 1000,
|
||||
update(t) {
|
||||
const tOutBounce = MamiEasings.inBounce(t);
|
||||
fromElem.style.top = `${tOutBounce * -100}%`;
|
||||
|
||||
const tOutExpo = MamiEasings.inExpo(t);
|
||||
toElem.style.transform = `scale(${1 * tOutExpo}) rotate(${rotate - (rotate * tOutExpo)}deg)`;
|
||||
toElem.style.filter = `grayscale(${100 - (tOutExpo * 100)}%)`;
|
||||
},
|
||||
});
|
||||
|
||||
fromElem.style.top = null;
|
||||
toElem.style.transform = null;
|
||||
toElem.style.filter = null;
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ const MamiYouAreAnIdiot = function(sndLibrary, views) {
|
|||
|
||||
const pub = {
|
||||
get element() { return html; },
|
||||
onViewPush: async () => {
|
||||
async onViewPush() {
|
||||
try {
|
||||
soundSrc = await sndLibrary.loadSource('misc:youare');
|
||||
soundSrc.muted = true;
|
||||
|
@ -32,29 +32,34 @@ const MamiYouAreAnIdiot = function(sndLibrary, views) {
|
|||
console.error(ex);
|
||||
}
|
||||
},
|
||||
onViewForeground: async () => {
|
||||
async onViewForeground() {
|
||||
if(soundSrc !== undefined)
|
||||
soundSrc.muted = false;
|
||||
},
|
||||
onViewBackground: async () => {
|
||||
async onViewBackground() {
|
||||
if(soundSrc !== undefined)
|
||||
soundSrc.muted = true;
|
||||
},
|
||||
onViewPop: async () => {
|
||||
async onViewPop() {
|
||||
if(soundSrc !== undefined)
|
||||
soundSrc.stop();
|
||||
soundSrc = undefined;
|
||||
},
|
||||
getViewTransition: mode => {
|
||||
getViewTransition(mode) {
|
||||
if(mode === 'push')
|
||||
return ctx => MamiAnimate({
|
||||
async: true,
|
||||
duration: 1500,
|
||||
easing: 'outBounce',
|
||||
start: () => ctx.toElem.style.top = '-100%',
|
||||
update: t => ctx.toElem.style.top = `${-100 + (t * 100)}%`,
|
||||
end: () => ctx.toElem.style.top = null,
|
||||
});
|
||||
return async ({ toElem }) => {
|
||||
toElem.style.top = '-100%';
|
||||
|
||||
await MamiAnimate({
|
||||
duration: 1500,
|
||||
easing: 'outBounce',
|
||||
update(t) {
|
||||
toElem.style.top = `${-100 + (t * 100)}%`;
|
||||
},
|
||||
});
|
||||
|
||||
toElem.style.top = null;
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include timedp.js
|
||||
#include awaitable.js
|
||||
#include proto/sockchat/authed.js
|
||||
#include proto/sockchat/ctx.js
|
||||
#include proto/sockchat/unauthed.js
|
||||
|
@ -125,36 +125,48 @@ const SockChatClient = function(dispatch, options) {
|
|||
sock?.send(args.join("\t"));
|
||||
};
|
||||
|
||||
const sendPing = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(ctx === undefined)
|
||||
throw 'no connection opened';
|
||||
if(!ctx.isAuthed)
|
||||
throw 'must be authenticated';
|
||||
if(ctx.pingPromise !== undefined)
|
||||
throw 'already sending a ping';
|
||||
const sendPing = async () => {
|
||||
return await MamiTimeout(
|
||||
new Promise((resolve, reject) => {
|
||||
if(ctx === undefined)
|
||||
throw 'no connection opened';
|
||||
if(!ctx.isAuthed)
|
||||
throw 'must be authenticated';
|
||||
if(ctx.pingPromise !== undefined)
|
||||
throw 'already sending a ping';
|
||||
|
||||
ctx.lastPing = Date.now();
|
||||
ctx.pingPromise = new TimedPromise(resolve, reject, () => ctx.pingPromise = undefined, 2000);
|
||||
ctx.lastPing = Date.now();
|
||||
ctx.pingPromise = {
|
||||
resolve(...args) { resolve(...args); },
|
||||
reject(...args) { reject(...args); },
|
||||
};
|
||||
|
||||
send('0', ctx.userId);
|
||||
});
|
||||
send('0', ctx.userId);
|
||||
}),
|
||||
2000
|
||||
).finally(() => { ctx.pingPromise = undefined; });
|
||||
};
|
||||
|
||||
const sendAuth = (...args) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(ctx === undefined)
|
||||
throw 'no connection opened';
|
||||
if(ctx.isAuthed)
|
||||
throw 'already authenticated';
|
||||
if(ctx.authPromise !== undefined)
|
||||
throw 'already authenticating';
|
||||
const sendAuth = async (...args) => {
|
||||
return await MamiTimeout(
|
||||
new Promise((resolve, reject) => {
|
||||
if(ctx === undefined)
|
||||
throw 'no connection opened';
|
||||
if(ctx.isAuthed)
|
||||
throw 'already authenticated';
|
||||
if(ctx.authPromise !== undefined)
|
||||
throw 'already authenticating';
|
||||
|
||||
ctx.authPromise = {
|
||||
resolve(...args) { resolve(...args); },
|
||||
reject(...args) { reject(...args); },
|
||||
};
|
||||
|
||||
send('1', ...args);
|
||||
}),
|
||||
// HttpClient in C# has its Moments, so lets give this way too long to do its thing
|
||||
ctx.authPromise = new TimedPromise(resolve, reject, () => ctx.authPromise = undefined, 10000);
|
||||
|
||||
send('1', ...args);
|
||||
});
|
||||
10000
|
||||
).finally(() => { ctx.authPromise = undefined; });
|
||||
};
|
||||
|
||||
const sendMessage = text => {
|
||||
|
@ -180,8 +192,7 @@ const SockChatClient = function(dispatch, options) {
|
|||
// server doesn't send a direct ACK and we can't tell what message
|
||||
// which response messages is actually associated with this
|
||||
// an ACK or request/response extension to the protocol will be required
|
||||
if(typeof resolve === 'function')
|
||||
resolve();
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -206,32 +217,43 @@ const SockChatClient = function(dispatch, options) {
|
|||
};
|
||||
|
||||
return {
|
||||
setDumpPackets: state => {
|
||||
dumpPackets = !!state;
|
||||
get dumpPackets() { return dumpPackets; },
|
||||
set dumpPackets(value) { dumpPackets = !!value; },
|
||||
|
||||
async open(url, timeout=5000) {
|
||||
return await MamiTimeout(
|
||||
new Promise((resolve, reject) => {
|
||||
if(typeof url !== 'string')
|
||||
throw 'url must be a string';
|
||||
if(ctx?.openPromise !== undefined)
|
||||
throw 'already opening a connection';
|
||||
|
||||
closeWebSocket();
|
||||
createContext();
|
||||
|
||||
ctx.openPromise = {
|
||||
resolve(...args) { resolve(...args); },
|
||||
reject(...args) { reject(...args); },
|
||||
};
|
||||
|
||||
sock = new WebSocket(url);
|
||||
sock.addEventListener('open', handleOpen);
|
||||
sock.addEventListener('close', handleClose);
|
||||
sock.addEventListener('message', handleMessage);
|
||||
}),
|
||||
timeout
|
||||
).finally(() => { ctx.openPromise = undefined; });
|
||||
},
|
||||
open: url => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(typeof url !== 'string')
|
||||
throw 'url must be a string';
|
||||
if(ctx?.openPromise !== undefined)
|
||||
throw 'already opening a connection';
|
||||
|
||||
closeWebSocket();
|
||||
createContext();
|
||||
|
||||
ctx.openPromise = new TimedPromise(resolve, reject, () => ctx.openPromise = undefined, 5000);
|
||||
|
||||
sock = new WebSocket(url);
|
||||
sock.addEventListener('open', handleOpen);
|
||||
sock.addEventListener('close', handleClose);
|
||||
sock.addEventListener('message', handleMessage);
|
||||
});
|
||||
close() {
|
||||
closeWebSocket();
|
||||
},
|
||||
close: () => { closeWebSocket(); },
|
||||
sendPing: sendPing,
|
||||
sendAuth: sendAuth,
|
||||
sendMessage: sendMessage,
|
||||
switchChannel: async info => {
|
||||
|
||||
sendPing,
|
||||
sendAuth,
|
||||
sendMessage,
|
||||
|
||||
async switchChannel(info) {
|
||||
if(!ctx.isAuthed)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include animate.js
|
||||
|
||||
const MamiSidebarPanelSettings = function(settings, msgBox) {
|
||||
const copyright = <div class="mami-copyright">
|
||||
<a href="//patchii.net/flashii/mami" target="_blank">Mami</a> # <a href={`//patchii.net/flashii/mami/commit/${window.GIT_HASH}`} target="_blank">{window.GIT_HASH.substring(0, 7)}</a> © <a href="//flash.moe" target="_blank">flash.moe</a><br/>
|
||||
|
@ -26,12 +28,11 @@ const MamiSidebarPanelSettings = function(settings, msgBox) {
|
|||
{body}
|
||||
</div>;
|
||||
|
||||
let animation;
|
||||
let animeAbort;
|
||||
header.onclick = () => {
|
||||
if(animation !== undefined) {
|
||||
animation.cancel();
|
||||
animation = undefined;
|
||||
}
|
||||
animeAbort?.abort();
|
||||
animeAbort = new AbortController;
|
||||
const signal = animeAbort.signal;
|
||||
|
||||
const closed = category.classList.contains('js-settings-closed');
|
||||
let start, update, end, height;
|
||||
|
@ -53,13 +54,13 @@ const MamiSidebarPanelSettings = function(settings, msgBox) {
|
|||
|
||||
category.classList.toggle('js-settings-closed', !closed);
|
||||
|
||||
animation = MamiAnimate({
|
||||
start();
|
||||
MamiAnimate({
|
||||
duration: 500,
|
||||
easing: 'outExpo',
|
||||
start: start,
|
||||
update: update,
|
||||
end: end,
|
||||
});
|
||||
signal,
|
||||
update,
|
||||
}).then(() => { end(); }).catch(ex => { });
|
||||
};
|
||||
|
||||
html.insertBefore(category, copyright);
|
||||
|
|
|
@ -113,7 +113,7 @@ const MamiSidebarPanelUploadsEntry = function(fileInfo) {
|
|||
const MamiSidebarPanelUploads = function() {
|
||||
const html = <div class="sidebar__menu--uploads"/>;
|
||||
const options = new Map;
|
||||
const entries = [];
|
||||
const entries = new Set;
|
||||
|
||||
const reloadOptionsFor = entry => {
|
||||
const names = entry.getOptionNames();
|
||||
|
@ -150,7 +150,7 @@ const MamiSidebarPanelUploads = function() {
|
|||
|
||||
createEntry: info => {
|
||||
const entry = new MamiSidebarPanelUploadsEntry(info);
|
||||
entries.push(entry);
|
||||
entries.add(entry);
|
||||
|
||||
reloadOptionsFor(entry);
|
||||
html.insertBefore(entry.element, html.firstElementChild);
|
||||
|
@ -158,11 +158,11 @@ const MamiSidebarPanelUploads = function() {
|
|||
return entry;
|
||||
},
|
||||
deleteEntry: entry => {
|
||||
if(!entries.includes(entry))
|
||||
if(!entries.has(entry))
|
||||
return;
|
||||
|
||||
html.removeChild(entry.element);
|
||||
$arrayRemoveValue(entries, entry);
|
||||
entries.delete(entry);
|
||||
},
|
||||
|
||||
addOption: option => {
|
||||
|
|
|
@ -61,7 +61,9 @@ const MamiSidebarPanelUsersEntry = function(info) {
|
|||
|
||||
setStatusMessage(statusMessage);
|
||||
|
||||
let optionsVisible = false, optionsAnim, optionsTimeout;
|
||||
let optionsVisible = false;
|
||||
let animeAbort;
|
||||
let optionsTimeout;
|
||||
const setOptionsVisible = state => {
|
||||
if(state === undefined)
|
||||
state = !optionsVisible;
|
||||
|
@ -73,10 +75,9 @@ const MamiSidebarPanelUsersEntry = function(info) {
|
|||
optionsTimeout = undefined;
|
||||
}
|
||||
|
||||
if(optionsAnim !== undefined) {
|
||||
optionsAnim.cancel();
|
||||
optionsAnim = undefined;
|
||||
}
|
||||
animeAbort?.abort();
|
||||
animeAbort = new AbortController;
|
||||
const signal = animeAbort.signal;
|
||||
|
||||
let start, update, end, height;
|
||||
|
||||
|
@ -94,7 +95,7 @@ const MamiSidebarPanelUsersEntry = function(info) {
|
|||
height = optsElem.clientHeight;
|
||||
optsElem.style.height = curHeight;
|
||||
};
|
||||
update = function(t) {
|
||||
update = t => {
|
||||
optsElem.style.height = `${height * t}px`;
|
||||
};
|
||||
end = () => {
|
||||
|
@ -113,19 +114,15 @@ const MamiSidebarPanelUsersEntry = function(info) {
|
|||
};
|
||||
}
|
||||
|
||||
optionsAnim = MamiAnimate({
|
||||
async: true,
|
||||
delayed: true,
|
||||
duration: 500,
|
||||
easing: 'outExpo',
|
||||
start: start,
|
||||
update: update,
|
||||
end: end,
|
||||
});
|
||||
|
||||
optionsVisible = state;
|
||||
|
||||
return optionsAnim.start();
|
||||
start();
|
||||
MamiAnimate({
|
||||
duration: 500,
|
||||
easing: 'outExpo',
|
||||
signal,
|
||||
update,
|
||||
}).then(() => { end(); }).catch(ex => { });
|
||||
};
|
||||
|
||||
let avatar;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include animate.js
|
||||
|
||||
const MamiSidebarGutterButton = function(name, info) {
|
||||
const html = <button type="button" class="sidebar__selector-mode" title={info.text ?? name}/>;
|
||||
const isBottom = info.pos === 'bottom';
|
||||
|
@ -126,7 +128,7 @@ const MamiSidebarPanelFrame = function() {
|
|||
const html = <div class="sidebar__menus"/>;
|
||||
const panels = new Map;
|
||||
let activePanel;
|
||||
let animation;
|
||||
let animeAbort;
|
||||
|
||||
const width = 220; // should probably not be hardcoded
|
||||
const isOpen = () => !html.classList.contains('js-menu-closed');
|
||||
|
@ -148,10 +150,9 @@ const MamiSidebarPanelFrame = function() {
|
|||
else if(isOpened === open)
|
||||
return;
|
||||
|
||||
if(animation !== undefined) {
|
||||
animation.cancel();
|
||||
animation = undefined;
|
||||
}
|
||||
animeAbort?.abort();
|
||||
animeAbort = new AbortController;
|
||||
const signal = animeAbort.signal;
|
||||
|
||||
html.classList.toggle('js-menu-closed', !open);
|
||||
html.dispatchEvent(new CustomEvent('mami:sidebar:toggle', {
|
||||
|
@ -162,31 +163,26 @@ const MamiSidebarPanelFrame = function() {
|
|||
? t => { html.style.width = `${width * t}px`; }
|
||||
: t => { html.style.width = `${width - (width * t)}px`; };
|
||||
|
||||
animation = MamiAnimate({
|
||||
async: true,
|
||||
delayed: true,
|
||||
html.style.width = null;
|
||||
html.style.overflowX = 'hidden';
|
||||
|
||||
if(activePanel !== undefined)
|
||||
activePanel.element.style.minWidth = `${width}px`;
|
||||
|
||||
MamiAnimate({
|
||||
duration: 500,
|
||||
easing: 'outExpo',
|
||||
start: () => {
|
||||
update,
|
||||
signal,
|
||||
}).then(() => {
|
||||
html.style.overflowX = null;
|
||||
|
||||
if(open)
|
||||
html.style.width = null;
|
||||
html.style.overflowX = 'hidden';
|
||||
|
||||
if(activePanel !== undefined)
|
||||
activePanel.element.style.minWidth = `${width}px`;
|
||||
},
|
||||
update: update,
|
||||
end: () => {
|
||||
html.style.overflowX = null;
|
||||
|
||||
if(open)
|
||||
html.style.width = null;
|
||||
|
||||
if(activePanel !== undefined)
|
||||
activePanel.element.style.minWidth = null;
|
||||
},
|
||||
});
|
||||
|
||||
return animation.start();
|
||||
if(activePanel !== undefined)
|
||||
activePanel.element.style.minWidth = null;
|
||||
}).catch(ex => { });
|
||||
},
|
||||
|
||||
getPanel: name => panels.get(name),
|
||||
|
|
|
@ -9,38 +9,36 @@ const MamiSockChat = function(eventTarget) {
|
|||
return {
|
||||
get client() { return client; },
|
||||
|
||||
get dumpPackets() { return dumpPackets; },
|
||||
set dumpPackets(value) {
|
||||
dumpPackets = !!value;
|
||||
if(client) client.dumpPackets = dumpPackets;
|
||||
},
|
||||
|
||||
watch: eventTarget.watch,
|
||||
unwatch: eventTarget.unwatch,
|
||||
|
||||
create: async () => {
|
||||
if(client !== undefined && typeof client.close === 'function')
|
||||
// intentional fire & forget, worker may be gone, don't want to wait for it to time out
|
||||
client.close();
|
||||
async create() {
|
||||
if(client) client.close();
|
||||
|
||||
restarting = false;
|
||||
client = new SockChatClient(eventTarget.dispatch, { ping: 30 });
|
||||
client.setDumpPackets(dumpPackets);
|
||||
client.dumpPackets = dumpPackets;
|
||||
|
||||
MamiCompat('Umi.Server', { get: () => client, configurable: true });
|
||||
MamiCompat('Umi.Server.SendMessage', { value: text => client.sendMessage(text), configurable: true });
|
||||
MamiCompat('Umi.Protocol.SockChat.Protocol.Instance.SendMessage', { value: text => client.sendMessage(text), configurable: true });
|
||||
MamiCompat('Umi.Protocol.SockLegacy.Protocol.Instance.SendMessage', { value: text => client.sendMessage(text), configurable: true });
|
||||
},
|
||||
connect: async url => {
|
||||
async connect(url) {
|
||||
try {
|
||||
await client.open(url);
|
||||
} catch(ex) {
|
||||
return ex.wasKicked === true;
|
||||
}
|
||||
},
|
||||
authenticate: async auth => {
|
||||
async authenticate(auth) {
|
||||
await client.sendAuth(auth.type, auth.token);
|
||||
},
|
||||
setDumpPackets: state => {
|
||||
dumpPackets = !!state;
|
||||
|
||||
if(client !== undefined && typeof client.setDumpPackets === 'function')
|
||||
client.setDumpPackets(dumpPackets);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include animate.js
|
||||
#include awaitable.js
|
||||
|
||||
const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
|
||||
|
@ -18,7 +19,7 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
|
|||
const detuneSetting = settings.info('soundDetune');
|
||||
const loopStartSetting = settings.info('soundLoopStart');
|
||||
const loopEndSetting = settings.info('soundLoopEnd');
|
||||
const sources = [];
|
||||
const sources = new Set;
|
||||
|
||||
let libraryButtons;
|
||||
let nowPlaying;
|
||||
|
@ -107,7 +108,7 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
|
|||
name.textContent += ` (${buffer.duration})`;
|
||||
|
||||
source = audio.createSource(buffer, settings.get('soundReverse'));
|
||||
sources.push(source);
|
||||
sources.add(source);
|
||||
|
||||
state.textContent = 'Configuring...';
|
||||
const rate = settings.get('soundRate');
|
||||
|
@ -130,7 +131,7 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
|
|||
console.error(ex);
|
||||
state.textContent = `Error: ${ex}`;
|
||||
} finally {
|
||||
$arrayRemoveValue(sources, source);
|
||||
sources.delete(source);
|
||||
await MamiSleep(2000);
|
||||
nowPlaying.removeChild(player);
|
||||
}
|
||||
|
@ -149,45 +150,48 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
|
|||
|
||||
return {
|
||||
get element() { return container; },
|
||||
onViewPop: async () => {
|
||||
async onViewPop() {
|
||||
for(const source of sources)
|
||||
source.stop();
|
||||
},
|
||||
getViewTransition: mode => {
|
||||
getViewTransition(mode) {
|
||||
if(!hasClickPos)
|
||||
return;
|
||||
|
||||
if(mode === 'push')
|
||||
return ctx => MamiAnimate({
|
||||
async: true,
|
||||
duration: 1500,
|
||||
easing: 'inQuad',
|
||||
start: () => {
|
||||
library.play('mario:keyhole');
|
||||
ctx.toElem.style.transform = 'scale(0) translate(25%, 25%)';
|
||||
ctx.toElem.style.transformOrigin = `${clickPos[0]}px ${clickPos[1]}px`;
|
||||
},
|
||||
update: (t, rt) => ctx.toElem.style.transform = `scale(${t}) translate(${25 * (1 - rt)}%, ${25 * (1 - rt)}%)`,
|
||||
end: () => {
|
||||
ctx.toElem.style.transform = null;
|
||||
ctx.toElem.style.transformOrigin = null;
|
||||
},
|
||||
});
|
||||
return async ({ toElem }) => {
|
||||
library.play('mario:keyhole');
|
||||
|
||||
toElem.style.transform = 'scale(0) translate(25%, 25%)';
|
||||
toElem.style.transformOrigin = `${clickPos[0]}px ${clickPos[1]}px`;
|
||||
|
||||
await MamiAnimate({
|
||||
duration: 1500,
|
||||
easing: 'inQuad',
|
||||
update(t, rt) {
|
||||
toElem.style.transform = `scale(${t}) translate(${25 * (1 - rt)}%, ${25 * (1 - rt)}%)`;
|
||||
},
|
||||
});
|
||||
|
||||
toElem.style.transform = null;
|
||||
toElem.style.transformOrigin = null;
|
||||
};
|
||||
|
||||
if(mode === 'pop')
|
||||
return ctx => MamiAnimate({
|
||||
async: true,
|
||||
duration: 1000,
|
||||
easing: 'outQuad',
|
||||
start: () => {
|
||||
ctx.fromElem.style.transformOrigin = `${clickPos[0]}px ${clickPos[1]}px`;
|
||||
},
|
||||
update: (t, rt) => ctx.fromElem.style.transform = `scale(${1 - t}) rotate(${-1080 * t}deg) translate(${50 * rt}%, ${50 * rt}%)`,
|
||||
end: () => {
|
||||
ctx.fromElem.style.transform = null;
|
||||
ctx.fromElem.style.transformOrigin = null;
|
||||
},
|
||||
});
|
||||
return async ({ fromElem }) => {
|
||||
fromElem.style.transformOrigin = `${clickPos[0]}px ${clickPos[1]}px`;
|
||||
|
||||
await MamiAnimate({
|
||||
duration: 1000,
|
||||
easing: 'outQuad',
|
||||
update(t, rt) {
|
||||
fromElem.style.transform = `scale(${1 - t}) rotate(${-1080 * t}deg) translate(${50 * rt}%, ${50 * rt}%)`;
|
||||
},
|
||||
})
|
||||
|
||||
fromElem.style.transform = null;
|
||||
fromElem.style.transformOrigin = null;
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
const MamiSRLE = (() => {
|
||||
return {
|
||||
encode: (input, cutoff) => {
|
||||
let output = '';
|
||||
let last = '';
|
||||
let repeat = 0;
|
||||
|
||||
input = (input || '').toString();
|
||||
cutoff = cutoff || 1
|
||||
|
||||
for(let i = 0; i <= input.length; ++i) {
|
||||
const chr = input[i];
|
||||
|
||||
if(last === chr)
|
||||
++repeat;
|
||||
else {
|
||||
if(repeat > cutoff)
|
||||
for(const repChr in repeat.toString())
|
||||
output += ')!@#$%^&*('[parseInt(repChr)];
|
||||
else
|
||||
output += last.repeat(repeat);
|
||||
|
||||
repeat = 0;
|
||||
|
||||
if(chr !== undefined) {
|
||||
output += chr;
|
||||
last = chr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
|
||||
decode: input => {
|
||||
let output = '';
|
||||
let repeat = '';
|
||||
let chr;
|
||||
|
||||
input = (input || '').toString().split('').reverse();
|
||||
|
||||
for(;;) {
|
||||
const chr = input.pop(), num = ')!@#$%^&*('.indexOf(chr);
|
||||
|
||||
if(num >= 0)
|
||||
repeat += num;
|
||||
else {
|
||||
if(repeat) {
|
||||
output += output.slice(-1).repeat(parseInt(repeat));
|
||||
repeat = '';
|
||||
}
|
||||
|
||||
if(chr === undefined)
|
||||
break;
|
||||
|
||||
output += chr;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
};
|
||||
})();
|
|
@ -1,48 +0,0 @@
|
|||
const TimedPromise = function(resolve, reject, always, timeoutMs) {
|
||||
let timeout, resolved = false;
|
||||
|
||||
const cancelTimeout = () => {
|
||||
if(timeout === undefined) {
|
||||
clearTimeout(timeout);
|
||||
timeout = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const doResolve = (...args) => {
|
||||
if(resolved) return;
|
||||
resolved = true;
|
||||
|
||||
cancelTimeout();
|
||||
reject = undefined;
|
||||
|
||||
if(typeof resolve === 'function')
|
||||
resolve(...args);
|
||||
if(typeof always === 'function')
|
||||
always();
|
||||
};
|
||||
|
||||
const doReject = (...args) => {
|
||||
if(resolved) return;
|
||||
resolved = true;
|
||||
|
||||
cancelTimeout();
|
||||
resolve = undefined;
|
||||
|
||||
if(typeof reject === 'function')
|
||||
reject(...args);
|
||||
if(typeof always === 'function')
|
||||
always();
|
||||
};
|
||||
|
||||
timeout = setTimeout(() => doReject('timeout'), timeoutMs);
|
||||
|
||||
return {
|
||||
resolve: doResolve,
|
||||
reject: doReject,
|
||||
cancel: () => {
|
||||
if(timeout === undefined)
|
||||
return;
|
||||
doReject('timeout');
|
||||
},
|
||||
};
|
||||
};
|
|
@ -1,27 +1,40 @@
|
|||
#include args.js
|
||||
const MamiWindowTitle = function({
|
||||
getName=()=>{},
|
||||
setTitle=text=> { document.title = text },
|
||||
strobeInterval=500,
|
||||
strobeRepeat=5,
|
||||
}) {
|
||||
if(typeof getName !== 'function')
|
||||
throw new Error('getName argument must be a function');
|
||||
if(typeof setTitle !== 'function')
|
||||
throw new Error('setTitle argument must be a function');
|
||||
|
||||
const MamiWindowTitle = function(options) {
|
||||
options = MamiArgs('options', options, define => {
|
||||
define('getName').default(() => {}).done();
|
||||
define('setTitle').default(text => { document.title = text; }).done();
|
||||
define('strobeInterval').constraint(value => typeof value === 'number' || typeof value === 'function').default(500).done();
|
||||
define('strobeRepeat').constraint(value => typeof value === 'number' || typeof value === 'function').default(5).done();
|
||||
});
|
||||
|
||||
const getName = options.getName;
|
||||
|
||||
const setTitleImpl = options.setTitle;
|
||||
const setTitle = text => {
|
||||
const setTitleWrap = text => {
|
||||
if(text === undefined || text === null)
|
||||
text = '';
|
||||
else if(typeof text !== 'string')
|
||||
text = text.toString();
|
||||
|
||||
setTitleImpl(text);
|
||||
setTitle(text);
|
||||
};
|
||||
|
||||
const defaultStrobeInterval = typeof options.strobeInterval === 'function' ? options.strobeInterval : () => options.strobeInterval;
|
||||
const defaultStrobeRepeat = typeof options.strobeRepeat === 'function' ? options.strobeRepeat : () => options.strobeRepeat;
|
||||
const getStrobeInverval = () => {
|
||||
let value = strobeInterval;
|
||||
if(typeof value === 'function')
|
||||
value = value();
|
||||
if(typeof value !== 'number' || value < 1)
|
||||
return 500;
|
||||
return value;
|
||||
};
|
||||
|
||||
const getStrobeRepeat = () => {
|
||||
let value = strobeRepeat;
|
||||
if(typeof value === 'function')
|
||||
value = value();
|
||||
if(typeof value !== 'number' || value < 1)
|
||||
return 5;
|
||||
return value;
|
||||
};
|
||||
|
||||
let activeStrobe;
|
||||
|
||||
|
@ -32,7 +45,7 @@ const MamiWindowTitle = function(options) {
|
|||
clearInterval(activeStrobe);
|
||||
activeStrobe = undefined;
|
||||
|
||||
setTitle(getName());
|
||||
setTitleWrap(getName());
|
||||
};
|
||||
|
||||
const strobeTitle = (titles, interval, repeat) => {
|
||||
|
@ -41,30 +54,30 @@ const MamiWindowTitle = function(options) {
|
|||
if(titles.length < 1)
|
||||
throw 'titles must contain at least one item';
|
||||
if(typeof interval !== 'number')
|
||||
interval = defaultStrobeInterval();
|
||||
interval = getStrobeInverval();
|
||||
if(typeof repeat !== 'number')
|
||||
repeat = defaultStrobeRepeat();
|
||||
repeat = getStrobeRepeat();
|
||||
|
||||
const target = titles.length * repeat;
|
||||
let round = 0;
|
||||
|
||||
clearTitle();
|
||||
setTitle(titles[0]);
|
||||
setTitleWrap(titles[0]);
|
||||
|
||||
activeStrobe = setInterval(() => {
|
||||
if(round >= target) {
|
||||
clearTitle();
|
||||
setTitle(getName());
|
||||
setTitleWrap(getName());
|
||||
return;
|
||||
}
|
||||
|
||||
++round;
|
||||
setTitle(titles[round % titles.length]);
|
||||
setTitleWrap(titles[round % titles.length]);
|
||||
}, interval);
|
||||
};
|
||||
|
||||
return {
|
||||
set: setTitle,
|
||||
set: setTitleWrap,
|
||||
clear: clearTitle,
|
||||
strobe: strobeTitle,
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include animate.js
|
||||
#include controls/throbber.jsx
|
||||
|
||||
Umi.UI.LoadingOverlay = function(icon, message) {
|
||||
|
@ -37,19 +38,19 @@ Umi.UI.LoadingOverlay = function(icon, message) {
|
|||
|
||||
getViewTransition(mode) {
|
||||
if(mode === 'pop')
|
||||
return ctx => MamiAnimate({
|
||||
async: true,
|
||||
duration: 200,
|
||||
easing: 'inQuint',
|
||||
start: () => {
|
||||
html.classList.remove('overlay-filter');
|
||||
html.style.pointerEvents = 'none';
|
||||
},
|
||||
update: t => {
|
||||
wrapper.style.bottom = `${0 - (104 * t)}px`;
|
||||
wrapper.style.opacity = 1 - (1 * t).toString();
|
||||
},
|
||||
});
|
||||
return async () => {
|
||||
html.classList.remove('overlay-filter');
|
||||
html.style.pointerEvents = 'none';
|
||||
|
||||
await MamiAnimate({
|
||||
duration: 200,
|
||||
easing: 'inQuint',
|
||||
update(t) {
|
||||
wrapper.style.bottom = `${0 - (104 * t)}px`;
|
||||
wrapper.style.opacity = 1 - (1 * t).toString();
|
||||
},
|
||||
});
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include parsing.js
|
||||
#include title.js
|
||||
#include txtrigs.js
|
||||
#include url.js
|
||||
#include users.js
|
||||
#include weeb.js
|
||||
#include sound/umisound.js
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
const $rngi = (min, max) => {
|
||||
let ret = 0;
|
||||
const range = max - min;
|
||||
|
||||
const bitsNeeded = Math.ceil(Math.log2(range));
|
||||
if(bitsNeeded > 53)
|
||||
return -1;
|
||||
|
||||
const bytesNeeded = Math.ceil(bitsNeeded / 8),
|
||||
mask = Math.pow(2, bitsNeeded) - 1;
|
||||
|
||||
const bytes = new Uint8Array(bytesNeeded);
|
||||
crypto.getRandomValues(bytes);
|
||||
|
||||
let p = (bytesNeeded - 1) * 8;
|
||||
for(let i = 0; i < bytesNeeded; ++i) {
|
||||
ret += bytes[i] * Math.pow(2, p);
|
||||
p -= 8;
|
||||
}
|
||||
|
||||
ret &= mask;
|
||||
|
||||
if(ret >= range)
|
||||
return $rngi(min, max);
|
||||
|
||||
return min + ret;
|
||||
};
|
||||
|
||||
const $rngs = (() => {
|
||||
const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789';
|
||||
|
||||
return length => {
|
||||
let str = '';
|
||||
for(let i = 0; i < length; ++i)
|
||||
str += chars[$rngi(0, chars.length)];
|
||||
return str;
|
||||
};
|
||||
})();
|
|
@ -1,53 +0,0 @@
|
|||
const MamiUriBase64 = (() => {
|
||||
const public = {};
|
||||
|
||||
const textEncoder = new TextEncoder('utf-8');
|
||||
const textDecoder = new TextDecoder('utf-8');
|
||||
|
||||
if(typeof Uint8Array.prototype.toBase64 === 'function')
|
||||
public.encode = data => {
|
||||
if(typeof data === 'string')
|
||||
data = textEncoder.encode(data);
|
||||
else if(!(data instanceof Uint8Array))
|
||||
throw 'data must be a string or a Uint8Array';
|
||||
|
||||
return data.toBase64({
|
||||
alphabet: 'base64url',
|
||||
omitPadding: true,
|
||||
});
|
||||
};
|
||||
else // toBase64 is very new, compatible impl
|
||||
public.encode = data => {
|
||||
if(typeof data === 'string')
|
||||
data = textEncoder.encode(data);
|
||||
else if(!(data instanceof Uint8Array))
|
||||
throw 'data must be a string or a Uint8Array';
|
||||
|
||||
return btoa(Array.from(data, byte => String.fromCodePoint(byte)).join(''))
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=+$/, '');
|
||||
};
|
||||
|
||||
if(typeof Uint8Array.fromBase64 === 'function')
|
||||
public.decode = (data, asString=false) => {
|
||||
if(typeof data !== 'string')
|
||||
throw 'data must be string';
|
||||
|
||||
const buffer = Uint8Array.fromBase64(data, {
|
||||
alphabet: 'base64url',
|
||||
});
|
||||
|
||||
return asString ? textDecoder.decode(buffer) : buffer;
|
||||
};
|
||||
else // fromBase64 is very new, compatible impl
|
||||
public.decode = (data, asString=false) => {
|
||||
if(typeof data !== 'string')
|
||||
throw 'data must be string';
|
||||
|
||||
const buffer = Uint8Array.from(atob(data), str => str.codePointAt(0));
|
||||
return asString ? textDecoder.decode(buffer) : buffer;
|
||||
};
|
||||
|
||||
return public;
|
||||
})();
|
|
@ -1,22 +0,0 @@
|
|||
Umi.URI = (function() {
|
||||
const regex = new RegExp("([A-Za-z][A-Za-z0-9+\\-.]*):(?:(//)(?:((?:[A-Za-z0-9\\-._~!$&'()*+,;=:]|%[0-9A-Fa-f]{2})*)@)?((?:\\[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|::(?:[0-9A-Fa-f]{1,4}:){5}|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|[Vv][0-9A-Fa-f]+\\.[A-Za-z0-9\\-._~!$&'()*+,;=:]+)\\]|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[A-Za-z0-9\\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*))(?::([0-9]*))?((?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)|/((?:(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)?)|((?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)|)(?:\\?((?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*))?(?:\\#((?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*))?");
|
||||
|
||||
return {
|
||||
Parse: function(url) {
|
||||
const match = url.match(regex);
|
||||
if(match === null)
|
||||
return null;
|
||||
|
||||
return {
|
||||
Protocol: match[1] || null,
|
||||
Slashes: match[2] || null,
|
||||
Authority: match[3] || null,
|
||||
Host: match[4] || null,
|
||||
Port: match[5] || null,
|
||||
Path: match[6] || match[7] || match[8] || null,
|
||||
Query: match[9] || null,
|
||||
Hash: match[10] || null,
|
||||
};
|
||||
},
|
||||
};
|
||||
})();
|
|
@ -1,48 +1,51 @@
|
|||
const $xhr = (function() {
|
||||
const send = function(method, url, options, body) {
|
||||
if(options === undefined)
|
||||
options = {};
|
||||
else if(typeof options !== 'object')
|
||||
throw 'options must be undefined or an object';
|
||||
|
||||
Object.freeze(options);
|
||||
const methods = ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'];
|
||||
|
||||
const send = function(
|
||||
method,
|
||||
url,
|
||||
{
|
||||
authed=false,
|
||||
download=null,
|
||||
headers=null,
|
||||
signal=null,
|
||||
timeout=null,
|
||||
type=null,
|
||||
upload=null,
|
||||
}={},
|
||||
body=null
|
||||
) {
|
||||
const xhr = new XMLHttpRequest;
|
||||
const requestHeaders = new Map;
|
||||
|
||||
if('headers' in options && typeof options.headers === 'object')
|
||||
for(const name in options.headers)
|
||||
if(options.headers.hasOwnProperty(name))
|
||||
requestHeaders.set(name.toLowerCase(), options.headers[name]);
|
||||
if(signal instanceof AbortSignal)
|
||||
signal.onabort = () => { xhr.abort(); };
|
||||
|
||||
if(typeof options.download === 'function') {
|
||||
xhr.onloadstart = ev => options.download(ev);
|
||||
xhr.onprogress = ev => options.download(ev);
|
||||
xhr.onloadend = ev => options.download(ev);
|
||||
if(typeof headers === 'object')
|
||||
for(const name in headers)
|
||||
if(headers.hasOwnProperty(name))
|
||||
requestHeaders.set(name.toLowerCase(), headers[name]);
|
||||
|
||||
if(typeof download === 'function') {
|
||||
xhr.onloadstart = ev => { download(ev); };
|
||||
xhr.onprogress = ev => { download(ev); };
|
||||
xhr.onloadend = ev => { download(ev); };
|
||||
}
|
||||
|
||||
if(typeof options.upload === 'function') {
|
||||
xhr.upload.onloadstart = ev => options.upload(ev);
|
||||
xhr.upload.onprogress = ev => options.upload(ev);
|
||||
xhr.upload.onloadend = ev => options.upload(ev);
|
||||
if(typeof upload === 'function') {
|
||||
xhr.upload.onloadstart = ev => { upload(ev); };
|
||||
xhr.upload.onprogress = ev => { upload(ev); };
|
||||
xhr.upload.onloadend = ev => { upload(ev); };
|
||||
}
|
||||
|
||||
if(options.authed)
|
||||
xhr.withCredentials = true;
|
||||
if(authed !== null)
|
||||
xhr.withCredentials = authed;
|
||||
if(timeout !== null)
|
||||
xhr.timeout = timeout;
|
||||
if(type !== null)
|
||||
xhr.responseType = type;
|
||||
|
||||
if(typeof options.timeout === 'number')
|
||||
xhr.timeout = options.timeout;
|
||||
|
||||
if(typeof options.type === 'string')
|
||||
xhr.responseType = options.type;
|
||||
|
||||
if(typeof options.abort === 'function')
|
||||
options.abort(() => xhr.abort());
|
||||
|
||||
if(typeof options.xhr === 'function')
|
||||
options.xhr(() => xhr);
|
||||
|
||||
if(typeof body === 'object') {
|
||||
if(typeof body === 'object' && body !== null) {
|
||||
if(body instanceof URLSearchParams) {
|
||||
requestHeaders.set('content-type', 'application/x-www-form-urlencoded');
|
||||
} else if(body instanceof FormData) {
|
||||
|
@ -87,17 +90,19 @@ const $xhr = (function() {
|
|||
});
|
||||
};
|
||||
|
||||
xhr.onabort = ev => reject({
|
||||
abort: true,
|
||||
xhr: xhr,
|
||||
ev: ev,
|
||||
});
|
||||
xhr.onabort = ev => {
|
||||
reject({
|
||||
aborted: true,
|
||||
ev,
|
||||
});
|
||||
};
|
||||
|
||||
xhr.onerror = ev => reject({
|
||||
abort: false,
|
||||
xhr: xhr,
|
||||
ev: ev,
|
||||
});
|
||||
xhr.onerror = ev => {
|
||||
reject({
|
||||
aborted: false,
|
||||
ev,
|
||||
});
|
||||
};
|
||||
|
||||
xhr.open(method, url);
|
||||
for(const [name, value] of requestHeaders)
|
||||
|
@ -106,12 +111,9 @@ const $xhr = (function() {
|
|||
});
|
||||
};
|
||||
|
||||
return {
|
||||
send: send,
|
||||
get: (url, options, body) => send('GET', url, options, body),
|
||||
post: (url, options, body) => send('POST', url, options, body),
|
||||
delete: (url, options, body) => send('DELETE', url, options, body),
|
||||
patch: (url, options, body) => send('PATCH', url, options, body),
|
||||
put: (url, options, body) => send('PUT', url, options, body),
|
||||
};
|
||||
const pub = { send };
|
||||
for(const method of methods)
|
||||
pub[method.toLowerCase()] = (...args) => send(method, ...args);
|
||||
|
||||
return pub;
|
||||
})();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue