Compare commits
3 Commits
5c7379b010
...
fb8b1325be
Author | SHA1 | Date |
---|---|---|
SArpnt | fb8b1325be | |
SArpnt | 40e1eccddd | |
SArpnt | 2066466bec |
|
@ -20,16 +20,16 @@
|
|||
'@codemirror/state': '^0.19.9',
|
||||
'@codemirror/view': '^0.19.48',
|
||||
'@jamshop/eleventy-plugin-esbuild': '^1.0.2',
|
||||
'@prettier/plugin-pug': '^3.0.0',
|
||||
//'@stdlib/constants-float32-eps': '^0.1.1',
|
||||
fflate: '^0.8.1',
|
||||
fflate: '^0.8.2',
|
||||
'html-minifier': '^4.0.0',
|
||||
minimatch: '^9.0.3',
|
||||
'ts-essentials': '^9.4.1',
|
||||
xxhash: '^0.3.0',
|
||||
},
|
||||
devDependencies: {
|
||||
prettier: '^3.1.1',
|
||||
typescript: '^5.3.3',
|
||||
'@prettier/plugin-pug': '^3.0.0',
|
||||
prettier: '^3.2.5',
|
||||
typescript: '^5.4.2',
|
||||
},
|
||||
}
|
||||
|
|
210
pnpm-lock.yaml
210
pnpm-lock.yaml
|
@ -47,12 +47,9 @@ dependencies:
|
|||
'@jamshop/eleventy-plugin-esbuild':
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
'@prettier/plugin-pug':
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(prettier@3.1.1)
|
||||
fflate:
|
||||
specifier: ^0.8.1
|
||||
version: 0.8.1
|
||||
specifier: ^0.8.2
|
||||
version: 0.8.2
|
||||
html-minifier:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
|
@ -61,18 +58,21 @@ dependencies:
|
|||
version: 9.0.3
|
||||
ts-essentials:
|
||||
specifier: ^9.4.1
|
||||
version: 9.4.1(typescript@5.3.3)
|
||||
version: 9.4.1(typescript@5.4.2)
|
||||
xxhash:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0
|
||||
|
||||
devDependencies:
|
||||
'@prettier/plugin-pug':
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(prettier@3.2.5)
|
||||
prettier:
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1
|
||||
specifier: ^3.2.5
|
||||
version: 3.2.5
|
||||
typescript:
|
||||
specifier: ^5.3.3
|
||||
version: 5.3.3
|
||||
specifier: ^5.4.2
|
||||
version: 5.4.2
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -86,13 +86,13 @@ packages:
|
|||
hasBin: true
|
||||
dependencies:
|
||||
'@11ty/eleventy-utils': 1.0.2
|
||||
chokidar: 3.5.3
|
||||
chokidar: 3.6.0
|
||||
debug: 4.3.4
|
||||
dev-ip: 1.0.1
|
||||
finalhandler: 1.2.0
|
||||
mime: 3.0.0
|
||||
minimist: 1.2.8
|
||||
morphdom: 2.7.1
|
||||
morphdom: 2.7.2
|
||||
please-upgrade-node: 3.2.0
|
||||
ssri: 8.0.1
|
||||
ws: 8.16.0
|
||||
|
@ -121,7 +121,7 @@ packages:
|
|||
'@iarna/toml': 2.2.5
|
||||
'@sindresorhus/slugify': 1.1.2
|
||||
bcp-47-normalize: 1.1.1
|
||||
chokidar: 3.5.3
|
||||
chokidar: 3.6.0
|
||||
cross-spawn: 7.0.3
|
||||
debug: 4.3.4
|
||||
dependency-graph: 0.11.0
|
||||
|
@ -134,7 +134,7 @@ packages:
|
|||
is-glob: 4.0.3
|
||||
iso-639-1: 2.1.15
|
||||
kleur: 4.1.5
|
||||
liquidjs: 10.10.0
|
||||
liquidjs: 10.10.1
|
||||
luxon: 3.4.4
|
||||
markdown-it: 13.0.2
|
||||
micromatch: 4.0.5
|
||||
|
@ -143,14 +143,14 @@ packages:
|
|||
multimatch: 5.0.0
|
||||
mustache: 4.2.0
|
||||
normalize-path: 3.0.0
|
||||
nunjucks: 3.2.4(chokidar@3.5.3)
|
||||
nunjucks: 3.2.4(chokidar@3.6.0)
|
||||
path-to-regexp: 6.2.1
|
||||
please-upgrade-node: 3.2.0
|
||||
posthtml: 0.16.6
|
||||
posthtml-urls: 1.0.0
|
||||
pug: 3.0.2
|
||||
recursive-copy: 2.0.14
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
slugify: 1.6.6
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
|
@ -173,16 +173,16 @@ packages:
|
|||
engines: {node: '>=6.9.0'}
|
||||
dev: false
|
||||
|
||||
/@babel/parser@7.23.6:
|
||||
resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==}
|
||||
/@babel/parser@7.24.0:
|
||||
resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.23.6
|
||||
'@babel/types': 7.24.0
|
||||
dev: false
|
||||
|
||||
/@babel/types@7.23.6:
|
||||
resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==}
|
||||
/@babel/types@7.24.0:
|
||||
resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.23.4
|
||||
|
@ -250,7 +250,7 @@ packages:
|
|||
'@codemirror/state': 0.19.9
|
||||
'@codemirror/view': 0.19.48
|
||||
'@lezer/common': 0.15.12
|
||||
style-mod: 4.1.0
|
||||
style-mod: 4.1.2
|
||||
dev: false
|
||||
|
||||
/@codemirror/history@0.19.2:
|
||||
|
@ -365,7 +365,7 @@ packages:
|
|||
'@codemirror/rangeset': 0.19.9
|
||||
'@codemirror/state': 0.19.9
|
||||
'@codemirror/text': 0.19.6
|
||||
style-mod: 4.1.0
|
||||
style-mod: 4.1.2
|
||||
w3c-keyname: 2.2.8
|
||||
dev: false
|
||||
|
||||
|
@ -413,18 +413,18 @@ packages:
|
|||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.16.0
|
||||
fastq: 1.17.1
|
||||
dev: false
|
||||
|
||||
/@prettier/plugin-pug@3.0.0(prettier@3.1.1):
|
||||
/@prettier/plugin-pug@3.0.0(prettier@3.2.5):
|
||||
resolution: {integrity: sha512-ERMMvGSJK/7CTc8OT7W/dtlV43sytyNeiCWckN0DIFepqwXotU0+coKMv5Wx6IWSNj7ZSjdNGBAA1nMPi388xw==}
|
||||
engines: {node: ^16.13.0 || >=18.0.0, npm: '>=7.10.0'}
|
||||
peerDependencies:
|
||||
prettier: ^3.0.0
|
||||
dependencies:
|
||||
prettier: 3.1.1
|
||||
prettier: 3.2.5
|
||||
pug-lexer: 5.0.1
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/@sindresorhus/slugify@1.1.2:
|
||||
resolution: {integrity: sha512-V9nR/W0Xd9TSGXpZ4iFUcFGhuOJtZX82Fzxj1YISlbSgKvIiNa7eLEZrT0vAraPOt++KHauIVNYgGRgjc13dXA==}
|
||||
|
@ -454,7 +454,6 @@ packages:
|
|||
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
|
@ -538,7 +537,7 @@ packages:
|
|||
resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.23.6
|
||||
'@babel/types': 7.24.0
|
||||
dev: false
|
||||
|
||||
/balanced-match@1.0.2:
|
||||
|
@ -589,13 +588,15 @@ packages:
|
|||
fill-range: 7.0.1
|
||||
dev: false
|
||||
|
||||
/call-bind@1.0.5:
|
||||
resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==}
|
||||
/call-bind@1.0.7:
|
||||
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
es-define-property: 1.0.0
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
get-intrinsic: 1.2.2
|
||||
set-function-length: 1.1.1
|
||||
dev: false
|
||||
get-intrinsic: 1.2.4
|
||||
set-function-length: 1.2.2
|
||||
|
||||
/camel-case@3.0.0:
|
||||
resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==}
|
||||
|
@ -616,10 +617,9 @@ packages:
|
|||
resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==}
|
||||
dependencies:
|
||||
is-regex: 1.1.4
|
||||
dev: false
|
||||
|
||||
/chokidar@3.5.3:
|
||||
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
|
||||
/chokidar@3.6.0:
|
||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||
engines: {node: '>= 8.10.0'}
|
||||
dependencies:
|
||||
anymatch: 3.1.3
|
||||
|
@ -672,8 +672,8 @@ packages:
|
|||
/constantinople@4.0.1:
|
||||
resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.23.6
|
||||
'@babel/types': 7.23.6
|
||||
'@babel/parser': 7.24.0
|
||||
'@babel/types': 7.24.0
|
||||
dev: false
|
||||
|
||||
/crelt@1.0.6:
|
||||
|
@ -712,14 +712,13 @@ packages:
|
|||
ms: 2.1.2
|
||||
dev: false
|
||||
|
||||
/define-data-property@1.1.1:
|
||||
resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==}
|
||||
/define-data-property@1.1.4:
|
||||
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.2
|
||||
es-define-property: 1.0.0
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.0.1
|
||||
has-property-descriptors: 1.0.1
|
||||
dev: false
|
||||
|
||||
/dependency-graph@0.11.0:
|
||||
resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==}
|
||||
|
@ -796,6 +795,16 @@ packages:
|
|||
prr: 1.0.1
|
||||
dev: false
|
||||
|
||||
/es-define-property@1.0.0:
|
||||
resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.4
|
||||
|
||||
/es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
/esbuild@0.7.22:
|
||||
resolution: {integrity: sha512-B43SYg8LGWYTCv9Gs0RnuLNwjzpuWOoCaZHTWEDEf5AfrnuDMerPVMdCEu7xOdhFvQ+UqfP2MGU9lxEy0JzccA==}
|
||||
hasBin: true
|
||||
|
@ -840,14 +849,14 @@ packages:
|
|||
micromatch: 4.0.5
|
||||
dev: false
|
||||
|
||||
/fastq@1.16.0:
|
||||
resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==}
|
||||
/fastq@1.17.1:
|
||||
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
|
||||
dependencies:
|
||||
reusify: 1.0.4
|
||||
dev: false
|
||||
|
||||
/fflate@0.8.1:
|
||||
resolution: {integrity: sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==}
|
||||
/fflate@0.8.2:
|
||||
resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
|
||||
dev: false
|
||||
|
||||
/filelist@1.0.4:
|
||||
|
@ -892,16 +901,16 @@ packages:
|
|||
|
||||
/function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
dev: false
|
||||
|
||||
/get-intrinsic@1.2.2:
|
||||
resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==}
|
||||
/get-intrinsic@1.2.4:
|
||||
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
has-proto: 1.0.1
|
||||
has-proto: 1.0.3
|
||||
has-symbols: 1.0.3
|
||||
hasown: 2.0.0
|
||||
dev: false
|
||||
hasown: 2.0.2
|
||||
|
||||
/glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
|
@ -924,8 +933,7 @@ packages:
|
|||
/gopd@1.0.1:
|
||||
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.2
|
||||
dev: false
|
||||
get-intrinsic: 1.2.4
|
||||
|
||||
/graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
@ -963,35 +971,30 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/has-property-descriptors@1.0.1:
|
||||
resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==}
|
||||
/has-property-descriptors@1.0.2:
|
||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.2
|
||||
dev: false
|
||||
es-define-property: 1.0.0
|
||||
|
||||
/has-proto@1.0.1:
|
||||
resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
|
||||
/has-proto@1.0.3:
|
||||
resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: false
|
||||
|
||||
/has-symbols@1.0.3:
|
||||
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: false
|
||||
|
||||
/has-tostringtag@1.0.0:
|
||||
resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
|
||||
/has-tostringtag@1.0.2:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
has-symbols: 1.0.3
|
||||
dev: false
|
||||
|
||||
/hasown@2.0.0:
|
||||
resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==}
|
||||
/hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
dev: false
|
||||
|
||||
/he@1.2.0:
|
||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||
|
@ -1058,7 +1061,7 @@ packages:
|
|||
/is-core-module@2.13.1:
|
||||
resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
|
||||
dependencies:
|
||||
hasown: 2.0.0
|
||||
hasown: 2.0.2
|
||||
dev: false
|
||||
|
||||
/is-decimal@1.0.4:
|
||||
|
@ -1070,7 +1073,6 @@ packages:
|
|||
dependencies:
|
||||
acorn: 7.4.1
|
||||
object-assign: 4.1.1
|
||||
dev: false
|
||||
|
||||
/is-extendable@0.1.1:
|
||||
resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
|
||||
|
@ -1106,9 +1108,8 @@ packages:
|
|||
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.5
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
call-bind: 1.0.7
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
/isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
@ -1170,8 +1171,8 @@ packages:
|
|||
uc.micro: 1.0.6
|
||||
dev: false
|
||||
|
||||
/liquidjs@10.10.0:
|
||||
resolution: {integrity: sha512-f4gPvCq4uV4Fm5YezVUQoAMPmBMEuIE2LvgCnzyWoPRx+ZefH6b8DU2eb7znltRqATHF8zYvOsd5FD2z1spJgg==}
|
||||
/liquidjs@10.10.1:
|
||||
resolution: {integrity: sha512-h699VW79OLoshCTjFF02tmRCrd8t/E49LSIsjLwlg4k0TbMVjxsCRXVUEsURXbfKl3HUln2cShlDQCrSNm2YaA==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
|
@ -1288,8 +1289,8 @@ packages:
|
|||
resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==}
|
||||
dev: false
|
||||
|
||||
/morphdom@2.7.1:
|
||||
resolution: {integrity: sha512-LwrrjplMolniWtOGluKF1EHZ0y78Fa4sq7f/MXCydyNkDof+POf+ruCn+k08l7H7b/JISfRo8Zd0HazuqySY9w==}
|
||||
/morphdom@2.7.2:
|
||||
resolution: {integrity: sha512-Dqb/lHFyTi7SZpY0a5R4I/0Edo+iPMbaUexsHHsLAByyixCDiLHPHyVoKVmrpL0THcT7V9Cgev9y21TQYq6wQg==}
|
||||
dev: false
|
||||
|
||||
/ms@2.0.0:
|
||||
|
@ -1316,8 +1317,8 @@ packages:
|
|||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/nan@2.18.0:
|
||||
resolution: {integrity: sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==}
|
||||
/nan@2.19.0:
|
||||
resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==}
|
||||
dev: false
|
||||
|
||||
/neo-async@2.6.2:
|
||||
|
@ -1335,7 +1336,7 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/nunjucks@3.2.4(chokidar@3.5.3):
|
||||
/nunjucks@3.2.4(chokidar@3.6.0):
|
||||
resolution: {integrity: sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==}
|
||||
engines: {node: '>= 6.9.0'}
|
||||
hasBin: true
|
||||
|
@ -1347,14 +1348,13 @@ packages:
|
|||
dependencies:
|
||||
a-sync-waterfall: 1.0.1
|
||||
asap: 2.0.6
|
||||
chokidar: 3.5.3
|
||||
chokidar: 3.6.0
|
||||
commander: 5.1.0
|
||||
dev: false
|
||||
|
||||
/object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/on-finished@2.4.1:
|
||||
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
|
||||
|
@ -1450,10 +1450,11 @@ packages:
|
|||
posthtml-render: 3.0.0
|
||||
dev: false
|
||||
|
||||
/prettier@3.1.1:
|
||||
resolution: {integrity: sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==}
|
||||
/prettier@3.2.5:
|
||||
resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/promise-each@2.2.0:
|
||||
resolution: {integrity: sha512-67roqt1k3QDA41DZ8xi0V+rF3GoaMiX7QilbXu0vXimut+9RcKBNZ/t60xCRgcsihmNUsEjh48xLfNqOrKblUg==}
|
||||
|
@ -1494,7 +1495,6 @@ packages:
|
|||
|
||||
/pug-error@2.0.0:
|
||||
resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==}
|
||||
dev: false
|
||||
|
||||
/pug-filters@4.0.0:
|
||||
resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==}
|
||||
|
@ -1512,7 +1512,6 @@ packages:
|
|||
character-parser: 2.2.0
|
||||
is-expression: 4.0.0
|
||||
pug-error: 2.0.0
|
||||
dev: false
|
||||
|
||||
/pug-linker@4.0.0:
|
||||
resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==}
|
||||
|
@ -1631,23 +1630,24 @@ packages:
|
|||
resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
|
||||
dev: false
|
||||
|
||||
/semver@7.5.4:
|
||||
resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
|
||||
/semver@7.6.0:
|
||||
resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
dev: false
|
||||
|
||||
/set-function-length@1.1.1:
|
||||
resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==}
|
||||
/set-function-length@1.2.2:
|
||||
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
define-data-property: 1.1.1
|
||||
get-intrinsic: 1.2.2
|
||||
define-data-property: 1.1.4
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
get-intrinsic: 1.2.4
|
||||
gopd: 1.0.1
|
||||
has-property-descriptors: 1.0.1
|
||||
dev: false
|
||||
has-property-descriptors: 1.0.2
|
||||
|
||||
/shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
|
@ -1697,8 +1697,8 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/style-mod@4.1.0:
|
||||
resolution: {integrity: sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA==}
|
||||
/style-mod@4.1.2:
|
||||
resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
|
||||
dev: false
|
||||
|
||||
/supports-color@7.2.0:
|
||||
|
@ -1729,7 +1729,7 @@ packages:
|
|||
resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==}
|
||||
dev: false
|
||||
|
||||
/ts-essentials@9.4.1(typescript@5.3.3):
|
||||
/ts-essentials@9.4.1(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-oke0rI2EN9pzHsesdmrOrnqv1eQODmJpd/noJjwj2ZPC3Z4N2wbjrOEqnsEgmvlO2+4fBb0a794DCna2elEVIQ==}
|
||||
peerDependencies:
|
||||
typescript: '>=4.1.0'
|
||||
|
@ -1737,11 +1737,11 @@ packages:
|
|||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
typescript: 5.3.3
|
||||
typescript: 5.4.2
|
||||
dev: false
|
||||
|
||||
/typescript@5.3.3:
|
||||
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
|
||||
/typescript@5.4.2:
|
||||
resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
|
@ -1786,8 +1786,8 @@ packages:
|
|||
resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
dependencies:
|
||||
'@babel/parser': 7.23.6
|
||||
'@babel/types': 7.23.6
|
||||
'@babel/parser': 7.24.0
|
||||
'@babel/types': 7.24.0
|
||||
assert-never: 1.2.1
|
||||
babel-walk: 3.0.0-canary-5
|
||||
dev: false
|
||||
|
@ -1818,7 +1818,7 @@ packages:
|
|||
engines: {node: '>=4.0.0'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
nan: 2.18.0
|
||||
nan: 2.19.0
|
||||
dev: false
|
||||
|
||||
/yallist@4.0.0:
|
||||
|
|
145
src/bytebeat.ts
145
src/bytebeat.ts
|
@ -1,6 +1,6 @@
|
|||
import { deflateSync, inflateSync } from "fflate";
|
||||
import { f32ToRound10, isPlainObject, Song, SongMode } from "./common.ts";
|
||||
import { f32ToRound10, isPlainObject, Song } from "./common.ts";
|
||||
import { elements as elementsPromise } from "./dom.ts";
|
||||
import { fromUrlData, setUrlData } from "./url/mod.ts";
|
||||
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
|
||||
|
@ -51,7 +51,7 @@ let elements = null; // TODO remove
|
|||
|
||||
import("./codemirror.ts").then(o => initCodemirror(o.default));
|
||||
if (globalThis.loadLibrary !== false) {
|
||||
import("./load-library.ts");
|
||||
import("./library/load.ts");
|
||||
}
|
||||
|
||||
handleWindowResize(true);
|
||||
|
@ -60,7 +60,7 @@ let elements = null; // TODO remove
|
|||
loadSettings();
|
||||
let urlData: Song | undefined;
|
||||
if (window.location.hash && globalThis.useUrlData !== false) {
|
||||
urlData = await getUrlData();
|
||||
urlData = await fromUrlData(window.location.hash);
|
||||
}
|
||||
setSong(urlData, false);
|
||||
updateCounterValue();
|
||||
|
@ -121,8 +121,8 @@ function handleMessage(e) {
|
|||
}
|
||||
}
|
||||
|
||||
if (data.updateUrl) {
|
||||
setUrlData();
|
||||
if (data.updateUrl && globalThis.useUrlData !== false) {
|
||||
setUrlData(getSong());
|
||||
}
|
||||
|
||||
if (data.errorMessage !== undefined) {
|
||||
|
@ -246,135 +246,6 @@ function setCodeEditorText(value: string) {
|
|||
}
|
||||
}
|
||||
|
||||
// see smallmode text file
|
||||
const smallmode_table = {
|
||||
Bytebeat: 0b00000111,
|
||||
"Signed Bytebeat": 0b00000110,
|
||||
Floatbeat: 0b00011100,
|
||||
Funcbeat: 0b11111100,
|
||||
} as const;
|
||||
|
||||
async function concatUint8Arrays(uint8arrays) {
|
||||
const blob = new Blob(uint8arrays);
|
||||
const buffer = await blob.arrayBuffer();
|
||||
return new Uint8Array(buffer);
|
||||
}
|
||||
|
||||
// handmade, not very effective. not using it right now
|
||||
//const deflateDictionary5 = new TextEncoder().encode(
|
||||
// Object.getOwnPropertyNames(Math).join("(t*") +
|
||||
// Object.getOwnPropertyNames(Math).join("(t+") +
|
||||
// Object.getOwnPropertyNames(Math).join("(PI*") +
|
||||
// Object.getOwnPropertyNames(Math).join("(t*=") +
|
||||
// "int(t/=)**int(t//t--t++t**t&&!(t||t]??=0,\n\n]||=.00x=x=>(),(+=this.globalThis.window.5*random()*=\"[t>>='[t>>=`[t>>t,\".charCodeAt(t,'.charCodeAt(t,`.charCodeAt(t;i++);i++);return Math.alse-(function(){for(i=0;i<(a,b)=>(",
|
||||
//);
|
||||
|
||||
async function getUrlData(): Promise<Song | undefined> {
|
||||
const hash = window.location.hash;
|
||||
const v = hash[1];
|
||||
|
||||
try {
|
||||
if (v === "5") {
|
||||
// #5
|
||||
|
||||
// add "00" to shift over float bytes and set first 4 bits to 0
|
||||
const rateMode = Uint8Array.from(
|
||||
atob("00" + hash.substring(2, 8)),
|
||||
// @ts-ignore
|
||||
c => c.charCodeAt(),
|
||||
);
|
||||
const compressedCode = Uint8Array.from(
|
||||
atob(hash.substring(8)),
|
||||
// @ts-ignore
|
||||
c => c.charCodeAt(),
|
||||
);
|
||||
|
||||
// this may be useful for extra properties without a new url version
|
||||
/*
|
||||
if (rateMode[1] >= 76) {
|
||||
// number >= 2**25
|
||||
}
|
||||
*/
|
||||
|
||||
const dataview = new DataView(rateMode.buffer);
|
||||
const sampleRate = dataview.getFloat32(1);
|
||||
if (sampleRate >= 2 ** 24) {
|
||||
console.error("Couldn't load data from url: invalid samplerate");
|
||||
return;
|
||||
}
|
||||
|
||||
const maybe_mode = Object.entries(smallmode_table).find(x => x[1] === rateMode[5]);
|
||||
if (maybe_mode === undefined) {
|
||||
console.error("Couldn't load data from url: invalid mode");
|
||||
return;
|
||||
}
|
||||
const mode = maybe_mode[0] as SongMode;
|
||||
|
||||
const code = new TextDecoder().decode(inflateSync(compressedCode,
|
||||
// a dictionary can be added later without breaking compatibility
|
||||
));
|
||||
|
||||
return { code, sampleRate, mode };
|
||||
} else if (v === "v") {
|
||||
// #v4, #v3b64
|
||||
const dataString = atob(hash.substring(hash[2] === "4" ? 3 : 6));
|
||||
|
||||
// @ts-ignore
|
||||
const dataBuffer = Uint8Array.from(
|
||||
dataString,
|
||||
// @ts-ignore
|
||||
c => c.charCodeAt(),
|
||||
);
|
||||
|
||||
const songDataString = new TextDecoder().decode(inflateSync(dataBuffer));
|
||||
let { code, sampleRate, mode } = JSON.parse(songDataString);
|
||||
|
||||
code = code + "";
|
||||
sampleRate = Math.fround(sampleRate ?? 8000);
|
||||
mode = mode ?? "Bytebeat";
|
||||
if (sampleRate < 2 || sampleRate >= 2 ** 24) {
|
||||
console.error("Couldn't load data from url: invalid samplerate");
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
if (smallmode_table[mode] === undefined) {
|
||||
console.error("Couldn't load data from url: invalid mode");
|
||||
return;
|
||||
}
|
||||
|
||||
return { code, sampleRate, mode };
|
||||
} else {
|
||||
console.error("Unrecognized url data");
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Couldn't load data from url:", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
async function setUrlData() {
|
||||
if (globalThis.useUrlData !== false) {
|
||||
const { code, mode, sampleRate } = getSong();
|
||||
const smallmode = smallmode_table[mode];
|
||||
|
||||
const compressedCode = deflateSync(new TextEncoder().encode(code), {
|
||||
level: 8,
|
||||
});
|
||||
|
||||
const buffer = new ArrayBuffer(6 + compressedCode.length);
|
||||
const dataview = new DataView(buffer);
|
||||
dataview.setFloat32(1, sampleRate);
|
||||
dataview.setUint8(5, smallmode);
|
||||
|
||||
const dataArray = new Uint8Array(buffer);
|
||||
dataArray.set(compressedCode, 6);
|
||||
|
||||
const dataString = dataArray.reduce((a, b) => a + String.fromCharCode(b), "");
|
||||
const base64 = btoa(dataString).substring(2).replaceAll("=", "");
|
||||
|
||||
window.location.hash = `#5${base64}`;
|
||||
}
|
||||
}
|
||||
function refreshCode() {
|
||||
if (audioWorklet) {
|
||||
audioWorklet.port.postMessage({ code: getCodeEditorText().trim() });
|
||||
|
@ -736,7 +607,9 @@ function setByteSample(value, send = true, clear = false) {
|
|||
function setPlaybackMode(playbackMode) {
|
||||
if (audioWorklet) {
|
||||
songData.mode = playbackMode;
|
||||
setUrlData();
|
||||
if (globalThis.useUrlData !== false) {
|
||||
setUrlData(getSong());
|
||||
}
|
||||
audioWorklet.port.postMessage({ songData });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { DeepReadonly } from "ts-essentials";
|
||||
import { SongMode, SmallSongMode } from "common.ts";
|
||||
import { SongMode, SmallSongMode } from "../common.ts";
|
||||
|
||||
|
||||
type RemixedEntry = Readonly<{
|
|
@ -1,5 +1,5 @@
|
|||
import { library, Entry, EntryBase, InlineEntry, FileEntry } from "./library.ts";
|
||||
import { setSong } from "./bytebeat.js";
|
||||
import { setSong } from "../bytebeat.js";
|
||||
|
||||
|
||||
function stripEntryToSong(entry: Entry) {
|
|
@ -0,0 +1,96 @@
|
|||
// TODO everything here is extremely poorly optimized
|
||||
// into and from iterate over bits at every step, they should go over full bytes at some point
|
||||
// should probably benchmark the website
|
||||
|
||||
const tochar =
|
||||
"!#$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
const fromchar = Object.fromEntries(Object.entries(tochar).map(([i, v]) => [v, BigInt(i)]));
|
||||
|
||||
// go through 123 bits at a time, into 19 character chunks
|
||||
// bitIndex from 0 to 7 to trim bits off the input data
|
||||
|
||||
// least amount of bits that requires a base 89 string of a specific length
|
||||
const lbl = Array(20)
|
||||
.fill(undefined)
|
||||
.map((v, i) => i && (89n ** BigInt(i - 1)).toString(2).length);
|
||||
|
||||
function into89(data: Uint8Array, bitIndex = 0): string {
|
||||
let coded = "";
|
||||
while (true) {
|
||||
//const byteIndex = bitIndex >> 3;
|
||||
//const bitOffset = bitIndex & 7;
|
||||
let bigint = 0n;
|
||||
for (let i = 0; i < 123; i++) {
|
||||
if (bitIndex >> 3 < data.length) {
|
||||
bigint += BigInt(!!(data[bitIndex >> 3] & (1 << (bitIndex & 7)))) << BigInt(i);
|
||||
bitIndex++;
|
||||
} else {
|
||||
//bigint = BigInt.asUintN(123, bigint << BigInt(bitOffset));
|
||||
// TODO length often wrong, i gave up on it for now
|
||||
/*
|
||||
for (const bits of lbl.slice(1).map(x => x - 1)) {
|
||||
if (bits >= i) {
|
||||
return coded;
|
||||
}
|
||||
coded += tochar[Number(bigint % 89n)];
|
||||
bigint /= 89n;
|
||||
}
|
||||
// unreachable
|
||||
*/
|
||||
while (bigint) {
|
||||
coded += tochar[Number(bigint % 89n)];
|
||||
bigint /= 89n;
|
||||
}
|
||||
return coded;
|
||||
}
|
||||
}
|
||||
//bigint = BigInt.asUintN(123, bigint << BigInt(bitOffset));
|
||||
for (let j = 0; j < 19; j++) {
|
||||
coded += tochar[Number(bigint % 89n)];
|
||||
bigint /= 89n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function from89(coded: string, bitIndex = 0/*, byteUp = true*/): Uint8Array {
|
||||
// all this code is PROBABLY correct but i'm not sure because into89 length is wrong anyways
|
||||
//const chunkCount = Math.max(Math.ceil(coded.length / 19) - 1, 0);
|
||||
//const chunkRem = coded.length - chunkCount * 19;
|
||||
//const lbla = lbl[chunkRem];
|
||||
//const bitrem = byteUp ? (lbla + 7 & ~7) - (bitIndex & 7) : lbla;
|
||||
//const bits = chunkCount * 123 + bitrem;
|
||||
const bits = Math.ceil(coded.length / 19) * 123; // always too long but that's good for now
|
||||
const data = new Uint8Array(((bits + bitIndex + 7) >> 3));
|
||||
|
||||
let currentByte = 0;
|
||||
if (coded.length) {
|
||||
const chunks = (coded.match(/.{1,19}/g) as RegExpMatchArray);
|
||||
for (const chunk of chunks) {
|
||||
let bigint = 0n;
|
||||
for (const letter of chunk.split("").reverse()) {
|
||||
bigint *= 89n;
|
||||
bigint += fromchar[letter];
|
||||
}
|
||||
for (let i = 123; i; i--) {
|
||||
let bit = Number(bigint & 1n);
|
||||
currentByte |= bit << (bitIndex & 7);
|
||||
if ((bitIndex & 7) === 7) {
|
||||
data[bitIndex >> 3] = currentByte;
|
||||
currentByte = 0;
|
||||
}
|
||||
bitIndex++;
|
||||
if (bitIndex === bits) {
|
||||
if ((bitIndex & 7) !== 0) {
|
||||
data[bitIndex >> 3] = currentByte;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
bigint >>= 1n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
export { into89, from89 };
|
|
@ -0,0 +1,133 @@
|
|||
import { deflateSync, inflateSync } from "fflate";
|
||||
import { into89, from89 } from "./base89.ts";
|
||||
import { Song, SongMode } from "../common.ts";
|
||||
|
||||
// see smallmode text file
|
||||
const smallmode_table = {
|
||||
Bytebeat: 0b00000111,
|
||||
"Signed Bytebeat": 0b00000110,
|
||||
Floatbeat: 0b00011100,
|
||||
Funcbeat: 0b11111100,
|
||||
} as const;
|
||||
|
||||
// handmade, not very effective. not using it right now
|
||||
//const deflateDictionary5 = new TextEncoder().encode(
|
||||
// Object.getOwnPropertyNames(Math).join("(t*") +
|
||||
// Object.getOwnPropertyNames(Math).join("(t+") +
|
||||
// Object.getOwnPropertyNames(Math).join("(PI*") +
|
||||
// Object.getOwnPropertyNames(Math).join("(t*=") +
|
||||
// "int(t/=)**int(t//t--t++t**t&&!(t||t]??=0,\n\n]||=.00x=x=>(),(+=this.globalThis.window.5*random()*=\"[t>>='[t>>=`[t>>t,\".charCodeAt(t,'.charCodeAt(t,`.charCodeAt(t;i++);i++);return Math.alse-(function(){for(i=0;i<(a,b)=>(",
|
||||
//);
|
||||
|
||||
async function fromUrlData(hash: string): Promise<Song | undefined> {
|
||||
const v = hash[1];
|
||||
|
||||
try {
|
||||
if (v === "6" || v === "5") {
|
||||
// #6, #5
|
||||
|
||||
let data: Uint8Array;
|
||||
let compressedCode;
|
||||
if (v === "6") {
|
||||
data = from89(hash.substring(2), 12);
|
||||
data[1] = data[1] >> 4 | 0x40;
|
||||
compressedCode = data.subarray(6);
|
||||
} else {
|
||||
// add "00" to shift over float bytes and set first 4 bits to 0100
|
||||
data = Uint8Array.from(
|
||||
atob("00" + hash.substring(2, 8)),
|
||||
// @ts-ignore
|
||||
c => c.charCodeAt(),
|
||||
);
|
||||
compressedCode = Uint8Array.from(
|
||||
atob(hash.substring(8)),
|
||||
// @ts-ignore
|
||||
c => c.charCodeAt(),
|
||||
);
|
||||
}
|
||||
|
||||
// this may be useful for extra properties without a new url version
|
||||
/*
|
||||
if (rateMode[1] >= 76) {
|
||||
// number >= 2**25
|
||||
}
|
||||
*/
|
||||
|
||||
const dataview = new DataView(data.buffer);
|
||||
const sampleRate = dataview.getFloat32(1);
|
||||
if (sampleRate >= 2 ** 24) {
|
||||
console.error("Couldn't load data from url: invalid samplerate");
|
||||
return;
|
||||
}
|
||||
|
||||
const maybe_mode = Object.entries(smallmode_table).find(x => x[1] === data[5]);
|
||||
if (maybe_mode === undefined) {
|
||||
console.error("Couldn't load data from url: invalid mode");
|
||||
return;
|
||||
}
|
||||
const mode = maybe_mode[0] as SongMode;
|
||||
|
||||
const code = new TextDecoder().decode(inflateSync(compressedCode,
|
||||
// a dictionary can be added later without breaking compatibility
|
||||
));
|
||||
|
||||
return { code, sampleRate, mode };
|
||||
} else if (v === "v") {
|
||||
// #v4, #v3b64
|
||||
const dataString = atob(hash.substring(hash[2] === "4" ? 3 : 6));
|
||||
|
||||
// @ts-ignore
|
||||
const dataBuffer = Uint8Array.from(
|
||||
dataString,
|
||||
// @ts-ignore
|
||||
c => c.charCodeAt(),
|
||||
);
|
||||
|
||||
const songDataString = new TextDecoder().decode(inflateSync(dataBuffer));
|
||||
let { code, sampleRate, mode } = JSON.parse(songDataString);
|
||||
|
||||
code = code + "";
|
||||
sampleRate = Math.fround(sampleRate ?? 8000);
|
||||
mode = mode ?? "Bytebeat";
|
||||
if (sampleRate < 2 || sampleRate >= 2 ** 24) {
|
||||
console.error("Couldn't load data from url: invalid samplerate");
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
if (smallmode_table[mode] === undefined) {
|
||||
console.error("Couldn't load data from url: invalid mode");
|
||||
return;
|
||||
}
|
||||
|
||||
return { code, sampleRate, mode };
|
||||
} else {
|
||||
console.error("Unrecognized url data");
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Couldn't load data from url:", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
async function setUrlData({ code, mode, sampleRate }: Song) {
|
||||
const smallmode = smallmode_table[mode];
|
||||
|
||||
const compressedCode = deflateSync(new TextEncoder().encode(code), {
|
||||
level: 8,
|
||||
});
|
||||
|
||||
const buffer = new ArrayBuffer(5 + compressedCode.length);
|
||||
const dataview = new DataView(buffer);
|
||||
dataview.setFloat32(0, sampleRate);
|
||||
dataview.setUint8(4, smallmode);
|
||||
|
||||
const dataArray = new Uint8Array(buffer);
|
||||
dataArray.set(compressedCode, 5);
|
||||
dataArray[0] <<= 4;
|
||||
|
||||
const base89 = into89(dataArray, 4);
|
||||
|
||||
window.location.hash = `#6${base89}`;
|
||||
}
|
||||
|
||||
export { fromUrlData, setUrlData };
|
Loading…
Reference in New Issue