From 1e64c06ad1c90d7751e9c09f5e8704fc8ef8d68a Mon Sep 17 00:00:00 2001 From: dianlight Date: Sun, 13 Oct 2024 22:37:34 +0200 Subject: [PATCH 1/4] Added support for byteorder in read --- CHANGELOG.md | 1 + pnpm-lock.yaml | 1380 +++++++++++++++++++++++++++++ src/bitstream/reader.test.ts | 217 +++-- src/bitstream/reader.ts | 151 ++-- src/bitstream/writer.ts | 57 +- src/elements/number-serializer.ts | 22 +- 6 files changed, 1627 insertions(+), 201 deletions(-) create mode 100644 pnpm-lock.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 017b2ac..a81c1e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # ⏩ vNext +- Fix ByteOrder in number serializer - aka support for lsb # v4.2.2 - Fix an issue where the new 53-bit oversize error is emitted when the `float` format is selected, even though it is diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..4952773 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1380 @@ +lockfileVersion: '6.1' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + reflect-metadata: + specifier: ^0.1.13 + version: 0.1.13 + +devDependencies: + '@types/chai': + specifier: ^4.2.14 + version: 4.2.14 + '@types/node': + specifier: ^14.0.4 + version: 14.0.4 + '@types/reflect-metadata': + specifier: ^0.1.0 + version: 0.1.0 + chai: + specifier: ^4.2.0 + version: 4.2.0 + nyc: + specifier: ^15.1.0 + version: 15.1.0 + razmin: + specifier: ^0.6.20 + version: 0.6.20 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + source-map-support: + specifier: ^0.5.21 + version: 0.5.21 + ts-node: + specifier: ^10.4.0 + version: 10.4.0(@types/node@14.0.4)(typescript@5.3.3) + typescript: + specifier: ^5.3.3 + version: 5.3.3 + +packages: + + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@babel/code-frame@7.25.7: + resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.25.7 + picocolors: 1.1.0 + dev: true + + /@babel/compat-data@7.25.8: + resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.25.8: + resolution: {integrity: sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helpers': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + convert-source-map: 2.0.0 + debug: 4.3.7 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.25.7: + resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.25.8 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + dev: true + + /@babel/helper-compilation-targets@7.25.7: + resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.25.8 + '@babel/helper-validator-option': 7.25.7 + browserslist: 4.24.0 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-module-imports@7.25.7: + resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-module-transforms@7.25.7(@babel/core@7.25.8): + resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-simple-access': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access@7.25.7: + resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-string-parser@7.25.7: + resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.25.7: + resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.25.7: + resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers@7.25.7: + resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + dev: true + + /@babel/highlight@7.25.7: + resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.25.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.0 + dev: true + + /@babel/parser@7.25.8: + resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.25.8 + dev: true + + /@babel/template@7.25.7: + resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + dev: true + + /@babel/traverse@7.25.7: + resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + debug: 4.3.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.25.8: + resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + to-fast-properties: 2.0.0 + dev: true + + /@cspotcode/source-map-consumer@0.8.0: + resolution: {integrity: sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==} + engines: {node: '>= 12'} + dev: true + + /@cspotcode/source-map-support@0.7.0: + resolution: {integrity: sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==} + engines: {node: '>=12'} + dependencies: + '@cspotcode/source-map-consumer': 0.8.0 + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.5.0: + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + dev: true + + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /@tsconfig/node10@1.0.11: + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/chai@4.2.14: + resolution: {integrity: sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==} + dev: true + + /@types/node@14.0.4: + resolution: {integrity: sha512-k3NqigXWRzQZVBDS5D1U70A5E8Qk4Kh+Ha/x4M8Bt9pF0X05eggfnC9+63Usc9Q928hRUIpIhTQaXsZwZBl4Ew==} + dev: true + + /@types/reflect-metadata@0.1.0: + resolution: {integrity: sha512-bXltFLY3qhzCnVYP5iUpeSICagQ8rc9K2liS+8M0lBcz54BHs3O6W5UvqespVSuebo1BXLi+/y9ioELAW9SC2A==} + deprecated: This is a stub types definition for reflect-metadata (https://github.com/rbuckton/ReflectDecorators). reflect-metadata provides its own type definitions, so you don't need @types/reflect-metadata installed! + dependencies: + reflect-metadata: 0.1.13 + dev: true + + /acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + dependencies: + acorn: 8.12.1 + dev: true + + /acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /append-transform@2.0.0: + resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} + engines: {node: '>=8'} + dependencies: + default-require-extensions: 3.0.1 + dev: true + + /archy@1.0.0: + resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /array-union@1.0.2: + resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} + engines: {node: '>=0.10.0'} + dependencies: + array-uniq: 1.0.3 + dev: true + + /array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + dev: true + + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /browserslist@4.24.0: + resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001668 + electron-to-chromium: 1.5.36 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.0) + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /caching-transform@4.0.0: + resolution: {integrity: sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==} + engines: {node: '>=8'} + dependencies: + hasha: 5.2.2 + make-dir: 3.1.0 + package-hash: 4.0.0 + write-file-atomic: 3.0.3 + dev: true + + /callsites@1.0.1: + resolution: {integrity: sha512-4pzUzADrTwH4QwhsYEY1yQYUYXb4Lp3CB7FVknTNtWNCFdcQkRV4ICEGnMQ35DcJhCVlAB1VD3A/SoWC0O2kMg==} + engines: {node: '>=0.10'} + dev: true + + /callsites@2.0.0: + resolution: {integrity: sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==} + engines: {node: '>=4'} + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /caniuse-lite@1.0.30001668: + resolution: {integrity: sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==} + dev: true + + /chai@4.2.0: + resolution: {integrity: sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 3.0.1 + get-func-name: 2.0.2 + pathval: 1.1.1 + type-detect: 4.1.0 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + dev: true + + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /deep-eql@3.0.1: + resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} + engines: {node: '>=0.12'} + dependencies: + type-detect: 4.1.0 + dev: true + + /default-require-extensions@3.0.1: + resolution: {integrity: sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==} + engines: {node: '>=8'} + dependencies: + strip-bom: 4.0.0 + dev: true + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /electron-to-chromium@1.5.36: + resolution: {integrity: sha512-HYTX8tKge/VNp6FGO+f/uVDmUkq+cEfcxYhKf15Akc4M5yxt5YmorwlAitKWjWhWQnKcDRBAQKXkhqqXMqcrjw==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + dev: true + + /escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /foreground-child@2.0.0: + resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} + engines: {node: '>=8.0.0'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 3.0.7 + dev: true + + /fromentries@1.3.2: + resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + dev: true + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /glob-parent@3.1.0: + resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} + dependencies: + is-glob: 3.1.0 + path-dirname: 1.0.2 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globby@6.1.0: + resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} + engines: {node: '>=0.10.0'} + dependencies: + array-union: 1.0.2 + glob: 7.2.3 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /hasha@5.2.2: + resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} + engines: {node: '>=8'} + dependencies: + is-stream: 2.0.1 + type-fest: 0.8.1 + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-glob@3.1.0: + resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-hook@3.0.0: + resolution: {integrity: sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==} + engines: {node: '>=8'} + dependencies: + append-transform: 2.0.0 + dev: true + + /istanbul-lib-instrument@4.0.3: + resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.25.8 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-processinfo@2.0.3: + resolution: {integrity: sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==} + engines: {node: '>=8'} + dependencies: + archy: 1.0.0 + cross-spawn: 7.0.3 + istanbul-lib-coverage: 3.2.2 + p-map: 3.0.0 + rimraf: 3.0.2 + uuid: 8.3.2 + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /lodash.flattendeep@4.4.0: + resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.1 + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.6.3 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /mersenne-twister@1.1.0: + resolution: {integrity: sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /node-preload@0.2.1: + resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} + engines: {node: '>=8'} + dependencies: + process-on-spawn: 1.0.0 + dev: true + + /node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + dev: true + + /nyc@15.1.0: + resolution: {integrity: sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==} + engines: {node: '>=8.9'} + hasBin: true + dependencies: + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + caching-transform: 4.0.0 + convert-source-map: 1.9.0 + decamelize: 1.2.0 + find-cache-dir: 3.3.2 + find-up: 4.1.0 + foreground-child: 2.0.0 + get-package-type: 0.1.0 + glob: 7.2.3 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-hook: 3.0.0 + istanbul-lib-instrument: 4.0.3 + istanbul-lib-processinfo: 2.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + make-dir: 3.1.0 + node-preload: 0.2.1 + p-map: 3.0.0 + process-on-spawn: 1.0.0 + resolve-from: 5.0.0 + rimraf: 3.0.2 + signal-exit: 3.0.7 + spawn-wrap: 2.0.0 + test-exclude: 6.0.0 + yargs: 15.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-map@3.0.0: + resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} + engines: {node: '>=8'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /package-hash@4.0.0: + resolution: {integrity: sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==} + engines: {node: '>=8'} + dependencies: + graceful-fs: 4.2.11 + hasha: 5.2.2 + lodash.flattendeep: 4.4.0 + release-zalgo: 1.0.0 + dev: true + + /parent-module@0.1.0: + resolution: {integrity: sha512-fkZFUUL8tSsJUm/WvAqyJLV/Aj9/jpnMXHy0leJYEUu2qw5FE6nJQI/bMVW2xbZySot4uaPb6cw4eY5zQn7/Ww==} + engines: {node: '>=0.10.0'} + dependencies: + callsites: 1.0.1 + dev: true + + /path-dirname@1.0.2: + resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + + /picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + dev: true + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + + /pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + dependencies: + pinkie: 2.0.4 + dev: true + + /pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + dev: true + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /process-on-spawn@1.0.0: + resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} + engines: {node: '>=8'} + dependencies: + fromentries: 1.3.2 + dev: true + + /razmin@0.6.20: + resolution: {integrity: sha512-ppu9Yn4V8KEiZX5J1MKICDw27cMyx1oidu3QrX2eW8KB5eosipAeZFQtkihOrxAJaErZGGghBfjM8xJZSnno8g==} + dependencies: + callsites: 2.0.0 + colors: 1.4.0 + mersenne-twister: 1.1.0 + require-glob: 3.2.0 + rxjs: 6.6.7 + source-map-support: 0.5.21 + zone.js: 0.10.3 + dev: true + + /reflect-metadata@0.1.13: + resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + + /release-zalgo@1.0.0: + resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} + engines: {node: '>=4'} + dependencies: + es6-error: 4.1.1 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-glob@3.2.0: + resolution: {integrity: sha512-F7diVunoVBanWJ4kq9t+ZKiPhxn588xBvFEDbe8XJnpZ68qEUZ3wXzoAaRSDYxylh6ssSIIPV2+qD6QIsOkR1g==} + engines: {node: '>= 0.12'} + dependencies: + glob-parent: 3.1.0 + globby: 6.1.0 + parent-module: 0.1.0 + dev: true + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + dependencies: + tslib: 1.14.1 + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /spawn-wrap@2.0.0: + resolution: {integrity: sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==} + engines: {node: '>=8'} + dependencies: + foreground-child: 2.0.0 + is-windows: 1.0.2 + make-dir: 3.1.0 + rimraf: 3.0.2 + signal-exit: 3.0.7 + which: 2.0.2 + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /ts-node@10.4.0(@types/node@14.0.4)(typescript@5.3.3): + resolution: {integrity: sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.7.0 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 14.0.4 + acorn: 8.12.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.3.3 + yn: 3.1.1 + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 + dev: true + + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /update-browserslist-db@1.1.1(browserslist@4.24.0): + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.24.0 + escalade: 3.2.0 + picocolors: 1.1.0 + dev: true + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: true + + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + dev: true + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /zone.js@0.10.3: + resolution: {integrity: sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==} + dev: true diff --git a/src/bitstream/reader.test.ts b/src/bitstream/reader.test.ts index 46b8ff9..ad64ad9 100644 --- a/src/bitstream/reader.test.ts +++ b/src/bitstream/reader.test.ts @@ -5,16 +5,16 @@ import { BitstreamReader } from "./reader"; describe('BitstreamReader', it => { it('can read a byte-aligned byte', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([123])); expect(bitstream.readSync(8)).to.equal(123); }); it('bufferIndex is always zero when retainBuffers=false', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 123 ])); - bitstream.addBuffer(Buffer.from([ 123, 123 ])); - bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([123, 123])); + bitstream.addBuffer(Buffer.from([123])); expect(bitstream.bufferIndex === 0); bitstream.readSync(8); @@ -27,9 +27,9 @@ describe('BitstreamReader', it => { it('.clean() causes buffers to be discarded when retainBuffers=true', () => { let bitstream = new BitstreamReader(); bitstream.retainBuffers = true; - bitstream.addBuffer(Buffer.from([ 123 ])); - bitstream.addBuffer(Buffer.from([ 123, 123 ])); - bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([123, 123])); + bitstream.addBuffer(Buffer.from([123])); bitstream.readSync(8); expect(bitstream.bufferIndex).to.equal(1); expect(bitstream.offset).to.equal(8); @@ -50,15 +50,15 @@ describe('BitstreamReader', it => { it('.clean() frees only the number of requested buffers', () => { let bitstream = new BitstreamReader(); bitstream.retainBuffers = true; - bitstream.addBuffer(Buffer.from([ 123 ])); - bitstream.addBuffer(Buffer.from([ 123 ])); - bitstream.addBuffer(Buffer.from([ 123 ])); - bitstream.addBuffer(Buffer.from([ 123, 123 ])); - + bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([123, 123])); + bitstream.readSync(8); bitstream.readSync(8); bitstream.readSync(8); - + expect(bitstream.bufferIndex).to.equal(3); bitstream.clean(1); expect(bitstream.bufferIndex).to.equal(2); @@ -69,9 +69,9 @@ describe('BitstreamReader', it => { }); it('spentBufferSize tracks read bits properly', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 123 ])); - bitstream.addBuffer(Buffer.from([ 123, 123 ])); - bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([123, 123])); + bitstream.addBuffer(Buffer.from([123])); expect(bitstream.spentBufferSize === 0); bitstream.readSync(8); @@ -84,21 +84,21 @@ describe('BitstreamReader', it => { it('offset should start at zero', () => { let bitstream = new BitstreamReader(); expect(bitstream.offset).to.equal(0); - bitstream.addBuffer(Buffer.from([ 1, 2, 3, 4, 5, 6 ])); + bitstream.addBuffer(Buffer.from([1, 2, 3, 4, 5, 6])); expect(bitstream.offset).to.equal(0); }); it('offset should not move as buffers are added', () => { let bitstream = new BitstreamReader(); expect(bitstream.offset).to.equal(0); - bitstream.addBuffer(Buffer.from([ 1, 2, 3, 4, 5, 6 ])); + bitstream.addBuffer(Buffer.from([1, 2, 3, 4, 5, 6])); expect(bitstream.offset).to.equal(0); bitstream.readSync(8); - bitstream.addBuffer(Buffer.from([ 1, 2, 3, 4, 5, 6 ])); + bitstream.addBuffer(Buffer.from([1, 2, 3, 4, 5, 6])); expect(bitstream.offset).to.equal(8); }); it('setting offset allows seeking within current buffer', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 1, 2, 3, 4, 5, 6 ])); + bitstream.addBuffer(Buffer.from([1, 2, 3, 4, 5, 6])); expect(bitstream.readSync(8)).to.equal(1); expect(bitstream.readSync(8)).to.equal(2); @@ -122,8 +122,8 @@ describe('BitstreamReader', it => { it('setting offset allows seeking into previous buffers when retainBuffers=true', () => { let bitstream = new BitstreamReader(); bitstream.retainBuffers = true; - bitstream.addBuffer(Buffer.from([ 1, 2, 3 ])); - bitstream.addBuffer(Buffer.from([ 4, 5, 6 ])); + bitstream.addBuffer(Buffer.from([1, 2, 3])); + bitstream.addBuffer(Buffer.from([4, 5, 6])); expect(bitstream.readSync(8)).to.equal(1); expect(bitstream.readSync(8)).to.equal(2); @@ -132,7 +132,7 @@ describe('BitstreamReader', it => { expect(bitstream.readSync(8)).to.equal(5); expect(bitstream.readSync(8)).to.equal(6); - bitstream.offset = 8*3; + bitstream.offset = 8 * 3; expect(bitstream.readSync(8)).to.equal(4); expect(bitstream.readSync(8)).to.equal(5); expect(bitstream.readSync(8)).to.equal(6); @@ -144,8 +144,8 @@ describe('BitstreamReader', it => { }); it('setting offset into discarded buffers should throw when retainBuffers=false', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 1, 2, 3 ])); - bitstream.addBuffer(Buffer.from([ 4, 5, 6 ])); + bitstream.addBuffer(Buffer.from([1, 2, 3])); + bitstream.addBuffer(Buffer.from([4, 5, 6])); expect(bitstream.readSync(8)).to.equal(1); expect(bitstream.readSync(8)).to.equal(2); @@ -157,15 +157,15 @@ describe('BitstreamReader', it => { let caught; try { bitstream.offset = 0; - } catch (e) { caught = e; } + } catch (e) { caught = e; } expect(caught).to.exist; }); it('offset is always increasing even when retainBuffers=false', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 123 ])); - bitstream.addBuffer(Buffer.from([ 123, 123 ])); - bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([123, 123])); + bitstream.addBuffer(Buffer.from([123])); expect(bitstream.offset === 0); bitstream.readSync(8); @@ -178,9 +178,9 @@ describe('BitstreamReader', it => { it('bufferIndex grows when retainBuffers=true', () => { let bitstream = new BitstreamReader(); bitstream.retainBuffers = true; - bitstream.addBuffer(Buffer.from([ 123 ])); - bitstream.addBuffer(Buffer.from([ 123, 123 ])); - bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([123, 123])); + bitstream.addBuffer(Buffer.from([123])); expect(bitstream.bufferIndex === 0); bitstream.readSync(8); @@ -199,7 +199,9 @@ describe('BitstreamReader', it => { 0b11101001, 0b01100100, - 0b10001110 + 0b10001110, + 0b11110000, + 0b10010000 ])); expect(bitstream.readSync(1)).to.equal(0b1); @@ -214,12 +216,15 @@ describe('BitstreamReader', it => { expect(bitstream.readSync(11)).to.equal(0b01100100100); expect(bitstream.readSync(5)).to.equal(0b01110); + + expect(bitstream.readSync(16, 'little-endian')).to.equal(0b1001000011110000); }); it('can correctly deserialize a simple example from multiple buffers', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0b11001000, 0b01010100 ])); - bitstream.addBuffer(Buffer.from([ 0b11101001, 0b01100100, 0b10001110 ])); + bitstream.addBuffer(Buffer.from([0b11001000, 0b01010100])); + bitstream.addBuffer(Buffer.from([0b11101001, 0b01100100, 0b10001110])); + bitstream.addBuffer(Buffer.from([0b11110000, 0b10010000])); expect(bitstream.readSync(1)).to.equal(0b1); expect(bitstream.readSync(3)).to.equal(0b100); @@ -233,6 +238,8 @@ describe('BitstreamReader', it => { expect(bitstream.readSync(11)).to.equal(0b01100100100); expect(bitstream.readSync(5)).to.equal(0b01110); + + expect(bitstream.readSync(16, 'little-endian')).to.equal(0b1001000011110000); }); it('can read fixed length UTF-8 strings', () => { @@ -265,8 +272,8 @@ describe('BitstreamReader', it => { it('correctly handles intra-byte skips', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0b11001010, 0b01010100 ])); - bitstream.addBuffer(Buffer.from([ 0b11101001, 0b01100100, 0b10001110 ])); + bitstream.addBuffer(Buffer.from([0b11001010, 0b01010100])); + bitstream.addBuffer(Buffer.from([0b11101001, 0b01100100, 0b10001110])); expect(bitstream.readSync(1)).to.equal(0b1); expect(bitstream.readSync(3)).to.equal(0b100); @@ -287,8 +294,8 @@ describe('BitstreamReader', it => { it('correctly handles inter-byte skips', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0b11001010, 0b01010100 ])); - bitstream.addBuffer(Buffer.from([ 0b11101001, 0b01100100, 0b10001110 ])); + bitstream.addBuffer(Buffer.from([0b11001010, 0b01010100])); + bitstream.addBuffer(Buffer.from([0b11101001, 0b01100100, 0b10001110])); expect(bitstream.readSync(1)).to.equal(0b1); expect(bitstream.readSync(3)).to.equal(0b100); @@ -309,8 +316,8 @@ describe('BitstreamReader', it => { it('correctly handles large inter-byte skips', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0b11001010, 0b01010100 ])); - bitstream.addBuffer(Buffer.from([ 0b11101001, 0b01100100, 0b10001110 ])); + bitstream.addBuffer(Buffer.from([0b11001010, 0b01010100])); + bitstream.addBuffer(Buffer.from([0b11101001, 0b01100100, 0b10001110])); expect(bitstream.readSync(1)).to.equal(0b1); expect(bitstream.readSync(3)).to.equal(0b100); @@ -323,7 +330,7 @@ describe('BitstreamReader', it => { it('peeks correctly', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0b11001010, 0b01010100 ])); + bitstream.addBuffer(Buffer.from([0b11001010, 0b01010100])); expect(bitstream.peekSync(4)).to.equal(0b1100); expect(bitstream.readSync(1)).to.equal(0b1); @@ -338,74 +345,85 @@ describe('BitstreamReader', it => { it('.readSignedSync() correctly handles signed integers', () => { let bitstream = new BitstreamReader(); - - bitstream.addBuffer(Buffer.from([ 0xFB ])); expect(bitstream.readSignedSync(8)).to.equal(-5); - bitstream.addBuffer(Buffer.from([ 5 ])); expect(bitstream.readSignedSync(8)).to.equal(5); - bitstream.addBuffer(Buffer.from([ 0 ])); expect(bitstream.readSignedSync(8)).to.equal(0); - bitstream.addBuffer(Buffer.from([ 0xFC, 0x0A ])); expect(bitstream.readSignedSync(16)).to.equal(-1014); - bitstream.addBuffer(Buffer.from([ 0x03, 0xF6 ])); expect(bitstream.readSignedSync(16)).to.equal(1014); - bitstream.addBuffer(Buffer.from([ 0, 0 ])); expect(bitstream.readSignedSync(16)).to.equal(0); + bitstream.addBuffer(Buffer.from([0xFB])); expect(bitstream.readSignedSync(8)).to.equal(-5); + bitstream.addBuffer(Buffer.from([5])); expect(bitstream.readSignedSync(8)).to.equal(5); + bitstream.addBuffer(Buffer.from([0])); expect(bitstream.readSignedSync(8)).to.equal(0); - bitstream.addBuffer(Buffer.from([ 0xFF, 0xFE, 0x70, 0x40 ])); expect(bitstream.readSignedSync(32)).to.equal(-102336); - bitstream.addBuffer(Buffer.from([ 0x00, 0x01, 0x8F, 0xC0 ])); expect(bitstream.readSignedSync(32)).to.equal(102336); - bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0 ])); expect(bitstream.readSignedSync(32)).to.equal(0); + bitstream.addBuffer(Buffer.from([0xFC, 0x0A])); expect(bitstream.readSignedSync(16)).to.equal(-1014); + bitstream.addBuffer(Buffer.from([0x03, 0xF6])); expect(bitstream.readSignedSync(16)).to.equal(1014); + bitstream.addBuffer(Buffer.from([0, 0])); expect(bitstream.readSignedSync(16)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xFF, 0xFE, 0x70, 0x40])); expect(bitstream.readSignedSync(32)).to.equal(-102336); + bitstream.addBuffer(Buffer.from([0x00, 0x01, 0x8F, 0xC0])); expect(bitstream.readSignedSync(32)).to.equal(102336); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(bitstream.readSignedSync(32)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xFF, 0x01])); expect(bitstream.readSignedSync(16, 'little-endian')).to.equal(0x01FF); }); it('.readSigned() correctly handles signed integers', async () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0xFB ])); expect(await bitstream.readSigned(8)).to.equal(-5); - bitstream.addBuffer(Buffer.from([ 5 ])); expect(await bitstream.readSigned(8)).to.equal(5); - bitstream.addBuffer(Buffer.from([ 0 ])); expect(await bitstream.readSigned(8)).to.equal(0); + bitstream.addBuffer(Buffer.from([0xFB])); expect(await bitstream.readSigned(8)).to.equal(-5); + bitstream.addBuffer(Buffer.from([5])); expect(await bitstream.readSigned(8)).to.equal(5); + bitstream.addBuffer(Buffer.from([0])); expect(await bitstream.readSigned(8)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xFC, 0x0A])); expect(await bitstream.readSigned(16)).to.equal(-1014); + bitstream.addBuffer(Buffer.from([0x03, 0xF6])); expect(await bitstream.readSigned(16)).to.equal(1014); + bitstream.addBuffer(Buffer.from([0, 0])); expect(await bitstream.readSigned(16)).to.equal(0); - bitstream.addBuffer(Buffer.from([ 0xFC, 0x0A ])); expect(await bitstream.readSigned(16)).to.equal(-1014); - bitstream.addBuffer(Buffer.from([ 0x03, 0xF6 ])); expect(await bitstream.readSigned(16)).to.equal(1014); - bitstream.addBuffer(Buffer.from([ 0, 0 ])); expect(await bitstream.readSigned(16)).to.equal(0); + bitstream.addBuffer(Buffer.from([0xFF, 0xFE, 0x70, 0x40])); expect(await bitstream.readSigned(32)).to.equal(-102336); + bitstream.addBuffer(Buffer.from([0x00, 0x01, 0x8F, 0xC0])); expect(await bitstream.readSigned(32)).to.equal(102336); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(await bitstream.readSigned(32)).to.equal(0); - bitstream.addBuffer(Buffer.from([ 0xFF, 0xFE, 0x70, 0x40 ])); expect(await bitstream.readSigned(32)).to.equal(-102336); - bitstream.addBuffer(Buffer.from([ 0x00, 0x01, 0x8F, 0xC0 ])); expect(await bitstream.readSigned(32)).to.equal(102336); - bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0 ])); expect(await bitstream.readSigned(32)).to.equal(0); + bitstream.addBuffer(Buffer.from([0xFF, 0x01])); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(0x01FF); }); it('.readSigned() can wait until data is available', async () => { let bitstream = new BitstreamReader(); - setTimeout(() => bitstream.addBuffer(Buffer.from([ 0xFB ])), 10); + setTimeout(() => bitstream.addBuffer(Buffer.from([0xFB])), 10); expect(await bitstream.readSigned(8)).to.equal(-5); }); it('.readFloatSync() correctly handles floats', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0x42, 0xCD, 0x00, 0x00 ])); expect(bitstream.readFloatSync(32)).to.equal(102.5); - bitstream.addBuffer(Buffer.from([ 0xC3, 0xDA, 0x00, 0x00 ])); expect(bitstream.readFloatSync(32)).to.equal(-436); - bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0 ])); expect(bitstream.readFloatSync(32)).to.equal(0); - - bitstream.addBuffer(Buffer.from([ 0x41, 0x60, 0xae, 0x29, 0x71, 0xeb, 0x85, 0x1f ])); + bitstream.addBuffer(Buffer.from([0x42, 0xCD, 0x00, 0x00])); expect(bitstream.readFloatSync(32)).to.equal(102.5); + bitstream.addBuffer(Buffer.from([0xC3, 0xDA, 0x00, 0x00])); expect(bitstream.readFloatSync(32)).to.equal(-436); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(bitstream.readFloatSync(32)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0x41, 0x60, 0xae, 0x29, 0x71, 0xeb, 0x85, 0x1f])); expect(bitstream.readFloatSync(64)).to.equal(8745291.56); - bitstream.addBuffer(Buffer.from([ 0xc1, 0x14, 0x00, 0xa4, 0xae, 0x14, 0x7a, 0xe1 ])); + bitstream.addBuffer(Buffer.from([0xc1, 0x14, 0x00, 0xa4, 0xae, 0x14, 0x7a, 0xe1])); expect(bitstream.readFloatSync(64)).to.equal(-327721.17); - bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0, 0, 0, 0, 0 ])); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0, 0, 0, 0, 0])); expect(bitstream.readFloatSync(64)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xe1, 0x7a, 0x14, 0xae, 0xa4, 0x00, 0x14, 0xc1])); + expect(bitstream.readFloatSync(64, 'little-endian')).to.equal(-327721.17); + }); it('.readFloat() correctly handles floats', async () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0x42, 0xCD, 0x00, 0x00 ])); expect(await bitstream.readFloat(32)).to.equal(102.5); - bitstream.addBuffer(Buffer.from([ 0xC3, 0xDA, 0x00, 0x00 ])); expect(await bitstream.readFloat(32)).to.equal(-436); - bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0 ])); expect(await bitstream.readFloat(32)).to.equal(0); - - bitstream.addBuffer(Buffer.from([ 0x41, 0x60, 0xae, 0x29, 0x71, 0xeb, 0x85, 0x1f ])); + bitstream.addBuffer(Buffer.from([0x42, 0xCD, 0x00, 0x00])); expect(await bitstream.readFloat(32)).to.equal(102.5); + bitstream.addBuffer(Buffer.from([0xC3, 0xDA, 0x00, 0x00])); expect(await bitstream.readFloat(32)).to.equal(-436); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(await bitstream.readFloat(32)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0x41, 0x60, 0xae, 0x29, 0x71, 0xeb, 0x85, 0x1f])); expect(await bitstream.readFloat(64)).to.equal(8745291.56); - bitstream.addBuffer(Buffer.from([ 0xc1, 0x14, 0x00, 0xa4, 0xae, 0x14, 0x7a, 0xe1 ])); + bitstream.addBuffer(Buffer.from([0xc1, 0x14, 0x00, 0xa4, 0xae, 0x14, 0x7a, 0xe1])); expect(await bitstream.readFloat(64)).to.equal(-327721.17); - bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0, 0, 0, 0, 0 ])); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0, 0, 0, 0, 0])); expect(await bitstream.readFloat(64)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xe1, 0x7a, 0x14, 0xae, 0xa4, 0x00, 0x14, 0xc1])); + expect(await bitstream.readFloat(64, 'little-endian')).to.equal(-327721.17); }); it('.readFloat() can wait until data is available', async () => { let bitstream = new BitstreamReader(); - setTimeout(() => bitstream.addBuffer(Buffer.from([ 0x42, 0xCD, 0x00, 0x00 ])), 10); + setTimeout(() => bitstream.addBuffer(Buffer.from([0x42, 0xCD, 0x00, 0x00])), 10); expect(await bitstream.readFloat(32)).to.equal(102.5); }); @@ -423,7 +441,7 @@ describe('BitstreamReader', it => { it('peek() reads an unsigned integer without consuming it', async () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 37 ])); + bitstream.addBuffer(Buffer.from([37])); expect(await bitstream.peek(8)).to.equal(37); expect(bitstream.offset).to.equal(0); @@ -485,19 +503,22 @@ describe('BitstreamReader', it => { it('correctly handles NaN', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0x7F, 0xC0, 0x00, 0x00 ])); expect(bitstream.readFloatSync(32)).to.be.NaN; - - bitstream.addBuffer(Buffer.from([ 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])); + bitstream.addBuffer(Buffer.from([0x7F, 0xC0, 0x00, 0x00])); expect(bitstream.readFloatSync(32)).to.be.NaN; + + bitstream.addBuffer(Buffer.from([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); expect(bitstream.readFloatSync(64)).to.be.NaN; }); it('correctly handles Infinity', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([ 0x7f, 0x80, 0x00, 0x00 ])); + bitstream.addBuffer(Buffer.from([0x7f, 0x80, 0x00, 0x00])); expect(bitstream.readFloatSync(32)).not.to.be.finite; - - bitstream.addBuffer(Buffer.from([ 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])); + + bitstream.addBuffer(Buffer.from([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); expect(bitstream.readFloatSync(64)).not.to.be.finite; + + bitstream.addBuffer(Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f])); + expect(bitstream.readFloatSync(64, 'little-endian')).not.to.be.finite; }); it('.read() allows only one async read at a time', async () => { let bitstream = new BitstreamReader(); @@ -507,7 +528,7 @@ describe('BitstreamReader', it => { try { await bitstream.read(8); } catch (e) { caught = e; } - + expect(caught, `Expected read() to throw`).to.exist; }); it('.assure() allows only one async call at a time', async () => { @@ -518,7 +539,7 @@ describe('BitstreamReader', it => { try { await bitstream.assure(8); } catch (e) { caught = e; } - + expect(caught, `Expected assure() to throw`).to.exist; }); it('.readStringSync() reads a string correctly', () => { @@ -630,21 +651,21 @@ describe('BitstreamReader', it => { }); it('.readBytes() reads a buffer correctly when the data is already available', async () => { let bitstream = new BitstreamReader(); - let buf = Buffer.from([ 12, 42, 15 ]); + let buf = Buffer.from([12, 42, 15]); bitstream.addBuffer(buf); let buf2 = Buffer.alloc(3); await bitstream.readBytesBlocking(buf2); - expect(Array.from(buf2)).to.eql([ 12, 42, 15 ]); + expect(Array.from(buf2)).to.eql([12, 42, 15]); }); it('.readBytes() reads a buffer correctly when the data is already available', async () => { let bitstream = new BitstreamReader(); - let buf = Buffer.from([ 12, 42, 15 ]); + let buf = Buffer.from([12, 42, 15]); setTimeout(() => bitstream.addBuffer(buf), 10); let buf2 = Buffer.alloc(3); await bitstream.readBytesBlocking(buf2); - expect(Array.from(buf2)).to.eql([ 12, 42, 15 ]); + expect(Array.from(buf2)).to.eql([12, 42, 15]); }); it('.addBuffer() throws when called on an ended stream', async () => { let bitstream = new BitstreamReader(); @@ -716,25 +737,25 @@ describe('BitstreamReader', it => { let bitstream = new BitstreamReader(); expect(bitstream.ended).to.be.false; bitstream.end(); - expect (bitstream.ended).to.be.true; + expect(bitstream.ended).to.be.true; }); it('.end() causes pending assure() to reject', async () => { let bitstream = new BitstreamReader(); let thrown = bitstream.assure(8).then(() => false).catch(() => true); bitstream.end(); - expect (await thrown).to.be.true; + expect(await thrown).to.be.true; }); it('.end() causes pending read() to reject', async () => { let bitstream = new BitstreamReader(); let thrown = bitstream.read(8).then(() => false).catch(() => true); bitstream.end(); - expect (await thrown).to.be.true; + expect(await thrown).to.be.true; }); it('.end() does not cause a pending optional assure() to reject', async () => { let bitstream = new BitstreamReader(); let thrown = bitstream.assure(8, true).then(() => false).catch(() => true); bitstream.end(); - expect (await thrown).to.be.false; + expect(await thrown).to.be.false; }); it('.reset() throws if there is a pending operation', async () => { let bitstream = new BitstreamReader(); @@ -770,7 +791,7 @@ describe('BitstreamReader', it => { expect(bitstream.bufferIndex).to.equal(2); expect(bitstream.offset).to.equal(16); expect(bitstream.available).to.equal(8); - + bitstream.reset(); expect(bitstream.bufferIndex).to.equal(0); @@ -787,7 +808,7 @@ describe('BitstreamReader (generated)', it => { let view = new DataView(buf); for (let i = 0; i < 10; ++i) { - let num = Math.floor(Math.random() * 2**size); + let num = Math.floor(Math.random() * 2 ** size); view.setBigUint64(0, BigInt(num), false); let reader = new BitstreamReader(); reader.addBuffer(new Uint8Array(buf)); @@ -804,7 +825,7 @@ describe('BitstreamReader (generated)', it => { let view = new DataView(buf); for (let i = 0; i < 10; ++i) { - let num = Math.floor(Math.random() * 2**size); + let num = Math.floor(Math.random() * 2 ** size); view.setBigUint64(0, BigInt(num) << BigInt(1), false); let reader = new BitstreamReader(); reader.addBuffer(new Uint8Array(buf)); @@ -821,7 +842,7 @@ describe('BitstreamReader (generated)', it => { let view = new DataView(buf); for (let i = 0; i < 10; ++i) { - let num = Math.floor(Math.random() * 2**size); + let num = Math.floor(Math.random() * 2 ** size); view.setBigUint64(0, BigInt(num) << BigInt(4), false); let reader = new BitstreamReader(); reader.addBuffer(new Uint8Array(buf)); diff --git a/src/bitstream/reader.ts b/src/bitstream/reader.ts index 1f1df55..aceca70 100644 --- a/src/bitstream/reader.ts +++ b/src/bitstream/reader.ts @@ -6,13 +6,13 @@ let maskMap: Map; * Represents a request to read a number of bits */ interface BitstreamRequest { - resolve : (buffer : number) => void; + resolve: (buffer: number) => void; reject: (error: Error) => void; promise: Promise; - length : number; - signed? : boolean; - float? : boolean; - assure? : boolean; + length: number; + signed?: boolean; + float?: boolean; + assure?: boolean; } /** @@ -20,9 +20,9 @@ interface BitstreamRequest { * order */ export class BitstreamReader { - private buffers : Uint8Array[] = []; - private bufferedLength : number = 0; - private blockedRequest : BitstreamRequest = null; + private buffers: Uint8Array[] = []; + private bufferedLength: number = 0; + private blockedRequest: BitstreamRequest = null; private _offsetIntoBuffer = 0; private _bufferIndex = 0; private _offset = 0; @@ -59,14 +59,14 @@ export class BitstreamReader { set offset(value) { if (value < this._spentBufferSize) { throw new Error( - `Offset ${value} points into a discarded buffer! ` + `Offset ${value} points into a discarded buffer! ` + `If you need to seek backwards outside the current buffer, make sure to set retainBuffers=true` ); } let offsetIntoBuffer = value - this._spentBufferSize; let bufferIndex = 0; - + for (let i = 0, max = this.buffers.length; i < max; ++i) { let buf = this.buffers[i]; let size = buf.length * 8; @@ -126,7 +126,7 @@ export class BitstreamReader { * visited. If you enable this, you will need to remove buffers manually using * clean() */ - retainBuffers : boolean = false; + retainBuffers: boolean = false; /** * Remove any fully used up buffers. Only has an effect if retainBuffers is true. @@ -159,7 +159,7 @@ export class BitstreamReader { * @param length The number of bits to check for * @returns True if the required number of bits is available, false otherwise */ - isAvailable(length : number) { + isAvailable(length: number) { return this.bufferedLength >= length; } @@ -177,9 +177,9 @@ export class BitstreamReader { * @param options A set of options to control conversion into a string. @see StringEncodingOptions * @returns The resulting string */ - async readString(length : number, options? : StringEncodingOptions): Promise { + async readString(length: number, options?: StringEncodingOptions): Promise { this.ensureNoReadPending(); - await this.assure(8*length); + await this.assure(8 * length); return this.readStringSync(length, options); } @@ -190,10 +190,10 @@ export class BitstreamReader { * @param options A set of options to control conversion into a string. @see StringEncodingOptions * @returns The resulting string */ - readStringSync(length : number, options? : StringEncodingOptions): string { + readStringSync(length: number, options?: StringEncodingOptions): string { if (!options) options = {}; - + this.ensureNoReadPending(); let buffer = new Uint8Array(length); @@ -212,7 +212,7 @@ export class BitstreamReader { for (let i = 0, max = length; i < max; i += charLength) { let char = buffer[i]; if (charLength === 2) - char = (char << 8) | (buffer[i+1] ?? 0); + char = (char << 8) | (buffer[i + 1] ?? 0); if (char === 0) { firstTerminator = i; @@ -241,7 +241,7 @@ export class BitstreamReader { * @param length The number of bits to read * @returns The number read from the bitstream */ - peekSync(length : number) { + peekSync(length: number) { return this.readCoreSync(length, false); } @@ -251,19 +251,22 @@ export class BitstreamReader { * Skip the given number of bits. * @param length The number of bits to skip */ - skip(length : number) { + skip(length: number) { this.skippedLength += length; } - + /** * Read an unsigned integer of the given bit length synchronously. If there are not enough * bits available, an error is thrown. * * @param length The number of bits to read + * @param byteOrder The byte order to use when the length is greater than 8 and is a multiple of 8. + * Defaults to MSB (most significant byte). If the length is not a multiple of 8, + * this is unused * @returns The unsigned integer that was read */ - readSync(length : number): number { - return this.readCoreSync(length, true); + readSync(length: number, byteOrder?: "big-endian" | "little-endian"): number { + return this.readCoreSync(length, true, byteOrder); } /** @@ -274,7 +277,7 @@ export class BitstreamReader { * @param offset The offset into the buffer to write to. Defaults to zero * @param length The length of bytes to read. Defaults to the length of the array (sans the offset) */ - *readBytes(buffer : Uint8Array, offset : number = 0, length? : number): Generator { + *readBytes(buffer: Uint8Array, offset: number = 0, length?: number): Generator { length ??= buffer.length - offset; let bitOffset = this._offsetIntoBuffer % 8; @@ -315,10 +318,10 @@ export class BitstreamReader { // Non-byte-aligned, we need to construct bytes using bit-wise operations. // readSync is perfect for this - for (let i = offset, max = Math.min(buffer.length, offset+length); i < max; ++i) { + for (let i = offset, max = Math.min(buffer.length, offset + length); i < max; ++i) { if (!this.isAvailable(8)) yield max - i; - + buffer[i] = this.readSync(8); } } @@ -334,7 +337,7 @@ export class BitstreamReader { * @param offset The offset into the buffer to write to. Defaults to zero * @param length The length of bytes to read. Defaults to the length of the array (sans the offset) */ - readBytesSync(buffer : Uint8Array, offset : number = 0, length? : number): Uint8Array { + readBytesSync(buffer: Uint8Array, offset: number = 0, length?: number): Uint8Array { length ??= buffer.length - offset; let gen = this.readBytes(buffer, offset, length); @@ -356,14 +359,14 @@ export class BitstreamReader { * @param offset The offset into the buffer to write to. Defaults to zero * @param length The length of bytes to read. Defaults to the length of the array (sans the offset) */ - async readBytesBlocking(buffer : Uint8Array, offset : number = 0, length? : number) { + async readBytesBlocking(buffer: Uint8Array, offset: number = 0, length?: number) { length ??= buffer.length - offset; let gen = this.readBytes(buffer, offset, length); while (true) { let result = gen.next(); if (result.done === false) - await this.assure(result.value*8); + await this.assure(result.value * 8); else break; } @@ -376,11 +379,14 @@ export class BitstreamReader { * enough bits available, an error is thrown. * * @param length The number of bits to read + * @param byteOrder The byte order to use when the length is greater than 8 and is a multiple of 8. + * Defaults to MSB (most significant byte). If the length is not a multiple of 8, + * this is unused * @returns The signed integer that was read */ - readSignedSync(length : number): number { - const u = this.readSync(length); - const signBit = (2**(length - 1)); + readSignedSync(length: number, byteOrder: "big-endian" | "little-endian" = 'big-endian'): number { + const u = this.readSync(length, byteOrder); + const signBit = (2 ** (length - 1)); const mask = signBit - 1; return (u & signBit) === 0 ? u : -((~(u - 1) & mask) >>> 0); } @@ -397,19 +403,22 @@ export class BitstreamReader { } - + /** * Read an IEEE 754 floating point value with the given bit length (32 or 64). If there are not * enough bits available, an error is thrown. * * @param length Must be 32 for 32-bit single-precision or 64 for 64-bit double-precision. All * other values result in TypeError + * @param byteOrder The byte order to use when the length is greater than 8 and is a multiple of 8. + * Defaults to MSB (most significant byte). If the length is not a multiple of 8, + * this is unused * @returns The floating point value that was read */ - readFloatSync(length : number): number { + readFloatSync(length: number, byteOrder: "big-endian" | "little-endian" = 'big-endian'): number { if (length !== 32 && length !== 64) throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); - + if (!this.isAvailable(length)) throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); @@ -418,11 +427,11 @@ export class BitstreamReader { for (let i = 0, max = buf.byteLength; i < max; ++i) view.setUint8(i, this.readSync(8)); - + if (length === 32) - return view.getFloat32(0, false); + return view.getFloat32(0, byteOrder === 'little-endian'); else if (length === 64) - return view.getFloat64(0, false); + return view.getFloat64(0, byteOrder === 'little-endian'); } private readByteAligned(consume: boolean): number { @@ -460,7 +469,7 @@ export class BitstreamReader { } } - private readShortByteAligned(consume: boolean, byteOrder: 'lsb' | 'msb'): number { + private readShortByteAligned(consume: boolean, byteOrder: "big-endian" | "little-endian"): number { let buffer = this.buffers[this._bufferIndex]; let bufferOffset = this._offsetIntoBuffer / 8; let firstByte = buffer[bufferOffset]; @@ -474,7 +483,7 @@ export class BitstreamReader { if (consume) this.consume(16); - if (byteOrder === 'lsb') { + if (byteOrder === 'little-endian') { let carry = firstByte; firstByte = secondByte; secondByte = carry; @@ -483,7 +492,7 @@ export class BitstreamReader { return firstByte << 8 | secondByte; } - private readLongByteAligned(consume: boolean, byteOrder: 'lsb' | 'msb'): number { + private readLongByteAligned(consume: boolean, byteOrder: "big-endian" | "little-endian"): number { let bufferIndex = this._bufferIndex; let buffer = this.buffers[bufferIndex]; let bufferOffset = this._offsetIntoBuffer / 8; @@ -518,7 +527,7 @@ export class BitstreamReader { let highBit = ((firstByte & 0x80) !== 0); firstByte &= ~0x80; - if (byteOrder === 'lsb') { + if (byteOrder === 'little-endian') { let b1 = fourthByte; let b2 = thirdByte; let b3 = secondByte; @@ -533,12 +542,12 @@ export class BitstreamReader { let value = firstByte << 24 | secondByte << 16 | thirdByte << 8 | fourthByte; if (highBit) - value += 2**31; - + value += 2 ** 31; + return value; } - private read3ByteAligned(consume: boolean, byteOrder: 'lsb' | 'msb'): number { + private read3ByteAligned(consume: boolean, byteOrder: "big-endian" | "little-endian"): number { let bufferIndex = this._bufferIndex; let buffer = this.buffers[bufferIndex]; let bufferOffset = this._offsetIntoBuffer / 8; @@ -564,7 +573,7 @@ export class BitstreamReader { if (consume) this.consume(24); - if (byteOrder === 'lsb') { + if (byteOrder === 'little-endian') { let carry = firstByte; firstByte = thirdByte; thirdByte = carry; @@ -592,9 +601,9 @@ export class BitstreamReader { * this is unused * @returns */ - private readCoreSync(length : number, consume : boolean, byteOrder: 'msb' | 'lsb' = 'msb'): number { + private readCoreSync(length: number, consume: boolean, byteOrder: "big-endian" | "little-endian" = 'big-endian'): number { this.ensureNoReadPending(); - + if (this.available < length) throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); @@ -642,16 +651,16 @@ export class BitstreamReader { let bitOffset = offset % 8; let bitContribution: number; let byte = buffer[byteOffset]; - + bitContribution = Math.min(8 - bitOffset, remainingLength); - + if (useBigInt) { - bigValue = (bigValue << BigInt(bitContribution)) - | ((BigInt(buffer[byteOffset]) >> (BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset))) + bigValue = (bigValue << BigInt(bitContribution)) + | ((BigInt(buffer[byteOffset]) >> (BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset))) & BigInt(this.maskOf(bitContribution))); } else { - value = (value << bitContribution) - | ((byte >> (8 - bitContribution - bitOffset)) + value = (value << bitContribution) + | ((byte >> (8 - bitContribution - bitOffset)) & this.maskOf(bitContribution)); } @@ -660,7 +669,7 @@ export class BitstreamReader { offset += bitContribution; remainingLength -= bitContribution | 0; - if (offset >= buffer.length*8) { + if (offset >= buffer.length * 8) { bufferIndex += 1; offset = 0; } @@ -678,10 +687,10 @@ export class BitstreamReader { private adjustSkip() { if (this.skippedLength <= 0) return; - + // First, remove any buffers that are completely skipped - while (this.buffers && this.skippedLength > this.buffers[0].length*8-this._offsetIntoBuffer) { - this.skippedLength -= (this.buffers[0].length*8 - this._offsetIntoBuffer); + while (this.buffers && this.skippedLength > this.buffers[0].length * 8 - this._offsetIntoBuffer) { + this.skippedLength -= (this.buffers[0].length * 8 - this._offsetIntoBuffer); this._offsetIntoBuffer = 0; this.buffers.shift(); } @@ -703,7 +712,7 @@ export class BitstreamReader { * @returns A promise which will resolve when the requested number of bits are available. Rejects if the stream * ends before the request is satisfied, unless optional parameter is true. */ - assure(length : number, optional = false) : Promise { + assure(length: number, optional = false): Promise { this.ensureNoReadPending(); if (this.bufferedLength >= length) { @@ -725,9 +734,9 @@ export class BitstreamReader { * @param length The number of bits to read * @returns A promise which resolves to the unsigned integer once it is read */ - read(length : number) : Promise { + read(length: number): Promise { this.ensureNoReadPending(); - + if (this.available >= length) { return Promise.resolve(this.readSync(length)); } else { @@ -740,13 +749,16 @@ export class BitstreamReader { * available for the operation. * * @param length The number of bits to read + * @param byteOrder The byte order to use when the length is greater than 8 and is a multiple of 8. + * Defaults to MSB (most significant byte). If the length is not a multiple of 8, + * this is unused * @returns A promise which resolves to the signed integer value once it is read */ - readSigned(length : number) : Promise { + readSigned(length: number, byteOrder?: "big-endian" | "little-endian"): Promise { this.ensureNoReadPending(); - + if (this.available >= length) { - return Promise.resolve(this.readSignedSync(length)); + return Promise.resolve(this.readSignedSync(length, byteOrder)); } else { return this.block({ length, signed: true }); } @@ -782,13 +794,16 @@ export class BitstreamReader { * * @param length The number of bits to read (must be 32 for 32-bit single-precision or * 64 for 64-bit double-precision) + * @param byteOrder The byte order to use when the length is greater than 8 and is a multiple of 8. + * Defaults to MSB (most significant byte). If the length is not a multiple of 8, + * this is unused * @returns A promise which resolves to the floating point value once it is read */ - readFloat(length : number) : Promise { + readFloat(length: number, byteOrder?: "big-endian" | "little-endian"): Promise { this.ensureNoReadPending(); - + if (this.available >= length) { - return Promise.resolve(this.readFloatSync(length)); + return Promise.resolve(this.readFloatSync(length, byteOrder)); } else { return this.block({ length, float: true }); } @@ -800,7 +815,7 @@ export class BitstreamReader { * to complete the operation, the operation is delayed until enough bits become available. * @returns A promise which resolves iwth the number read from the bitstream */ - async peek(length : number): Promise { + async peek(length: number): Promise { await this.assure(length); return this.peekSync(length); } @@ -809,7 +824,7 @@ export class BitstreamReader { * Add a buffer onto the end of the bitstream. * @param buffer The buffer to add to the bitstream */ - addBuffer(buffer : Uint8Array) { + addBuffer(buffer: Uint8Array) { if (this._ended) throw new Error(`Cannot add buffers to a reader which has been marked as ended without calling reset() first`); diff --git a/src/bitstream/writer.ts b/src/bitstream/writer.ts index 0f90bbc..d90ae7d 100644 --- a/src/bitstream/writer.ts +++ b/src/bitstream/writer.ts @@ -10,13 +10,13 @@ export class BitstreamWriter { * @param stream The writable stream to write to * @param bufferSize The number of bytes to buffer before flushing onto the writable */ - constructor(public stream : Writable, readonly bufferSize = 1) { + constructor(public stream: Writable, readonly bufferSize = 1) { this.buffer = new Uint8Array(bufferSize); } - private pendingByte : bigint = BigInt(0); - private pendingBits : number = 0; - private buffer : Uint8Array; + private pendingByte: bigint = BigInt(0); + private pendingBits: number = 0; + private buffer: Uint8Array; private bufferedBytes = 0; private _offset = 0; @@ -59,7 +59,7 @@ export class BitstreamWriter { this.pendingByte = BigInt(0); } } - + flush() { if (this.bufferedBytes > 0) { this.stream.write(Buffer.from(this.buffer.slice(0, this.bufferedBytes))); @@ -76,7 +76,7 @@ export class BitstreamWriter { * @param value The string to decode and write * @param encoding The encoding to use when writing the string. Defaults to utf-8 */ - writeString(byteCount : number, value : string, encoding : string = 'utf-8') { + writeString(byteCount: number, value: string, encoding: string = 'utf-8') { if (encoding === 'utf-8') { let buffer = new Uint8Array(byteCount); let strBuf = this.textEncoder.encode(value); @@ -100,7 +100,7 @@ export class BitstreamWriter { * @param buffer The buffer to write * @deprecated Use writeBytes() instead */ - writeBuffer(buffer : Uint8Array) { + writeBuffer(buffer: Uint8Array) { this.writeBytes(buffer); } @@ -110,7 +110,7 @@ export class BitstreamWriter { * a set of bytes at a non=zero bit offset if you wish. * @param chunk The buffer to write */ - writeBytes(chunk : Uint8Array, offset = 0, length? : number) { + writeBytes(chunk: Uint8Array, offset = 0, length?: number) { length ??= chunk.length - offset; // Fast path: Byte-aligned @@ -128,11 +128,11 @@ export class BitstreamWriter { return; } - for (let i = offset, max = Math.min(chunk.length, offset+length); i < max; ++i) + for (let i = offset, max = Math.min(chunk.length, offset + length); i < max; ++i) this.write(8, chunk[i]); } - private min(a : bigint, b : bigint) { + private min(a: bigint, b: bigint) { if (a < b) return a; else @@ -145,10 +145,10 @@ export class BitstreamWriter { * @param length The number of bits to write * @param value The number to write */ - write(length : number, value : number) { + write(length: number, value: number, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (value === void 0 || value === null) value = 0; - + value = Number(value); if (Number.isNaN(value)) @@ -157,9 +157,11 @@ export class BitstreamWriter { throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); let valueN = BigInt(value % Math.pow(2, length)); - + let remainingLength = length; + // FIXME: Support little-endian + if (byteOrder === 'little-endian') throw new Error("Little-endian not yet supported in write!"); while (remainingLength > 0) { let shift = BigInt(8 - this.pendingBits - remainingLength); let contribution = (shift >= 0 ? (valueN << shift) : (valueN >> -shift)); @@ -168,7 +170,7 @@ export class BitstreamWriter { this.pendingByte = this.pendingByte | contribution; this.pendingBits += writtenLength; this._offset += writtenLength; - + remainingLength -= writtenLength; valueN = valueN % BigInt(Math.pow(2, remainingLength)); @@ -182,13 +184,16 @@ export class BitstreamWriter { } } - writeSigned(length : number, value : number) { + writeSigned(length: number, value: number, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (value === undefined || value === null) value = 0; - + + // FIXME: Support little-endian + if (byteOrder === 'little-endian') throw new Error("Little-endian is not yet supported in write!"); + const originalValue = value; - const max = 2**(length - 1) - 1; // ie 127 - const min = -(2**(length - 1)); // ie -128 + const max = 2 ** (length - 1) - 1; // ie 127 + const min = -(2 ** (length - 1)); // ie -128 value = Number(value); @@ -200,14 +205,18 @@ export class BitstreamWriter { throw new TypeError(`Cannot represent ${value} in I${length} format: Value too large (min=${min}, max=${max})`); if (value < min) throw new TypeError(`Cannot represent ${value} in I${length} format: Negative value too small (min=${min}, max=${max})`); - + return this.write(length, value >= 0 ? value : (~(-value) + 1) >>> 0); } - writeFloat(length : number, value : number) { + writeFloat(length: number, value: number, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (length !== 32 && length !== 64) throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); - + + // FIXME: Support little-endian + if (byteOrder === 'little-endian') throw new Error("Little-endian is not yet supported in write!"); + + let buf = new ArrayBuffer(length / 8); let view = new DataView(buf); @@ -232,15 +241,15 @@ export class BitstreamMeasurer extends BitstreamWriter { bitLength = 0; - writeString(byteCount : number, value : string, encoding : string = 'utf-8') { + writeString(byteCount: number, value: string, encoding: string = 'utf-8') { this.bitLength += byteCount * 8; } - writeBuffer(buffer : Uint8Array) { + writeBuffer(buffer: Uint8Array) { this.bitLength += buffer.length * 8; } - write(length : number, value : number) { + write(length: number, value: number) { this.bitLength += length; } } diff --git a/src/elements/number-serializer.ts b/src/elements/number-serializer.ts index 7878597..ce37371 100644 --- a/src/elements/number-serializer.ts +++ b/src/elements/number-serializer.ts @@ -10,8 +10,8 @@ import { summarizeField } from "./utils"; * Serializes numbers to/from bitstreams */ export class NumberSerializer implements Serializer { - *read(reader: BitstreamReader, type : any, parent : BitstreamElement, field: FieldDefinition): Generator { - let length : number; + *read(reader: BitstreamReader, type: any, parent: BitstreamElement, field: FieldDefinition): Generator { + let length: number; try { length = resolveLength(field.length, parent, field); } catch (e) { @@ -20,23 +20,23 @@ export class NumberSerializer implements Serializer { if (!reader.isAvailable(length)) yield { remaining: length, contextHint: () => summarizeField(field) }; - + let format = field.options?.number?.format ?? 'unsigned'; if (format === 'unsigned') - return reader.readSync(length); + return reader.readSync(length, field.options?.number?.byteOrder); else if (format === 'signed') - return reader.readSignedSync(length); + return reader.readSignedSync(length, field.options?.number?.byteOrder); else if (format === 'float') - return reader.readFloatSync(length); + return reader.readFloatSync(length, field.options?.number?.byteOrder); else throw new TypeError(`Unsupported number format '${format}'`); } - write(writer: BitstreamWriter, type : any, instance: any, field: FieldDefinition, value: any) { + write(writer: BitstreamWriter, type: any, instance: any, field: FieldDefinition, value: any) { if (value === undefined) value = 0; - let length : number; + let length: number; try { length = resolveLength(field.length, instance, field); } catch (e) { @@ -46,11 +46,11 @@ export class NumberSerializer implements Serializer { let format = field.options?.number?.format ?? 'unsigned'; if (format === 'unsigned') - writer.write(length, value); + writer.write(length, value, field.options?.number?.byteOrder); else if (format === 'signed') - writer.writeSigned(length, value); + writer.writeSigned(length, value, field.options?.number?.byteOrder); else if (format === 'float') - writer.writeFloat(length, value); + writer.writeFloat(length, value, field.options?.number?.byteOrder); else throw new TypeError(`Unsupported number format '${format}'`); } From afdfef8988586a530cc0c30a3ff7333b191ef15c Mon Sep 17 00:00:00 2001 From: dianlight Date: Tue, 15 Oct 2024 02:00:05 +0200 Subject: [PATCH 2/4] Correct uint32 and int32 padding read --- src/bitstream/reader.test.ts | 114 ++++++++++++++++++- src/bitstream/reader.ts | 117 +++++++++++-------- src/bitstream/writer.test.ts | 211 +++++++++++++++++++++++------------ src/bitstream/writer.ts | 84 +++++++++----- 4 files changed, 374 insertions(+), 152 deletions(-) diff --git a/src/bitstream/reader.test.ts b/src/bitstream/reader.test.ts index ad64ad9..88105df 100644 --- a/src/bitstream/reader.test.ts +++ b/src/bitstream/reader.test.ts @@ -1,5 +1,5 @@ import { expect } from "chai"; -import { describe } from "razmin"; +import { describe, skip } from "razmin"; import { BitstreamReader } from "./reader"; describe('BitstreamReader', it => { @@ -343,6 +343,52 @@ describe('BitstreamReader', it => { expect(bitstream.readSync(4)).to.equal(0b0100); }); + it('.readSync() correctly handles unsigned integers', () => { + let bitstream = new BitstreamReader(); + + bitstream.addBuffer(Buffer.from([0xFB])); expect(bitstream.readSync(8)).to.equal(0xFB); + bitstream.addBuffer(Buffer.from([5])); expect(bitstream.readSync(8)).to.equal(5); + bitstream.addBuffer(Buffer.from([0])); expect(bitstream.readSync(8)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xFC, 0x0A])); expect(bitstream.readSync(16)).to.equal(0xFC0A); + bitstream.addBuffer(Buffer.from([0x03, 0xF6])); expect(bitstream.readSync(16)).to.equal(0x03F6); + bitstream.addBuffer(Buffer.from([0, 0])); expect(bitstream.readSync(16)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0x0A, 0xFC])); expect(bitstream.readSync(16, 'little-endian')).to.equal(0xFC0A); + bitstream.addBuffer(Buffer.from([0xF6, 0x03])); expect(bitstream.readSync(16, 'little-endian')).to.equal(0x03F6); + bitstream.addBuffer(Buffer.from([0, 0])); expect(bitstream.readSync(16, 'little-endian')).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xFF, 0xFE, 0x70, 0x40])); expect(bitstream.readSync(32)).to.equal(0xFFFE7040); + bitstream.addBuffer(Buffer.from([0x00, 0x01, 0x8F, 0xC0])); expect(bitstream.readSync(32)).to.equal(0x00018FC0); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(bitstream.readSync(32)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0x40, 0x70, 0xFE, 0xFF])); expect(bitstream.readSync(32, 'little-endian')).to.equal(0xFFFE7040); + bitstream.addBuffer(Buffer.from([0xC0, 0x8F, 0x01, 0x00])); expect(bitstream.readSync(32, 'little-endian')).to.equal(0x00018FC0); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(bitstream.readSync(32)).to.equal(0); + }); + it('.read() correctly handles unsigned integers', async () => { + let bitstream = new BitstreamReader(); + bitstream.addBuffer(Buffer.from([0xFB])); expect(await bitstream.read(8)).to.equal(0xFB); + bitstream.addBuffer(Buffer.from([5])); expect(await bitstream.read(8)).to.equal(5); + bitstream.addBuffer(Buffer.from([0])); expect(await bitstream.read(8)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0x0A, 0xFC])); expect(await bitstream.read(16)).to.equal(0x0AFC); + bitstream.addBuffer(Buffer.from([0xF6, 0x03])); expect(await bitstream.read(16)).to.equal(0xF603); + bitstream.addBuffer(Buffer.from([0, 0])); expect(await bitstream.read(16)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xFC, 0x0A])); expect(await bitstream.read(16, 'little-endian')).to.equal(0x0AFC); + bitstream.addBuffer(Buffer.from([0x03, 0xF6])); expect(await bitstream.read(16, 'little-endian')).to.equal(0xF603); + bitstream.addBuffer(Buffer.from([0, 0])); expect(await bitstream.read(16, 'little-endian')).to.equal(0); + + bitstream.addBuffer(Buffer.from([0xFF, 0xFE, 0x70, 0x40])); expect(await bitstream.read(32)).to.equal(0xFFFE7040); + bitstream.addBuffer(Buffer.from([0x00, 0x01, 0x8F, 0xC0])); expect(await bitstream.read(32)).to.equal(0x00018FC0); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(await bitstream.read(32)).to.equal(0); + + bitstream.addBuffer(Buffer.from([0x40, 0x70, 0xFE, 0xFF])); expect(await bitstream.read(32, 'little-endian')).to.equal(0xFFFE7040); + bitstream.addBuffer(Buffer.from([0xC0, 0x8F, 0x01, 0x00])); expect(await bitstream.read(32, 'little-endian')).to.equal(0x00018FC0); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(await bitstream.read(32)).to.equal(0); + }); + it('.readSignedSync() correctly handles signed integers', () => { let bitstream = new BitstreamReader(); @@ -354,11 +400,17 @@ describe('BitstreamReader', it => { bitstream.addBuffer(Buffer.from([0x03, 0xF6])); expect(bitstream.readSignedSync(16)).to.equal(1014); bitstream.addBuffer(Buffer.from([0, 0])); expect(bitstream.readSignedSync(16)).to.equal(0); + bitstream.addBuffer(Buffer.from([0x0A, 0xFC])); expect(bitstream.readSignedSync(16, 'little-endian')).to.equal(-1014); + bitstream.addBuffer(Buffer.from([0xF6, 0x03])); expect(bitstream.readSignedSync(16, 'little-endian')).to.equal(1014); + bitstream.addBuffer(Buffer.from([0, 0])); expect(bitstream.readSignedSync(16, 'big-endian')).to.equal(0); + bitstream.addBuffer(Buffer.from([0xFF, 0xFE, 0x70, 0x40])); expect(bitstream.readSignedSync(32)).to.equal(-102336); bitstream.addBuffer(Buffer.from([0x00, 0x01, 0x8F, 0xC0])); expect(bitstream.readSignedSync(32)).to.equal(102336); bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(bitstream.readSignedSync(32)).to.equal(0); - bitstream.addBuffer(Buffer.from([0xFF, 0x01])); expect(bitstream.readSignedSync(16, 'little-endian')).to.equal(0x01FF); + bitstream.addBuffer(Buffer.from([0x40, 0x70, 0xFE, 0xFF])); expect(bitstream.readSignedSync(32, 'little-endian')).to.equal(-102336); + bitstream.addBuffer(Buffer.from([0xC0, 0x8F, 0x01, 0x00])); expect(bitstream.readSignedSync(32, 'little-endian')).to.equal(102336); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(bitstream.readSignedSync(32, 'little-endian')).to.equal(0); }); it('.readSigned() correctly handles signed integers', async () => { let bitstream = new BitstreamReader(); @@ -370,11 +422,17 @@ describe('BitstreamReader', it => { bitstream.addBuffer(Buffer.from([0x03, 0xF6])); expect(await bitstream.readSigned(16)).to.equal(1014); bitstream.addBuffer(Buffer.from([0, 0])); expect(await bitstream.readSigned(16)).to.equal(0); + bitstream.addBuffer(Buffer.from([0xFC, 0x0A].reverse())); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(-1014); + bitstream.addBuffer(Buffer.from([0x03, 0xF6].reverse())); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(1014); + bitstream.addBuffer(Buffer.from([0, 0])); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(0); + bitstream.addBuffer(Buffer.from([0xFF, 0xFE, 0x70, 0x40])); expect(await bitstream.readSigned(32)).to.equal(-102336); bitstream.addBuffer(Buffer.from([0x00, 0x01, 0x8F, 0xC0])); expect(await bitstream.readSigned(32)).to.equal(102336); bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(await bitstream.readSigned(32)).to.equal(0); - bitstream.addBuffer(Buffer.from([0xFF, 0x01])); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(0x01FF); + bitstream.addBuffer(Buffer.from([0x40, 0x70, 0xFE, 0xFF])); expect(await bitstream.readSigned(32, 'little-endian')).to.equal(-102336); + bitstream.addBuffer(Buffer.from([0xC0, 0x8F, 0x01, 0x00])); expect(await bitstream.readSigned(32, 'little-endian')).to.equal(102336); + bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(await bitstream.readSigned(32, 'little-endian')).to.equal(0); }); it('.readSigned() can wait until data is available', async () => { let bitstream = new BitstreamReader(); @@ -816,6 +874,18 @@ describe('BitstreamReader (generated)', it => { expect(reader.readSync(size), `Test number #${i} (${num}) should have been read properly`).to.equal(num); } }); + if (size > 8 && (size % 8 == 0) && size <= 32) it(`reads ${size}bit values correctly (LE)`, async () => { + let buf = new ArrayBuffer(8); + let view = new DataView(buf); + + for (let i = 0; i < 10; ++i) { + let num = Math.floor(Math.random() * 2 ** size); + view.setBigUint64(0, BigInt(num), true); + let reader = new BitstreamReader(); + reader.addBuffer(new Uint8Array(buf)); + expect(reader.readSync(size, 'little-endian'), `Test number #${i} (${num}) should have been read properly`).to.equal(num); + } + }); } for (let size = 1; size < 52; ++size) { @@ -833,6 +903,25 @@ describe('BitstreamReader (generated)', it => { expect(reader.readSync(size), `Test number #${i} (${num}) should have been read properly`).to.equal(num); } }); + if (size > 8 && (size % 8 == 0) && size <= 32) it(`reads cross-byte ${size}bit values correctly [1-bit offset] LE`, async () => { + let buf = new ArrayBuffer(8); + let view = new DataView(buf); + + for (let i = 0; i < 10; ++i) { + let num = Math.floor(Math.random() * 2 ** size); + view.setBigUint64(0, BigInt(num), true); + let reader = new BitstreamReader(); + let shifted = new Uint8Array(buf).reduce((prev, cur, index, arr) => { + prev[index] = cur >> 1 | prev[index]; + prev[index + 1] = cur << 7; + // console.log(`Index ${index} ${cur.toString(2).padStart(8, '0')} -> ${prev[index].toString(2).padStart(8, '0')}:${prev[index + 1].toString(2).padStart(8, '0')}`) + return prev; + }, new Uint8Array(buf.byteLength + 1)); + reader.addBuffer(shifted); + reader.readSync(1); + expect(reader.readSync(size, 'little-endian'), `Test number #${i} (${num}) should have been read properly`).to.equal(num); + } + }); } for (let size = 1; size < 49; ++size) { @@ -850,5 +939,24 @@ describe('BitstreamReader (generated)', it => { expect(reader.readSync(size), `Test number #${i} (${num}) should have been read properly`).to.equal(num); } }); + if (size > 8 && (size % 8 == 0) && size <= 32) it(`reads cross-byte ${size}bit values correctly [4-bit offset] LE`, async () => { + let buf = new ArrayBuffer(8); + let view = new DataView(buf); + + for (let i = 0; i < 10; ++i) { + let num = Math.floor(Math.random() * 2 ** size); + view.setBigUint64(0, BigInt(num), true); + let reader = new BitstreamReader(); + let shifted = new Uint8Array(buf).reduce((prev, cur, index, arr) => { + prev[index] = cur >> 4 | prev[index]; + prev[index + 1] = cur << 4; + // console.log(`Index ${index} ${cur.toString(2).padStart(8, '0')} -> ${prev[index].toString(2).padStart(8, '0')}:${prev[index + 1].toString(2).padStart(8, '0')}`) + return prev; + }, new Uint8Array(buf.byteLength + 1)); + reader.addBuffer(shifted); + reader.readSync(4); + expect(reader.readSync(size, 'little-endian'), `Test number #${i} (${num}) should have been read properly`).to.equal(num); + } + }); } }); \ No newline at end of file diff --git a/src/bitstream/reader.ts b/src/bitstream/reader.ts index aceca70..f747ed4 100644 --- a/src/bitstream/reader.ts +++ b/src/bitstream/reader.ts @@ -497,53 +497,59 @@ export class BitstreamReader { let buffer = this.buffers[bufferIndex]; let bufferOffset = this._offsetIntoBuffer / 8; - let firstByte = buffer[bufferOffset++]; - if (bufferOffset >= buffer.length) { - buffer = this.buffers[++bufferIndex]; - bufferOffset = 0; - } - - let secondByte = buffer[bufferOffset++]; - if (bufferOffset >= buffer.length) { - buffer = this.buffers[++bufferIndex]; - bufferOffset = 0; - } - - let thirdByte = buffer[bufferOffset++]; - if (bufferOffset >= buffer.length) { - buffer = this.buffers[++bufferIndex]; - bufferOffset = 0; - } - - let fourthByte = buffer[bufferOffset++]; - if (bufferOffset >= buffer.length) { - buffer = this.buffers[++bufferIndex]; - bufferOffset = 0; - } - + const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); + + const value = dv.getUint32(bufferOffset, byteOrder === 'little-endian'); + bufferOffset += 4; + /* + let firstByte = buffer[bufferOffset++]; + if (bufferOffset >= buffer.length) { + buffer = this.buffers[++bufferIndex]; + bufferOffset = 0; + } + + let secondByte = buffer[bufferOffset++]; + if (bufferOffset >= buffer.length) { + buffer = this.buffers[++bufferIndex]; + bufferOffset = 0; + } + + let thirdByte = buffer[bufferOffset++]; + if (bufferOffset >= buffer.length) { + buffer = this.buffers[++bufferIndex]; + bufferOffset = 0; + } + + let fourthByte = buffer[bufferOffset++]; + if (bufferOffset >= buffer.length) { + buffer = this.buffers[++bufferIndex]; + bufferOffset = 0; + } + */ if (consume) this.consume(32); - - let highBit = ((firstByte & 0x80) !== 0); - firstByte &= ~0x80; - - if (byteOrder === 'little-endian') { - let b1 = fourthByte; - let b2 = thirdByte; - let b3 = secondByte; - let b4 = firstByte; - - firstByte = b1; - secondByte = b2; - thirdByte = b3; - fourthByte = b4; - } - - let value = firstByte << 24 | secondByte << 16 | thirdByte << 8 | fourthByte; - - if (highBit) - value += 2 ** 31; - + /* + let highBit = ((firstByte & 0x80) !== 0); + firstByte &= ~0x80; + + if (byteOrder === 'little-endian') { + let b1 = fourthByte; + let b2 = thirdByte; + let b3 = secondByte; + let b4 = firstByte; + + firstByte = b1; + secondByte = b2; + thirdByte = b3; + fourthByte = b4; + } + + let value = firstByte << 24 | secondByte << 16 | thirdByte << 8 | fourthByte; + + if (highBit) + value += 2 ** 31; + + */ return value; } @@ -654,6 +660,20 @@ export class BitstreamReader { bitContribution = Math.min(8 - bitOffset, remainingLength); + // if (useBigInt) { + // const dv = new DataView(new ArrayBuffer(8)); + // dv.setBigUint64(0, (bigValue << BigInt(bitContribution)) + // | ((BigInt(buffer[byteOffset]) >> (BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset))) + // & BigInt(this.maskOf(bitContribution))), false); + // bigValue = dv.getBigUint64(0, byteOrder == 'little-endian'); + // } else { + // const dv = new DataView(new ArrayBuffer(4)); + // dv.setUint32(0, (value << bitContribution) + // | ((byte >> (8 - bitContribution - bitOffset)) + // & this.maskOf(bitContribution)), false); + // value = dv.getUint32(0, byteOrder == 'little-endian'); + // } + if (useBigInt) { bigValue = (bigValue << BigInt(bitContribution)) | ((BigInt(buffer[byteOffset]) >> (BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset))) @@ -732,13 +752,16 @@ export class BitstreamReader { * available for the operation. * * @param length The number of bits to read + * @param byteOrder The byte order to use when the length is greater than 8 and is a multiple of 8. + * Defaults to MSB (most significant byte). If the length is not a multiple of 8, + * this is unused * @returns A promise which resolves to the unsigned integer once it is read */ - read(length: number): Promise { + read(length: number, byteOrder?: "big-endian" | "little-endian"): Promise { this.ensureNoReadPending(); if (this.available >= length) { - return Promise.resolve(this.readSync(length)); + return Promise.resolve(this.readSync(length, byteOrder)); } else { return this.block({ length }); } diff --git a/src/bitstream/writer.test.ts b/src/bitstream/writer.test.ts index f61287f..5f85e0e 100644 --- a/src/bitstream/writer.test.ts +++ b/src/bitstream/writer.test.ts @@ -4,8 +4,8 @@ import { BitstreamWriter } from "./writer"; describe('BitstreamWriter', it => { it('works for bit writes', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(1, 0b1); writer.write(1, 0b0); @@ -28,8 +28,8 @@ describe('BitstreamWriter', it => { expect(bufs[1][0]).to.equal(0b01100110); }); it('works for short writes', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(3, 0b010); writer.write(3, 0b101); @@ -38,16 +38,16 @@ describe('BitstreamWriter', it => { expect(bufs[0][0]).to.equal(0b01010111); }); it('works for full-byte writes', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(8, 0b01010111); expect(bufs.length).to.equal(1); expect(bufs[0][0]).to.equal(0b01010111); }); it('works for offset full-byte writes', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(4, 0b1111); writer.write(8, 0b01010111); @@ -57,8 +57,8 @@ describe('BitstreamWriter', it => { expect(bufs[1][0]).to.equal(0b01111111); }); it('works for large writes (1)', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(16, 0b1111111100000000); expect(bufs.length).to.equal(2); @@ -66,17 +66,35 @@ describe('BitstreamWriter', it => { expect(bufs[1][0]).to.equal(0b00000000); }); it('works for large writes (2)', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(16, 0b0101010110101010); expect(bufs.length).to.equal(2); expect(bufs[0][0]).to.equal(0b01010101); expect(bufs[1][0]).to.equal(0b10101010); }); + it('works for large writes (1) LE', () => { + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } + let writer = new BitstreamWriter(fakeStream); + writer.write(16, 0b1111111100000000, 'little-endian'); + expect(bufs.length).to.equal(2); + expect(bufs[0][0]).to.equal(0b00000000); + expect(bufs[1][0]).to.equal(0b11111111); + }); + it('works for large writes (2) LE', () => { + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } + let writer = new BitstreamWriter(fakeStream); + writer.write(16, 0b0101010110101010, 'little-endian'); + expect(bufs.length).to.equal(2); + expect(bufs[0][0]).to.equal(0b10101010); + expect(bufs[1][0]).to.equal(0b01010101); + }); it('works for offset large writes', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(4, 0b1111); writer.write(16, 0b0101010110101010); @@ -87,9 +105,22 @@ describe('BitstreamWriter', it => { expect(bufs[1][0]).to.equal(0b01011010); expect(bufs[2][0]).to.equal(0b10101111); }); + it('works for offset large writes LE', () => { + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } + let writer = new BitstreamWriter(fakeStream); + writer.write(4, 0b1111); + writer.write(16, 0b0101010110101010, 'little-endian'); + writer.write(4, 0b1111); + + expect(bufs.length).to.equal(3); + expect(bufs[0][0]).to.equal(0b11111010); + expect(bufs[1][0]).to.equal(0b10100101); + expect(bufs[2][0]).to.equal(0b01011111); + }); it('respects configured buffer size', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); writer.write(8, 0b11111100); expect(bufs.length).to.equal(0); @@ -108,8 +139,8 @@ describe('BitstreamWriter', it => { expect(bufs[1][1]).to.equal(0b11111111); }); it('throws when writing NaN as an unsigned integer', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); let caught; @@ -121,8 +152,8 @@ describe('BitstreamWriter', it => { expect(caught, `Expected write(8, NaN) to throw an exception`).to.exist; }); it('throws when writing Infinity as an unsigned integer', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); let caught; @@ -133,8 +164,8 @@ describe('BitstreamWriter', it => { expect(caught, `Expected write(8, Infinity) to throw an exception`).to.exist; }); it('throws when writing NaN as a signed integer', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); let caught; @@ -145,8 +176,8 @@ describe('BitstreamWriter', it => { expect(caught, `Expected write(8, NaN) to throw an exception`).to.exist; }); it('throws when writing values outside of range', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); writer.writeSigned(8, 0); @@ -157,14 +188,14 @@ describe('BitstreamWriter', it => { try { writer.writeSigned(8, 200); } catch (e) { caught = e; } - + expect(caught, `Expected writeSigned(8, 200) to throw an exception`).to.exist; caught = undefined; try { writer.writeSigned(8, 128); } catch (e) { caught = e; } - + expect(caught, `Expected writeSigned(8, 128) to throw an exception`).to.exist; caught = undefined; @@ -178,7 +209,7 @@ describe('BitstreamWriter', it => { try { writer.writeSigned(16, 999999); } catch (e) { caught = e; } - + expect(caught, `Expected writeSigned(8, 200) to throw an exception`).to.exist; caught = undefined; @@ -190,8 +221,8 @@ describe('BitstreamWriter', it => { caught = undefined; }); it('throws when writing Infinity as a signed integer', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); let caught; @@ -202,40 +233,40 @@ describe('BitstreamWriter', it => { expect(caught, `Expected write(8, Infinity) to throw an exception`).to.exist; }); it('writes undefined as zero when unsigned', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 1); writer.write(8, undefined); expect(bufs[0][0]).to.equal(0); }); it('writes null as zero when unsigned', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 1); writer.write(8, null); expect(bufs[0][0]).to.equal(0); }); it('writes undefined as zero when signed', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 1); writer.writeSigned(8, undefined); expect(bufs[0][0]).to.equal(0); }); it('writes null as zero when signed', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 1); writer.writeSigned(8, null); expect(bufs[0][0]).to.equal(0); }); it('correctly handles signed integers', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.writeSigned(8, -5); expect(bufs[0][0]).to.equal(0xFB); @@ -249,6 +280,13 @@ describe('BitstreamWriter', it => { writer.writeSigned(16, 1014); expect(Array.from(bufs[1])).to.eql([0x03, 0xF6]); writer.writeSigned(16, 0); expect(Array.from(bufs[2])).to.eql([0, 0]); + bufs = []; + writer = new BitstreamWriter(fakeStream, 2); + + writer.writeSigned(16, -1014, 'little-endian'); expect(Array.from(bufs[0])).to.eql([0x0A, 0xFC]); + writer.writeSigned(16, 1014, 'little-endian'); expect(Array.from(bufs[1])).to.eql([0xF6, 0x03]); + writer.writeSigned(16, 0, 'little-endian'); expect(Array.from(bufs[2])).to.eql([0, 0]); + bufs = []; writer = new BitstreamWriter(fakeStream, 4); @@ -256,15 +294,29 @@ describe('BitstreamWriter', it => { writer.writeSigned(32, 102336); expect(Array.from(bufs[1])).to.eql([0x00, 0x01, 0x8F, 0xC0]); writer.writeSigned(32, 0); expect(Array.from(bufs[2])).to.eql([0, 0, 0, 0]); + bufs = []; + writer = new BitstreamWriter(fakeStream, 4); + + writer.writeSigned(32, -102336, 'little-endian'); expect(Array.from(bufs[0])).to.eql([0x40, 0x70, 0xFE, 0xFF]); + writer.writeSigned(32, 102336, 'little-endian'); expect(Array.from(bufs[1])).to.eql([0xC0, 0x8F, 0x01, 0x00]); + writer.writeSigned(32, 0, 'little-endian'); expect(Array.from(bufs[2])).to.eql([0, 0, 0, 0]); + }); it('correctly handles floats', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); writer.writeFloat(32, 102.5); expect(Array.from(bufs[0])).to.eql([0x42, 0xCD, 0x00, 0x00]); writer.writeFloat(32, -436); expect(Array.from(bufs[1])).to.eql([0xC3, 0xDA, 0x00, 0x00]); - writer.writeFloat(32, 0); expect(Array.from(bufs[2])).to.eql([0,0,0,0]); + writer.writeFloat(32, 0); expect(Array.from(bufs[2])).to.eql([0, 0, 0, 0]); + + bufs = []; + writer = new BitstreamWriter(fakeStream, 4); + + writer.writeFloat(32, 102.5, 'little-endian'); expect(Array.from(bufs[0])).to.eql([0x00, 0x00, 0xCD, 0x42]); + writer.writeFloat(32, -436, 'little-endian'); expect(Array.from(bufs[1])).to.eql([0x00, 0x00, 0xDA, 0xC3]); + writer.writeFloat(32, 0, 'little-endian'); expect(Array.from(bufs[2])).to.eql([0, 0, 0, 0]); bufs = []; writer = new BitstreamWriter(fakeStream, 8); @@ -277,11 +329,24 @@ describe('BitstreamWriter', it => { writer.writeFloat(64, 0); expect(Array.from(bufs[2])).to.eql([0, 0, 0, 0, 0, 0, 0, 0]); + + bufs = []; + writer = new BitstreamWriter(fakeStream, 8); + + writer.writeFloat(64, 8745291.56, 'little-endian'); + expect(Array.from(bufs[0])).to.eql([0x1f, 0x85, 0xeb, 0x71, 0x29, 0xae, 0x60, 0x41]); + + writer.writeFloat(64, -327721.17, 'little-endian'); + expect(Array.from(bufs[1])).to.eql([0xe1, 0x7a, 0x14, 0xae, 0xa4, 0x00, 0x14, 0xc1]); + + writer.writeFloat(64, 0, 'little-endian'); + expect(Array.from(bufs[2])).to.eql([0, 0, 0, 0, 0, 0, 0, 0]); + }); it('.writeFloat() throws for lengths other than 32 and 64', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); let caught; @@ -293,35 +358,35 @@ describe('BitstreamWriter', it => { }); it('correctly handles NaN', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); writer.writeFloat(32, NaN); expect(Array.from(bufs[0])).to.eql([0x7F, 0xC0, 0x00, 0x00]); - + bufs = []; writer = new BitstreamWriter(fakeStream, 8); - writer.writeFloat(64, NaN); - expect(Array.from(bufs[0])).to.eql([ 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); + writer.writeFloat(64, NaN); + expect(Array.from(bufs[0])).to.eql([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); }); it('correctly handles Infinity', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); - writer.writeFloat(32, Infinity); expect(Array.from(bufs[0])).to.eql([ 0x7f, 0x80, 0x00, 0x00 ]); - + writer.writeFloat(32, Infinity); expect(Array.from(bufs[0])).to.eql([0x7f, 0x80, 0x00, 0x00]); + bufs = []; writer = new BitstreamWriter(fakeStream, 8); - writer.writeFloat(64, Infinity); - expect(Array.from(bufs[0])).to.eql([ 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); + writer.writeFloat(64, Infinity); + expect(Array.from(bufs[0])).to.eql([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); }); it('.end() flushes full bytes', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); writer.write(8, 44); @@ -332,8 +397,8 @@ describe('BitstreamWriter', it => { expect(bufs[0][0]).to.equal(44); }); it('.end() flushes partial bytes', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); writer.write(4, 0b1111); @@ -344,8 +409,8 @@ describe('BitstreamWriter', it => { expect(bufs[0][0]).to.equal(0b11110000); }); it('.writeString() writes utf-8 strings correctly', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 5); writer.writeString(5, 'hello', 'utf-8'); @@ -357,8 +422,8 @@ describe('BitstreamWriter', it => { expect(buf.toString('utf-8')).to.equal('hello'); }); it('.writeString() writes utf16le strings correctly', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 10); writer.writeString(10, 'hello', 'utf16le'); @@ -372,8 +437,8 @@ describe('BitstreamWriter', it => { (globalThis as any).Buffer = undefined; try { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 10); let caught; @@ -388,12 +453,12 @@ describe('BitstreamWriter', it => { } }); it('.writeBuffer() works correctly', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); - let buf = Buffer.from([ 12, 34, 56, 78 ]); - writer.writeBuffer(buf); + let buf = Buffer.from([12, 34, 56, 78]); + writer.writeBytes(buf); expect(bufs.length).to.equal(2); expect(bufs[0][0]).to.equal(12); @@ -402,13 +467,13 @@ describe('BitstreamWriter', it => { expect(bufs[1][1]).to.equal(78); }); it('.writeBuffer() works even when not byte-aligned', () => { - let bufs : Buffer[] = []; - let fakeStream : any = { write(buf) { bufs.push(buf); } } + let bufs: Buffer[] = []; + let fakeStream: any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 5); - let buf = Buffer.from([ 12, 34, 56, 78 ]); + let buf = Buffer.from([12, 34, 56, 78]); writer.write(4, 0); - writer.writeBuffer(buf); + writer.writeBytes(buf); writer.write(4, 0); expect(bufs.length).to.equal(1); diff --git a/src/bitstream/writer.ts b/src/bitstream/writer.ts index d90ae7d..5e0a49b 100644 --- a/src/bitstream/writer.ts +++ b/src/bitstream/writer.ts @@ -145,7 +145,7 @@ export class BitstreamWriter { * @param length The number of bits to write * @param value The number to write */ - write(length: number, value: number, byteOrder: "big-endian" | "little-endian" = 'big-endian') { + write(length: number, value: number | bigint, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (value === void 0 || value === null) value = 0; @@ -156,41 +156,54 @@ export class BitstreamWriter { if (!Number.isFinite(value)) throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); - let valueN = BigInt(value % Math.pow(2, length)); + if (byteOrder === 'little-endian') { + if (length != 16 && length != 32) throw new Error("Little-endian is only supported for 16,32"); - let remainingLength = length; + let buf = new ArrayBuffer(length / 8); + let view = new DataView(buf); - // FIXME: Support little-endian - if (byteOrder === 'little-endian') throw new Error("Little-endian not yet supported in write!"); - while (remainingLength > 0) { - let shift = BigInt(8 - this.pendingBits - remainingLength); - let contribution = (shift >= 0 ? (valueN << shift) : (valueN >> -shift)); - let writtenLength = Number(shift >= 0 ? remainingLength : this.min(-shift, BigInt(8 - this.pendingBits))); + if (length === 16) + view.setUint16(0, value, byteOrder === 'little-endian'); + else if (length === 32) + view.setUint32(0, value, byteOrder === 'little-endian'); + else if (length === 64) + view.setBigUint64(0, BigInt(value), byteOrder === 'little-endian') - this.pendingByte = this.pendingByte | contribution; - this.pendingBits += writtenLength; - this._offset += writtenLength; + for (let i = 0, max = buf.byteLength; i < max; ++i) + this.write(8, view.getUint8(i)); + } else { - remainingLength -= writtenLength; - valueN = valueN % BigInt(Math.pow(2, remainingLength)); + let valueN = BigInt(value % Math.pow(2, length)); - if (this.pendingBits === 8) { - this.finishByte(); + let remainingLength = length; - if (this.bufferedBytes >= this.buffer.length) { - this.flush(); + while (remainingLength > 0) { + let shift = BigInt(8 - this.pendingBits - remainingLength); + let contribution = (shift >= 0 ? (valueN << shift) : (valueN >> -shift)); + let writtenLength = Number(shift >= 0 ? remainingLength : this.min(-shift, BigInt(8 - this.pendingBits))); + + this.pendingByte = this.pendingByte | contribution; + this.pendingBits += writtenLength; + this._offset += writtenLength; + + remainingLength -= writtenLength; + valueN = valueN % BigInt(Math.pow(2, remainingLength)); + + if (this.pendingBits === 8) { + this.finishByte(); + + if (this.bufferedBytes >= this.buffer.length) { + this.flush(); + } } } } } - writeSigned(length: number, value: number, byteOrder: "big-endian" | "little-endian" = 'big-endian') { + writeSigned(length: number, value: number | bigint, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (value === undefined || value === null) value = 0; - // FIXME: Support little-endian - if (byteOrder === 'little-endian') throw new Error("Little-endian is not yet supported in write!"); - const originalValue = value; const max = 2 ** (length - 1) - 1; // ie 127 const min = -(2 ** (length - 1)); // ie -128 @@ -206,24 +219,37 @@ export class BitstreamWriter { if (value < min) throw new TypeError(`Cannot represent ${value} in I${length} format: Negative value too small (min=${min}, max=${max})`); - return this.write(length, value >= 0 ? value : (~(-value) + 1) >>> 0); + if (byteOrder === 'little-endian') { + if (length != 16 && length != 32 && length != 64) throw new Error("Little-endian is only supported for 16,32"); + + let buf = new ArrayBuffer(length / 8); + let view = new DataView(buf); + + if (length === 16) + view.setInt16(0, value, byteOrder === 'little-endian'); + else if (length === 32) + view.setInt32(0, value, byteOrder === 'little-endian'); + else if (length === 64) + view.setBigInt64(0, BigInt(value), byteOrder === 'little-endian'); + + for (let i = 0, max = buf.byteLength; i < max; ++i) + this.write(8, view.getUint8(i)); + } else { + return this.write(length, value >= 0 ? value : (~(-value) + 1) >>> 0); + } } writeFloat(length: number, value: number, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (length !== 32 && length !== 64) throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); - // FIXME: Support little-endian - if (byteOrder === 'little-endian') throw new Error("Little-endian is not yet supported in write!"); - - let buf = new ArrayBuffer(length / 8); let view = new DataView(buf); if (length === 32) - view.setFloat32(0, value); + view.setFloat32(0, value, byteOrder === 'little-endian'); else if (length === 64) - view.setFloat64(0, value); + view.setFloat64(0, value, byteOrder === 'little-endian'); for (let i = 0, max = buf.byteLength; i < max; ++i) this.write(8, view.getUint8(i)); From e5d17fd97ae5b482d22b4050d2cd3faf734d5724 Mon Sep 17 00:00:00 2001 From: dianlight Date: Wed, 16 Oct 2024 23:03:38 +0200 Subject: [PATCH 3/4] Full support to LE and code cleanup --- src/bitstream/reader.test.ts | 17 ++++++++--------- src/bitstream/reader.ts | 33 ++++++++++++++++----------------- src/bitstream/writer.ts | 2 +- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/bitstream/reader.test.ts b/src/bitstream/reader.test.ts index 88105df..8ff3387 100644 --- a/src/bitstream/reader.test.ts +++ b/src/bitstream/reader.test.ts @@ -874,7 +874,7 @@ describe('BitstreamReader (generated)', it => { expect(reader.readSync(size), `Test number #${i} (${num}) should have been read properly`).to.equal(num); } }); - if (size > 8 && (size % 8 == 0) && size <= 32) it(`reads ${size}bit values correctly (LE)`, async () => { + if (size > 8 && (size % 8 == 0)) it(`reads ${size}bit values correctly (LE)`, async () => { let buf = new ArrayBuffer(8); let view = new DataView(buf); @@ -903,7 +903,7 @@ describe('BitstreamReader (generated)', it => { expect(reader.readSync(size), `Test number #${i} (${num}) should have been read properly`).to.equal(num); } }); - if (size > 8 && (size % 8 == 0) && size <= 32) it(`reads cross-byte ${size}bit values correctly [1-bit offset] LE`, async () => { + if (size > 8 && (size % 8 == 0)) it(`reads cross-byte ${size}bit values correctly [1-bit offset] LE`, async () => { let buf = new ArrayBuffer(8); let view = new DataView(buf); @@ -911,15 +911,15 @@ describe('BitstreamReader (generated)', it => { let num = Math.floor(Math.random() * 2 ** size); view.setBigUint64(0, BigInt(num), true); let reader = new BitstreamReader(); - let shifted = new Uint8Array(buf).reduce((prev, cur, index, arr) => { - prev[index] = cur >> 1 | prev[index]; - prev[index + 1] = cur << 7; - // console.log(`Index ${index} ${cur.toString(2).padStart(8, '0')} -> ${prev[index].toString(2).padStart(8, '0')}:${prev[index + 1].toString(2).padStart(8, '0')}`) + let shifted = new Uint8Array(buf).reduce((prev, cur, index: number, arr) => { + prev[index] = (cur >> 1) | ((index == 0) ? 0x0 : prev[index]); + prev[index + 1] = (cur << 7) & 0b10000000; return prev; }, new Uint8Array(buf.byteLength + 1)); reader.addBuffer(shifted); reader.readSync(1); - expect(reader.readSync(size, 'little-endian'), `Test number #${i} (${num}) should have been read properly`).to.equal(num); + const target = reader.readSync(size, 'little-endian'); + expect(target, `Test number #${i} (${num}) should have been read properly`).to.equal(num); } }); } @@ -939,7 +939,7 @@ describe('BitstreamReader (generated)', it => { expect(reader.readSync(size), `Test number #${i} (${num}) should have been read properly`).to.equal(num); } }); - if (size > 8 && (size % 8 == 0) && size <= 32) it(`reads cross-byte ${size}bit values correctly [4-bit offset] LE`, async () => { + if (size > 8 && (size % 8 == 0)) it(`reads cross-byte ${size}bit values correctly [4-bit offset] LE`, async () => { let buf = new ArrayBuffer(8); let view = new DataView(buf); @@ -950,7 +950,6 @@ describe('BitstreamReader (generated)', it => { let shifted = new Uint8Array(buf).reduce((prev, cur, index, arr) => { prev[index] = cur >> 4 | prev[index]; prev[index + 1] = cur << 4; - // console.log(`Index ${index} ${cur.toString(2).padStart(8, '0')} -> ${prev[index].toString(2).padStart(8, '0')}:${prev[index + 1].toString(2).padStart(8, '0')}`) return prev; }, new Uint8Array(buf.byteLength + 1)); reader.addBuffer(shifted); diff --git a/src/bitstream/reader.ts b/src/bitstream/reader.ts index f747ed4..d9dae74 100644 --- a/src/bitstream/reader.ts +++ b/src/bitstream/reader.ts @@ -613,6 +613,9 @@ export class BitstreamReader { if (this.available < length) throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + if (byteOrder === 'little-endian' && (length < 8 || length % 8)) + throw new Error(`little-endian is only supported for 16,32 or 64bit length (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); + this.adjustSkip(); let offsetIntoByte = this._offsetIntoBuffer % 8; @@ -660,20 +663,6 @@ export class BitstreamReader { bitContribution = Math.min(8 - bitOffset, remainingLength); - // if (useBigInt) { - // const dv = new DataView(new ArrayBuffer(8)); - // dv.setBigUint64(0, (bigValue << BigInt(bitContribution)) - // | ((BigInt(buffer[byteOffset]) >> (BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset))) - // & BigInt(this.maskOf(bitContribution))), false); - // bigValue = dv.getBigUint64(0, byteOrder == 'little-endian'); - // } else { - // const dv = new DataView(new ArrayBuffer(4)); - // dv.setUint32(0, (value << bitContribution) - // | ((byte >> (8 - bitContribution - bitOffset)) - // & this.maskOf(bitContribution)), false); - // value = dv.getUint32(0, byteOrder == 'little-endian'); - // } - if (useBigInt) { bigValue = (bigValue << BigInt(bitContribution)) | ((BigInt(buffer[byteOffset]) >> (BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset))) @@ -698,10 +687,20 @@ export class BitstreamReader { if (consume) this.consume(length); - if (useBigInt) - return Number(bigValue); - else + value = useBigInt ? Number(bigValue) : value; + + if (byteOrder === 'little-endian') { + let nvalue = BigInt(0); + //if (length == 32) console.log(value.toString(2).padStart(64, '.').match(/.{1,8}/g).join(":"), '++++++++'); + for (let i = 0; i < length; i += 8) { + nvalue = nvalue | ((BigInt(value) >> BigInt(i)) & BigInt(0xFF)) << BigInt(length - i - 8); + } + //if (length == 32) console.log(nvalue.toString(2).padStart(64, '.').match(/.{1,8}/g).join(":"), '--------'); + return Number(nvalue); + } else { return value; + } + } private adjustSkip() { diff --git a/src/bitstream/writer.ts b/src/bitstream/writer.ts index 5e0a49b..41b7840 100644 --- a/src/bitstream/writer.ts +++ b/src/bitstream/writer.ts @@ -157,7 +157,7 @@ export class BitstreamWriter { throw new Error(`Cannot write to bitstream: Value ${value} must be finite`); if (byteOrder === 'little-endian') { - if (length != 16 && length != 32) throw new Error("Little-endian is only supported for 16,32"); + if (length % 8 && length > 8) throw new Error("Little-endian is only supported for 16,32 or 64bit length"); let buf = new ArrayBuffer(length / 8); let view = new DataView(buf); From 3c5f8b6f0516b6277fb570c8619954b537aa2c45 Mon Sep 17 00:00:00 2001 From: dianlight Date: Wed, 16 Oct 2024 23:44:17 +0200 Subject: [PATCH 4/4] Revert formatting for merge --- pnpm-lock.yaml | 1380 ----------------------------- src/bitstream/reader.test.ts | 206 ++--- src/bitstream/reader.ts | 96 +- src/bitstream/writer.test.ts | 146 +-- src/bitstream/writer.ts | 20 +- src/elements/number-serializer.ts | 10 +- 6 files changed, 240 insertions(+), 1618 deletions(-) delete mode 100644 pnpm-lock.yaml diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 4952773..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,1380 +0,0 @@ -lockfileVersion: '6.1' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - reflect-metadata: - specifier: ^0.1.13 - version: 0.1.13 - -devDependencies: - '@types/chai': - specifier: ^4.2.14 - version: 4.2.14 - '@types/node': - specifier: ^14.0.4 - version: 14.0.4 - '@types/reflect-metadata': - specifier: ^0.1.0 - version: 0.1.0 - chai: - specifier: ^4.2.0 - version: 4.2.0 - nyc: - specifier: ^15.1.0 - version: 15.1.0 - razmin: - specifier: ^0.6.20 - version: 0.6.20 - rimraf: - specifier: ^3.0.2 - version: 3.0.2 - source-map-support: - specifier: ^0.5.21 - version: 0.5.21 - ts-node: - specifier: ^10.4.0 - version: 10.4.0(@types/node@14.0.4)(typescript@5.3.3) - typescript: - specifier: ^5.3.3 - version: 5.3.3 - -packages: - - /@ampproject/remapping@2.3.0: - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - dev: true - - /@babel/code-frame@7.25.7: - resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.25.7 - picocolors: 1.1.0 - dev: true - - /@babel/compat-data@7.25.8: - resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/core@7.25.8: - resolution: {integrity: sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.25.7 - '@babel/generator': 7.25.7 - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) - '@babel/helpers': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/template': 7.25.7 - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 - convert-source-map: 2.0.0 - debug: 4.3.7 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/generator@7.25.7: - resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.25.8 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.0.2 - dev: true - - /@babel/helper-compilation-targets@7.25.7: - resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/compat-data': 7.25.8 - '@babel/helper-validator-option': 7.25.7 - browserslist: 4.24.0 - lru-cache: 5.1.1 - semver: 6.3.1 - dev: true - - /@babel/helper-module-imports@7.25.7: - resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-module-transforms@7.25.7(@babel/core@7.25.8): - resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-imports': 7.25.7 - '@babel/helper-simple-access': 7.25.7 - '@babel/helper-validator-identifier': 7.25.7 - '@babel/traverse': 7.25.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-simple-access@7.25.7: - resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-string-parser@7.25.7: - resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.25.7: - resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-option@7.25.7: - resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helpers@7.25.7: - resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 - dev: true - - /@babel/highlight@7.25.7: - resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.25.7 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.1.0 - dev: true - - /@babel/parser@7.25.8: - resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.25.8 - dev: true - - /@babel/template@7.25.7: - resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/types': 7.25.8 - dev: true - - /@babel/traverse@7.25.7: - resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.25.7 - '@babel/generator': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 - debug: 4.3.7 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types@7.25.8: - resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.25.7 - '@babel/helper-validator-identifier': 7.25.7 - to-fast-properties: 2.0.0 - dev: true - - /@cspotcode/source-map-consumer@0.8.0: - resolution: {integrity: sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==} - engines: {node: '>= 12'} - dev: true - - /@cspotcode/source-map-support@0.7.0: - resolution: {integrity: sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==} - engines: {node: '>=12'} - dependencies: - '@cspotcode/source-map-consumer': 0.8.0 - dev: true - - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - dev: true - - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true - - /@jridgewell/gen-mapping@0.3.5: - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - dev: true - - /@jridgewell/resolve-uri@3.1.2: - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/set-array@1.2.1: - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/sourcemap-codec@1.5.0: - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - dev: true - - /@jridgewell/trace-mapping@0.3.25: - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - dev: true - - /@tsconfig/node10@1.0.11: - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true - - /@types/chai@4.2.14: - resolution: {integrity: sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==} - dev: true - - /@types/node@14.0.4: - resolution: {integrity: sha512-k3NqigXWRzQZVBDS5D1U70A5E8Qk4Kh+Ha/x4M8Bt9pF0X05eggfnC9+63Usc9Q928hRUIpIhTQaXsZwZBl4Ew==} - dev: true - - /@types/reflect-metadata@0.1.0: - resolution: {integrity: sha512-bXltFLY3qhzCnVYP5iUpeSICagQ8rc9K2liS+8M0lBcz54BHs3O6W5UvqespVSuebo1BXLi+/y9ioELAW9SC2A==} - deprecated: This is a stub types definition for reflect-metadata (https://github.com/rbuckton/ReflectDecorators). reflect-metadata provides its own type definitions, so you don't need @types/reflect-metadata installed! - dependencies: - reflect-metadata: 0.1.13 - dev: true - - /acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} - dependencies: - acorn: 8.12.1 - dev: true - - /acorn@8.12.1: - resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - dev: true - - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - - /append-transform@2.0.0: - resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} - engines: {node: '>=8'} - dependencies: - default-require-extensions: 3.0.1 - dev: true - - /archy@1.0.0: - resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} - dev: true - - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - - /array-union@1.0.2: - resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} - engines: {node: '>=0.10.0'} - dependencies: - array-uniq: 1.0.3 - dev: true - - /array-uniq@1.0.3: - resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} - engines: {node: '>=0.10.0'} - dev: true - - /assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - dev: true - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - /browserslist@4.24.0: - resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001668 - electron-to-chromium: 1.5.36 - node-releases: 2.0.18 - update-browserslist-db: 1.1.1(browserslist@4.24.0) - dev: true - - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /caching-transform@4.0.0: - resolution: {integrity: sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==} - engines: {node: '>=8'} - dependencies: - hasha: 5.2.2 - make-dir: 3.1.0 - package-hash: 4.0.0 - write-file-atomic: 3.0.3 - dev: true - - /callsites@1.0.1: - resolution: {integrity: sha512-4pzUzADrTwH4QwhsYEY1yQYUYXb4Lp3CB7FVknTNtWNCFdcQkRV4ICEGnMQ35DcJhCVlAB1VD3A/SoWC0O2kMg==} - engines: {node: '>=0.10'} - dev: true - - /callsites@2.0.0: - resolution: {integrity: sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==} - engines: {node: '>=4'} - dev: true - - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true - - /caniuse-lite@1.0.30001668: - resolution: {integrity: sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==} - dev: true - - /chai@4.2.0: - resolution: {integrity: sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==} - engines: {node: '>=4'} - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 3.0.1 - get-func-name: 2.0.2 - pathval: 1.1.1 - type-detect: 4.1.0 - dev: true - - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - - /check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - dependencies: - get-func-name: 2.0.2 - dev: true - - /clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - dev: true - - /cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - dev: true - - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - - /colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} - dev: true - - /commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - dev: true - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true - - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - - /debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - - /decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - dev: true - - /deep-eql@3.0.1: - resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} - engines: {node: '>=0.12'} - dependencies: - type-detect: 4.1.0 - dev: true - - /default-require-extensions@3.0.1: - resolution: {integrity: sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==} - engines: {node: '>=8'} - dependencies: - strip-bom: 4.0.0 - dev: true - - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - - /electron-to-chromium@1.5.36: - resolution: {integrity: sha512-HYTX8tKge/VNp6FGO+f/uVDmUkq+cEfcxYhKf15Akc4M5yxt5YmorwlAitKWjWhWQnKcDRBAQKXkhqqXMqcrjw==} - dev: true - - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - - /es6-error@4.1.1: - resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} - dev: true - - /escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - dev: true - - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true - - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /find-cache-dir@3.3.2: - resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} - engines: {node: '>=8'} - dependencies: - commondir: 1.0.1 - make-dir: 3.1.0 - pkg-dir: 4.2.0 - dev: true - - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - - /foreground-child@2.0.0: - resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} - engines: {node: '>=8.0.0'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 3.0.7 - dev: true - - /fromentries@1.3.2: - resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} - dev: true - - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - dev: true - - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true - - /glob-parent@3.1.0: - resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} - dependencies: - is-glob: 3.1.0 - path-dirname: 1.0.2 - dev: true - - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true - - /globby@6.1.0: - resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} - engines: {node: '>=0.10.0'} - dependencies: - array-union: 1.0.2 - glob: 7.2.3 - object-assign: 4.1.1 - pify: 2.3.0 - pinkie-promise: 2.0.1 - dev: true - - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true - - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true - - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - /hasha@5.2.2: - resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} - engines: {node: '>=8'} - dependencies: - is-stream: 2.0.1 - type-fest: 0.8.1 - dev: true - - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true - - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true - - /indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - dev: true - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true - - /is-glob@3.1.0: - resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true - - /is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: true - - /is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - - /istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-hook@3.0.0: - resolution: {integrity: sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==} - engines: {node: '>=8'} - dependencies: - append-transform: 2.0.0 - dev: true - - /istanbul-lib-instrument@4.0.3: - resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} - engines: {node: '>=8'} - dependencies: - '@babel/core': 7.25.8 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-lib-processinfo@2.0.3: - resolution: {integrity: sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==} - engines: {node: '>=8'} - dependencies: - archy: 1.0.0 - cross-spawn: 7.0.3 - istanbul-lib-coverage: 3.2.2 - p-map: 3.0.0 - rimraf: 3.0.2 - uuid: 8.3.2 - dev: true - - /istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - dev: true - - /istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - dependencies: - debug: 4.3.7 - istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - dev: true - - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true - - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - - /jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - - /lodash.flattendeep@4.4.0: - resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} - dev: true - - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 - dev: true - - /make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.1 - dev: true - - /make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - dependencies: - semver: 7.6.3 - dev: true - - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - - /mersenne-twister@1.1.0: - resolution: {integrity: sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==} - dev: true - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true - - /node-preload@0.2.1: - resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} - engines: {node: '>=8'} - dependencies: - process-on-spawn: 1.0.0 - dev: true - - /node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} - dev: true - - /nyc@15.1.0: - resolution: {integrity: sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==} - engines: {node: '>=8.9'} - hasBin: true - dependencies: - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - caching-transform: 4.0.0 - convert-source-map: 1.9.0 - decamelize: 1.2.0 - find-cache-dir: 3.3.2 - find-up: 4.1.0 - foreground-child: 2.0.0 - get-package-type: 0.1.0 - glob: 7.2.3 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-hook: 3.0.0 - istanbul-lib-instrument: 4.0.3 - istanbul-lib-processinfo: 2.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - make-dir: 3.1.0 - node-preload: 0.2.1 - p-map: 3.0.0 - process-on-spawn: 1.0.0 - resolve-from: 5.0.0 - rimraf: 3.0.2 - signal-exit: 3.0.7 - spawn-wrap: 2.0.0 - test-exclude: 6.0.0 - yargs: 15.4.1 - transitivePeerDependencies: - - supports-color - dev: true - - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: true - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true - - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-map@3.0.0: - resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} - engines: {node: '>=8'} - dependencies: - aggregate-error: 3.1.0 - dev: true - - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true - - /package-hash@4.0.0: - resolution: {integrity: sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==} - engines: {node: '>=8'} - dependencies: - graceful-fs: 4.2.11 - hasha: 5.2.2 - lodash.flattendeep: 4.4.0 - release-zalgo: 1.0.0 - dev: true - - /parent-module@0.1.0: - resolution: {integrity: sha512-fkZFUUL8tSsJUm/WvAqyJLV/Aj9/jpnMXHy0leJYEUu2qw5FE6nJQI/bMVW2xbZySot4uaPb6cw4eY5zQn7/Ww==} - engines: {node: '>=0.10.0'} - dependencies: - callsites: 1.0.1 - dev: true - - /path-dirname@1.0.2: - resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} - dev: true - - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true - - /pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - dev: true - - /picocolors@1.1.0: - resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} - dev: true - - /pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - dev: true - - /pinkie-promise@2.0.1: - resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} - engines: {node: '>=0.10.0'} - dependencies: - pinkie: 2.0.4 - dev: true - - /pinkie@2.0.4: - resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} - engines: {node: '>=0.10.0'} - dev: true - - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true - - /process-on-spawn@1.0.0: - resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} - engines: {node: '>=8'} - dependencies: - fromentries: 1.3.2 - dev: true - - /razmin@0.6.20: - resolution: {integrity: sha512-ppu9Yn4V8KEiZX5J1MKICDw27cMyx1oidu3QrX2eW8KB5eosipAeZFQtkihOrxAJaErZGGghBfjM8xJZSnno8g==} - dependencies: - callsites: 2.0.0 - colors: 1.4.0 - mersenne-twister: 1.1.0 - require-glob: 3.2.0 - rxjs: 6.6.7 - source-map-support: 0.5.21 - zone.js: 0.10.3 - dev: true - - /reflect-metadata@0.1.13: - resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} - - /release-zalgo@1.0.0: - resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} - engines: {node: '>=4'} - dependencies: - es6-error: 4.1.1 - dev: true - - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /require-glob@3.2.0: - resolution: {integrity: sha512-F7diVunoVBanWJ4kq9t+ZKiPhxn588xBvFEDbe8XJnpZ68qEUZ3wXzoAaRSDYxylh6ssSIIPV2+qD6QIsOkR1g==} - engines: {node: '>= 0.12'} - dependencies: - glob-parent: 3.1.0 - globby: 6.1.0 - parent-module: 0.1.0 - dev: true - - /require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - dev: true - - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true - - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - - /rxjs@6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - dev: true - - /semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - dev: true - - /semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} - engines: {node: '>=10'} - hasBin: true - dev: true - - /set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: true - - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true - - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true - - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - - /spawn-wrap@2.0.0: - resolution: {integrity: sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==} - engines: {node: '>=8'} - dependencies: - foreground-child: 2.0.0 - is-windows: 1.0.2 - make-dir: 3.1.0 - rimraf: 3.0.2 - signal-exit: 3.0.7 - which: 2.0.2 - dev: true - - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true - - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: true - - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true - - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - dev: true - - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true - - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - dev: true - - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true - - /ts-node@10.4.0(@types/node@14.0.4)(typescript@5.3.3): - resolution: {integrity: sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.7.0 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 14.0.4 - acorn: 8.12.1 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.3.3 - yn: 3.1.1 - dev: true - - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true - - /type-detect@4.1.0: - resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} - engines: {node: '>=4'} - dev: true - - /type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - dev: true - - /typedarray-to-buffer@3.1.5: - resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - dependencies: - is-typedarray: 1.0.0 - dev: true - - /typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} - engines: {node: '>=14.17'} - hasBin: true - dev: true - - /update-browserslist-db@1.1.1(browserslist@4.24.0): - resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.24.0 - escalade: 3.2.0 - picocolors: 1.1.0 - dev: true - - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: true - - /which-module@2.0.1: - resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - dev: true - - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - - /wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true - - /write-file-atomic@3.0.3: - resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} - dependencies: - imurmurhash: 0.1.4 - is-typedarray: 1.0.0 - signal-exit: 3.0.7 - typedarray-to-buffer: 3.1.5 - dev: true - - /y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - dev: true - - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true - - /yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - dev: true - - /yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} - dependencies: - cliui: 6.0.0 - decamelize: 1.2.0 - find-up: 4.1.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 4.2.3 - which-module: 2.0.1 - y18n: 4.0.3 - yargs-parser: 18.1.3 - dev: true - - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true - - /zone.js@0.10.3: - resolution: {integrity: sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==} - dev: true diff --git a/src/bitstream/reader.test.ts b/src/bitstream/reader.test.ts index 8ff3387..b6e5878 100644 --- a/src/bitstream/reader.test.ts +++ b/src/bitstream/reader.test.ts @@ -1,20 +1,20 @@ import { expect } from "chai"; -import { describe, skip } from "razmin"; +import { describe } from "razmin"; import { BitstreamReader } from "./reader"; describe('BitstreamReader', it => { it('can read a byte-aligned byte', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([ 123 ])); expect(bitstream.readSync(8)).to.equal(123); }); it('bufferIndex is always zero when retainBuffers=false', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([123])); - bitstream.addBuffer(Buffer.from([123, 123])); - bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([ 123, 123 ])); + bitstream.addBuffer(Buffer.from([ 123 ])); expect(bitstream.bufferIndex === 0); bitstream.readSync(8); @@ -27,9 +27,9 @@ describe('BitstreamReader', it => { it('.clean() causes buffers to be discarded when retainBuffers=true', () => { let bitstream = new BitstreamReader(); bitstream.retainBuffers = true; - bitstream.addBuffer(Buffer.from([123])); - bitstream.addBuffer(Buffer.from([123, 123])); - bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([ 123, 123 ])); + bitstream.addBuffer(Buffer.from([ 123 ])); bitstream.readSync(8); expect(bitstream.bufferIndex).to.equal(1); expect(bitstream.offset).to.equal(8); @@ -50,15 +50,15 @@ describe('BitstreamReader', it => { it('.clean() frees only the number of requested buffers', () => { let bitstream = new BitstreamReader(); bitstream.retainBuffers = true; - bitstream.addBuffer(Buffer.from([123])); - bitstream.addBuffer(Buffer.from([123])); - bitstream.addBuffer(Buffer.from([123])); - bitstream.addBuffer(Buffer.from([123, 123])); - + bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([ 123, 123 ])); + bitstream.readSync(8); bitstream.readSync(8); bitstream.readSync(8); - + expect(bitstream.bufferIndex).to.equal(3); bitstream.clean(1); expect(bitstream.bufferIndex).to.equal(2); @@ -69,9 +69,9 @@ describe('BitstreamReader', it => { }); it('spentBufferSize tracks read bits properly', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([123])); - bitstream.addBuffer(Buffer.from([123, 123])); - bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([ 123, 123 ])); + bitstream.addBuffer(Buffer.from([ 123 ])); expect(bitstream.spentBufferSize === 0); bitstream.readSync(8); @@ -84,21 +84,21 @@ describe('BitstreamReader', it => { it('offset should start at zero', () => { let bitstream = new BitstreamReader(); expect(bitstream.offset).to.equal(0); - bitstream.addBuffer(Buffer.from([1, 2, 3, 4, 5, 6])); + bitstream.addBuffer(Buffer.from([ 1, 2, 3, 4, 5, 6 ])); expect(bitstream.offset).to.equal(0); }); it('offset should not move as buffers are added', () => { let bitstream = new BitstreamReader(); expect(bitstream.offset).to.equal(0); - bitstream.addBuffer(Buffer.from([1, 2, 3, 4, 5, 6])); + bitstream.addBuffer(Buffer.from([ 1, 2, 3, 4, 5, 6 ])); expect(bitstream.offset).to.equal(0); bitstream.readSync(8); - bitstream.addBuffer(Buffer.from([1, 2, 3, 4, 5, 6])); + bitstream.addBuffer(Buffer.from([ 1, 2, 3, 4, 5, 6 ])); expect(bitstream.offset).to.equal(8); }); it('setting offset allows seeking within current buffer', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([1, 2, 3, 4, 5, 6])); + bitstream.addBuffer(Buffer.from([ 1, 2, 3, 4, 5, 6 ])); expect(bitstream.readSync(8)).to.equal(1); expect(bitstream.readSync(8)).to.equal(2); @@ -122,8 +122,8 @@ describe('BitstreamReader', it => { it('setting offset allows seeking into previous buffers when retainBuffers=true', () => { let bitstream = new BitstreamReader(); bitstream.retainBuffers = true; - bitstream.addBuffer(Buffer.from([1, 2, 3])); - bitstream.addBuffer(Buffer.from([4, 5, 6])); + bitstream.addBuffer(Buffer.from([ 1, 2, 3 ])); + bitstream.addBuffer(Buffer.from([ 4, 5, 6 ])); expect(bitstream.readSync(8)).to.equal(1); expect(bitstream.readSync(8)).to.equal(2); @@ -132,7 +132,7 @@ describe('BitstreamReader', it => { expect(bitstream.readSync(8)).to.equal(5); expect(bitstream.readSync(8)).to.equal(6); - bitstream.offset = 8 * 3; + bitstream.offset = 8*3; expect(bitstream.readSync(8)).to.equal(4); expect(bitstream.readSync(8)).to.equal(5); expect(bitstream.readSync(8)).to.equal(6); @@ -144,8 +144,8 @@ describe('BitstreamReader', it => { }); it('setting offset into discarded buffers should throw when retainBuffers=false', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([1, 2, 3])); - bitstream.addBuffer(Buffer.from([4, 5, 6])); + bitstream.addBuffer(Buffer.from([ 1, 2, 3 ])); + bitstream.addBuffer(Buffer.from([ 4, 5, 6 ])); expect(bitstream.readSync(8)).to.equal(1); expect(bitstream.readSync(8)).to.equal(2); @@ -157,15 +157,15 @@ describe('BitstreamReader', it => { let caught; try { bitstream.offset = 0; - } catch (e) { caught = e; } + } catch (e) { caught = e; } expect(caught).to.exist; }); it('offset is always increasing even when retainBuffers=false', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([123])); - bitstream.addBuffer(Buffer.from([123, 123])); - bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([ 123, 123 ])); + bitstream.addBuffer(Buffer.from([ 123 ])); expect(bitstream.offset === 0); bitstream.readSync(8); @@ -178,9 +178,9 @@ describe('BitstreamReader', it => { it('bufferIndex grows when retainBuffers=true', () => { let bitstream = new BitstreamReader(); bitstream.retainBuffers = true; - bitstream.addBuffer(Buffer.from([123])); - bitstream.addBuffer(Buffer.from([123, 123])); - bitstream.addBuffer(Buffer.from([123])); + bitstream.addBuffer(Buffer.from([ 123 ])); + bitstream.addBuffer(Buffer.from([ 123, 123 ])); + bitstream.addBuffer(Buffer.from([ 123 ])); expect(bitstream.bufferIndex === 0); bitstream.readSync(8); @@ -217,14 +217,14 @@ describe('BitstreamReader', it => { expect(bitstream.readSync(11)).to.equal(0b01100100100); expect(bitstream.readSync(5)).to.equal(0b01110); - expect(bitstream.readSync(16, 'little-endian')).to.equal(0b1001000011110000); + expect(bitstream.readSync(16, 'little-endian')).to.equal( 0b1001000011110000 ); }); it('can correctly deserialize a simple example from multiple buffers', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0b11001000, 0b01010100])); - bitstream.addBuffer(Buffer.from([0b11101001, 0b01100100, 0b10001110])); - bitstream.addBuffer(Buffer.from([0b11110000, 0b10010000])); + bitstream.addBuffer(Buffer.from([ 0b11001000, 0b01010100 ])); + bitstream.addBuffer(Buffer.from([ 0b11101001, 0b01100100, 0b10001110 ])); + bitstream.addBuffer(Buffer.from([ 0b11110000, 0b10010000 ])); expect(bitstream.readSync(1)).to.equal(0b1); expect(bitstream.readSync(3)).to.equal(0b100); @@ -272,8 +272,8 @@ describe('BitstreamReader', it => { it('correctly handles intra-byte skips', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0b11001010, 0b01010100])); - bitstream.addBuffer(Buffer.from([0b11101001, 0b01100100, 0b10001110])); + bitstream.addBuffer(Buffer.from([ 0b11001010, 0b01010100 ])); + bitstream.addBuffer(Buffer.from([ 0b11101001, 0b01100100, 0b10001110 ])); expect(bitstream.readSync(1)).to.equal(0b1); expect(bitstream.readSync(3)).to.equal(0b100); @@ -294,8 +294,8 @@ describe('BitstreamReader', it => { it('correctly handles inter-byte skips', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0b11001010, 0b01010100])); - bitstream.addBuffer(Buffer.from([0b11101001, 0b01100100, 0b10001110])); + bitstream.addBuffer(Buffer.from([ 0b11001010, 0b01010100 ])); + bitstream.addBuffer(Buffer.from([ 0b11101001, 0b01100100, 0b10001110 ])); expect(bitstream.readSync(1)).to.equal(0b1); expect(bitstream.readSync(3)).to.equal(0b100); @@ -316,8 +316,8 @@ describe('BitstreamReader', it => { it('correctly handles large inter-byte skips', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0b11001010, 0b01010100])); - bitstream.addBuffer(Buffer.from([0b11101001, 0b01100100, 0b10001110])); + bitstream.addBuffer(Buffer.from([ 0b11001010, 0b01010100 ])); + bitstream.addBuffer(Buffer.from([ 0b11101001, 0b01100100, 0b10001110 ])); expect(bitstream.readSync(1)).to.equal(0b1); expect(bitstream.readSync(3)).to.equal(0b100); @@ -330,7 +330,7 @@ describe('BitstreamReader', it => { it('peeks correctly', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0b11001010, 0b01010100])); + bitstream.addBuffer(Buffer.from([ 0b11001010, 0b01010100 ])); expect(bitstream.peekSync(4)).to.equal(0b1100); expect(bitstream.readSync(1)).to.equal(0b1); @@ -391,22 +391,22 @@ describe('BitstreamReader', it => { it('.readSignedSync() correctly handles signed integers', () => { let bitstream = new BitstreamReader(); + + bitstream.addBuffer(Buffer.from([ 0xFB ])); expect(bitstream.readSignedSync(8)).to.equal(-5); + bitstream.addBuffer(Buffer.from([ 5 ])); expect(bitstream.readSignedSync(8)).to.equal(5); + bitstream.addBuffer(Buffer.from([ 0 ])); expect(bitstream.readSignedSync(8)).to.equal(0); - bitstream.addBuffer(Buffer.from([0xFB])); expect(bitstream.readSignedSync(8)).to.equal(-5); - bitstream.addBuffer(Buffer.from([5])); expect(bitstream.readSignedSync(8)).to.equal(5); - bitstream.addBuffer(Buffer.from([0])); expect(bitstream.readSignedSync(8)).to.equal(0); - - bitstream.addBuffer(Buffer.from([0xFC, 0x0A])); expect(bitstream.readSignedSync(16)).to.equal(-1014); - bitstream.addBuffer(Buffer.from([0x03, 0xF6])); expect(bitstream.readSignedSync(16)).to.equal(1014); - bitstream.addBuffer(Buffer.from([0, 0])); expect(bitstream.readSignedSync(16)).to.equal(0); + bitstream.addBuffer(Buffer.from([ 0xFC, 0x0A ])); expect(bitstream.readSignedSync(16)).to.equal(-1014); + bitstream.addBuffer(Buffer.from([ 0x03, 0xF6 ])); expect(bitstream.readSignedSync(16)).to.equal(1014); + bitstream.addBuffer(Buffer.from([ 0, 0 ])); expect(bitstream.readSignedSync(16)).to.equal(0); bitstream.addBuffer(Buffer.from([0x0A, 0xFC])); expect(bitstream.readSignedSync(16, 'little-endian')).to.equal(-1014); bitstream.addBuffer(Buffer.from([0xF6, 0x03])); expect(bitstream.readSignedSync(16, 'little-endian')).to.equal(1014); bitstream.addBuffer(Buffer.from([0, 0])); expect(bitstream.readSignedSync(16, 'big-endian')).to.equal(0); - bitstream.addBuffer(Buffer.from([0xFF, 0xFE, 0x70, 0x40])); expect(bitstream.readSignedSync(32)).to.equal(-102336); - bitstream.addBuffer(Buffer.from([0x00, 0x01, 0x8F, 0xC0])); expect(bitstream.readSignedSync(32)).to.equal(102336); - bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(bitstream.readSignedSync(32)).to.equal(0); + bitstream.addBuffer(Buffer.from([ 0xFF, 0xFE, 0x70, 0x40 ])); expect(bitstream.readSignedSync(32)).to.equal(-102336); + bitstream.addBuffer(Buffer.from([ 0x00, 0x01, 0x8F, 0xC0 ])); expect(bitstream.readSignedSync(32)).to.equal(102336); + bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0 ])); expect(bitstream.readSignedSync(32)).to.equal(0); bitstream.addBuffer(Buffer.from([0x40, 0x70, 0xFE, 0xFF])); expect(bitstream.readSignedSync(32, 'little-endian')).to.equal(-102336); bitstream.addBuffer(Buffer.from([0xC0, 0x8F, 0x01, 0x00])); expect(bitstream.readSignedSync(32, 'little-endian')).to.equal(102336); @@ -414,21 +414,21 @@ describe('BitstreamReader', it => { }); it('.readSigned() correctly handles signed integers', async () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0xFB])); expect(await bitstream.readSigned(8)).to.equal(-5); - bitstream.addBuffer(Buffer.from([5])); expect(await bitstream.readSigned(8)).to.equal(5); - bitstream.addBuffer(Buffer.from([0])); expect(await bitstream.readSigned(8)).to.equal(0); + bitstream.addBuffer(Buffer.from([ 0xFB ])); expect(await bitstream.readSigned(8)).to.equal(-5); + bitstream.addBuffer(Buffer.from([ 5 ])); expect(await bitstream.readSigned(8)).to.equal(5); + bitstream.addBuffer(Buffer.from([ 0 ])); expect(await bitstream.readSigned(8)).to.equal(0); - bitstream.addBuffer(Buffer.from([0xFC, 0x0A])); expect(await bitstream.readSigned(16)).to.equal(-1014); - bitstream.addBuffer(Buffer.from([0x03, 0xF6])); expect(await bitstream.readSigned(16)).to.equal(1014); - bitstream.addBuffer(Buffer.from([0, 0])); expect(await bitstream.readSigned(16)).to.equal(0); + bitstream.addBuffer(Buffer.from([ 0xFC, 0x0A ])); expect(await bitstream.readSigned(16)).to.equal(-1014); + bitstream.addBuffer(Buffer.from([ 0x03, 0xF6 ])); expect(await bitstream.readSigned(16)).to.equal(1014); + bitstream.addBuffer(Buffer.from([ 0, 0 ])); expect(await bitstream.readSigned(16)).to.equal(0); - bitstream.addBuffer(Buffer.from([0xFC, 0x0A].reverse())); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(-1014); - bitstream.addBuffer(Buffer.from([0x03, 0xF6].reverse())); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(1014); - bitstream.addBuffer(Buffer.from([0, 0])); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(0); + bitstream.addBuffer(Buffer.from([ 0x0A, 0xFC ])); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(-1014); + bitstream.addBuffer(Buffer.from([ 0xF6, 0x03 ])); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(1014); + bitstream.addBuffer(Buffer.from([ 0, 0 ])); expect(await bitstream.readSigned(16, 'little-endian')).to.equal(0); - bitstream.addBuffer(Buffer.from([0xFF, 0xFE, 0x70, 0x40])); expect(await bitstream.readSigned(32)).to.equal(-102336); - bitstream.addBuffer(Buffer.from([0x00, 0x01, 0x8F, 0xC0])); expect(await bitstream.readSigned(32)).to.equal(102336); - bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(await bitstream.readSigned(32)).to.equal(0); + bitstream.addBuffer(Buffer.from([ 0xFF, 0xFE, 0x70, 0x40 ])); expect(await bitstream.readSigned(32)).to.equal(-102336); + bitstream.addBuffer(Buffer.from([ 0x00, 0x01, 0x8F, 0xC0 ])); expect(await bitstream.readSigned(32)).to.equal(102336); + bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0 ])); expect(await bitstream.readSigned(32)).to.equal(0); bitstream.addBuffer(Buffer.from([0x40, 0x70, 0xFE, 0xFF])); expect(await bitstream.readSigned(32, 'little-endian')).to.equal(-102336); bitstream.addBuffer(Buffer.from([0xC0, 0x8F, 0x01, 0x00])); expect(await bitstream.readSigned(32, 'little-endian')).to.equal(102336); @@ -436,43 +436,43 @@ describe('BitstreamReader', it => { }); it('.readSigned() can wait until data is available', async () => { let bitstream = new BitstreamReader(); - setTimeout(() => bitstream.addBuffer(Buffer.from([0xFB])), 10); + setTimeout(() => bitstream.addBuffer(Buffer.from([ 0xFB ])), 10); expect(await bitstream.readSigned(8)).to.equal(-5); }); it('.readFloatSync() correctly handles floats', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0x42, 0xCD, 0x00, 0x00])); expect(bitstream.readFloatSync(32)).to.equal(102.5); - bitstream.addBuffer(Buffer.from([0xC3, 0xDA, 0x00, 0x00])); expect(bitstream.readFloatSync(32)).to.equal(-436); - bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(bitstream.readFloatSync(32)).to.equal(0); - - bitstream.addBuffer(Buffer.from([0x41, 0x60, 0xae, 0x29, 0x71, 0xeb, 0x85, 0x1f])); + bitstream.addBuffer(Buffer.from([ 0x42, 0xCD, 0x00, 0x00 ])); expect(bitstream.readFloatSync(32)).to.equal(102.5); + bitstream.addBuffer(Buffer.from([ 0xC3, 0xDA, 0x00, 0x00 ])); expect(bitstream.readFloatSync(32)).to.equal(-436); + bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0 ])); expect(bitstream.readFloatSync(32)).to.equal(0); + + bitstream.addBuffer(Buffer.from([ 0x41, 0x60, 0xae, 0x29, 0x71, 0xeb, 0x85, 0x1f ])); expect(bitstream.readFloatSync(64)).to.equal(8745291.56); - bitstream.addBuffer(Buffer.from([0xc1, 0x14, 0x00, 0xa4, 0xae, 0x14, 0x7a, 0xe1])); + bitstream.addBuffer(Buffer.from([ 0xc1, 0x14, 0x00, 0xa4, 0xae, 0x14, 0x7a, 0xe1 ])); expect(bitstream.readFloatSync(64)).to.equal(-327721.17); - bitstream.addBuffer(Buffer.from([0, 0, 0, 0, 0, 0, 0, 0])); + bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0, 0, 0, 0, 0 ])); expect(bitstream.readFloatSync(64)).to.equal(0); - bitstream.addBuffer(Buffer.from([0xe1, 0x7a, 0x14, 0xae, 0xa4, 0x00, 0x14, 0xc1])); + bitstream.addBuffer(Buffer.from([ 0xe1, 0x7a, 0x14, 0xae, 0xa4, 0x00, 0x14, 0xc1 ])); expect(bitstream.readFloatSync(64, 'little-endian')).to.equal(-327721.17); }); it('.readFloat() correctly handles floats', async () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0x42, 0xCD, 0x00, 0x00])); expect(await bitstream.readFloat(32)).to.equal(102.5); - bitstream.addBuffer(Buffer.from([0xC3, 0xDA, 0x00, 0x00])); expect(await bitstream.readFloat(32)).to.equal(-436); - bitstream.addBuffer(Buffer.from([0, 0, 0, 0])); expect(await bitstream.readFloat(32)).to.equal(0); - - bitstream.addBuffer(Buffer.from([0x41, 0x60, 0xae, 0x29, 0x71, 0xeb, 0x85, 0x1f])); + bitstream.addBuffer(Buffer.from([ 0x42, 0xCD, 0x00, 0x00 ])); expect(await bitstream.readFloat(32)).to.equal(102.5); + bitstream.addBuffer(Buffer.from([ 0xC3, 0xDA, 0x00, 0x00 ])); expect(await bitstream.readFloat(32)).to.equal(-436); + bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0 ])); expect(await bitstream.readFloat(32)).to.equal(0); + + bitstream.addBuffer(Buffer.from([ 0x41, 0x60, 0xae, 0x29, 0x71, 0xeb, 0x85, 0x1f ])); expect(await bitstream.readFloat(64)).to.equal(8745291.56); - bitstream.addBuffer(Buffer.from([0xc1, 0x14, 0x00, 0xa4, 0xae, 0x14, 0x7a, 0xe1])); + bitstream.addBuffer(Buffer.from([ 0xc1, 0x14, 0x00, 0xa4, 0xae, 0x14, 0x7a, 0xe1 ])); expect(await bitstream.readFloat(64)).to.equal(-327721.17); - bitstream.addBuffer(Buffer.from([0, 0, 0, 0, 0, 0, 0, 0])); + bitstream.addBuffer(Buffer.from([ 0, 0, 0, 0, 0, 0, 0, 0 ])); expect(await bitstream.readFloat(64)).to.equal(0); bitstream.addBuffer(Buffer.from([0xe1, 0x7a, 0x14, 0xae, 0xa4, 0x00, 0x14, 0xc1])); @@ -481,7 +481,7 @@ describe('BitstreamReader', it => { it('.readFloat() can wait until data is available', async () => { let bitstream = new BitstreamReader(); - setTimeout(() => bitstream.addBuffer(Buffer.from([0x42, 0xCD, 0x00, 0x00])), 10); + setTimeout(() => bitstream.addBuffer(Buffer.from([ 0x42, 0xCD, 0x00, 0x00 ])), 10); expect(await bitstream.readFloat(32)).to.equal(102.5); }); @@ -499,7 +499,7 @@ describe('BitstreamReader', it => { it('peek() reads an unsigned integer without consuming it', async () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([37])); + bitstream.addBuffer(Buffer.from([ 37 ])); expect(await bitstream.peek(8)).to.equal(37); expect(bitstream.offset).to.equal(0); @@ -561,18 +561,18 @@ describe('BitstreamReader', it => { it('correctly handles NaN', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0x7F, 0xC0, 0x00, 0x00])); expect(bitstream.readFloatSync(32)).to.be.NaN; - - bitstream.addBuffer(Buffer.from([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); + bitstream.addBuffer(Buffer.from([ 0x7F, 0xC0, 0x00, 0x00 ])); expect(bitstream.readFloatSync(32)).to.be.NaN; + + bitstream.addBuffer(Buffer.from([ 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])); expect(bitstream.readFloatSync(64)).to.be.NaN; }); it('correctly handles Infinity', () => { let bitstream = new BitstreamReader(); - bitstream.addBuffer(Buffer.from([0x7f, 0x80, 0x00, 0x00])); + bitstream.addBuffer(Buffer.from([ 0x7f, 0x80, 0x00, 0x00 ])); expect(bitstream.readFloatSync(32)).not.to.be.finite; - - bitstream.addBuffer(Buffer.from([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); + + bitstream.addBuffer(Buffer.from([ 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])); expect(bitstream.readFloatSync(64)).not.to.be.finite; bitstream.addBuffer(Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f])); @@ -586,7 +586,7 @@ describe('BitstreamReader', it => { try { await bitstream.read(8); } catch (e) { caught = e; } - + expect(caught, `Expected read() to throw`).to.exist; }); it('.assure() allows only one async call at a time', async () => { @@ -597,7 +597,7 @@ describe('BitstreamReader', it => { try { await bitstream.assure(8); } catch (e) { caught = e; } - + expect(caught, `Expected assure() to throw`).to.exist; }); it('.readStringSync() reads a string correctly', () => { @@ -709,21 +709,21 @@ describe('BitstreamReader', it => { }); it('.readBytes() reads a buffer correctly when the data is already available', async () => { let bitstream = new BitstreamReader(); - let buf = Buffer.from([12, 42, 15]); + let buf = Buffer.from([ 12, 42, 15 ]); bitstream.addBuffer(buf); let buf2 = Buffer.alloc(3); await bitstream.readBytesBlocking(buf2); - expect(Array.from(buf2)).to.eql([12, 42, 15]); + expect(Array.from(buf2)).to.eql([ 12, 42, 15 ]); }); it('.readBytes() reads a buffer correctly when the data is already available', async () => { let bitstream = new BitstreamReader(); - let buf = Buffer.from([12, 42, 15]); + let buf = Buffer.from([ 12, 42, 15 ]); setTimeout(() => bitstream.addBuffer(buf), 10); let buf2 = Buffer.alloc(3); await bitstream.readBytesBlocking(buf2); - expect(Array.from(buf2)).to.eql([12, 42, 15]); + expect(Array.from(buf2)).to.eql([ 12, 42, 15 ]); }); it('.addBuffer() throws when called on an ended stream', async () => { let bitstream = new BitstreamReader(); @@ -795,25 +795,25 @@ describe('BitstreamReader', it => { let bitstream = new BitstreamReader(); expect(bitstream.ended).to.be.false; bitstream.end(); - expect(bitstream.ended).to.be.true; + expect (bitstream.ended).to.be.true; }); it('.end() causes pending assure() to reject', async () => { let bitstream = new BitstreamReader(); let thrown = bitstream.assure(8).then(() => false).catch(() => true); bitstream.end(); - expect(await thrown).to.be.true; + expect (await thrown).to.be.true; }); it('.end() causes pending read() to reject', async () => { let bitstream = new BitstreamReader(); let thrown = bitstream.read(8).then(() => false).catch(() => true); bitstream.end(); - expect(await thrown).to.be.true; + expect (await thrown).to.be.true; }); it('.end() does not cause a pending optional assure() to reject', async () => { let bitstream = new BitstreamReader(); let thrown = bitstream.assure(8, true).then(() => false).catch(() => true); bitstream.end(); - expect(await thrown).to.be.false; + expect (await thrown).to.be.false; }); it('.reset() throws if there is a pending operation', async () => { let bitstream = new BitstreamReader(); @@ -866,7 +866,7 @@ describe('BitstreamReader (generated)', it => { let view = new DataView(buf); for (let i = 0; i < 10; ++i) { - let num = Math.floor(Math.random() * 2 ** size); + let num = Math.floor(Math.random() * 2**size); view.setBigUint64(0, BigInt(num), false); let reader = new BitstreamReader(); reader.addBuffer(new Uint8Array(buf)); @@ -895,7 +895,7 @@ describe('BitstreamReader (generated)', it => { let view = new DataView(buf); for (let i = 0; i < 10; ++i) { - let num = Math.floor(Math.random() * 2 ** size); + let num = Math.floor(Math.random() * 2**size); view.setBigUint64(0, BigInt(num) << BigInt(1), false); let reader = new BitstreamReader(); reader.addBuffer(new Uint8Array(buf)); @@ -931,7 +931,7 @@ describe('BitstreamReader (generated)', it => { let view = new DataView(buf); for (let i = 0; i < 10; ++i) { - let num = Math.floor(Math.random() * 2 ** size); + let num = Math.floor(Math.random() * 2**size); view.setBigUint64(0, BigInt(num) << BigInt(4), false); let reader = new BitstreamReader(); reader.addBuffer(new Uint8Array(buf)); diff --git a/src/bitstream/reader.ts b/src/bitstream/reader.ts index d9dae74..cbbf0c3 100644 --- a/src/bitstream/reader.ts +++ b/src/bitstream/reader.ts @@ -6,13 +6,13 @@ let maskMap: Map; * Represents a request to read a number of bits */ interface BitstreamRequest { - resolve: (buffer: number) => void; + resolve : (buffer : number) => void; reject: (error: Error) => void; promise: Promise; - length: number; - signed?: boolean; - float?: boolean; - assure?: boolean; + length : number; + signed? : boolean; + float? : boolean; + assure? : boolean; } /** @@ -20,9 +20,9 @@ interface BitstreamRequest { * order */ export class BitstreamReader { - private buffers: Uint8Array[] = []; - private bufferedLength: number = 0; - private blockedRequest: BitstreamRequest = null; + private buffers : Uint8Array[] = []; + private bufferedLength : number = 0; + private blockedRequest : BitstreamRequest = null; private _offsetIntoBuffer = 0; private _bufferIndex = 0; private _offset = 0; @@ -59,14 +59,14 @@ export class BitstreamReader { set offset(value) { if (value < this._spentBufferSize) { throw new Error( - `Offset ${value} points into a discarded buffer! ` + `Offset ${value} points into a discarded buffer! ` + `If you need to seek backwards outside the current buffer, make sure to set retainBuffers=true` ); } let offsetIntoBuffer = value - this._spentBufferSize; let bufferIndex = 0; - + for (let i = 0, max = this.buffers.length; i < max; ++i) { let buf = this.buffers[i]; let size = buf.length * 8; @@ -126,7 +126,7 @@ export class BitstreamReader { * visited. If you enable this, you will need to remove buffers manually using * clean() */ - retainBuffers: boolean = false; + retainBuffers : boolean = false; /** * Remove any fully used up buffers. Only has an effect if retainBuffers is true. @@ -159,7 +159,7 @@ export class BitstreamReader { * @param length The number of bits to check for * @returns True if the required number of bits is available, false otherwise */ - isAvailable(length: number) { + isAvailable(length : number) { return this.bufferedLength >= length; } @@ -177,9 +177,9 @@ export class BitstreamReader { * @param options A set of options to control conversion into a string. @see StringEncodingOptions * @returns The resulting string */ - async readString(length: number, options?: StringEncodingOptions): Promise { + async readString(length : number, options? : StringEncodingOptions): Promise { this.ensureNoReadPending(); - await this.assure(8 * length); + await this.assure(8*length); return this.readStringSync(length, options); } @@ -190,10 +190,10 @@ export class BitstreamReader { * @param options A set of options to control conversion into a string. @see StringEncodingOptions * @returns The resulting string */ - readStringSync(length: number, options?: StringEncodingOptions): string { + readStringSync(length : number, options? : StringEncodingOptions): string { if (!options) options = {}; - + this.ensureNoReadPending(); let buffer = new Uint8Array(length); @@ -212,7 +212,7 @@ export class BitstreamReader { for (let i = 0, max = length; i < max; i += charLength) { let char = buffer[i]; if (charLength === 2) - char = (char << 8) | (buffer[i + 1] ?? 0); + char = (char << 8) | (buffer[i+1] ?? 0); if (char === 0) { firstTerminator = i; @@ -241,7 +241,7 @@ export class BitstreamReader { * @param length The number of bits to read * @returns The number read from the bitstream */ - peekSync(length: number) { + peekSync(length : number) { return this.readCoreSync(length, false); } @@ -251,10 +251,10 @@ export class BitstreamReader { * Skip the given number of bits. * @param length The number of bits to skip */ - skip(length: number) { + skip(length : number) { this.skippedLength += length; } - + /** * Read an unsigned integer of the given bit length synchronously. If there are not enough * bits available, an error is thrown. @@ -277,7 +277,7 @@ export class BitstreamReader { * @param offset The offset into the buffer to write to. Defaults to zero * @param length The length of bytes to read. Defaults to the length of the array (sans the offset) */ - *readBytes(buffer: Uint8Array, offset: number = 0, length?: number): Generator { + *readBytes(buffer : Uint8Array, offset : number = 0, length? : number): Generator { length ??= buffer.length - offset; let bitOffset = this._offsetIntoBuffer % 8; @@ -318,10 +318,10 @@ export class BitstreamReader { // Non-byte-aligned, we need to construct bytes using bit-wise operations. // readSync is perfect for this - for (let i = offset, max = Math.min(buffer.length, offset + length); i < max; ++i) { + for (let i = offset, max = Math.min(buffer.length, offset+length); i < max; ++i) { if (!this.isAvailable(8)) yield max - i; - + buffer[i] = this.readSync(8); } } @@ -337,7 +337,7 @@ export class BitstreamReader { * @param offset The offset into the buffer to write to. Defaults to zero * @param length The length of bytes to read. Defaults to the length of the array (sans the offset) */ - readBytesSync(buffer: Uint8Array, offset: number = 0, length?: number): Uint8Array { + readBytesSync(buffer : Uint8Array, offset : number = 0, length? : number): Uint8Array { length ??= buffer.length - offset; let gen = this.readBytes(buffer, offset, length); @@ -359,14 +359,14 @@ export class BitstreamReader { * @param offset The offset into the buffer to write to. Defaults to zero * @param length The length of bytes to read. Defaults to the length of the array (sans the offset) */ - async readBytesBlocking(buffer: Uint8Array, offset: number = 0, length?: number) { + async readBytesBlocking(buffer : Uint8Array, offset : number = 0, length? : number) { length ??= buffer.length - offset; let gen = this.readBytes(buffer, offset, length); while (true) { let result = gen.next(); if (result.done === false) - await this.assure(result.value * 8); + await this.assure(result.value*8); else break; } @@ -386,7 +386,7 @@ export class BitstreamReader { */ readSignedSync(length: number, byteOrder: "big-endian" | "little-endian" = 'big-endian'): number { const u = this.readSync(length, byteOrder); - const signBit = (2 ** (length - 1)); + const signBit = (2**(length - 1)); const mask = signBit - 1; return (u & signBit) === 0 ? u : -((~(u - 1) & mask) >>> 0); } @@ -403,7 +403,7 @@ export class BitstreamReader { } - + /** * Read an IEEE 754 floating point value with the given bit length (32 or 64). If there are not * enough bits available, an error is thrown. @@ -418,7 +418,7 @@ export class BitstreamReader { readFloatSync(length: number, byteOrder: "big-endian" | "little-endian" = 'big-endian'): number { if (length !== 32 && length !== 64) throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); - + if (!this.isAvailable(length)) throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); @@ -427,7 +427,7 @@ export class BitstreamReader { for (let i = 0, max = buf.byteLength; i < max; ++i) view.setUint8(i, this.readSync(8)); - + if (length === 32) return view.getFloat32(0, byteOrder === 'little-endian'); else if (length === 64) @@ -609,7 +609,7 @@ export class BitstreamReader { */ private readCoreSync(length: number, consume: boolean, byteOrder: "big-endian" | "little-endian" = 'big-endian'): number { this.ensureNoReadPending(); - + if (this.available < length) throw new Error(`underrun: Not enough bits are available (requested=${length}, available=${this.bufferedLength}, buffers=${this.buffers.length})`); @@ -660,16 +660,16 @@ export class BitstreamReader { let bitOffset = offset % 8; let bitContribution: number; let byte = buffer[byteOffset]; - + bitContribution = Math.min(8 - bitOffset, remainingLength); - + if (useBigInt) { - bigValue = (bigValue << BigInt(bitContribution)) - | ((BigInt(buffer[byteOffset]) >> (BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset))) + bigValue = (bigValue << BigInt(bitContribution)) + | ((BigInt(buffer[byteOffset]) >> (BigInt(8) - BigInt(bitContribution) - BigInt(bitOffset))) & BigInt(this.maskOf(bitContribution))); } else { - value = (value << bitContribution) - | ((byte >> (8 - bitContribution - bitOffset)) + value = (value << bitContribution) + | ((byte >> (8 - bitContribution - bitOffset)) & this.maskOf(bitContribution)); } @@ -678,7 +678,7 @@ export class BitstreamReader { offset += bitContribution; remainingLength -= bitContribution | 0; - if (offset >= buffer.length * 8) { + if (offset >= buffer.length*8) { bufferIndex += 1; offset = 0; } @@ -691,11 +691,9 @@ export class BitstreamReader { if (byteOrder === 'little-endian') { let nvalue = BigInt(0); - //if (length == 32) console.log(value.toString(2).padStart(64, '.').match(/.{1,8}/g).join(":"), '++++++++'); for (let i = 0; i < length; i += 8) { nvalue = nvalue | ((BigInt(value) >> BigInt(i)) & BigInt(0xFF)) << BigInt(length - i - 8); } - //if (length == 32) console.log(nvalue.toString(2).padStart(64, '.').match(/.{1,8}/g).join(":"), '--------'); return Number(nvalue); } else { return value; @@ -706,10 +704,10 @@ export class BitstreamReader { private adjustSkip() { if (this.skippedLength <= 0) return; - + // First, remove any buffers that are completely skipped - while (this.buffers && this.skippedLength > this.buffers[0].length * 8 - this._offsetIntoBuffer) { - this.skippedLength -= (this.buffers[0].length * 8 - this._offsetIntoBuffer); + while (this.buffers && this.skippedLength > this.buffers[0].length*8-this._offsetIntoBuffer) { + this.skippedLength -= (this.buffers[0].length*8 - this._offsetIntoBuffer); this._offsetIntoBuffer = 0; this.buffers.shift(); } @@ -731,7 +729,7 @@ export class BitstreamReader { * @returns A promise which will resolve when the requested number of bits are available. Rejects if the stream * ends before the request is satisfied, unless optional parameter is true. */ - assure(length: number, optional = false): Promise { + assure(length : number, optional = false) : Promise { this.ensureNoReadPending(); if (this.bufferedLength >= length) { @@ -758,7 +756,7 @@ export class BitstreamReader { */ read(length: number, byteOrder?: "big-endian" | "little-endian"): Promise { this.ensureNoReadPending(); - + if (this.available >= length) { return Promise.resolve(this.readSync(length, byteOrder)); } else { @@ -778,7 +776,7 @@ export class BitstreamReader { */ readSigned(length: number, byteOrder?: "big-endian" | "little-endian"): Promise { this.ensureNoReadPending(); - + if (this.available >= length) { return Promise.resolve(this.readSignedSync(length, byteOrder)); } else { @@ -823,7 +821,7 @@ export class BitstreamReader { */ readFloat(length: number, byteOrder?: "big-endian" | "little-endian"): Promise { this.ensureNoReadPending(); - + if (this.available >= length) { return Promise.resolve(this.readFloatSync(length, byteOrder)); } else { @@ -837,7 +835,7 @@ export class BitstreamReader { * to complete the operation, the operation is delayed until enough bits become available. * @returns A promise which resolves iwth the number read from the bitstream */ - async peek(length: number): Promise { + async peek(length : number): Promise { await this.assure(length); return this.peekSync(length); } @@ -846,7 +844,7 @@ export class BitstreamReader { * Add a buffer onto the end of the bitstream. * @param buffer The buffer to add to the bitstream */ - addBuffer(buffer: Uint8Array) { + addBuffer(buffer : Uint8Array) { if (this._ended) throw new Error(`Cannot add buffers to a reader which has been marked as ended without calling reset() first`); diff --git a/src/bitstream/writer.test.ts b/src/bitstream/writer.test.ts index 5f85e0e..f400f70 100644 --- a/src/bitstream/writer.test.ts +++ b/src/bitstream/writer.test.ts @@ -4,8 +4,8 @@ import { BitstreamWriter } from "./writer"; describe('BitstreamWriter', it => { it('works for bit writes', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(1, 0b1); writer.write(1, 0b0); @@ -28,8 +28,8 @@ describe('BitstreamWriter', it => { expect(bufs[1][0]).to.equal(0b01100110); }); it('works for short writes', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(3, 0b010); writer.write(3, 0b101); @@ -38,16 +38,16 @@ describe('BitstreamWriter', it => { expect(bufs[0][0]).to.equal(0b01010111); }); it('works for full-byte writes', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(8, 0b01010111); expect(bufs.length).to.equal(1); expect(bufs[0][0]).to.equal(0b01010111); }); it('works for offset full-byte writes', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(4, 0b1111); writer.write(8, 0b01010111); @@ -57,8 +57,8 @@ describe('BitstreamWriter', it => { expect(bufs[1][0]).to.equal(0b01111111); }); it('works for large writes (1)', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(16, 0b1111111100000000); expect(bufs.length).to.equal(2); @@ -66,8 +66,8 @@ describe('BitstreamWriter', it => { expect(bufs[1][0]).to.equal(0b00000000); }); it('works for large writes (2)', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(16, 0b0101010110101010); expect(bufs.length).to.equal(2); @@ -93,8 +93,8 @@ describe('BitstreamWriter', it => { expect(bufs[1][0]).to.equal(0b01010101); }); it('works for offset large writes', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.write(4, 0b1111); writer.write(16, 0b0101010110101010); @@ -119,8 +119,8 @@ describe('BitstreamWriter', it => { expect(bufs[2][0]).to.equal(0b01011111); }); it('respects configured buffer size', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); writer.write(8, 0b11111100); expect(bufs.length).to.equal(0); @@ -139,8 +139,8 @@ describe('BitstreamWriter', it => { expect(bufs[1][1]).to.equal(0b11111111); }); it('throws when writing NaN as an unsigned integer', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); let caught; @@ -152,8 +152,8 @@ describe('BitstreamWriter', it => { expect(caught, `Expected write(8, NaN) to throw an exception`).to.exist; }); it('throws when writing Infinity as an unsigned integer', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); let caught; @@ -164,8 +164,8 @@ describe('BitstreamWriter', it => { expect(caught, `Expected write(8, Infinity) to throw an exception`).to.exist; }); it('throws when writing NaN as a signed integer', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); let caught; @@ -176,8 +176,8 @@ describe('BitstreamWriter', it => { expect(caught, `Expected write(8, NaN) to throw an exception`).to.exist; }); it('throws when writing values outside of range', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); writer.writeSigned(8, 0); @@ -188,14 +188,14 @@ describe('BitstreamWriter', it => { try { writer.writeSigned(8, 200); } catch (e) { caught = e; } - + expect(caught, `Expected writeSigned(8, 200) to throw an exception`).to.exist; caught = undefined; try { writer.writeSigned(8, 128); } catch (e) { caught = e; } - + expect(caught, `Expected writeSigned(8, 128) to throw an exception`).to.exist; caught = undefined; @@ -209,7 +209,7 @@ describe('BitstreamWriter', it => { try { writer.writeSigned(16, 999999); } catch (e) { caught = e; } - + expect(caught, `Expected writeSigned(8, 200) to throw an exception`).to.exist; caught = undefined; @@ -221,8 +221,8 @@ describe('BitstreamWriter', it => { caught = undefined; }); it('throws when writing Infinity as a signed integer', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); let caught; @@ -233,40 +233,40 @@ describe('BitstreamWriter', it => { expect(caught, `Expected write(8, Infinity) to throw an exception`).to.exist; }); it('writes undefined as zero when unsigned', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 1); writer.write(8, undefined); expect(bufs[0][0]).to.equal(0); }); it('writes null as zero when unsigned', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 1); writer.write(8, null); expect(bufs[0][0]).to.equal(0); }); it('writes undefined as zero when signed', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 1); writer.writeSigned(8, undefined); expect(bufs[0][0]).to.equal(0); }); it('writes null as zero when signed', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 1); writer.writeSigned(8, null); expect(bufs[0][0]).to.equal(0); }); it('correctly handles signed integers', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream); writer.writeSigned(8, -5); expect(bufs[0][0]).to.equal(0xFB); @@ -303,13 +303,13 @@ describe('BitstreamWriter', it => { }); it('correctly handles floats', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); writer.writeFloat(32, 102.5); expect(Array.from(bufs[0])).to.eql([0x42, 0xCD, 0x00, 0x00]); writer.writeFloat(32, -436); expect(Array.from(bufs[1])).to.eql([0xC3, 0xDA, 0x00, 0x00]); - writer.writeFloat(32, 0); expect(Array.from(bufs[2])).to.eql([0, 0, 0, 0]); + writer.writeFloat(32, 0); expect(Array.from(bufs[2])).to.eql([0,0,0,0]); bufs = []; writer = new BitstreamWriter(fakeStream, 4); @@ -345,8 +345,8 @@ describe('BitstreamWriter', it => { }); it('.writeFloat() throws for lengths other than 32 and 64', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); let caught; @@ -358,35 +358,35 @@ describe('BitstreamWriter', it => { }); it('correctly handles NaN', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); writer.writeFloat(32, NaN); expect(Array.from(bufs[0])).to.eql([0x7F, 0xC0, 0x00, 0x00]); - + bufs = []; writer = new BitstreamWriter(fakeStream, 8); - writer.writeFloat(64, NaN); - expect(Array.from(bufs[0])).to.eql([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); + writer.writeFloat(64, NaN); + expect(Array.from(bufs[0])).to.eql([ 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); }); it('correctly handles Infinity', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); - writer.writeFloat(32, Infinity); expect(Array.from(bufs[0])).to.eql([0x7f, 0x80, 0x00, 0x00]); - + writer.writeFloat(32, Infinity); expect(Array.from(bufs[0])).to.eql([ 0x7f, 0x80, 0x00, 0x00 ]); + bufs = []; writer = new BitstreamWriter(fakeStream, 8); - writer.writeFloat(64, Infinity); - expect(Array.from(bufs[0])).to.eql([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); + writer.writeFloat(64, Infinity); + expect(Array.from(bufs[0])).to.eql([ 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); }); it('.end() flushes full bytes', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); writer.write(8, 44); @@ -397,8 +397,8 @@ describe('BitstreamWriter', it => { expect(bufs[0][0]).to.equal(44); }); it('.end() flushes partial bytes', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 4); writer.write(4, 0b1111); @@ -409,8 +409,8 @@ describe('BitstreamWriter', it => { expect(bufs[0][0]).to.equal(0b11110000); }); it('.writeString() writes utf-8 strings correctly', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 5); writer.writeString(5, 'hello', 'utf-8'); @@ -422,8 +422,8 @@ describe('BitstreamWriter', it => { expect(buf.toString('utf-8')).to.equal('hello'); }); it('.writeString() writes utf16le strings correctly', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 10); writer.writeString(10, 'hello', 'utf16le'); @@ -437,8 +437,8 @@ describe('BitstreamWriter', it => { (globalThis as any).Buffer = undefined; try { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 10); let caught; @@ -453,12 +453,12 @@ describe('BitstreamWriter', it => { } }); it('.writeBuffer() works correctly', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 2); - let buf = Buffer.from([12, 34, 56, 78]); - writer.writeBytes(buf); + let buf = Buffer.from([ 12, 34, 56, 78 ]); + writer.writeBuffer(buf); expect(bufs.length).to.equal(2); expect(bufs[0][0]).to.equal(12); @@ -467,13 +467,13 @@ describe('BitstreamWriter', it => { expect(bufs[1][1]).to.equal(78); }); it('.writeBuffer() works even when not byte-aligned', () => { - let bufs: Buffer[] = []; - let fakeStream: any = { write(buf) { bufs.push(buf); } } + let bufs : Buffer[] = []; + let fakeStream : any = { write(buf) { bufs.push(buf); } } let writer = new BitstreamWriter(fakeStream, 5); - let buf = Buffer.from([12, 34, 56, 78]); + let buf = Buffer.from([ 12, 34, 56, 78 ]); writer.write(4, 0); - writer.writeBytes(buf); + writer.writeBuffer(buf); writer.write(4, 0); expect(bufs.length).to.equal(1); diff --git a/src/bitstream/writer.ts b/src/bitstream/writer.ts index 41b7840..635f930 100644 --- a/src/bitstream/writer.ts +++ b/src/bitstream/writer.ts @@ -144,11 +144,15 @@ export class BitstreamWriter { * number of bits specified, the lower-order bits are written and the higher-order bits are ignored. * @param length The number of bits to write * @param value The number to write + * @param byteOrder The byte order to use when the length is greater than 8 and is a multiple of 8. + * Defaults to MSB (most significant byte). If the length is not a multiple of 8, + * this is unused + * */ write(length: number, value: number | bigint, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (value === void 0 || value === null) value = 0; - + value = Number(value); if (Number.isNaN(value)) @@ -203,10 +207,10 @@ export class BitstreamWriter { writeSigned(length: number, value: number | bigint, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (value === undefined || value === null) value = 0; - + const originalValue = value; - const max = 2 ** (length - 1) - 1; // ie 127 - const min = -(2 ** (length - 1)); // ie -128 + const max = 2**(length - 1) - 1; // ie 127 + const min = -(2**(length - 1)); // ie -128 value = Number(value); @@ -242,7 +246,7 @@ export class BitstreamWriter { writeFloat(length: number, value: number, byteOrder: "big-endian" | "little-endian" = 'big-endian') { if (length !== 32 && length !== 64) throw new TypeError(`Invalid length (${length} bits) Only 4-byte (32 bit / single-precision) and 8-byte (64 bit / double-precision) IEEE 754 values are supported`); - + let buf = new ArrayBuffer(length / 8); let view = new DataView(buf); @@ -267,15 +271,15 @@ export class BitstreamMeasurer extends BitstreamWriter { bitLength = 0; - writeString(byteCount: number, value: string, encoding: string = 'utf-8') { + writeString(byteCount : number, value : string, encoding : string = 'utf-8') { this.bitLength += byteCount * 8; } - writeBuffer(buffer: Uint8Array) { + writeBuffer(buffer : Uint8Array) { this.bitLength += buffer.length * 8; } - write(length: number, value: number) { + write(length : number, value : number) { this.bitLength += length; } } diff --git a/src/elements/number-serializer.ts b/src/elements/number-serializer.ts index ce37371..a214027 100644 --- a/src/elements/number-serializer.ts +++ b/src/elements/number-serializer.ts @@ -10,8 +10,8 @@ import { summarizeField } from "./utils"; * Serializes numbers to/from bitstreams */ export class NumberSerializer implements Serializer { - *read(reader: BitstreamReader, type: any, parent: BitstreamElement, field: FieldDefinition): Generator { - let length: number; + *read(reader: BitstreamReader, type : any, parent : BitstreamElement, field: FieldDefinition): Generator { + let length : number; try { length = resolveLength(field.length, parent, field); } catch (e) { @@ -20,7 +20,7 @@ export class NumberSerializer implements Serializer { if (!reader.isAvailable(length)) yield { remaining: length, contextHint: () => summarizeField(field) }; - + let format = field.options?.number?.format ?? 'unsigned'; if (format === 'unsigned') return reader.readSync(length, field.options?.number?.byteOrder); @@ -32,11 +32,11 @@ export class NumberSerializer implements Serializer { throw new TypeError(`Unsupported number format '${format}'`); } - write(writer: BitstreamWriter, type: any, instance: any, field: FieldDefinition, value: any) { + write(writer: BitstreamWriter, type : any, instance: any, field: FieldDefinition, value: any) { if (value === undefined) value = 0; - let length: number; + let length : number; try { length = resolveLength(field.length, instance, field); } catch (e) {