From 082fcefdc9ee977a6b92511fa7f914ee2ce0f442 Mon Sep 17 00:00:00 2001 From: Luiz Americo Date: Fri, 9 Oct 2026 19:47:35 -0300 Subject: [PATCH 1/6] Update dependencies. Remove dependencies with vulnerabilities --- package-lock.json | 6171 ++++++++--------------- package.json | 28 +- scripts/clean.js | 14 + src/opentype/shapers/ArabicShaper.js | 4 +- src/opentype/shapers/IndicShaper.js | 4 +- src/opentype/shapers/UniversalShaper.js | 2 +- src/opentype/shapers/gen-indic.js | 2 +- src/opentype/shapers/gen-use.js | 2 +- src/opentype/shapers/generate-data.js | 4 +- 9 files changed, 2049 insertions(+), 4182 deletions(-) create mode 100644 scripts/clean.js diff --git a/package-lock.json b/package-lock.json index 0002abe3..b4b3e1ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,145 +9,40 @@ "version": "2.0.4", "license": "MIT", "dependencies": { - "@swc/helpers": "^0.5.12", - "brotli": "^1.3.2", + "@swc/helpers": "^0.5.23", + "brotli": "^1.3.3", "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", - "restructure": "^3.0.0", + "restructure": "^3.0.2", "tiny-inflate": "^1.0.3", - "unicode-properties": "^1.4.0", - "unicode-trie": "^2.0.0" + "unicode-properties": "^2.0.1", + "unicode-trie": "^3.0.0" }, "devDependencies": { - "c8": "^7.11.3", - "codepoints": "^1.2.0", + "c8": "^12.0.0", + "codepoints": "^1.3.0", "concat-stream": "^2.0.0", - "mocha": "^10.0.0", - "npm-run-all": "^4.1.5", - "parcel": "2.0.0-canary.1713", - "shx": "^0.3.4" + "mocha": "^12.0.3", + "parcel": "2.16.4" } }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -178,16 +73,18 @@ } }, "node_modules/@lezer/common": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", - "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.3.tgz", + "integrity": "sha512-H0iErY4e43LpXbYDyBci5W4v/RwTgGV3YzYOlJPiGZ8RY8w51kVE+xLn1tg3Z6UmSfyETvtsUK3r7YsgDQEI7Q==", + "dev": true, + "license": "MIT" }, "node_modules/@lezer/lr": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", - "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.11.tgz", + "integrity": "sha512-UwgZcl1R66H2hDzBrA7kWyYmX6s8p5TQ+e/t7CuvgCtBEPxbEPaHYHu+pJBvTvDotEJpuQkJjbXuHiw5Cixxgw==", "dev": true, + "license": "MIT", "dependencies": { "@lezer/common": "^1.0.0" } @@ -200,6 +97,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -213,6 +111,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -226,6 +125,7 @@ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -239,6 +139,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -252,6 +153,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -265,6 +167,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -275,6 +178,7 @@ "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz", "integrity": "sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w==", "dev": true, + "license": "MIT", "dependencies": { "@lezer/common": "^1.0.0", "@lezer/lr": "^1.0.0", @@ -285,99 +189,106 @@ } }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", + "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz", + "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz", + "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz", + "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", - "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz", + "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz", + "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@parcel/bundler-default": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.0.0-canary.1715.tgz", - "integrity": "sha512-yxu4KENy0Dyv+qWU2/+4+OYma1p5toe4p5c+4JKPr8apIujyAmzCILdeEqTmmgD+jj1hsIqswKgYa9WxAW4Dig==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.16.4.tgz", + "integrity": "sha512-Nb8peNvhfm1+660CLwssWh4weY+Mv6vEGS6GPKqzJmTMw50udi0eS1YuWFzvmhSiu1KsYcUD37mqQ1LuIDtWoA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/graph": "3.2.1-canary.3338+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/graph": "3.6.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -385,14 +296,15 @@ } }, "node_modules/@parcel/cache": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.0.0-canary.1715.tgz", - "integrity": "sha512-Dg2L3Zln0h3pFdNH9i8XVrddhhczewHfCBIrd4pGuHJnSEK0gV0mXgGNLnumgUFrAdNwfvc8xJma8HE+GFTgfA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.16.4.tgz", + "integrity": "sha512-+uCyeElSga2MBbmbXpIj/WVKH7TByCrKaxtHbelfKKIJpYMgEHVjO4cuc7GUfTrUAmRUS8ZGvnX7Etgq6/jQhw==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/fs": "2.0.0-canary.1715+d599275b1", - "@parcel/logger": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/utils": "2.16.4", "lmdb": "2.8.5" }, "engines": { @@ -403,16 +315,17 @@ "url": "https://opencollective.com/parcel" }, "peerDependencies": { - "@parcel/core": "^2.0.0-canary.1713+d599275b1" + "@parcel/core": "^2.16.4" } }, "node_modules/@parcel/codeframe": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.0.0-canary.1715.tgz", - "integrity": "sha512-FsGeW4vBBX9V0kZWgiqhxS+5cnhyXaS4XguMWolbqbeuSSLNSOdmrBJ8NZ/vzvmQ8OFAlq0oCAsiVxg3Z4VkRg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.16.4.tgz", + "integrity": "sha512-s64aMfOJoPrXhKH+Y98ahX0O8aXWvTR+uNlOaX4yFkpr4FFDnviLcGngDe/Yo4Qq2FJZ0P6dNswbJTUH9EGxkQ==", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^4.1.0" + "chalk": "^4.1.2" }, "engines": { "node": ">= 16.0.0" @@ -423,16 +336,17 @@ } }, "node_modules/@parcel/compressor-raw": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.12.1-canary.3338.tgz", - "integrity": "sha512-RvAp7KpsIF8kUwqov2j6+qikHk2JbJmtHe2kYkapY0K085orH3+IE/gLCNCtPArPpLCHgbgSzKJaRi57HqSV6w==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.16.4.tgz", + "integrity": "sha512-IK8IpNhw61B2HKgA1JhGhO9y+ZJFRZNTEmvhN1NdLdPqvgEXm2EunT+m6D9z7xeoeT6XnUKqM0eRckEdD0OXbA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1" + "@parcel/plugin": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -440,82 +354,86 @@ } }, "node_modules/@parcel/config-default": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.0.0-canary.1715.tgz", - "integrity": "sha512-2gn3sg/7mffnVXGagbEh425LjoTDbS52HtMaBX4bN2xBlcWTaGNGWyY/vgPm5Nufck5MtNInMm+y5Dlaook8ZQ==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.16.4.tgz", + "integrity": "sha512-kBxuTY/5trEVnvXk92l7LVkYjNuz3SaqWymFhPjEnc8GY4ZVdcWrWdXWTB9hUhpmRYJctFCyGvM0nN05JTiM2g==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/bundler-default": "2.0.0-canary.1715+d599275b1", - "@parcel/compressor-raw": "2.12.1-canary.3338+d599275b1", - "@parcel/namer-default": "2.0.0-canary.1715+d599275b1", - "@parcel/optimizer-css": "2.12.1-canary.3338+d599275b1", - "@parcel/optimizer-htmlnano": "2.0.0-canary.1715+d599275b1", - "@parcel/optimizer-image": "2.12.1-canary.3338+d599275b1", - "@parcel/optimizer-svgo": "2.12.1-canary.3338+d599275b1", - "@parcel/optimizer-swc": "2.12.1-canary.3338+d599275b1", - "@parcel/packager-css": "2.0.0-canary.1715+d599275b1", - "@parcel/packager-html": "2.0.0-canary.1715+d599275b1", - "@parcel/packager-js": "2.0.0-canary.1715+d599275b1", - "@parcel/packager-raw": "2.0.0-canary.1715+d599275b1", - "@parcel/packager-svg": "2.12.1-canary.3338+d599275b1", - "@parcel/packager-wasm": "2.12.1-canary.3338+d599275b1", - "@parcel/reporter-dev-server": "2.0.0-canary.1715+d599275b1", - "@parcel/resolver-default": "2.0.0-canary.1715+d599275b1", - "@parcel/runtime-browser-hmr": "2.0.0-canary.1715+d599275b1", - "@parcel/runtime-js": "2.0.0-canary.1715+d599275b1", - "@parcel/runtime-react-refresh": "2.0.0-canary.1715+d599275b1", - "@parcel/runtime-service-worker": "2.12.1-canary.3338+d599275b1", - "@parcel/transformer-babel": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-css": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-html": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-image": "2.12.1-canary.3338+d599275b1", - "@parcel/transformer-js": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-json": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-postcss": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-posthtml": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-raw": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-react-refresh-wrap": "2.0.0-canary.1715+d599275b1", - "@parcel/transformer-svg": "2.12.1-canary.3338+d599275b1" + "@parcel/bundler-default": "2.16.4", + "@parcel/compressor-raw": "2.16.4", + "@parcel/namer-default": "2.16.4", + "@parcel/optimizer-css": "2.16.4", + "@parcel/optimizer-html": "2.16.4", + "@parcel/optimizer-image": "2.16.4", + "@parcel/optimizer-svg": "2.16.4", + "@parcel/optimizer-swc": "2.16.4", + "@parcel/packager-css": "2.16.4", + "@parcel/packager-html": "2.16.4", + "@parcel/packager-js": "2.16.4", + "@parcel/packager-raw": "2.16.4", + "@parcel/packager-svg": "2.16.4", + "@parcel/packager-wasm": "2.16.4", + "@parcel/reporter-dev-server": "2.16.4", + "@parcel/resolver-default": "2.16.4", + "@parcel/runtime-browser-hmr": "2.16.4", + "@parcel/runtime-js": "2.16.4", + "@parcel/runtime-rsc": "2.16.4", + "@parcel/runtime-service-worker": "2.16.4", + "@parcel/transformer-babel": "2.16.4", + "@parcel/transformer-css": "2.16.4", + "@parcel/transformer-html": "2.16.4", + "@parcel/transformer-image": "2.16.4", + "@parcel/transformer-js": "2.16.4", + "@parcel/transformer-json": "2.16.4", + "@parcel/transformer-node": "2.16.4", + "@parcel/transformer-postcss": "2.16.4", + "@parcel/transformer-posthtml": "2.16.4", + "@parcel/transformer-raw": "2.16.4", + "@parcel/transformer-react-refresh-wrap": "2.16.4", + "@parcel/transformer-svg": "2.16.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "peerDependencies": { - "@parcel/core": "^2.0.0-canary.1713+d599275b1" + "@parcel/core": "^2.16.4" } }, "node_modules/@parcel/core": { - "version": "2.0.0-canary.1713", - "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.0.0-canary.1713.tgz", - "integrity": "sha512-YTpUEAbdHGViwEwjvT9Qul5G1g3X/MGMJnGyT6/29QoQbT1/h2JCRd0gI4ReUC2RFRSVvn+RI4HXFSgB9pV1OA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.16.4.tgz", + "integrity": "sha512-a0CgrW5A5kwuSu5J1RFRoMQaMs9yagvfH2jJMYVw56+/7NRI4KOtu612SG9Y1ERWfY55ZwzyFxtLWvD6LO+Anw==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "@mischnic/json-sourcemap": "^0.1.0", - "@parcel/cache": "2.0.0-canary.1715+d599275b1", - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/events": "2.0.0-canary.1715+d599275b1", - "@parcel/feature-flags": "2.12.1-canary.3338+d599275b1", - "@parcel/fs": "2.0.0-canary.1715+d599275b1", - "@parcel/graph": "3.2.1-canary.3338+d599275b1", - "@parcel/logger": "2.0.0-canary.1715+d599275b1", - "@parcel/package-manager": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/profiler": "2.12.1-canary.3338+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", + "@mischnic/json-sourcemap": "^0.1.1", + "@parcel/cache": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/feature-flags": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/graph": "3.6.4", + "@parcel/logger": "2.16.4", + "@parcel/package-manager": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/profiler": "2.16.4", + "@parcel/rust": "2.16.4", "@parcel/source-map": "^2.1.1", - "@parcel/types": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "@parcel/workers": "2.0.0-canary.1715+d599275b1", - "base-x": "^3.0.8", - "browserslist": "^4.6.6", - "clone": "^2.1.1", - "dotenv": "^7.0.0", - "dotenv-expand": "^5.1.0", - "json5": "^2.2.0", - "msgpackr": "^1.9.9", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "base-x": "^3.0.11", + "browserslist": "^4.24.5", + "clone": "^2.1.2", + "dotenv": "^16.5.0", + "dotenv-expand": "^11.0.7", + "json5": "^2.2.3", + "msgpackr": "^1.11.2", "nullthrows": "^1.1.1", - "semver": "^7.5.2" + "semver": "^7.7.1" }, "engines": { "node": ">= 16.0.0" @@ -526,12 +444,13 @@ } }, "node_modules/@parcel/diagnostic": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.0.0-canary.1715.tgz", - "integrity": "sha512-014HZ3cIkqcOxMg4LxVTzfqItIRu+cmpTukqh2j7TWrcYBxTgARqE5seqO0z/7w4gigwBu6E5nS+2AVerFgLdw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.16.4.tgz", + "integrity": "sha512-YN5CfX7lFd6yRLxyZT4Sj3sR6t7nnve4TdXSIqapXzQwL7Bw+sj79D95wTq2rCm3mzk5SofGxFAXul2/nG6gcQ==", "dev": true, + "license": "MIT", "dependencies": { - "@mischnic/json-sourcemap": "^0.1.0", + "@mischnic/json-sourcemap": "^0.1.1", "nullthrows": "^1.1.1" }, "engines": { @@ -542,11 +461,26 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@parcel/error-overlay": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/error-overlay/-/error-overlay-2.16.4.tgz", + "integrity": "sha512-e8KYKnMsfmQnqIhsUWBUZAXlDK30wkxsAGle1tZ0gOdoplaIdVq/WjGPatHLf6igLM76c3tRn2vw8jZFput0jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@parcel/events": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.0.0-canary.1715.tgz", - "integrity": "sha512-Ch3zd2/V3ncdHrRVT4lfVBKzxJxe0j5puezYoGqbnPl+IhPDMaTu37aqc4CHR+zmGV6T2Jc7UK0CuprpooptkA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.16.4.tgz", + "integrity": "sha512-slWQkBRAA7o0cN0BLEd+yCckPmlVRVhBZn5Pn6ktm4EzEtrqoMzMeJOxxH8TXaRzrQDYnTcnYIHFgXWd4kkUfg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 16.0.0" }, @@ -556,10 +490,11 @@ } }, "node_modules/@parcel/feature-flags": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/feature-flags/-/feature-flags-2.12.1-canary.3338.tgz", - "integrity": "sha512-37rMX82vMf1wBKgKZTClAgmnNFlfT/SJuQlqRslh+VggoW18mjGOf610L+q5WfJ8qfsKZvRAGCN1+y15wqd9iA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/feature-flags/-/feature-flags-2.16.4.tgz", + "integrity": "sha512-nYdx53siKPLYikHHxfzgjzzgxdrjquK6DMnuSgOTyIdRG4VHdEN0+NqKijRLuVgiUFo/dtxc2h+amwqFENMw8w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 16.0.0" }, @@ -569,17 +504,18 @@ } }, "node_modules/@parcel/fs": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.0.0-canary.1715.tgz", - "integrity": "sha512-Hnn42r0Bd02iamYPChoJi9Jx+BFsKxKQZG/2/abB4fMI8JLsi2iLOLpxHB3VImJQrDhW4YfKjofTZfiFrAoLeg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.16.4.tgz", + "integrity": "sha512-maCMOiVn7oJYZlqlfxgLne8n6tSktIT1k0AeyBp4UGWCXyeJUJ+nL7QYShFpKNLtMLeF0cEtgwRAknWzbcDS1g==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/feature-flags": "2.12.1-canary.3338+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", - "@parcel/types-internal": "2.12.1-canary.3338+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", + "@parcel/feature-flags": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types-internal": "2.16.4", + "@parcel/utils": "2.16.4", "@parcel/watcher": "^2.0.7", - "@parcel/workers": "2.0.0-canary.1715+d599275b1" + "@parcel/workers": "2.16.4" }, "engines": { "node": ">= 16.0.0" @@ -589,16 +525,17 @@ "url": "https://opencollective.com/parcel" }, "peerDependencies": { - "@parcel/core": "^2.0.0-canary.1713+d599275b1" + "@parcel/core": "^2.16.4" } }, "node_modules/@parcel/graph": { - "version": "3.2.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-3.2.1-canary.3338.tgz", - "integrity": "sha512-su2Vrkdbv5M4C4pkz5/DidFuvCGus53OAST76vdD0OR9K8YBTU7uAfxd+W3iUWnkgE8NS0W/kNPJzQHNPQy8RQ==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-3.6.4.tgz", + "integrity": "sha512-Cj9yV+/k88kFhE+D+gz0YuNRpvNOCVDskO9pFqkcQhGbsGq6kg2XpZ9V7HlYraih31xf8Vb589bZOwjKIiHixQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/feature-flags": "2.12.1-canary.3338+d599275b1", + "@parcel/feature-flags": "2.16.4", "nullthrows": "^1.1.1" }, "engines": { @@ -610,13 +547,14 @@ } }, "node_modules/@parcel/logger": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.0.0-canary.1715.tgz", - "integrity": "sha512-IJSpdB96pPI7emX8stvYzFNQYRTcsDDyWDXYJqPonZ1eaw5Vq9ARqBckb/Iys6qq/aiojobCLpjTdR5pXmVyWA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.16.4.tgz", + "integrity": "sha512-QR8QLlKo7xAy9JBpPDAh0RvluaixqPCeyY7Fvo2K7hrU3r85vBNNi06pHiPbWoDmB4x1+QoFwMaGnJOHR+/fMA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/events": "2.0.0-canary.1715+d599275b1" + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4" }, "engines": { "node": ">= 16.0.0" @@ -627,12 +565,13 @@ } }, "node_modules/@parcel/markdown-ansi": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.0.0-canary.1715.tgz", - "integrity": "sha512-VXBcEBWM5DkAkyV918W20/7X0FaB5lPVU8ZEwu5xMZsBGFsLFv/CSVNB2fCxFVb8qqTCwdIlGmv6l+eKEz8v8w==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.16.4.tgz", + "integrity": "sha512-0+oQApAVF3wMcQ6d1ZfZ0JsRzaMUYj9e4U+naj6YEsFsFGOPp+pQYKXBf1bobQeeB7cPKPT3SUHxFqced722Hw==", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^4.1.0" + "chalk": "^4.1.2" }, "engines": { "node": ">= 16.0.0" @@ -643,18 +582,19 @@ } }, "node_modules/@parcel/namer-default": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.0.0-canary.1715.tgz", - "integrity": "sha512-u3KuPxUrGfMyg5xmPdgMrcXrkNOZwSOtpoGGRiyDOlCJVKQMWvzWy9ioo/4c1bButroVjA0lgcAwFhjhQGIa1Q==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.16.4.tgz", + "integrity": "sha512-CE+0lFg881sJq575EXxj2lKUn81tsS5itpNUUErHxit195m3PExyAhoXM6ed/SXxwi+uv+T5FS/jjDLBNuUFDA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -662,19 +602,19 @@ } }, "node_modules/@parcel/node-resolver-core": { - "version": "3.3.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-3.3.1-canary.3338.tgz", - "integrity": "sha512-sbSEXTxSwY5FDUiLXoMnUQBOQcIfjncQq3IlvxQVW1fvf7y3EcuZf3M5Oy3nKdJ0/L3rejNLg+CkNeGCiIqNFg==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-3.7.4.tgz", + "integrity": "sha512-b3VDG+um6IWW5CTod6M9hQsTX5mdIelKmam7mzxzgqg4j5hnycgTWqPMc9UxhYoUY/Q/PHfWepccNcKtvP5JiA==", "dev": true, + "license": "MIT", "dependencies": { - "@mischnic/json-sourcemap": "^0.1.0", - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/feature-flags": "2.12.1-canary.3338+d599275b1", - "@parcel/fs": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", + "@mischnic/json-sourcemap": "^0.1.1", + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1", - "semver": "^7.5.2" + "semver": "^7.7.1" }, "engines": { "node": ">= 16.0.0" @@ -685,245 +625,111 @@ } }, "node_modules/@parcel/optimizer-css": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.12.1-canary.3338.tgz", - "integrity": "sha512-aYH4BBw7KJCXqwOhh/OOmHGwow3veUIWzTZPpDjiO+hmMMSHHFGlMiDiF68yJEYq0kwe1fFBLXVpiXnirdh9hA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.16.4.tgz", + "integrity": "sha512-aqdXCtmvpcXYgJFGk2DtXF34wuM2TD1fZorKMrJdKB9sSkWVRs1tq6RAXQrbi0ZPDH9wfE/9An3YdkTex7RHuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "browserslist": "^4.6.6", - "lightningcss": "^1.22.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "lightningcss": "^1.30.1", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/optimizer-htmlnano": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.0.0-canary.1715.tgz", - "integrity": "sha512-L4VgEvX0PCRRf5J/WPk+Qr3BDWnVUN7I+cDzLfziR9SeNMdyCneh+slS5av4w1dlLG2mFgxxu589fKDWs3dGTg==", + "node_modules/@parcel/optimizer-html": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-html/-/optimizer-html-2.16.4.tgz", + "integrity": "sha512-vg/R2uuSni+NYYUUV8m+5bz8p5zBv8wc/nNleoBnGuCDwn7uaUwTZ8Gt9CjZO8jjG0xCLILoc/TW+e2FF3pfgQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "htmlnano": "^2.0.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "svgo": "^2.4.0" + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/optimizer-htmlnano/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/@parcel/optimizer-htmlnano/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@parcel/optimizer-htmlnano/node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@parcel/optimizer-htmlnano/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "node_modules/@parcel/optimizer-htmlnano/node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/@parcel/optimizer-image": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.12.1-canary.3338.tgz", - "integrity": "sha512-Ojeggg9SFiWQ53s59yZPszuEuyA+4mBAIXX4c9gSxnBcs1A3gJY/CsgHuwwDQm1e/YVUL1vlwteN2kw1KP32Zg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.16.4.tgz", + "integrity": "sha512-2RV54WnvMYr18lxSx7Zlx/DXpJwMzOiPxDnoFyvaUoYutvgHO6chtcgFgh1Bvw/PoI95vYzlTkZ8QfUOk5A0JA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "@parcel/workers": "2.0.0-canary.1715+d599275b1" + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "peerDependencies": { - "@parcel/core": "^2.0.0-canary.1713+d599275b1" + "@parcel/core": "^2.16.4" } }, - "node_modules/@parcel/optimizer-svgo": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-svgo/-/optimizer-svgo-2.12.1-canary.3338.tgz", - "integrity": "sha512-jzljE2LurQj3OXXjOjZmw4thUbppcn04vjSDcjFuwCOPgvyHBUaih7lsujcr0JR2Bl2IYmIgp8tpsAtR1mUyZw==", + "node_modules/@parcel/optimizer-svg": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-svg/-/optimizer-svg-2.16.4.tgz", + "integrity": "sha512-22+BqIffCrVErg8y2XwhasbTaFNn75OKXZ3KTDBIfOSAZKLUKs1iHfDXETzTRN7cVcS+Q36/6EHd7N/RA8i1fg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "svgo": "^2.4.0" + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/optimizer-svgo/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/@parcel/optimizer-svgo/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@parcel/optimizer-svgo/node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@parcel/optimizer-svgo/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "node_modules/@parcel/optimizer-svgo/node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/@parcel/optimizer-swc": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-swc/-/optimizer-swc-2.12.1-canary.3338.tgz", - "integrity": "sha512-9CPlaGNBEMTH/9VU14ewa23EOLDqezEM2at7IYCLBLnUg/36thsPoZ6vDdGhvGk8DXASnPaHjRAZk+vXcvXj/A==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-swc/-/optimizer-swc-2.16.4.tgz", + "integrity": "sha512-+URqwnB6u1gqaLbG1O1DDApH+UVj4WCbK9No1fdxLBxQ9a84jyli25o1kK1hYB9Nb/JMyYNnEBfvYUW6RphOxw==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "@swc/core": "^1.3.36", + "@parcel/utils": "2.16.4", + "@swc/core": "^1.11.24", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -931,20 +737,21 @@ } }, "node_modules/@parcel/package-manager": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.0.0-canary.1715.tgz", - "integrity": "sha512-g4YAk8mESDtam6FygZolHYTT8qvXPopxbuTYBWA6cQXQAFsQZ+oN2u3Rs9BVVIgVsXi6hXRcKGerdxpvm8cOxA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.16.4.tgz", + "integrity": "sha512-obWv9gZgdnkT3Kd+fBkKjhdNEY7zfOP5gVaox5i4nQstVCaVnDlMv5FwLEXwehL+WbwEcGyEGGxOHHkAFKk7Cg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/fs": "2.0.0-canary.1715+d599275b1", - "@parcel/logger": "2.0.0-canary.1715+d599275b1", - "@parcel/node-resolver-core": "3.3.1-canary.3338+d599275b1", - "@parcel/types": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "@parcel/workers": "2.0.0-canary.1715+d599275b1", - "@swc/core": "^1.3.36", - "semver": "^7.5.2" + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/node-resolver-core": "3.7.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "@swc/core": "^1.11.24", + "semver": "^7.7.1" }, "engines": { "node": ">= 16.0.0" @@ -954,25 +761,26 @@ "url": "https://opencollective.com/parcel" }, "peerDependencies": { - "@parcel/core": "^2.0.0-canary.1713+d599275b1" + "@parcel/core": "^2.16.4" } }, "node_modules/@parcel/packager-css": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.0.0-canary.1715.tgz", - "integrity": "sha512-R072803fhJ2CSzo5+2+uxj7CUO8k83praFKF4Ge4xKqdWaevjAsBVaWModDqZI5Hekg740pG6/IY8J1z6qI/OA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.16.4.tgz", + "integrity": "sha512-rWRtfiX+VVIOZvq64jpeNUKkvWAbnokfHQsk/js1s5jD4ViNQgPcNLiRaiIANjymqL6+dQqWvGUSW2a5FAZYfg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "lightningcss": "^1.22.1", + "@parcel/utils": "2.16.4", + "lightningcss": "^1.30.1", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -980,20 +788,20 @@ } }, "node_modules/@parcel/packager-html": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.0.0-canary.1715.tgz", - "integrity": "sha512-PunlYKsy/54OvRfG318jeoj03zgyqWXo31SqQEhrmlMBLzlrqElWvAUbarGQOKFV92JfBY+EoOcMTBgSM/5nyw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.16.4.tgz", + "integrity": "sha512-AWo5f6SSqBsg2uWOsX0gPX8hCx2iE6GYLg2Z4/cDy2mPlwDICN8/bxItEztSZFmObi+ti26eetBKRDxAUivyIQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/types": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5" + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1001,23 +809,24 @@ } }, "node_modules/@parcel/packager-js": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.0.0-canary.1715.tgz", - "integrity": "sha512-mpfr7B3TAzMlhA7jA8D3sJI0f6qAagbyFjBMQLuAAsHzZ76MGWCPuPQDze/BIEmGUd548gXM3c8IhwFch5LmhA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.16.4.tgz", + "integrity": "sha512-L2o39f/fhta+hxto7w8OTUKdstY+te5BmHZREckbQm0KTBg93BG7jB0bfoxLSZF0d8uuAYIVXjzeHNqha+du1g==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", "@parcel/source-map": "^2.1.1", - "@parcel/types": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "globals": "^13.2.0", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "globals": "^13.24.0", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1025,16 +834,17 @@ } }, "node_modules/@parcel/packager-raw": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.0.0-canary.1715.tgz", - "integrity": "sha512-4qwYlxnek+r58UdiuJZTkpaVcV/2VfAGVPAOnqyR5O5r9dcTBE79VdMqEgCVk04+r6cu4Wkl9ODezc2cYnp6AQ==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.16.4.tgz", + "integrity": "sha512-A9j60G9OmbTkEeE4WRMXCiErEprHLs9NkUlC4HXCxmSrPMOVaMaMva2LdejE3A9kujZqYtYfuc8+a+jN+Nro4w==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1" + "@parcel/plugin": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1042,19 +852,20 @@ } }, "node_modules/@parcel/packager-svg": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.12.1-canary.3338.tgz", - "integrity": "sha512-IvEq4rX4LAP18xpcuEh7/G621sSQHZlX2DSE8obBxCLPENjq1hELWcgckwRmQOeMgzHInCCulKLJ+OmzJ9Utzg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.16.4.tgz", + "integrity": "sha512-LT9l7eInFrAZJ6w3mYzAUgDq3SIzYbbQyW46Dz26M9lJQbf6uCaATUTac3BEHegW0ikDuw4OOGHK41BVqeeusg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/types": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "posthtml": "^0.16.4" + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1062,16 +873,17 @@ } }, "node_modules/@parcel/packager-wasm": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/packager-wasm/-/packager-wasm-2.12.1-canary.3338.tgz", - "integrity": "sha512-9lFOKcDE0QPngNar4EDiVIKYTqYDj0iSlOUYi5Sf0rSR6V1TWV6ePw0RXZG/xP9o/K7p9tgrzSyvKHWK/3stlQ==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-wasm/-/packager-wasm-2.16.4.tgz", + "integrity": "sha512-AY96Aqu/RpmaSZK2RGkIrZWjAperDw8DAlxLAiaP1D/RPVnikZtl5BmcUt/Wz3PrzG7/q9ZVqqKkWsLmhkjXZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1" + "@parcel/plugin": "2.16.4" }, "engines": { "node": ">=16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1079,12 +891,13 @@ } }, "node_modules/@parcel/plugin": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.0.0-canary.1715.tgz", - "integrity": "sha512-noG9MEPS1WL3qFZywp8ako8hBhIt0QcswPiPUEb/615juec1VZWeVx9w3szsC8yCH+PDB2ewLbZ0MEg2Gpvrhg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.16.4.tgz", + "integrity": "sha512-aN2VQoRGC1eB41ZCDbPR/Sp0yKOxe31oemzPx1nJzOuebK2Q6FxSrJ9Bjj9j/YCaLzDtPwelsuLOazzVpXJ6qg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/types": "2.0.0-canary.1715+d599275b1" + "@parcel/types": "2.16.4" }, "engines": { "node": ">= 16.0.0" @@ -1095,14 +908,15 @@ } }, "node_modules/@parcel/profiler": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/profiler/-/profiler-2.12.1-canary.3338.tgz", - "integrity": "sha512-HKlhjT06RGZkbXLVOKnXurawByCb0rFgjp1xmAk8Z36Dwof6dIp1rmZxk7krsO/CDF+rDl91tyNjLYSHWP2Nnw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/profiler/-/profiler-2.16.4.tgz", + "integrity": "sha512-R3JhfcnoReTv2sVFHPR2xKZvs3d3IRrBl9sWmAftbIJFwT4rU70/W7IdwfaJVkD/6PzHq9mcgOh1WKL4KAxPdA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/events": "2.0.0-canary.1715+d599275b1", - "@parcel/types-internal": "2.12.1-canary.3338+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/types-internal": "2.16.4", "chrome-trace-event": "^1.0.2" }, "engines": { @@ -1114,20 +928,21 @@ } }, "node_modules/@parcel/reporter-cli": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.0.0-canary.1715.tgz", - "integrity": "sha512-Aj+4ePYCBLadfBb63idtKtOpZRv6lgD3dHPq1kSmP2RBao9ho90kMMal9+IZRQXHqUmsAG+f8461iL7Qy+pPtA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.16.4.tgz", + "integrity": "sha512-DQx9TwcTZrDv828+tcwEi//xyW7OHTGzGX1+UEVxPp0mSzuOmDn0zfER8qNIqGr1i4D/FXhb5UJQDhGHV8mOpQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/types": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "chalk": "^4.1.0", + "@parcel/plugin": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "chalk": "^4.1.2", "term-size": "^2.2.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1135,17 +950,20 @@ } }, "node_modules/@parcel/reporter-dev-server": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.0.0-canary.1715.tgz", - "integrity": "sha512-pbQY1ItOovT+o+QE4Ed/PXj1OjcSiLDFUV0c05cZ2ia7Gh/Z3zujXdsohUsoID7fkpddsUXwD9nUzlWO/I7O5A==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.16.4.tgz", + "integrity": "sha512-YWvay25htQDifpDRJ0+yFh6xUxKnbfeJxYkPYyuXdxpEUhq4T0UWW0PbPCN/wFX7StgeUTXq5Poeo/+eys9m3w==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1" + "@parcel/codeframe": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1153,19 +971,20 @@ } }, "node_modules/@parcel/reporter-tracer": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/reporter-tracer/-/reporter-tracer-2.12.1-canary.3338.tgz", - "integrity": "sha512-QB10+S4fVYNbuH9Lwm9SMyV27TIJ2iKIMQd1SeEqVRQTo9pDBc+ZMHkuJEfZhQ/0Dbe4MeemrAvyeaSwt10wSw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-tracer/-/reporter-tracer-2.16.4.tgz", + "integrity": "sha512-JKnlXpPepak0/ZybmZn9JtyjJiDBWYrt7ZUlXQhQb0xzNcd/k+RqfwVkTKIwyFHsWtym0cwibkvsi2bWFzS7tw==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", "chrome-trace-event": "^1.0.3", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1173,17 +992,18 @@ } }, "node_modules/@parcel/resolver-default": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.0.0-canary.1715.tgz", - "integrity": "sha512-5tVpomPE0ebeUl22E664nw9hh/ygilcnNH4z+IkB1JRJdSYABo6Aa2CWsvlxvLaHyoHl3+PkJwoPpvDo+kL0wg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.16.4.tgz", + "integrity": "sha512-wJe9XQS0hn/t32pntQpJbls3ZL8mGVVhK9L7s7BTmZT9ufnvP2nif1psJz/nbgnP9LF6mLSk43OdMJKpoStsjQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/node-resolver-core": "3.3.1-canary.3338+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1" + "@parcel/node-resolver-core": "3.7.4", + "@parcel/plugin": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1191,17 +1011,18 @@ } }, "node_modules/@parcel/runtime-browser-hmr": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.0.0-canary.1715.tgz", - "integrity": "sha512-/t9o0k4VS8IZzIvR80uKBpighDToXXhDzSJ8nuDCI68n3ZKYXz+DwkeZl2oocQBiok9SVWykKhY5VbQjy+yfcQ==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.16.4.tgz", + "integrity": "sha512-asx7p3NjUSfibI3bC7+8+jUIGHWVk2Zuq9SjJGCGDt+auT9A4uSGljnsk1BWWPqqZ0WILubq4czSAqm0+wt4cw==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1" + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1209,39 +1030,41 @@ } }, "node_modules/@parcel/runtime-js": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.0.0-canary.1715.tgz", - "integrity": "sha512-2VGRzTO0EHG/2CzKxD+JPpvx9m1WdkWArAFyhcCfSRk7y/tUJAO9C6/n1JZKYpVqBfsYrJIWpGTHJxO5Af7uuA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.16.4.tgz", + "integrity": "sha512-gUKmsjg+PULQBu2QbX0QKll9tXSqHPO8NrfxHwWb2lz5xDKDos1oV0I7BoMWbHhUHkoToXZrm654oGViujtVUA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/runtime-react-refresh": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.0.0-canary.1715.tgz", - "integrity": "sha512-S7N994hXqz085CDYufhOsIY8NNtzpLMoXyLumQ7dF7ajzOGiacItT1xrIkvetbY+w9NjEGpF6w7mE4DAvfdTrg==", + "node_modules/@parcel/runtime-rsc": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-rsc/-/runtime-rsc-2.16.4.tgz", + "integrity": "sha512-CHkotYE/cNiUjJmrc5FD9YhlFp1UF5wMNNJmoWaL40eBzsqcaV0sSn5V3bNapwewn3wrMYgdPgvOTHfaZaG73A==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "react-error-overlay": "6.0.9", - "react-refresh": ">=0.9 <=0.14" + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" }, "engines": { - "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "node": ">= 12.0.0", + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1249,18 +1072,19 @@ } }, "node_modules/@parcel/runtime-service-worker": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.12.1-canary.3338.tgz", - "integrity": "sha512-+f7op42LaOsSdTRQSjOTW2dJncFWwMLIYvmx66Sbf5I3N1XYdEWTXkJ0guYdDch4WHUcxCusTEmESWhfS1m6Aw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.16.4.tgz", + "integrity": "sha512-FT0Q58bf5Re+dq5cL2XHbxqHHFZco6qtRijeVpT3TSPMRPlniMArypSytTeZzVNL7h/hxjWsNu7fRuC0yLB5hA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1268,175 +1092,369 @@ } }, "node_modules/@parcel/rust": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/rust/-/rust-2.12.1-canary.3338.tgz", - "integrity": "sha512-7kWYJnmxnX2smhjLAAzvDcLCR15bWEU5yPdqVkS51Wf2lc2MwatMn0kSPMsQhXo8ki8aUeRBS8CQpdcfTBX16A==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust/-/rust-2.16.4.tgz", + "integrity": "sha512-RBMKt9rCdv6jr4vXG6LmHtxzO5TuhQvXo1kSoSIF7fURRZ81D1jzBtLxwLmfxCPsofJNqWwdhy5vIvisX+TLlQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/source-map": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", - "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" }, - "engines": { - "node": "^12.18.3 || >=14" + "optionalDependencies": { + "@parcel/rust-darwin-arm64": "2.16.4", + "@parcel/rust-darwin-x64": "2.16.4", + "@parcel/rust-linux-arm-gnueabihf": "2.16.4", + "@parcel/rust-linux-arm64-gnu": "2.16.4", + "@parcel/rust-linux-arm64-musl": "2.16.4", + "@parcel/rust-linux-x64-gnu": "2.16.4", + "@parcel/rust-linux-x64-musl": "2.16.4", + "@parcel/rust-win32-x64-msvc": "2.16.4" + }, + "peerDependencies": { + "napi-wasm": "^1.1.2" + }, + "peerDependenciesMeta": { + "napi-wasm": { + "optional": true + } } }, - "node_modules/@parcel/transformer-babel": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.0.0-canary.1715.tgz", - "integrity": "sha512-luj51+x9OyU6KhO1luYSvLPB9OwMjxC+K6H810L6hYh3ccyrJSUTc5Qg45NOGxQD0iH64sDI7V//6uLWZOpS+Q==", + "node_modules/@parcel/rust-darwin-arm64": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-darwin-arm64/-/rust-darwin-arm64-2.16.4.tgz", + "integrity": "sha512-P3Se36H9EO1fOlwXqQNQ+RsVKTGn5ztRSUGbLcT8ba6oOMmU1w7J4R810GgsCbwCuF10TJNUMkuD3Q2Sz15Q3Q==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "browserslist": "^4.6.6", - "json5": "^2.2.0", - "nullthrows": "^1.1.1", - "semver": "^7.5.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "node": ">= 10" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/transformer-css": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.0.0-canary.1715.tgz", - "integrity": "sha512-Au+Imn1kp0OjBhz4ulfXZ7NLKGCA+HViK1PH3TnYnFk+q1rWGiFr81lEXJnQ/A7Por/5twRUsrkOOlAnpWRKfw==", + "node_modules/@parcel/rust-darwin-x64": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-darwin-x64/-/rust-darwin-x64-2.16.4.tgz", + "integrity": "sha512-8aNKNyPIx3EthYpmVJevIdHmFsOApXAEYGi3HU69jTxLgSIfyEHDdGE9lEsMvhSrd/SSo4/euAtiV+pqK04wnA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "browserslist": "^4.6.6", - "lightningcss": "^1.22.1", - "nullthrows": "^1.1.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "node": ">= 10" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/transformer-html": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.0.0-canary.1715.tgz", - "integrity": "sha512-Z7aEZgJSHlCHzQj5ROI9/fDn7M+lAz9IqiCnSV6quXD9JujUxZkNOz2J+VDaNMbXkr56OF/yo9fXwqx7xQ6oCg==", + "node_modules/@parcel/rust-linux-arm-gnueabihf": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm-gnueabihf/-/rust-linux-arm-gnueabihf-2.16.4.tgz", + "integrity": "sha512-QrvqiSHaWRLc0JBHgUHVvDthfWSkA6AFN+ikV1UGENv4j2r/QgvuwJiG0VHrsL6pH5dRqj0vvngHzEgguke9DA==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^7.5.2", - "srcset": "4" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "node": ">= 10" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/transformer-html/node_modules/srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "node_modules/@parcel/rust-linux-arm64-gnu": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm64-gnu/-/rust-linux-arm64-gnu-2.16.4.tgz", + "integrity": "sha512-f3gBWQHLHRUajNZi3SMmDQiEx54RoRbXtZYQNuBQy7+NolfFcgb1ik3QhkT7xovuTF/LBmaqP3UFy0PxvR/iwQ==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" + "node": ">= 10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-arm64-musl": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm64-musl/-/rust-linux-arm64-musl-2.16.4.tgz", + "integrity": "sha512-cwml18RNKsBwHyZnrZg4jpecXkWjaY/mCArocWUxkFXjjB97L56QWQM9W86f2/Y3HcFcnIGJwx1SDDKJrV6OIA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-x64-gnu": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-x64-gnu/-/rust-linux-x64-gnu-2.16.4.tgz", + "integrity": "sha512-0xIjQaN8hiG0F9R8coPYidHslDIrbfOS/qFy5GJNbGA3S49h61wZRBMQqa7JFW4+2T8R0J9j0SKHhLXpbLXrIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-x64-musl": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-x64-musl/-/rust-linux-x64-musl-2.16.4.tgz", + "integrity": "sha512-fYn21GIecHK9RoZPKwT9NOwxwl3Gy3RYPR6zvsUi0+hpFo19Ph9EzFXN3lT8Pi5KiwQMCU4rsLb5HoWOBM1FeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-win32-x64-msvc": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-win32-x64-msvc/-/rust-win32-x64-msvc-2.16.4.tgz", + "integrity": "sha512-TcpWC3I1mJpfP2++018lgvM7UX0P8IrzNxceBTHUKEIDMwmAYrUKAQFiaU0j1Ldqk6yP8SPZD3cvphumsYpJOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/source-map": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", + "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": "^12.18.3 || >=14" + } + }, + "node_modules/@parcel/transformer-babel": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.16.4.tgz", + "integrity": "sha512-CMDUOQYX7+cmeyHxHSFnoPcwvXNL7rRFE+Q06uVFzsYYiVhbwGF/1J5Bx4cW3Froumqla4YTytTsEteJEybkdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "json5": "^2.2.3", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-css": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.16.4.tgz", + "integrity": "sha512-VG/+DbDci2HKe20GFRDs65ZQf5GUFfnmZAa1BhVl/MO+ijT3XC3eoVUy5cExRkq4VLcPY4ytL0g/1T2D6x7lBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "lightningcss": "^1.30.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-html": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.16.4.tgz", + "integrity": "sha512-w6JErYTeNS+KAzUAER18NHFIFFvxiLGd4Fht1UYcb/FDjJdLAMB/FljyEs0Rto/WAhZ2D0MuSL25HQh837R62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/@parcel/transformer-image": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.12.1-canary.3338.tgz", - "integrity": "sha512-c5j3eGpLH6uvc+SIt0uUMqt7GZap8TDQb8jgVR2hJrVKD1MjhN+4GUTELdyPF6g+QY+QftAJY9IciVZC8Gbk7A==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.16.4.tgz", + "integrity": "sha512-ZzIn3KvvRqMfcect4Dy+57C9XoQXZhpVJKBdQWMp9wM1qJEgsVgGDcaSBYCs/UYSKMRMP6Wm20pKCt408RkQzg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "@parcel/workers": "2.0.0-canary.1715+d599275b1", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", "nullthrows": "^1.1.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "peerDependencies": { - "@parcel/core": "^2.0.0-canary.1713+d599275b1" + "@parcel/core": "^2.16.4" } }, "node_modules/@parcel/transformer-js": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.0.0-canary.1715.tgz", - "integrity": "sha512-CnshYaSM5tpJFJAZn6mG2h5zdvepZ7hRHROajuh+g4JK+4Nz2Thh/1M5QZx6QMNSekmriaeBHpTQL2wEx6/OyQ==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.16.4.tgz", + "integrity": "sha512-FD2fdO6URwAGBPidb3x1dDgLBt972mko0LelcSU05aC/pcKaV9mbCtINbPul1MlStzkxDelhuImcCYIyerheVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "@parcel/workers": "2.0.0-canary.1715+d599275b1", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", "@swc/helpers": "^0.5.0", - "browserslist": "^4.6.6", + "browserslist": "^4.24.5", "nullthrows": "^1.1.1", - "regenerator-runtime": "^0.13.7", - "semver": "^7.5.2" + "regenerator-runtime": "^0.14.1", + "semver": "^7.7.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "peerDependencies": { - "@parcel/core": "^2.0.0-canary.1713+d599275b1" + "@parcel/core": "^2.16.4" } }, "node_modules/@parcel/transformer-json": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.0.0-canary.1715.tgz", - "integrity": "sha512-ZZB8jk2vC+4339PCifk0NNCyNQdMO53VN2/5mMJ3pkDu2pzDrMUOD3xXO8yOcaZoMX/ML3ele5JBgNM6czwhmw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.16.4.tgz", + "integrity": "sha512-pB3ZNqgokdkBCJ+4G0BrPYcIkyM9K1HVk0GvjzcLEFDKsoAp8BGEM68FzagFM/nVq9anYTshIaoh349GK0M/bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "json5": "^2.2.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-node": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-node/-/transformer-node-2.16.4.tgz", + "integrity": "sha512-7t43CPGfMJk1LqFokwxHSsRi+kKC2QvDXaMtqiMShmk50LCwn81WgzuFvNhMwf6lSiBihWupGwF3Fqksg+aisg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "json5": "^2.2.0" + "@parcel/plugin": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1444,23 +1462,24 @@ } }, "node_modules/@parcel/transformer-postcss": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.0.0-canary.1715.tgz", - "integrity": "sha512-5vOIa15OF5gVjFtQGCtk0MaGhkeHl7NjwVZ/S1+TB64Z4IKfdO4cBPrgW3Z3v69smEHdmtPloIVddUWty/cXgA==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.16.4.tgz", + "integrity": "sha512-jfmh9ho03H+qwz9S1b/a/oaOmgfMovtHKYDweIGMjKULKIee3AFRqo8RZIOuUMjDuqHWK8SqQmjery4syFV3Xw==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "clone": "^2.1.1", + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "clone": "^2.1.2", "nullthrows": "^1.1.1", "postcss-value-parser": "^4.2.0", - "semver": "^7.5.2" + "semver": "^7.7.1" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1468,22 +1487,18 @@ } }, "node_modules/@parcel/transformer-posthtml": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.0.0-canary.1715.tgz", - "integrity": "sha512-6RPWr7N9+7v3hIBkn3VCBw/FYt/DedQhUfYGq7QHtlb4ygOLAumLYySaBARqIVqnSufy4MgpLOb3BQ99wuVCXg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.16.4.tgz", + "integrity": "sha512-+GXsmGx1L25KQGQnwclgEuQe1t4QU+IoDkgN+Ikj+EnQCOWG4/ts2VpMBeqP5F18ZT4cCSRafj6317o/2lSGJg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^7.5.2" + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1491,16 +1506,17 @@ } }, "node_modules/@parcel/transformer-raw": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.0.0-canary.1715.tgz", - "integrity": "sha512-zbekZkfcFb6hmJCFrDF3PzXQvwF9i//jmDd4Ho4rV7E6IVP1RAqBHijp6XiGyPZdzL1G5pEPVqdIa3idt0jrFw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.16.4.tgz", + "integrity": "sha512-7WDUPq+bW11G9jKxaQIVL+NPGolV99oq/GXhpjYip0SaGaLzRCW7gEk60cftuk0O7MsDaX5jcAJm3G/AX+LJKg==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1" + "@parcel/plugin": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1508,18 +1524,20 @@ } }, "node_modules/@parcel/transformer-react-refresh-wrap": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.0.0-canary.1715.tgz", - "integrity": "sha512-V/9h4WyzdQyW+JW6gjo2CtkECwhipfINziqOdlXfGuQx+9sl2yQ3sV7JBlUrXaP2lPli5Zjf5gMLPbqR0XPMsw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.16.4.tgz", + "integrity": "sha512-MiLNZrsGQJTANKKa4lzZyUbGj/en0Hms474mMdQkCBFg6GmjfmXwaMMgtTfPA3ZwSp2+3LeObCyca/f9B2gBZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "react-refresh": ">=0.9 <=0.14" + "@parcel/error-overlay": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "react-refresh": "^0.16.0" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1527,23 +1545,19 @@ } }, "node_modules/@parcel/transformer-svg": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.12.1-canary.3338.tgz", - "integrity": "sha512-jbN/ucGKkYAsYI3kd70cdrEgACOSJrYYzBQO8kV0ZTnCV4b7/xjubLNfiQdLrXUQqs/d7ocNmpW05tGFdPHjsg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.16.4.tgz", + "integrity": "sha512-0dm4cQr/WpfQP6N0xjFtwdLTxcONDfoLgTOMk4eNUWydHipSgmLtvUk/nOc/FWkwztRScfAObtZXOiPOd3Oy9A==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/plugin": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^7.5.2" + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4" }, "engines": { "node": ">= 16.0.0", - "parcel": "^2.0.0-canary.1713+d599275b1" + "parcel": "^2.16.4" }, "funding": { "type": "opencollective", @@ -1551,40 +1565,43 @@ } }, "node_modules/@parcel/types": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.0.0-canary.1715.tgz", - "integrity": "sha512-u/rmRYBhZxNAwDX0g+gUxW7UQv1gQxmnG0pVa9uRI1GT+7MiT7FcZea7h4N4xoKB3TIDykp5B8VriIuoIALoaQ==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.16.4.tgz", + "integrity": "sha512-ctx4mBskZHXeDVHg4OjMwx18jfYH9BzI/7yqbDQVGvd5lyA+/oVVzYdpele2J2i2sSaJ87cA8nb57GDQ8kHAqA==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/types-internal": "2.12.1-canary.3338+d599275b1", - "@parcel/workers": "2.0.0-canary.1715+d599275b1" + "@parcel/types-internal": "2.16.4", + "@parcel/workers": "2.16.4" } }, "node_modules/@parcel/types-internal": { - "version": "2.12.1-canary.3338", - "resolved": "https://registry.npmjs.org/@parcel/types-internal/-/types-internal-2.12.1-canary.3338.tgz", - "integrity": "sha512-5jTM9H3QR+jbuey1jYxeO/VwZ/jk2RPCeeCQ1lb53wI+ebdi6fJhp/+xH74cEI1Mlyz8jvrSUPc8LDRep8GJpQ==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/types-internal/-/types-internal-2.16.4.tgz", + "integrity": "sha512-PE6Qmt5cjzBxX+6MPLiF7r+twoC+V9Skt3zyuBQ+H1c0i9o07Bbz2NKX10nvlPukfmW6Fu/1RvTLkzBZR1bU6A==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/feature-flags": "2.12.1-canary.3338+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/feature-flags": "2.16.4", "@parcel/source-map": "^2.1.1", - "utility-types": "^3.10.0" + "utility-types": "^3.11.0" } }, "node_modules/@parcel/utils": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.0.0-canary.1715.tgz", - "integrity": "sha512-XhdXFACtl3P0VsyXyRc5/qFyNCskmumjjAC9fwIBRU7xX3BF3pRavWKf4V0PeC8/U+sezXvItibu7RSCz5jQlw==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.16.4.tgz", + "integrity": "sha512-lkmxQHcHyOWZLbV8t+h2CGZIkPiBurLm/TS5wNT7+tq0qt9KbVwL7FP2K93TbXhLMGTmpI79Bf3qKniPM167Mw==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/codeframe": "2.0.0-canary.1715+d599275b1", - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/logger": "2.0.0-canary.1715+d599275b1", - "@parcel/markdown-ansi": "2.0.0-canary.1715+d599275b1", - "@parcel/rust": "2.12.1-canary.3338+d599275b1", + "@parcel/codeframe": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/markdown-ansi": "2.16.4", + "@parcel/rust": "2.16.4", "@parcel/source-map": "^2.1.1", - "chalk": "^4.1.0", + "chalk": "^4.1.2", "nullthrows": "^1.1.1" }, "engines": { @@ -1596,15 +1613,17 @@ } }, "node_modules/@parcel/watcher": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", - "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz", + "integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==", "dev": true, + "hasInstallScript": true, + "license": "MIT", "dependencies": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.3", "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.4" }, "engines": { "node": ">= 10.0.0" @@ -1614,28 +1633,29 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.4.1", - "@parcel/watcher-darwin-arm64": "2.4.1", - "@parcel/watcher-darwin-x64": "2.4.1", - "@parcel/watcher-freebsd-x64": "2.4.1", - "@parcel/watcher-linux-arm-glibc": "2.4.1", - "@parcel/watcher-linux-arm64-glibc": "2.4.1", - "@parcel/watcher-linux-arm64-musl": "2.4.1", - "@parcel/watcher-linux-x64-glibc": "2.4.1", - "@parcel/watcher-linux-x64-musl": "2.4.1", - "@parcel/watcher-win32-arm64": "2.4.1", - "@parcel/watcher-win32-ia32": "2.4.1", - "@parcel/watcher-win32-x64": "2.4.1" + "@parcel/watcher-android-arm64": "2.6.0", + "@parcel/watcher-darwin-arm64": "2.6.0", + "@parcel/watcher-darwin-x64": "2.6.0", + "@parcel/watcher-freebsd-x64": "2.6.0", + "@parcel/watcher-linux-arm-glibc": "2.6.0", + "@parcel/watcher-linux-arm-musl": "2.6.0", + "@parcel/watcher-linux-arm64-glibc": "2.6.0", + "@parcel/watcher-linux-arm64-musl": "2.6.0", + "@parcel/watcher-linux-x64-glibc": "2.6.0", + "@parcel/watcher-linux-x64-musl": "2.6.0", + "@parcel/watcher-win32-arm64": "2.6.0", + "@parcel/watcher-win32-x64": "2.6.0" } }, "node_modules/@parcel/watcher-android-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", - "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz", + "integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -1649,13 +1669,14 @@ } }, "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", - "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz", + "integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1669,13 +1690,14 @@ } }, "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", - "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz", + "integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1689,13 +1711,14 @@ } }, "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", - "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz", + "integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -1709,13 +1732,14 @@ } }, "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", - "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz", + "integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1728,14 +1752,15 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", - "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz", + "integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==", "cpu": [ - "arm64" + "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1748,14 +1773,15 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", - "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz", + "integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1768,14 +1794,15 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", - "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==", + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz", + "integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==", "cpu": [ - "x64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1788,14 +1815,15 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz", - "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==", + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz", + "integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1808,17 +1836,18 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", - "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz", + "integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==", "cpu": [ - "arm64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { "node": ">= 10.0.0" @@ -1828,14 +1857,15 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", - "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz", + "integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==", "cpu": [ - "ia32" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -1849,13 +1879,14 @@ } }, "node_modules/@parcel/watcher-win32-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", - "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz", + "integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -1868,17 +1899,28 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/@parcel/workers": { - "version": "2.0.0-canary.1715", - "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.0.0-canary.1715.tgz", - "integrity": "sha512-8SL74hWQfaQocpVmoq7N865tV6yDW+GN+eGBP3Axx2AudxD6YgymjjSUqzuf8W1o22gjC2DNcyf1hClNfN5Pwg==", + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.16.4.tgz", + "integrity": "sha512-dkBEWqnHXDZnRbTZouNt4uEGIslJT+V0c8OH1MPOfjISp1ucD6/u9ET8k9d/PxS9h1hL53og0SpBuuSEPLDl6A==", "dev": true, + "license": "MIT", "dependencies": { - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/logger": "2.0.0-canary.1715+d599275b1", - "@parcel/profiler": "2.12.1-canary.3338+d599275b1", - "@parcel/types-internal": "2.12.1-canary.3338+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", + "@parcel/diagnostic": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/profiler": "2.16.4", + "@parcel/types-internal": "2.16.4", + "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" }, "engines": { @@ -1889,18 +1931,19 @@ "url": "https://opencollective.com/parcel" }, "peerDependencies": { - "@parcel/core": "^2.0.0-canary.1713+d599275b1" + "@parcel/core": "^2.16.4" } }, "node_modules/@swc/core": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.9.tgz", - "integrity": "sha512-GUS7qH2/vOgLIiu3lCUheCo/r/ppj/fDjhRUuhXb/S13CeTQ1YJwLYpL5QCUZDas2Hn0aKrB4TiQtyM1cCpDRA==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.16.13.tgz", + "integrity": "sha512-k4uUsIMS0IwOKVsrQs48IZK75O4roV3FnuJEdL7ES+DFESftdgvz73QBqN3VUAbUmUr78We4tzG0kgYj36M22Q==", "dev": true, "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.12" + "@swc/types": "^0.1.28" }, "engines": { "node": ">=10" @@ -1910,19 +1953,21 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.7.9", - "@swc/core-darwin-x64": "1.7.9", - "@swc/core-linux-arm-gnueabihf": "1.7.9", - "@swc/core-linux-arm64-gnu": "1.7.9", - "@swc/core-linux-arm64-musl": "1.7.9", - "@swc/core-linux-x64-gnu": "1.7.9", - "@swc/core-linux-x64-musl": "1.7.9", - "@swc/core-win32-arm64-msvc": "1.7.9", - "@swc/core-win32-ia32-msvc": "1.7.9", - "@swc/core-win32-x64-msvc": "1.7.9" + "@swc/core-darwin-arm64": "1.16.13", + "@swc/core-darwin-x64": "1.16.13", + "@swc/core-linux-arm-gnueabihf": "1.16.13", + "@swc/core-linux-arm64-gnu": "1.16.13", + "@swc/core-linux-arm64-musl": "1.16.13", + "@swc/core-linux-ppc64-gnu": "1.16.13", + "@swc/core-linux-s390x-gnu": "1.16.13", + "@swc/core-linux-x64-gnu": "1.16.13", + "@swc/core-linux-x64-musl": "1.16.13", + "@swc/core-win32-arm64-msvc": "1.16.13", + "@swc/core-win32-ia32-msvc": "1.16.13", + "@swc/core-win32-x64-msvc": "1.16.13" }, "peerDependencies": { - "@swc/helpers": "*" + "@swc/helpers": ">=0.5.17" }, "peerDependenciesMeta": { "@swc/helpers": { @@ -1931,13 +1976,14 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.9.tgz", - "integrity": "sha512-OIfjf7iK0OCZ87IASLymq6HO9nT0s80R7hI9zHfsJJ9vxKc63iAKe+oxgXzljecBGPlkjUjj6nTFlN0wVeraUQ==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.16.13.tgz", + "integrity": "sha512-JrMH2h7ohd4mOIneNRx/diqTmCDSdWfp9uOdQ8VJ2V2CA7jOJ1jWb+qp8RoZLqgiVmwDDC7eySKB1kbvZ+jVXQ==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -1947,13 +1993,14 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.9.tgz", - "integrity": "sha512-8ekLnd6IdOudNtm2ru0FrUCEBzs46Gg5f5Wkm7TPV6xA1hgIQMUbc9NJ/unRTh0FRvO1hbtoIz06GGD9MRQW8Q==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.16.13.tgz", + "integrity": "sha512-HauZMRxpOImRxgY6GXjw5gbD8ts2NcPZuLMM8htY8Mic7j1Izt/lxkXrKYUwqyU56YLwQZ4dHRT+6jFHkztcag==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -1963,13 +2010,14 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.9.tgz", - "integrity": "sha512-6kSe+cCp0nrf1JP9MYrJxsjATq2Abs4RrZ501EXfcJuP9pJrdlX3UlGvT7kboeXP1723eWgMOEjRsx/qW5E4QQ==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.16.13.tgz", + "integrity": "sha512-tUSojGIythnHJKrElDM9OvuhBnK+FF39eM9iIBgj9kdfbAm6PhAM7dKbaSDcnX2gOLG2slkasjD0Z8m/YUlzOA==", "cpu": [ "arm" ], "dev": true, + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -1979,13 +2027,14 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.9.tgz", - "integrity": "sha512-I+cGw4N9xqprsvPywU1vt+Ni4LnZMlDzH7Ow3n4KWKRJ34V9/0jnnmTYd7twpjpib9TsdEzAADFwlP3dVvetCQ==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.16.13.tgz", + "integrity": "sha512-qS3bk/ezRrLXGn1b764S/EG3/oKj6uRhnTNRAALpnuu8d9I0YwSiUkQghnX7lOH9X/yRr+qrFI3R0wAruO47Tg==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -1995,13 +2044,48 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.9.tgz", - "integrity": "sha512-u5ryq5fe8DZMLoyv8h3970NzuNdsdOmOod48b0EFVbNwHm0Tpz9wTRuzzGfpZXOR5xjgBiO+MbxiTU2vSdHo/g==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.16.13.tgz", + "integrity": "sha512-aeoYoG6fQsOS3mFOuTKvnJo1aaaxYNI0aRRlhdHaGP4q1YQx4XOc5Hkd35IFduWCBG3eZl3fPTjRuYvxpl7eTA==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.16.13.tgz", + "integrity": "sha512-eEFoueZXWZ2S1lsqL8Ve2C8RjhzH9+Ktj8U4IGTUQL6CNG04+VhQiYQWJOf5xfVBU6I+PbH80yvsYegqZOOSZQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.16.13.tgz", + "integrity": "sha512-K0q1ReVXL3d5bzBgZxS+yJq5q2xRjg4k2XXGj9yiCEpE5ZqJGQ4Gtk1sRrk8W2lo3KY0DCJD3Myt6x2SMvGArQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2011,13 +2095,14 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.9.tgz", - "integrity": "sha512-rpdjz8kqLDqLyWEfhzYtGkGxh4oDRxnf7xLmNUptX6WyBDnOxcAjyBpeaNIV2mhIM4e1jmNtiUHDTwjLX15ECA==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.16.13.tgz", + "integrity": "sha512-Qvpihw30irhIjy2f91BR1pamcJBCgf8hmr9XWenztAX1YLkneRkkTB/PFGWQubhaBqQhY2uZKViMj/xV61uMBQ==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2027,13 +2112,14 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.9.tgz", - "integrity": "sha512-KPTzWcAbnb1Cu8Jjs/Kty26TGT+PwT6l1jmXtVoKlc+5/ewM7CxSD7ZbutvFriJrg4Z1i3oyEOaQ2eM9T+LOVA==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.16.13.tgz", + "integrity": "sha512-iCGxHbh3Cq5vqRvCPlw3XkkDz4RlkPSyQwfFKbOKTMj5tiEuojY/rLmf4BMfI9Z8yPJTf9VB07t3NbKInoC97g==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2043,13 +2129,14 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.9.tgz", - "integrity": "sha512-ZFbgm7ye/mTyeXik4o/3KqoEOSA2E2eb3e4JkAsVJB0K/hZdAoUtyyRCKlnq7nqbInhyKr0Pxqas6LkfyCQ48g==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.16.13.tgz", + "integrity": "sha512-iOabn6cd+hg3cnoKlAC8j3Yufv8nQHBVU5OIDX8dCPA95PjAZ0B0TlDn9sWivk8ezo/cLJux7p9n0B9vRej+1Q==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2059,13 +2146,14 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.9.tgz", - "integrity": "sha512-xIcQost/1XcDL38pPQtBG1E4cOGHUorBxfD1S3/B9vVJlaAJIfZ8vwmOKpMIcRGXAQOXd0MXsBz+kaaOIJfqQQ==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.16.13.tgz", + "integrity": "sha512-+1b/3xBNuVbpnJIZUCAaSdscOPYRWq85eohKx44y/3qbPp56UMiCJWBiWtyr7K5F1nf1JENXm2IBSEJaLgWq6Q==", "cpu": [ "ia32" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2075,13 +2163,14 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.9.tgz", - "integrity": "sha512-VSMce64nnvz1dDjbpUrtvi7wcXqdXkCwyXLp5ohAKG/ECy2JxZXdDB+FiP4BeYgH59ANRVVlmcaPrQGpK3QAnQ==", + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.16.13.tgz", + "integrity": "sha512-6kEJhYshk7OVoVIWryiHqjCNuwZeOlPTS6et+bKV/WhtHs8fLA01wyTLrQGi+4ultgRe/o0M4b25K/KKdvl0dQ==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2094,56 +2183,45 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@swc/helpers": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.12.tgz", - "integrity": "sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==", + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.8.0" } }, "node_modules/@swc/types": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", - "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", + "version": "0.1.28", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.28.tgz", + "integrity": "sha512-V6Mnml8v09QALx6K0elJ7o9K/MkVDtW3t6L+7Ou/JcWtb3xwId2AH4FeOceySd2JaO87IMw4+6vSZxLm34LPbw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" } }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -2151,6 +2229,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -2161,89 +2240,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", - "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.0.1" } @@ -2267,43 +2276,40 @@ } ] }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "node_modules/baseline-browser-mapping": { + "version": "2.11.28", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.28.tgz", + "integrity": "sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==", "dev": true, - "engines": { - "node": ">=8" + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "node_modules/brace-expansion/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" } }, "node_modules/brotli": { @@ -2321,9 +2327,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.29.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", + "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", "dev": true, "funding": [ { @@ -2339,11 +2345,14 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", + "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "baseline-browser-mapping": "^2.11.26", + "caniuse-lite": "^1.0.30001813", + "electron-to-chromium": "^1.5.439", + "node-releases": "^2.0.57", + "update-browserslist-db": "^1.3.3" }, "bin": { "browserslist": "cli.js" @@ -2359,75 +2368,43 @@ "dev": true }, "node_modules/c8": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/c8/-/c8-7.14.0.tgz", - "integrity": "sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-12.0.0.tgz", + "integrity": "sha512-4zpJvrd1nKWutnnKC2pXkFmb6iM1l+ffN//o1CzlTNwW7GSOs9a1xrLqkC48nU8oEkjmPZLPiwMsIaOvoF4Pqg==", "dev": true, + "license": "ISC", "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", + "@bcoe/v8-coverage": "^1.0.1", "@istanbuljs/schema": "^0.1.3", "find-up": "^5.0.0", - "foreground-child": "^2.0.0", + "foreground-child": "^3.1.1", "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-reports": "^3.1.4", - "rimraf": "^3.0.2", - "test-exclude": "^6.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^8.0.0", "v8-to-istanbul": "^9.0.0", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9" + "yargs": "^18.0.0", + "yargs-parser": "^21.1.1" }, "bin": { "c8": "bin/c8.js" }, "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" + "node": "^20.19.0 || ^22.12.0 || >=23" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" + "peerDependencies": { + "monocart-coverage-reports": "^2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "monocart-coverage-reports": { + "optional": true + } } }, "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "version": "1.0.30001815", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001815.tgz", + "integrity": "sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==", "dev": true, "funding": [ { @@ -2442,13 +2419,15 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2461,27 +2440,19 @@ } }, "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", "dev": true, + "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^5.0.0" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" } }, "node_modules/chrome-trace-event": { @@ -2489,19 +2460,42 @@ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/clone": { @@ -2523,6 +2517,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2534,23 +2529,19 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, "node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", @@ -2572,3178 +2563,1240 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" }, - "peerDependencies": { - "typescript": ">=4.9.5" + "engines": { + "node": ">=6.0" }, "peerDependenciesMeta": { - "typescript": { + "supports-color": { "optional": true } } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" }, "engines": { - "node": ">= 8" + "node": ">=0.10" } }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "node_modules/dfa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", + "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" + }, + "node_modules/diff": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz", + "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==", "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" } }, - "node_modules/css-select/node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + "url": "https://dotenvx.com" } }, - "node_modules/css-select/node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", "dev": true, - "optional": true, - "peer": true, + "license": "BSD-2-Clause", "dependencies": { - "domelementtype": "^2.3.0" + "dotenv": "^16.4.5" }, "engines": { - "node": ">= 4" + "node": ">=12" }, "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "url": "https://dotenvx.com" } }, - "node_modules/css-select/node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "node_modules/electron-to-chromium": { + "version": "1.5.452", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.452.tgz", + "integrity": "sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==", "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } + "license": "ISC" }, - "node_modules/css-select/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, - "optional": true, - "peer": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "node": ">=6" } }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fflate": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz", + "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/fb55" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, - "optional": true, - "peer": true, + "license": "ISC", "dependencies": { - "css-tree": "~2.2.0" + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, + "license": "ISC", "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "node_modules/get-east-asian-width": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz", + "integrity": "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==", "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "node_modules/get-port": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", + "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">= 0.4" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "type-fest": "^0.20.2" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=8" } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, + "license": "MIT", "engines": { - "node": ">=0.10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dfa": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", - "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, - "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "engines": { - "node": ">=0.3.1" + "node": ">=8" } }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + "engines": { + "node": ">=10" } }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "node_modules/js-yaml": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.3.tgz", + "integrity": "sha512-yzzNtgczwgoVHNigCyKTXcQJU4Y8t/ikU4UxXW0BvrLfHTGWZhsNcOT2s/a7vn81/4KqVnNmHjaUEPlvWnNwVw==", "dev": true, "funding": [ { "type": "github", - "url": "https://github.com/sponsors/fb55" + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" } - ] - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, + ], + "license": "MIT", "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" + "argparse": "^2.0.1" }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "bin": { + "js-yaml": "bin/js-yaml.mjs" } }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "license": "MIT", + "bin": { + "json5": "lib/cli.js" }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dotenv": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", - "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==", - "dev": true, "engines": { "node": ">=6" } }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "node_modules/electron-to-chromium": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", - "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, "engines": { - "node": ">=0.12" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.4" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.4" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "es-errors": "^1.3.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">= 0.4" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-port": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", - "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/htmlnano": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-2.1.1.tgz", - "integrity": "sha512-kAERyg/LuNZYmdqgCdYvugyLWNFAm8MWXpQMz1pLpetmCbFwoMxvkSoaAMlFrOC4OKTWI4KlZGT/RsNxg4ghOw==", - "dev": true, - "dependencies": { - "cosmiconfig": "^9.0.0", - "posthtml": "^0.16.5", - "timsort": "^0.3.0" - }, - "peerDependencies": { - "cssnano": "^7.0.0", - "postcss": "^8.3.11", - "purgecss": "^6.0.0", - "relateurl": "^0.2.7", - "srcset": "5.0.1", - "svgo": "^3.0.2", - "terser": "^5.10.0", - "uncss": "^0.17.3" - }, - "peerDependenciesMeta": { - "cssnano": { - "optional": true - }, - "postcss": { - "optional": true - }, - "purgecss": { - "optional": true - }, - "relateurl": { - "optional": true - }, - "srcset": { - "optional": true - }, - "svgo": { - "optional": true - }, - "terser": { - "optional": true - }, - "uncss": { - "optional": true - } - } - }, - "node_modules/htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", - "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", - "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", - "dev": true - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lightningcss": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.26.0.tgz", - "integrity": "sha512-a/XZ5hdgifrofQJUArr5AiJjx26SwMam3SJUSMjgebZbESZ96i+6Qsl8tLi0kaUsdMzBWXh9sN1Oe6hp2/dkQw==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.26.0", - "lightningcss-darwin-x64": "1.26.0", - "lightningcss-freebsd-x64": "1.26.0", - "lightningcss-linux-arm-gnueabihf": "1.26.0", - "lightningcss-linux-arm64-gnu": "1.26.0", - "lightningcss-linux-arm64-musl": "1.26.0", - "lightningcss-linux-x64-gnu": "1.26.0", - "lightningcss-linux-x64-musl": "1.26.0", - "lightningcss-win32-arm64-msvc": "1.26.0", - "lightningcss-win32-x64-msvc": "1.26.0" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.26.0.tgz", - "integrity": "sha512-n4TIvHO1NY1ondKFYpL2ZX0bcC2y6yjXMD6JfyizgR8BCFNEeArINDzEaeqlfX9bXz73Bpz/Ow0nu+1qiDrBKg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.26.0.tgz", - "integrity": "sha512-Rf9HuHIDi1R6/zgBkJh25SiJHF+dm9axUZW/0UoYCW1/8HV0gMI0blARhH4z+REmWiU1yYT/KyNF3h7tHyRXUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.26.0.tgz", - "integrity": "sha512-C/io7POAxp6sZxFSVGezjajMlCKQ8KSwISLLGRq8xLQpQMokYrUoqYEwmIX8mLmF6C/CZPk0gFmRSzd8biWM0g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.26.0.tgz", - "integrity": "sha512-Aag9kqXqkyPSW+dXMgyWk66C984Nay2pY8Nws+67gHlDzV3cWh7TvFlzuaTaVFMVqdDTzN484LSK3u39zFBnzg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.26.0.tgz", - "integrity": "sha512-iJmZM7fUyVjH+POtdiCtExG+67TtPUTer7K/5A8DIfmPfrmeGvzfRyBltGhQz13Wi15K1lf2cPYoRaRh6vcwNA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.26.0.tgz", - "integrity": "sha512-XxoEL++tTkyuvu+wq/QS8bwyTXZv2y5XYCMcWL45b8XwkiS8eEEEej9BkMGSRwxa5J4K+LDeIhLrS23CpQyfig==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.26.0.tgz", - "integrity": "sha512-1dkTfZQAYLj8MUSkd6L/+TWTG8V6Kfrzfa0T1fSlXCXQHrt1HC1/UepXHtKHDt/9yFwyoeayivxXAsApVxn6zA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.26.0.tgz", - "integrity": "sha512-yX3Rk9m00JGCUzuUhFEojY+jf/6zHs3XU8S8Vk+FRbnr4St7cjyMXdNjuA2LjiT8e7j8xHRCH8hyZ4H/btRE4A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.26.0.tgz", - "integrity": "sha512-X/597/cFnCogy9VItj/+7Tgu5VLbAtDF7KZDPdSw0MaL6FL940th1y3HiOzFIlziVvAtbo0RB3NAae1Oofr+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.26.0.tgz", - "integrity": "sha512-pYS3EyGP3JRhfqEFYmfFDiZ9/pVNfy8jVIYtrx9TVNusVyDK3gpW1w/rbvroQ4bDJi7grdUtyrYU6V2xkY/bBw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/lmdb": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.8.5.tgz", - "integrity": "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "msgpackr": "^1.9.5", - "node-addon-api": "^6.1.0", - "node-gyp-build-optional-packages": "5.1.1", - "ordered-binary": "^1.4.1", - "weak-lru-cache": "^1.2.2" - }, - "bin": { - "download-lmdb-prebuilds": "bin/download-prebuilds.js" - }, - "optionalDependencies": { - "@lmdb/lmdb-darwin-arm64": "2.8.5", - "@lmdb/lmdb-darwin-x64": "2.8.5", - "@lmdb/lmdb-linux-arm": "2.8.5", - "@lmdb/lmdb-linux-arm64": "2.8.5", - "@lmdb/lmdb-linux-x64": "2.8.5", - "@lmdb/lmdb-win32-x64": "2.8.5" - } - }, - "node_modules/lmdb/node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", - "dev": true - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mocha": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", - "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.3", - "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", - "debug": "^4.3.5", - "diff": "^5.2.0", - "escape-string-regexp": "^4.0.0", - "find-up": "^5.0.0", - "glob": "^8.1.0", - "he": "^1.2.0", - "js-yaml": "^4.1.0", - "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", - "ms": "^2.1.3", - "serialize-javascript": "^6.0.2", - "strip-json-comments": "^3.1.1", - "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", - "yargs-unparser": "^2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/msgpackr": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz", - "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==", - "dev": true, - "optionalDependencies": { - "msgpackr-extract": "^3.0.2" - } - }, - "node_modules/msgpackr-extract": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", - "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build-optional-packages": "5.2.2" - }, - "bin": { - "download-msgpackr-prebuilds": "bin/download-prebuilds.js" - }, - "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" - } - }, - "node_modules/msgpackr-extract/node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", - "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", - "dev": true, - "optional": true, - "dependencies": { - "detect-libc": "^2.0.1" - }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true - }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", - "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", - "dev": true, - "dependencies": { - "detect-libc": "^2.0.1" - }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, - "node_modules/node-gyp-build-optional-packages/node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "bin": { - "npm-run-all": "bin/npm-run-all/index.js", - "run-p": "bin/run-p/index.js", - "run-s": "bin/run-s/index.js" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm-run-all/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npm-run-all/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/npm-run-all/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/npm-run-all/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/npm-run-all/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npm-run-all/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npm-run-all/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nullthrows": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/ordered-binary": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.1.tgz", - "integrity": "sha512-5VyHfHY3cd0iza71JepYG50My+YUbrFtGoUz2ooEydPyPM7Aai/JW098juLr+RG6+rDJuzNNTsEQu2DZa1A41A==", - "dev": true - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" - }, - "node_modules/parcel": { - "version": "2.0.0-canary.1713", - "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.0.0-canary.1713.tgz", - "integrity": "sha512-QkZxmScIeueCKaSAbC3FEZ19LZCnOonqzyWjhDw7dS+SNdKypCbRddN4LNtj+WHq1zklzEhumj3Lrs3DKQqo+A==", + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@parcel/config-default": "2.0.0-canary.1715+d599275b1", - "@parcel/core": "2.0.0-canary.1713+d599275b1", - "@parcel/diagnostic": "2.0.0-canary.1715+d599275b1", - "@parcel/events": "2.0.0-canary.1715+d599275b1", - "@parcel/feature-flags": "2.12.1-canary.3338+d599275b1", - "@parcel/fs": "2.0.0-canary.1715+d599275b1", - "@parcel/logger": "2.0.0-canary.1715+d599275b1", - "@parcel/package-manager": "2.0.0-canary.1715+d599275b1", - "@parcel/reporter-cli": "2.0.0-canary.1715+d599275b1", - "@parcel/reporter-dev-server": "2.0.0-canary.1715+d599275b1", - "@parcel/reporter-tracer": "2.12.1-canary.3338+d599275b1", - "@parcel/utils": "2.0.0-canary.1715+d599275b1", - "chalk": "^4.1.0", - "commander": "^7.0.0", - "get-port": "^4.2.0" - }, - "bin": { - "parcel": "bin/parcel.js" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 16.0.0" + "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=8" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "node_modules/lmdb": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.8.5.tgz", + "integrity": "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ==", "dev": true, + "hasInstallScript": true, + "license": "MIT", "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" + "msgpackr": "^1.9.5", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.1.1", + "ordered-binary": "^1.4.1", + "weak-lru-cache": "^1.2.2" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true, "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "node_modules/posthtml": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.6.tgz", - "integrity": "sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==", - "dev": true, - "dependencies": { - "posthtml-parser": "^0.11.0", - "posthtml-render": "^3.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/posthtml-parser": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.10.2.tgz", - "integrity": "sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg==", - "dev": true, - "dependencies": { - "htmlparser2": "^7.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/posthtml-render": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", - "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", - "dev": true, - "dependencies": { - "is-json": "^2.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/posthtml/node_modules/posthtml-parser": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", - "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", - "dev": true, - "dependencies": { - "htmlparser2": "^7.1.1" + "download-lmdb-prebuilds": "bin/download-prebuilds.js" }, - "engines": { - "node": ">=12" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "2.8.5", + "@lmdb/lmdb-darwin-x64": "2.8.5", + "@lmdb/lmdb-linux-arm": "2.8.5", + "@lmdb/lmdb-linux-arm64": "2.8.5", + "@lmdb/lmdb-linux-x64": "2.8.5", + "@lmdb/lmdb-win32-x64": "2.8.5" } }, - "node_modules/react-error-overlay": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", - "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==", - "dev": true - }, - "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "node_modules/lmdb/node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "node": ">=10" }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/lru-cache": { + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8.10.0" + "node": "20 || >=22" } }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "resolve": "^1.1.6" + "semver": "^7.5.3" }, "engines": { - "node": ">= 0.10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "brace-expansion": "^5.0.8" }, "engines": { - "node": ">= 0.4" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "node_modules/mocha": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-12.0.3.tgz", + "integrity": "sha512-beammieDdiWdkjANWeWPpkxUROYGi5FN88fPOkLiticz7HTg3Y+Pho3EYE6SUdcuWnZ3h2WD8EXCA55JF4o6wg==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "browser-stdout": "^1.3.1", + "chokidar": "^5.0.0", + "debug": "^4.3.5", + "diff": "^9.0.0", + "find-up-simple": "^1.0.1", + "glob": "^13.0.0", + "is-path-inside": "^4.0.0", + "is-unicode-supported": "^0.1.0", + "js-yaml": "^5.0.0", + "minimatch": "^10.2.2", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^7.1.1", + "strip-json-comments": "^5.0.3", + "supports-color": "^8.1.1", + "workerpool": "^10.0.0" }, "bin": { - "resolve": "bin/resolve" + "mocha": "bin/mocha.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { - "node": ">=4" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/restructure": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz", - "integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==" - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "has-flag": "^4.0.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/msgpackr": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.12.1.tgz", + "integrity": "sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "node_modules/msgpackr-extract": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", + "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "node-gyp-build-optional-packages": "5.2.2" }, - "engines": { - "node": "*" + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" } }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/msgpackr-extract/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "Apache-2.0", + "optional": true, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" + "detect-libc": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "license": "MIT" }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" + "detect-libc": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" } }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "node_modules/node-gyp-build-optional-packages/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, - "bin": { - "semver": "bin/semver.js" - }, + "license": "Apache-2.0", "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "node_modules/node-releases": { + "version": "2.0.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.58.tgz", + "integrity": "sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==", "dev": true, - "dependencies": { - "randombytes": "^2.1.0" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ordered-binary": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.2.tgz", + "integrity": "sha512-BY+qgDArmYpvvmij141xbkB4Cw8RFLBQM5Zj4MODFb1SyXBRE/xO4Xj/QWbR7aUEBxbkjuNdsFVCL2TmbYrlNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" + "p-limit": "^3.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/parcel": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.16.4.tgz", + "integrity": "sha512-RQlrqs4ujYNJpTQi+dITqPKNhRWEqpjPd1YBcGp50Wy3FcJHpwu0/iRm7XWz2dKU/Bwp2qCcVYPIeEDYi2uOUw==", "dev": true, + "license": "MIT", "dependencies": { - "shebang-regex": "^3.0.0" + "@parcel/config-default": "2.16.4", + "@parcel/core": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/feature-flags": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/package-manager": "2.16.4", + "@parcel/reporter-cli": "2.16.4", + "@parcel/reporter-dev-server": "2.16.4", + "@parcel/reporter-tracer": "2.16.4", + "@parcel/utils": "2.16.4", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "get-port": "^4.2.0" + }, + "bin": { + "parcel": "lib/bin.js" }, "engines": { - "node": ">=8" + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=4" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/shelljs/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "license": "ISC" }, - "node_modules/shelljs/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/shelljs/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "license": "MIT" }, - "node_modules/shx": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", - "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", + "node_modules/react-refresh": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.16.0.tgz", + "integrity": "sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A==", "dev": true, - "dependencies": { - "minimist": "^1.2.3", - "shelljs": "^0.8.5" - }, - "bin": { - "shx": "lib/cli.js" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "node_modules/readdirp": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz", + "integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==", "dev": true, - "optional": true, - "peer": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } + "license": "MIT" }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true + "node_modules/restructure": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz", + "integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==" }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "dev": true + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/srcset": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-5.0.1.tgz", - "integrity": "sha512-/P1UYbGfJVlxZag7aABNRrulEXAwCSDo7fklafOQrantuPTDmYgijJMks2zusPCVzgW9+4P69mq7w6pYuZpgxw==", + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10" } }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/serialize-javascript": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.1.2.tgz", + "integrity": "sha512-GL2BWwVa6JydKO6l/ljVgjAZF4QJ3S7dWDWi53s5GZT8PJzD2fNxi67HANQGKAqPrwEpL5ba7gUBGi0Ls/sEoQ==", "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" + "license": "BSD-3-Clause", + "engines": { + "node": ">=20.0.0" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/string.prototype.padend": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", - "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, + "license": "ISC", "engines": { - "node": ">= 0.4" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "safe-buffer": "~5.2.0" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "node_modules/string-width": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.3.0.tgz", + "integrity": "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">= 0.4" + "node": ">=20" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", + "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5761,50 +3814,12 @@ "node": ">=8" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, "node_modules/term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -5813,95 +3828,37 @@ } }, "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-8.0.0.tgz", + "integrity": "sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" + "glob": "^13.0.6", + "minimatch": "^10.2.2" }, "engines": { - "node": "*" + "node": "20 || >=22" } }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "dev": true - }, "node_modules/tiny-inflate": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -5909,122 +3866,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/unicode-properties": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", - "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-2.0.1.tgz", + "integrity": "sha512-hv6H7A0LZVW/42alBg9b35eGqaJ9SQ3t9rnBrqqkp/qwvrLETtABdVAOesUwFk9WbJtBY3zgpsqgFUZ1Tqy6jw==", + "license": "MIT", "dependencies": { - "base64-js": "^1.3.0", - "unicode-trie": "^2.0.0" + "unicode-trie": "^3.0.0" } }, "node_modules/unicode-trie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", - "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-3.0.0.tgz", + "integrity": "sha512-Cy+7EIpopVQ7ZCVZ8dFo1fmTk1lHMNxY62SeEhxsVEmISZEryEGgKSLzz6z6pquJXXopamfpi2AzsDCJ7KmAOA==", + "license": "MIT", "dependencies": { - "pako": "^0.2.5", - "tiny-inflate": "^1.0.0" + "fflate": "^0.8.3" + }, + "engines": { + "node": ">=20.17.0" } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", "dev": true, "funding": [ { @@ -6040,9 +3912,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -6062,6 +3935,7 @@ "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -6080,27 +3954,19 @@ "node": ">=10.12.0" } }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/weak-lru-cache": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -6111,119 +3977,108 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "node_modules/workerpool": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-10.0.3.tgz", + "integrity": "sha512-6z2Iis68Wqth93/G/wJP9u+R3O+d2XTlgWChGCwuT1qLbBsOYueGRZuJ++v3mtDP5KjYdy+WzvWC+VWETSVXJA==", "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.2.0.tgz", + "integrity": "sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==", "dev": true, + "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^8.2.1", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=10" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "node_modules/yargs/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, + "license": "ISC", "engines": { - "node": ">=10" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yocto-queue": { diff --git a/package.json b/package.json index dff6f0f8..8dd70da6 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,14 @@ "layout" ], "scripts": { - "test": "run-s build mocha", + "test": "npm run build && npm run mocha", "mocha": "mocha", "build": "parcel build", - "prepublish": "run-s clean trie:** build", + "prepublish": "npm run clean && npm run trie:data && npm run trie:use && npm run trie:indic && npm run build", "trie:data": "node src/opentype/shapers/generate-data.js", "trie:use": "node src/opentype/shapers/gen-use.js", "trie:indic": "node src/opentype/shapers/gen-indic.js", - "clean": "shx rm -rf src/opentype/shapers/data.trie src/opentype/shapers/use.trie src/opentype/shapers/use.json src/opentype/shapers/indic.trie src/opentype/shapers/indic.json dist", + "clean": "node scripts/clean.js", "coverage": "c8 mocha" }, "type": "module", @@ -76,23 +76,21 @@ "url": "git://github.com/foliojs/fontkit.git" }, "dependencies": { - "@swc/helpers": "^0.5.12", - "brotli": "^1.3.2", + "@swc/helpers": "^0.5.23", + "brotli": "^1.3.3", "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", - "restructure": "^3.0.0", + "restructure": "^3.0.2", "tiny-inflate": "^1.0.3", - "unicode-properties": "^1.4.0", - "unicode-trie": "^2.0.0" + "unicode-properties": "^2.0.1", + "unicode-trie": "^3.0.0" }, "devDependencies": { - "c8": "^7.11.3", - "codepoints": "^1.2.0", + "c8": "^12.0.0", + "codepoints": "^1.3.0", "concat-stream": "^2.0.0", - "mocha": "^10.0.0", - "npm-run-all": "^4.1.5", - "parcel": "2.0.0-canary.1713", - "shx": "^0.3.4" + "mocha": "^12.0.3", + "parcel": "2.16.4" } -} +} \ No newline at end of file diff --git a/scripts/clean.js b/scripts/clean.js new file mode 100644 index 00000000..a6963320 --- /dev/null +++ b/scripts/clean.js @@ -0,0 +1,14 @@ +import { rmSync } from 'node:fs'; + +const pathsToRemove = [ + 'src/opentype/shapers/data.trie', + 'src/opentype/shapers/use.trie', + 'src/opentype/shapers/use.json', + 'src/opentype/shapers/indic.trie', + 'src/opentype/shapers/indic.json', + 'dist' +]; + +for (const pathToRemove of pathsToRemove) { + rmSync(pathToRemove, { recursive: true, force: true }); +} \ No newline at end of file diff --git a/src/opentype/shapers/ArabicShaper.js b/src/opentype/shapers/ArabicShaper.js index fb6d20ef..6b8d289f 100644 --- a/src/opentype/shapers/ArabicShaper.js +++ b/src/opentype/shapers/ArabicShaper.js @@ -1,6 +1,6 @@ import DefaultShaper from './DefaultShaper'; -import {getCategory} from 'unicode-properties'; -import UnicodeTrie from 'unicode-trie'; +import { getCategory } from 'unicode-properties'; +import { UnicodeTrie } from 'unicode-trie'; import { decodeBase64 } from '../../utils'; const trie = new UnicodeTrie(decodeBase64(require('fs').readFileSync(__dirname + '/data.trie', 'base64'))); diff --git a/src/opentype/shapers/IndicShaper.js b/src/opentype/shapers/IndicShaper.js index 104198c5..77793b38 100644 --- a/src/opentype/shapers/IndicShaper.js +++ b/src/opentype/shapers/IndicShaper.js @@ -1,7 +1,7 @@ import DefaultShaper from './DefaultShaper'; import StateMachine from 'dfa'; -import UnicodeTrie from 'unicode-trie'; -import {getCategory} from 'unicode-properties'; +import { UnicodeTrie } from 'unicode-trie'; +import { getCategory } from 'unicode-properties'; import * as Script from '../../layout/Script'; import GlyphInfo from '../GlyphInfo'; import indicMachine from './indic.json'; diff --git a/src/opentype/shapers/UniversalShaper.js b/src/opentype/shapers/UniversalShaper.js index 3057dd14..15434b8d 100644 --- a/src/opentype/shapers/UniversalShaper.js +++ b/src/opentype/shapers/UniversalShaper.js @@ -1,6 +1,6 @@ import DefaultShaper from './DefaultShaper'; import StateMachine from 'dfa'; -import UnicodeTrie from 'unicode-trie'; +import { UnicodeTrie } from 'unicode-trie'; import GlyphInfo from '../GlyphInfo'; import useData from './use.json'; import { decodeBase64 } from '../../utils'; diff --git a/src/opentype/shapers/gen-indic.js b/src/opentype/shapers/gen-indic.js index 7cd39894..d8b46b6b 100644 --- a/src/opentype/shapers/gen-indic.js +++ b/src/opentype/shapers/gen-indic.js @@ -1,6 +1,6 @@ import codepoints from 'codepoints'; import fs from 'fs'; -import UnicodeTrieBuilder from 'unicode-trie/builder.js'; +import { UnicodeTrieBuilder } from 'unicode-trie/builder.js'; import dfa from 'dfa/compile.js'; import { CATEGORIES, POSITIONS, CONSONANT_FLAGS } from './indic-data.js'; diff --git a/src/opentype/shapers/gen-use.js b/src/opentype/shapers/gen-use.js index cb7eda55..3c5cb5f4 100644 --- a/src/opentype/shapers/gen-use.js +++ b/src/opentype/shapers/gen-use.js @@ -1,6 +1,6 @@ import codepoints from 'codepoints'; import fs from 'fs'; -import UnicodeTrieBuilder from 'unicode-trie/builder.js'; +import { UnicodeTrieBuilder } from 'unicode-trie/builder.js'; import dfa from 'dfa/compile.js'; const compile = dfa.default; diff --git a/src/opentype/shapers/generate-data.js b/src/opentype/shapers/generate-data.js index e8ad55b9..f7634952 100644 --- a/src/opentype/shapers/generate-data.js +++ b/src/opentype/shapers/generate-data.js @@ -4,7 +4,7 @@ // import codepoints from 'codepoints'; import fs from 'fs'; -import UnicodeTrieBuilder from 'unicode-trie/builder.js'; +import { UnicodeTrieBuilder } from 'unicode-trie/builder.js'; let ShapingClasses = { Non_Joining: 0, @@ -17,7 +17,7 @@ let ShapingClasses = { Transparent: 6 }; -let trie = new UnicodeTrieBuilder; +let trie = new UnicodeTrieBuilder(); for (let i = 0; i < codepoints.length; i++) { let codepoint = codepoints[i]; if (codepoint) { From 588dee52dabf284b4a5b2fb8b3c89c1d8371290d Mon Sep 17 00:00:00 2001 From: Luiz Americo Date: Fri, 9 Oct 2026 20:02:48 -0300 Subject: [PATCH 2/6] Add agents and changelog files --- AGENTS.md | 31 +++++++++++++++++++++++++++++++ CHANGELOG.md | 16 ++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 AGENTS.md create mode 100644 CHANGELOG.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..c3c4509b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,31 @@ +# Repository Guidelines + +## Project Structure & Module Organization + +Fontkit is a font engine for Node.js and browsers. Implementation lives in `src/`: `tables/` defines binary font tables, `glyph/` handles outlines and metrics, `layout/`, `opentype/`, and `aat/` implement shaping, and `subset/` encodes font subsets. Browser exports start in `src/index.js`; Node exports start in `src/node.js`. + +Tests live in `test/`, with font fixtures and their licenses in `test/data/`. `scripts/clean.js` removes generated artifacts. Parcel writes distributable bundles to the ignored `dist/` directory. + +## Build, Test, and Development Commands + +- `npm install`: install dependencies and run the existing `prepublish` lifecycle to generate shaping data and build bundles. +- `npm run build`: build Node/browser CommonJS and ES module bundles with Parcel. +- `npm test`: rebuild bundles, then run the complete Mocha suite. +- `npm run mocha -- test/glyph_mapping.js`: run one test file against the current build; rebuild after source changes. +- `npm run coverage`: run Mocha through c8 against the current build. +- `npm run trie:data`, `npm run trie:use`, `npm run trie:indic`: regenerate shaping data after changing generators or state machines. +- `npm run prepublish`: clean, regenerate all shaping data, and build. `npm run clean` also removes shaping assets, so regenerate them before rebuilding. + +## Coding Style & Naming Conventions + +Use JavaScript ES modules, two-space indentation, semicolons, and generally single-quoted strings. Match surrounding code where conventions differ. Use PascalCase for classes and class filenames (`TTFGlyph.js`), camelCase for methods and variables, and exact font-table tags for table modules (`cmap.js`, `GPOS.js`). No formatter or linter is configured; keep changes focused and avoid unrelated formatting. + +## Testing Guidelines + +Use Mocha `describe`/`it` blocks and Node's `assert`. Name test files by behavior, following `test/glyph_mapping.js` and `test/variations.js`. Add regression tests for parsing, shaping, mapping, or metrics changes; use `test/issues.js` for issue-specific regressions. Prefer existing fixtures; include licensing and provenance for new fonts. Tests import the built package as `fontkit`. Run `npm test` before submitting. No numeric coverage threshold is configured. + +## Commit & Pull Request Guidelines + +Prefer small, self-contained changes; they are most likely to be merged. Keep each PR focused on one fix or feature, and submit unrelated changes separately. + +Recent commits use short, descriptive subjects such as “Map space and missing code points correctly,” often with issue or PR numbers. Follow that style; Conventional Commit prefixes are not established. Keep commits focused. PR descriptions should explain the affected behavior, reproduction or regression case, linked issues, and validation commands/results. Update `README.md` when public API behavior changes. Update `CHANGELOG.md` for notable changes. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..75ad2c25 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +## fontkit changelog + +### Unreleased + + - Map space and missing code points correctly with a legacy Mac cmap (#394) + - Keep a glyph's variation metrics stable when several composites use it + - Return the requested code points for glyphs shared by several code points (#342) (#395) + - Map glyphs back to code points for cmap formats 6 and 10 (#392) + - Size cmap format 10 glyph indices by entryCount (#391) + - Leave code points mapped to .notdef out of characterSet (#390) + - Fix glyph code point cache after composite decomposition (#387) + - Fix off-diagonal coefficients in composite glyph transforms (#388) + + +### [v2.0.4] - 08-09-2024 + From 154960e3cc7cec413ddd2d2ff41c0b843281bf70 Mon Sep 17 00:00:00 2001 From: Luiz Americo Date: Fri, 9 Oct 2026 22:06:55 -0300 Subject: [PATCH 3/6] Replace cache decorators with specialized lazy caching --- CHANGELOG.md | 1 + jsconfig.json | 5 -- src/CmapProcessor.js | 9 ++- src/TTFFont.js | 19 +++-- src/aat/AATLookupTable.js | 7 +- src/aat/AATMorxProcessor.js | 7 +- src/cache.js | 69 +++++++++++++++++ src/decorators.js | 36 --------- src/glyph/Glyph.js | 17 +++-- test/cache.js | 145 ++++++++++++++++++++++++++++++++++++ test/glyph_mapping.js | 25 +++++++ 11 files changed, 277 insertions(+), 63 deletions(-) delete mode 100644 jsconfig.json create mode 100644 src/cache.js delete mode 100644 src/decorators.js create mode 100644 test/cache.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 75ad2c25..114a4303 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Unreleased + - Replace cache decorators with specialized lazy caching - Map space and missing code points correctly with a legacy Mac cmap (#394) - Keep a glyph's variation metrics stable when several composites use it - Return the requested code points for glyphs shared by several code points (#342) (#395) diff --git a/jsconfig.json b/jsconfig.json deleted file mode 100644 index a178f9dc..00000000 --- a/jsconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "compilerOptions": { - "experimentalDecorators": true - } -} \ No newline at end of file diff --git a/src/CmapProcessor.js b/src/CmapProcessor.js index de7e66e2..77aea861 100644 --- a/src/CmapProcessor.js +++ b/src/CmapProcessor.js @@ -1,6 +1,6 @@ import { binarySearch } from './utils'; import { encodingExists, getEncoding, getEncodingMapping } from './encodings'; -import { cache } from './decorators'; +import { cache } from './cache'; import { range } from './utils'; export default class CmapProcessor { @@ -181,7 +181,6 @@ export default class CmapProcessor { return 0; } - @cache getCharacterSet() { // Codes that map to glyph 0 (.notdef) are not supported characters return this._getCodes().filter(code => this._lookupCode(code) !== 0); @@ -230,7 +229,6 @@ export default class CmapProcessor { } } - @cache codePointsForGlyph(gid) { let cmap = this.cmap; switch (cmap.version) { @@ -313,3 +311,8 @@ export default class CmapProcessor { } } } + +cache(CmapProcessor, { + getCharacterSet: 'once', + codePointsForGlyph: 'key' +}); diff --git a/src/TTFFont.js b/src/TTFFont.js index 04ef9500..ab467f5e 100644 --- a/src/TTFFont.js +++ b/src/TTFFont.js @@ -1,5 +1,5 @@ import * as r from 'restructure'; -import { cache } from './decorators'; +import { cache } from './cache'; import * as fontkit from './base'; import Directory from './tables/directory'; import tables from './tables'; @@ -258,12 +258,10 @@ export default class TTFFont { * The font’s bounding box, i.e. the box that encloses all glyphs in the font. * @type {BBox} */ - @cache get bbox() { return Object.freeze(new BBox(this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax)); } - @cache get _cmapProcessor() { return new CmapProcessor(this.cmap); } @@ -272,7 +270,6 @@ export default class TTFFont { * An array of all of the unicode code points supported by the font. * @type {number[]} */ - @cache get characterSet() { return this._cmapProcessor.getCharacterSet(); } @@ -350,7 +347,6 @@ export default class TTFFont { return glyphs; } - @cache get _layoutEngine() { return new LayoutEngine(this); } @@ -471,7 +467,6 @@ export default class TTFFont { * * @type {object} */ - @cache get variationAxes() { let res = {}; if (!this.fvar) { @@ -497,7 +492,6 @@ export default class TTFFont { * * @type {object} */ - @cache get namedVariations() { let res = {}; if (!this.fvar) { @@ -557,7 +551,6 @@ export default class TTFFont { return font; } - @cache get _variationProcessor() { if (!this.fvar) { return null; @@ -582,3 +575,13 @@ export default class TTFFont { return this.getVariation(name); } } + +cache(TTFFont, { + bbox: 'once', + _cmapProcessor: 'once', + characterSet: 'once', + _layoutEngine: 'once', + variationAxes: 'once', + namedVariations: 'once', + _variationProcessor: 'once' +}); diff --git a/src/aat/AATLookupTable.js b/src/aat/AATLookupTable.js index 74f764c7..62ae190c 100644 --- a/src/aat/AATLookupTable.js +++ b/src/aat/AATLookupTable.js @@ -1,4 +1,4 @@ -import {cache} from '../decorators'; +import {cache} from '../cache'; import {range} from '../utils'; export default class AATLookupTable { @@ -74,7 +74,6 @@ export default class AATLookupTable { } } - @cache glyphsForValue(classValue) { let res = []; @@ -123,3 +122,7 @@ export default class AATLookupTable { return res; } } + +cache(AATLookupTable, { + glyphsForValue: 'key' +}); diff --git a/src/aat/AATMorxProcessor.js b/src/aat/AATMorxProcessor.js index 94744e1a..2acf98c1 100644 --- a/src/aat/AATMorxProcessor.js +++ b/src/aat/AATMorxProcessor.js @@ -1,6 +1,6 @@ import AATStateMachine from './AATStateMachine'; import AATLookupTable from './AATLookupTable'; -import {cache} from '../decorators'; +import {cache} from '../cache'; // indic replacement flags const MARK_FIRST = 0x8000; @@ -104,7 +104,6 @@ export default class AATMorxProcessor { return stateMachine.process(this.glyphs, reverse, process); } - @cache getStateMachine(subtable) { return new AATStateMachine(subtable.table.stateTable); } @@ -355,6 +354,10 @@ export default class AATMorxProcessor { } } +cache(AATMorxProcessor, { + getStateMachine: 'key' +}); + // swaps the glyphs in rangeA with those in rangeB // reverse the glyphs inside those ranges if specified // ranges are in [offset, length] format diff --git a/src/cache.js b/src/cache.js new file mode 100644 index 00000000..338f61f6 --- /dev/null +++ b/src/cache.js @@ -0,0 +1,69 @@ +/** + * Registers lazy, per-instance caches without decorator syntax. + * Use 'once' for getters and zero-argument methods, or 'key' for + * methods whose result depends on a single argument. + * @private + */ +export function cache(Class, members) { + for (let [key, mode] of Object.entries(members)) { + let descriptor = Object.getOwnPropertyDescriptor(Class.prototype, key); + if (mode !== 'once' && mode !== 'key') { + throw new TypeError(`Unknown cache mode for ${key}: ${mode}`); + } + + if (!descriptor || (!descriptor.get && typeof descriptor.value !== 'function')) { + throw new TypeError(`Cannot cache ${key}: expected an own getter or method`); + } + + if (descriptor.get) { + if (mode !== 'once') { + throw new TypeError(`Cannot cache getter ${key} by argument`); + } + + let get = descriptor.get; + descriptor.get = function() { + let value = get.call(this); + Object.defineProperty(this, key, { value }); + return value; + }; + } else { + let fn = descriptor.value; + descriptor = { + configurable: descriptor.configurable, + enumerable: descriptor.enumerable, + get() { + let memoized; + if (mode === 'once') { + let computed = false; + let value; + memoized = function() { + if (!computed) { + value = fn.call(this); + computed = true; + } + + return value; + }; + } else { + let values = new Map(); + memoized = function(arg) { + let value = values.get(arg); + if (value !== undefined || values.has(arg)) { + return value; + } + + value = fn.call(this, arg); + values.set(arg, value); + return value; + }; + } + + Object.defineProperty(this, key, { value: memoized }); + return memoized; + } + }; + } + + Object.defineProperty(Class.prototype, key, descriptor); + } +} diff --git a/src/decorators.js b/src/decorators.js deleted file mode 100644 index ce0d90b8..00000000 --- a/src/decorators.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This decorator caches the results of a getter or method such that - * the results are lazily computed once, and then cached. - * @private - */ -export function cache(target, key, descriptor) { - if (descriptor.get) { - let get = descriptor.get; - descriptor.get = function() { - let value = get.call(this); - Object.defineProperty(this, key, { value }); - return value; - }; - } else if (typeof descriptor.value === 'function') { - let fn = descriptor.value; - - return { - get() { - let cache = new Map; - function memoized(...args) { - let key = args.length > 0 ? args[0] : 'value'; - if (cache.has(key)) { - return cache.get(key); - } - - let result = fn.apply(this, args); - cache.set(key, result); - return result; - }; - - Object.defineProperty(this, key, {value: memoized}); - return memoized; - } - }; - } -} diff --git a/src/glyph/Glyph.js b/src/glyph/Glyph.js index 3592150f..3eb7ed6f 100644 --- a/src/glyph/Glyph.js +++ b/src/glyph/Glyph.js @@ -1,4 +1,4 @@ -import { cache } from '../decorators'; +import { cache } from '../cache'; import Path from './Path'; import {isMark} from 'unicode-properties'; import StandardNames from './StandardNames'; @@ -101,7 +101,6 @@ export default class Glyph { * * @type {BBox} */ - @cache get cbox() { return this._getCBox(); } @@ -111,7 +110,6 @@ export default class Glyph { * glyph outline as tightly as possible. * @type {BBox} */ - @cache get bbox() { return this._getBBox(); } @@ -120,7 +118,6 @@ export default class Glyph { * A vector Path object representing the glyph outline. * @type {Path} */ - @cache get path() { // Cache the path so we only decode it once // Decoding is actually performed by subclasses @@ -141,7 +138,6 @@ export default class Glyph { * The glyph's advance width. * @type {number} */ - @cache get advanceWidth() { return this._getMetrics().advanceWidth; } @@ -150,7 +146,6 @@ export default class Glyph { * The glyph's advance height. * @type {number} */ - @cache get advanceHeight() { return this._getMetrics().advanceHeight; } @@ -187,7 +182,6 @@ export default class Glyph { * The glyph's name * @type {string} */ - @cache get name() { return this._getName(); } @@ -210,3 +204,12 @@ export default class Glyph { ctx.restore(); } } + +cache(Glyph, { + cbox: 'once', + bbox: 'once', + path: 'once', + advanceWidth: 'once', + advanceHeight: 'once', + name: 'once' +}); diff --git a/test/cache.js b/test/cache.js new file mode 100644 index 00000000..2440e8f2 --- /dev/null +++ b/test/cache.js @@ -0,0 +1,145 @@ +import assert from 'assert'; +import { cache } from '../src/cache.js'; + +class CachedFixture { + constructor(compute = function(key) { return { owner: this, key }; }) { + this.compute = compute; + this.calls = 0; + } + + get property() { + this.calls++; + return this.compute(); + } + + once() { + this.calls++; + return this.compute(); + } + + keyed(key) { + this.calls++; + return this.compute(key); + } +} + +cache(CachedFixture, { + property: 'once', + once: 'once', + keyed: 'key' +}); + +describe('lazy caching without decorators', function () { + it('should defer computation until a getter is read or a method is called', function () { + let fixture = new CachedFixture(); + let once = fixture.once; + let keyed = fixture.keyed; + assert.equal(fixture.calls, 0); + assert.strictEqual(fixture.once, once); + assert.strictEqual(fixture.keyed, keyed); + + fixture.property; + once.call(fixture); + keyed.call(fixture, 0); + assert.equal(fixture.calls, 3); + }); + + it('should preserve the receiver and return the same result on cache hits', function () { + let fixture = new CachedFixture(); + let property = fixture.property; + let once = fixture.once(); + let keyed = fixture.keyed(0); + + assert.strictEqual(fixture.property, property); + assert.strictEqual(fixture.once(), once); + assert.strictEqual(fixture.keyed(0), keyed); + assert.strictEqual(property.owner, fixture); + assert.strictEqual(once.owner, fixture); + assert.strictEqual(keyed.owner, fixture); + assert.equal(fixture.calls, 3); + }); + + it('should keep caches separate for each instance and member', function () { + let first = new CachedFixture(); + let second = new CachedFixture(); + assert.notStrictEqual(first.property, second.property); + assert.notStrictEqual(first.once(), second.once()); + assert.notStrictEqual(first.keyed(0), second.keyed(0)); + assert.notStrictEqual(first.property, first.once()); + assert.notStrictEqual(first.once(), first.keyed(0)); + assert.equal(first.calls, 3); + assert.equal(second.calls, 3); + }); + + it('should distinguish argument values and use object identity for keys', function () { + let fixture = new CachedFixture(); + let keys = [0, '0', false, null, undefined, NaN, {}, {}, Symbol('key')]; + let results = keys.map(key => fixture.keyed(key)); + assert.equal(new Set(results).size, keys.length); + + for (let i = 0; i < keys.length; i++) { + assert.strictEqual(fixture.keyed(keys[i]), results[i]); + } + + assert.equal(fixture.calls, keys.length); + }); + + it('should cache falsy results including undefined', function () { + for (let value of [undefined, null, false, 0, '']) { + let fixture = new CachedFixture(() => value); + for (let i = 0; i < 3; i++) { + assert.strictEqual(fixture.property, value); + assert.strictEqual(fixture.once(), value); + assert.strictEqual(fixture.keyed(0), value); + } + + assert.equal(fixture.calls, 3); + } + }); + + it('should retry computations that throw without caching the exception', function () { + for (let member of ['property', 'once', 'keyed']) { + let fixture = new CachedFixture(function() { + if (this.calls === 1) { + throw new Error('retry'); + } + + return {}; + }); + let read = () => member === 'property' ? fixture.property : fixture[member](0); + assert.throws(read, /retry/); + let result = read(); + assert.strictEqual(read(), result); + assert.equal(fixture.calls, 2); + } + }); + + it('should preserve prototype attributes and define immutable, hidden own properties', function () { + let fixture = new CachedFixture(); + fixture.property; + fixture.once(); + fixture.keyed(0); + + for (let member of ['property', 'once', 'keyed']) { + let prototype = Object.getOwnPropertyDescriptor(CachedFixture.prototype, member); + assert.equal(prototype.configurable, true); + assert.equal(prototype.enumerable, false); + + let descriptor = Object.getOwnPropertyDescriptor(fixture, member); + assert.equal(descriptor.configurable, false); + assert.equal(descriptor.enumerable, false); + assert.equal(descriptor.writable, false); + } + }); + + it('should reject unsupported members and cache modes', function () { + class Fixture { + get property() { return 1; } + method() { return 1; } + } + + assert.throws(() => cache(Fixture, { method: 'unknown' }), TypeError); + assert.throws(() => cache(Fixture, { missing: 'once' }), TypeError); + assert.throws(() => cache(Fixture, { property: 'key' }), TypeError); + }); +}); diff --git a/test/glyph_mapping.js b/test/glyph_mapping.js index 121fec49..6e3282dd 100644 --- a/test/glyph_mapping.js +++ b/test/glyph_mapping.js @@ -10,6 +10,31 @@ describe('character to glyph mapping', function () { return assert.equal(font.characterSet.length, 883); }); + it('should cache character sets separately for each cmap processor', function () { + let other = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let processor = font._cmapProcessor; + let characterSet = processor.getCharacterSet(); + assert.strictEqual(processor.getCharacterSet(), characterSet); + assert.deepEqual(other._cmapProcessor.getCharacterSet(), characterSet); + assert.notStrictEqual(other._cmapProcessor.getCharacterSet(), characterSet); + }); + + it('should cache code points separately for each glyph and cmap processor', function () { + let other = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let processor = font._cmapProcessor; + let codePoints = processor.codePointsForGlyph(68); + assert.deepEqual(codePoints, [97]); + assert.strictEqual(processor.codePointsForGlyph(68), codePoints); + assert.deepEqual(processor.codePointsForGlyph(69), [98]); + assert.notStrictEqual(processor.codePointsForGlyph(69), codePoints); + assert.deepEqual(other._cmapProcessor.codePointsForGlyph(68), codePoints); + assert.notStrictEqual(other._cmapProcessor.codePointsForGlyph(68), codePoints); + + let missing = processor.codePointsForGlyph(0xffff); + assert.deepEqual(missing, []); + assert.strictEqual(processor.codePointsForGlyph(0xffff), missing); + }); + it('should leave code points mapped to .notdef out of characterSet', function () { // U+FFFF is only the closing segment of the format 4 subtable (#158) assert(!font.characterSet.includes(0xffff)); From 57d01d78d2c5e3862132f4e72a617e1b7070453f Mon Sep 17 00:00:00 2001 From: Luiz Americo Date: Fri, 9 Oct 2026 22:12:44 -0300 Subject: [PATCH 4/6] Add prettier format --- .prettierrc | 3 + AGENTS.md | 4 +- package-lock.json | 19 +- package.json | 5 +- src/CmapProcessor.js | 36 +- src/DFont.js | 24 +- src/TTFFont.js | 87 +- src/TrueTypeCollection.js | 22 +- src/WOFF2Font.js | 45 +- src/WOFFFont.js | 5 +- src/aat/AATFeatureMap.js | 149 +- src/aat/AATLayoutEngine.js | 7 +- src/aat/AATLookupTable.js | 17 +- src/aat/AATMorxProcessor.js | 80 +- src/aat/AATStateMachine.js | 17 +- src/base.js | 8 +- src/cache.js | 17 +- src/cff/CFFCharsets.js | 573 ++++- src/cff/CFFDict.js | 20 +- src/cff/CFFEncodings.js | 550 ++++- src/cff/CFFFont.js | 6 +- src/cff/CFFIndex.js | 16 +- src/cff/CFFOperand.js | 52 +- src/cff/CFFPointer.js | 6 +- src/cff/CFFPrivateDict.js | 40 +- src/cff/CFFStandardStrings.js | 458 +++- src/cff/CFFTop.js | 167 +- src/encodings.js | 524 +++- src/glyph/BBox.js | 7 +- src/glyph/CFFGlyph.js | 26 +- src/glyph/COLRGlyph.js | 17 +- src/glyph/Glyph.js | 39 +- src/glyph/GlyphVariationProcessor.js | 150 +- src/glyph/Path.js | 56 +- src/glyph/SBIXGlyph.js | 14 +- src/glyph/StandardNames.js | 283 ++- src/glyph/TTFGlyph.js | 143 +- src/glyph/TTFGlyphEncoder.js | 83 +- src/index.js | 7 +- src/layout/GlyphRun.js | 18 +- src/layout/KernProcessor.js | 28 +- src/layout/LayoutEngine.js | 60 +- src/layout/Script.js | 54 +- src/layout/UnicodeLayoutEngine.js | 25 +- src/node.js | 7 +- src/opentype/GPOSProcessor.js | 106 +- src/opentype/GSUBProcessor.js | 32 +- src/opentype/GlyphInfo.js | 6 +- src/opentype/GlyphIterator.js | 18 +- src/opentype/OTLayoutEngine.js | 26 +- src/opentype/OTProcessor.js | 93 +- src/opentype/ShapingPlan.js | 3 +- src/opentype/shapers/ArabicShaper.js | 71 +- src/opentype/shapers/DefaultShaper.js | 9 +- src/opentype/shapers/HangulShaper.js | 156 +- src/opentype/shapers/IndicShaper.js | 295 ++- src/opentype/shapers/UniversalShaper.js | 46 +- src/opentype/shapers/gen-indic.js | 210 +- src/opentype/shapers/gen-use.js | 166 +- src/opentype/shapers/generate-data.js | 8 +- src/opentype/shapers/index.js | 60 +- src/opentype/shapers/indic-data.js | 70 +- src/subset/CFFSubset.js | 34 +- src/subset/TTFSubset.js | 12 +- src/tables/BASE.js | 80 +- src/tables/COLR.js | 33 +- src/tables/CPAL.js | 24 +- src/tables/DSIG.js | 18 +- src/tables/EBDT.js | 29 +- src/tables/EBLC.js | 40 +- src/tables/GDEF.js | 62 +- src/tables/GPOS.js | 261 +- src/tables/GSUB.js | 119 +- src/tables/HVAR.js | 25 +- src/tables/JSTF.js | 45 +- src/tables/LTSH.js | 6 +- src/tables/OS2.js | 128 +- src/tables/PCLT.js | 30 +- src/tables/VDMX.js | 34 +- src/tables/VORG.js | 14 +- src/tables/WOFF2Directory.js | 91 +- src/tables/WOFFDirectory.js | 38 +- src/tables/aat.js | 75 +- src/tables/avar.js | 6 +- src/tables/bsln.js | 24 +- src/tables/cmap.js | 160 +- src/tables/cvt.js | 2 +- src/tables/directory.js | 32 +- src/tables/feat.js | 20 +- src/tables/fpgm.js | 2 +- src/tables/fvar.js | 13 +- src/tables/gasp.js | 19 +- src/tables/glyf.js | 2 +- src/tables/gvar.js | 17 +- src/tables/hdmx.js | 14 +- src/tables/head.js | 41 +- src/tables/hhea.js | 28 +- src/tables/hmtx.js | 9 +- src/tables/index.js | 5 - src/tables/just.js | 48 +- src/tables/kern.js | 125 +- src/tables/loca.js | 10 +- src/tables/maxp.js | 30 +- src/tables/morx.js | 63 +- src/tables/name.js | 72 +- src/tables/opbd.js | 4 +- src/tables/opentype.js | 224 +- src/tables/post.js | 27 +- src/tables/prep.js | 2 +- src/tables/sbix.js | 7 +- src/tables/variations.js | 52 +- src/tables/vhea.js | 28 +- src/tables/vmtx.js | 11 +- src/utils.js | 3 +- test/cache.js | 28 +- test/data/README.md | 2 +- test/directory.js | 5 +- test/glyph_mapping.js | 267 +- test/glyph_positioning.js | 30 +- test/glyphs.js | 166 +- test/i18n.js | 38 +- test/index.js | 82 +- test/issues.js | 108 +- test/metadata.js | 10 +- test/opentype.js | 5 +- test/shaping.js | 3000 +++++++++++++++++++---- test/subset.js | 65 +- test/variations.js | 105 +- 128 files changed, 8546 insertions(+), 3012 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..92cde390 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index c3c4509b..c59418e0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,6 +10,8 @@ Tests live in `test/`, with font fixtures and their licenses in `test/data/`. `s - `npm install`: install dependencies and run the existing `prepublish` lifecycle to generate shaping data and build bundles. - `npm run build`: build Node/browser CommonJS and ES module bundles with Parcel. +- `npm run format`: format files in `src/` and `test/` with Prettier. +- `npm run format:check`: check formatting in `src/` and `test/` without modifying files. - `npm test`: rebuild bundles, then run the complete Mocha suite. - `npm run mocha -- test/glyph_mapping.js`: run one test file against the current build; rebuild after source changes. - `npm run coverage`: run Mocha through c8 against the current build. @@ -18,7 +20,7 @@ Tests live in `test/`, with font fixtures and their licenses in `test/data/`. `s ## Coding Style & Naming Conventions -Use JavaScript ES modules, two-space indentation, semicolons, and generally single-quoted strings. Match surrounding code where conventions differ. Use PascalCase for classes and class filenames (`TTFGlyph.js`), camelCase for methods and variables, and exact font-table tags for table modules (`cmap.js`, `GPOS.js`). No formatter or linter is configured; keep changes focused and avoid unrelated formatting. +Use JavaScript ES modules. Coding style is enforced through Prettier via `npm run format`. Validate formatting with `npm run format:check`. Use PascalCase for classes and class filenames (`TTFGlyph.js`), camelCase for methods and variables, and exact font-table tags for table modules (`cmap.js`, `GPOS.js`). No linter is configured; keep changes focused and avoid unrelated formatting. ## Testing Guidelines diff --git a/package-lock.json b/package-lock.json index b4b3e1ba..7e6d0b04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,8 @@ "codepoints": "^1.3.0", "concat-stream": "^2.0.0", "mocha": "^12.0.3", - "parcel": "2.16.4" + "parcel": "2.16.4", + "prettier": "^3.9.9" } }, "node_modules/@bcoe/v8-coverage": { @@ -3618,6 +3619,22 @@ "dev": true, "license": "MIT" }, + "node_modules/prettier": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.9.tgz", + "integrity": "sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/react-refresh": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.16.0.tgz", diff --git a/package.json b/package.json index 8dd70da6..becb9e9a 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "test": "npm run build && npm run mocha", "mocha": "mocha", "build": "parcel build", + "format": "prettier --write src test", + "format:check": "prettier --check src test", "prepublish": "npm run clean && npm run trie:data && npm run trie:use && npm run trie:indic && npm run build", "trie:data": "node src/opentype/shapers/generate-data.js", "trie:use": "node src/opentype/shapers/gen-use.js", @@ -91,6 +93,7 @@ "codepoints": "^1.3.0", "concat-stream": "^2.0.0", "mocha": "^12.0.3", - "parcel": "2.16.4" + "parcel": "2.16.4", + "prettier": "^3.9.9" } } \ No newline at end of file diff --git a/src/CmapProcessor.js b/src/CmapProcessor.js index 77aea861..15c35c39 100644 --- a/src/CmapProcessor.js +++ b/src/CmapProcessor.js @@ -18,13 +18,17 @@ export default class CmapProcessor { [0, 3], [0, 2], [0, 1], - [0, 0] + [0, 0], ]); // If not unicode cmap was found, take the first table with a supported encoding. if (!this.cmap) { for (let cmap of cmapTable.tables) { - let encoding = getEncoding(cmap.platformID, cmap.encodingID, cmap.table.language - 1); + let encoding = getEncoding( + cmap.platformID, + cmap.encodingID, + cmap.table.language - 1, + ); let mapping = getEncodingMapping(encoding); if (mapping) { this.cmap = cmap.table; @@ -34,7 +38,7 @@ export default class CmapProcessor { } if (!this.cmap) { - throw new Error("Could not find a supported cmap table"); + throw new Error('Could not find a supported cmap table'); } this.uvs = this.findSubtable(cmapTable, [[0, 5]]); @@ -103,7 +107,10 @@ export default class CmapProcessor { if (rangeOffset === 0) { gid = codepoint + cmap.idDelta.get(mid); } else { - let index = rangeOffset / 2 + (codepoint - cmap.startCode.get(mid)) - (cmap.segCount - mid); + let index = + rangeOffset / 2 + + (codepoint - cmap.startCode.get(mid)) - + (cmap.segCount - mid); gid = cmap.glyphIndexArray.get(index) || 0; if (gid !== 0) { gid += cmap.idDelta.get(mid); @@ -162,17 +169,21 @@ export default class CmapProcessor { } let selectors = this.uvs.varSelectors.toArray(); - let i = binarySearch(selectors, x => variationSelector - x.varSelector); + let i = binarySearch(selectors, (x) => variationSelector - x.varSelector); let sel = selectors[i]; if (i !== -1 && sel.defaultUVS) { - i = binarySearch(sel.defaultUVS, x => - codepoint < x.startUnicodeValue ? -1 : codepoint > x.startUnicodeValue + x.additionalCount ? +1 : 0 + i = binarySearch(sel.defaultUVS, (x) => + codepoint < x.startUnicodeValue + ? -1 + : codepoint > x.startUnicodeValue + x.additionalCount + ? +1 + : 0, ); } if (i !== -1 && sel.nonDefaultUVS) { - i = binarySearch(sel.nonDefaultUVS, x => codepoint - x.unicodeValue); + i = binarySearch(sel.nonDefaultUVS, (x) => codepoint - x.unicodeValue); if (i !== -1) { return sel.nonDefaultUVS[i].glyphID; } @@ -183,7 +194,7 @@ export default class CmapProcessor { getCharacterSet() { // Codes that map to glyph 0 (.notdef) are not supported characters - return this._getCodes().filter(code => this._lookupCode(code) !== 0); + return this._getCodes().filter((code) => this._lookupCode(code) !== 0); } _getCodes() { @@ -287,7 +298,10 @@ export default class CmapProcessor { case 12: { let res = []; for (let group of cmap.groups.toArray()) { - if (gid >= group.glyphID && gid <= group.glyphID + (group.endCharCode - group.startCharCode)) { + if ( + gid >= group.glyphID && + gid <= group.glyphID + (group.endCharCode - group.startCharCode) + ) { res.push(group.startCharCode + (gid - group.glyphID)); } } @@ -314,5 +328,5 @@ export default class CmapProcessor { cache(CmapProcessor, { getCharacterSet: 'once', - codePointsForGlyph: 'key' + codePointsForGlyph: 'key', }); diff --git a/src/DFont.js b/src/DFont.js index 5f606f60..c855d9b8 100644 --- a/src/DFont.js +++ b/src/DFont.js @@ -4,7 +4,7 @@ import TTFFont from './TTFFont'; let DFontName = new r.String(r.uint8); let DFontData = new r.Struct({ len: r.uint32, - buf: new r.Buffer('len') + buf: new r.Buffer('len'), }); let Ref = new r.Struct({ @@ -12,31 +12,35 @@ let Ref = new r.Struct({ nameOffset: r.int16, attr: r.uint8, dataOffset: r.uint24, - handle: r.uint32 + handle: r.uint32, }); let Type = new r.Struct({ name: new r.String(4), maxTypeIndex: r.uint16, - refList: new r.Pointer(r.uint16, new r.Array(Ref, t => t.maxTypeIndex + 1), { type: 'parent' }) + refList: new r.Pointer( + r.uint16, + new r.Array(Ref, (t) => t.maxTypeIndex + 1), + { type: 'parent' }, + ), }); let TypeList = new r.Struct({ length: r.uint16, - types: new r.Array(Type, t => t.length + 1) + types: new r.Array(Type, (t) => t.length + 1), }); let DFontMap = new r.Struct({ reserved: new r.Reserved(r.uint8, 24), typeList: new r.Pointer(r.uint16, TypeList), - nameListOffset: new r.Pointer(r.uint16, 'void') + nameListOffset: new r.Pointer(r.uint16, 'void'), }); let DFontHeader = new r.Struct({ dataOffset: r.uint32, map: new r.Pointer(r.uint32, DFontMap), dataLength: r.uint32, - mapLength: r.uint32 + mapLength: r.uint32, }); export default class DFont { @@ -91,11 +95,9 @@ export default class DFont { let font = new TTFFont(stream); if ( font.postscriptName === name || - ( - font.postscriptName instanceof Uint8Array && - name instanceof Uint8Array && - font.postscriptName.every((v, i) => name[i] === v) - ) + (font.postscriptName instanceof Uint8Array && + name instanceof Uint8Array && + font.postscriptName.every((v, i) => name[i] === v)) ) { return font; } diff --git a/src/TTFFont.js b/src/TTFFont.js index ab467f5e..95acbab9 100644 --- a/src/TTFFont.js +++ b/src/TTFFont.js @@ -20,7 +20,10 @@ function needsCodePoints(glyph, characters) { } function hasCodePoints(glyph, characters) { - return glyph.codePoints.length === characters.length && glyph.codePoints.every((c, i) => c === characters[i]); + return ( + glyph.codePoints.length === characters.length && + glyph.codePoints.every((c, i) => c === characters[i]) + ); } /** @@ -32,7 +35,11 @@ export default class TTFFont { static probe(buffer) { let format = asciiDecoder.decode(buffer.slice(0, 4)); - return format === 'true' || format === 'OTTO' || format === String.fromCharCode(0, 1, 0, 0); + return ( + format === 'true' || + format === 'OTTO' || + format === String.fromCharCode(0, 1, 0, 0) + ); } constructor(stream, variationCoords = null) { @@ -51,7 +58,7 @@ export default class TTFFont { let table = this.directory.tables[tag]; if (tables[tag] && table.length > 0) { Object.defineProperty(this, tag, { - get: this._getTable.bind(this, table) + get: this._getTable.bind(this, table), }); } } @@ -87,7 +94,9 @@ export default class TTFFont { } _decodeDirectory() { - return this.directory = Directory.decode(this.stream, {_startOffset: 0}); + return (this.directory = Directory.decode(this.stream, { + _startOffset: 0, + })); } _decodeTable(table) { @@ -110,12 +119,12 @@ export default class TTFFont { if (record) { // Attempt to retrieve the entry, depending on which translation is available: return ( - record[lang] - || record[this.defaultLanguage] - || record[fontkit.defaultLanguage] - || record['en'] - || record[Object.keys(record)[0]] // Seriously, ANY language would be fine - || null + record[lang] || + record[this.defaultLanguage] || + record[fontkit.defaultLanguage] || + record['en'] || + record[Object.keys(record)[0]] || // Seriously, ANY language would be fine + null ); } @@ -259,7 +268,9 @@ export default class TTFFont { * @type {BBox} */ get bbox() { - return Object.freeze(new BBox(this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax)); + return Object.freeze( + new BBox(this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax), + ); } get _cmapProcessor() { @@ -327,14 +338,20 @@ export default class TTFFont { } // Compute the next state: 1 if the next codepoint is a variation selector, 0 otherwise. - nextState = ((0xfe00 <= code && code <= 0xfe0f) || (0xe0100 <= code && code <= 0xe01ef)) ? 1 : 0; + nextState = + (0xfe00 <= code && code <= 0xfe0f) || + (0xe0100 <= code && code <= 0xe01ef) + ? 1 + : 0; } else { idx++; } if (state === 0 && nextState === 1) { // Variation selector following normal codepoint. - glyphs.push(this.getGlyph(this._cmapProcessor.lookup(last, code), [last, code])); + glyphs.push( + this.getGlyph(this._cmapProcessor.lookup(last, code), [last, code]), + ); } else if (state === 0 && nextState === 0) { // Normal codepoint following normal codepoint. glyphs.push(this.glyphForCodePoint(last)); @@ -362,7 +379,13 @@ export default class TTFFont { * @return {GlyphRun} */ layout(string, userFeatures, script, language, direction) { - return this._layoutEngine.layout(string, userFeatures, script, language, direction); + return this._layoutEngine.layout( + string, + userFeatures, + script, + language, + direction, + ); } /** @@ -393,7 +416,6 @@ export default class TTFFont { if (!this._glyphs[glyph]) { if (this.directory.tables.glyf) { this._glyphs[glyph] = new TTFGlyph(glyph, characters, this); - } else if (this.directory.tables['CFF '] || this.directory.tables.CFF2) { this._glyphs[glyph] = new CFFGlyph(glyph, characters, this); } @@ -420,10 +442,8 @@ export default class TTFFont { if (!this._glyphs[glyph]) { if (this.directory.tables.sbix) { this._glyphs[glyph] = new SBIXGlyph(glyph, characters, this); - - } else if ((this.directory.tables.COLR) && (this.directory.tables.CPAL)) { + } else if (this.directory.tables.COLR && this.directory.tables.CPAL) { this._glyphs[glyph] = new COLRGlyph(glyph, characters, this); - } else { this._getBaseGlyph(glyph, characters); } @@ -442,7 +462,11 @@ export default class TTFFont { _getGlyphForCharacters(base, characters) { let key = base.id + ':' + characters.join(','); if (!this._glyphsByCharacters[key]) { - this._glyphsByCharacters[key] = new base.constructor(base.id, characters, this); + this._glyphsByCharacters[key] = new base.constructor( + base.id, + characters, + this, + ); } return this._glyphsByCharacters[key]; @@ -478,7 +502,7 @@ export default class TTFFont { name: axis.name.en, min: axis.minValue, default: axis.defaultValue, - max: axis.maxValue + max: axis.maxValue, }; } @@ -520,8 +544,14 @@ export default class TTFFont { * @return {TTFFont} */ getVariation(settings) { - if (!(this.directory.tables.fvar && ((this.directory.tables.gvar && this.directory.tables.glyf) || this.directory.tables.CFF2))) { - throw new Error('Variations require a font with the fvar, gvar and glyf, or CFF2 tables.'); + if (!( + this.directory.tables.fvar && + ((this.directory.tables.gvar && this.directory.tables.glyf) || + this.directory.tables.CFF2) + )) { + throw new Error( + 'Variations require a font with the fvar, gvar and glyf, or CFF2 tables.', + ); } if (typeof settings === 'string') { @@ -529,14 +559,19 @@ export default class TTFFont { } if (typeof settings !== 'object') { - throw new Error('Variation settings must be either a variation name or settings object.'); + throw new Error( + 'Variation settings must be either a variation name or settings object.', + ); } // normalize the coordinates let coords = this.fvar.axis.map((axis, i) => { let axisTag = axis.axisTag.trim(); if (axisTag in settings) { - return Math.max(axis.minValue, Math.min(axis.maxValue, settings[axisTag])); + return Math.max( + axis.minValue, + Math.min(axis.maxValue, settings[axisTag]), + ); } else { return axis.defaultValue; } @@ -564,7 +599,7 @@ export default class TTFFont { } if (!variationCoords) { - variationCoords = this.fvar.axis.map(axis => axis.defaultValue); + variationCoords = this.fvar.axis.map((axis) => axis.defaultValue); } return new GlyphVariationProcessor(this, variationCoords); @@ -583,5 +618,5 @@ cache(TTFFont, { _layoutEngine: 'once', variationAxes: 'once', namedVariations: 'once', - _variationProcessor: 'once' + _variationProcessor: 'once', }); diff --git a/src/TrueTypeCollection.js b/src/TrueTypeCollection.js index 2d273093..6b4cfa5f 100644 --- a/src/TrueTypeCollection.js +++ b/src/TrueTypeCollection.js @@ -6,16 +6,16 @@ import { asciiDecoder } from './utils'; let TTCHeader = new r.VersionedStruct(r.uint32, { 0x00010000: { - numFonts: r.uint32, - offsets: new r.Array(r.uint32, 'numFonts') + numFonts: r.uint32, + offsets: new r.Array(r.uint32, 'numFonts'), }, 0x00020000: { - numFonts: r.uint32, - offsets: new r.Array(r.uint32, 'numFonts'), - dsigTag: r.uint32, + numFonts: r.uint32, + offsets: new r.Array(r.uint32, 'numFonts'), + dsigTag: r.uint32, dsigLength: r.uint32, - dsigOffset: r.uint32 - } + dsigOffset: r.uint32, + }, }); export default class TrueTypeCollection { @@ -41,11 +41,9 @@ export default class TrueTypeCollection { let font = new TTFFont(stream); if ( font.postscriptName === name || - ( - font.postscriptName instanceof Uint8Array && - name instanceof Uint8Array && - font.postscriptName.every((v, i) => name[i] === v) - ) + (font.postscriptName instanceof Uint8Array && + name instanceof Uint8Array && + font.postscriptName.every((v, i) => name[i] === v)) ) { return font; } diff --git a/src/WOFF2Font.js b/src/WOFF2Font.js index 2cb327d8..7b34b04e 100644 --- a/src/WOFF2Font.js +++ b/src/WOFF2Font.js @@ -32,7 +32,8 @@ export default class WOFF2Font extends TTFFont { for (let tag in this.directory.tables) { let entry = this.directory.tables[tag]; entry.offset = decompressedSize; - decompressedSize += (entry.transformLength != null) ? entry.transformLength : entry.length; + decompressedSize += + entry.transformLength != null ? entry.transformLength : entry.length; } let decompressed = brotli(buffer, decompressedSize); @@ -54,10 +55,14 @@ export default class WOFF2Font extends TTFFont { // custom subclass if there is a glyf table. _getBaseGlyph(glyph, characters = []) { if (!this._glyphs[glyph]) { - if (this.directory.tables.glyf && this.directory.tables.glyf.transformed) { - if (!this._transformedGlyphs) { this._transformGlyfTable(); } - return this._glyphs[glyph] = new WOFF2Glyph(glyph, characters, this); - + if ( + this.directory.tables.glyf && + this.directory.tables.glyf.transformed + ) { + if (!this._transformedGlyphs) { + this._transformGlyfTable(); + } + return (this._glyphs[glyph] = new WOFF2Glyph(glyph, characters, this)); } else { return super._getBaseGlyph(glyph, characters); } @@ -75,7 +80,8 @@ export default class WOFF2Font extends TTFFont { let nContours = table.nContours.readInt16BE(); glyph.numberOfContours = nContours; - if (nContours > 0) { // simple glyph + if (nContours > 0) { + // simple glyph let nPoints = []; let totalPoints = 0; @@ -91,9 +97,13 @@ export default class WOFF2Font extends TTFFont { } var instructionSize = read255UInt16(table.glyphs); - - } else if (nContours < 0) { // composite glyph - let haveInstructions = TTFGlyph.prototype._decodeComposite.call({ _font: this }, glyph, table.composites); + } else if (nContours < 0) { + // composite glyph + let haveInstructions = TTFGlyph.prototype._decodeComposite.call( + { _font: this }, + glyph, + table.composites, + ); if (haveInstructions) { var instructionSize = read255UInt16(table.glyphs); } @@ -136,7 +146,7 @@ let GlyfTable = new r.Struct({ glyphs: new Substream('glyphStreamSize'), composites: new Substream('compositeStreamSize'), bboxes: new Substream('bboxStreamSize'), - instructions: new Substream('instructionStreamSize') + instructions: new Substream('instructionStreamSize'), }); const WORD_CODE = 253; @@ -168,11 +178,12 @@ function withSign(flag, baseval) { function decodeTriplet(flags, glyphs, nPoints) { let y; - let x = y = 0; + let x = (y = 0); let res = []; for (let i = 0; i < nPoints; i++) { - let dx = 0, dy = 0; + let dx = 0, + dy = 0; let flag = flags.readUInt8(); let onCurve = !(flag >> 7); flag &= 0x7f; @@ -180,28 +191,26 @@ function decodeTriplet(flags, glyphs, nPoints) { if (flag < 10) { dx = 0; dy = withSign(flag, ((flag & 14) << 7) + glyphs.readUInt8()); - } else if (flag < 20) { dx = withSign(flag, (((flag - 10) & 14) << 7) + glyphs.readUInt8()); dy = 0; - } else if (flag < 84) { var b0 = flag - 20; var b1 = glyphs.readUInt8(); dx = withSign(flag, 1 + (b0 & 0x30) + (b1 >> 4)); dy = withSign(flag >> 1, 1 + ((b0 & 0x0c) << 2) + (b1 & 0x0f)); - } else if (flag < 120) { var b0 = flag - 84; dx = withSign(flag, 1 + ((b0 / 12) << 8) + glyphs.readUInt8()); - dy = withSign(flag >> 1, 1 + (((b0 % 12) >> 2) << 8) + glyphs.readUInt8()); - + dy = withSign( + flag >> 1, + 1 + (((b0 % 12) >> 2) << 8) + glyphs.readUInt8(), + ); } else if (flag < 124) { var b1 = glyphs.readUInt8(); let b2 = glyphs.readUInt8(); dx = withSign(flag, (b1 << 4) + (b2 >> 4)); dy = withSign(flag >> 1, ((b2 & 0x0f) << 8) + glyphs.readUInt8()); - } else { dx = withSign(flag, glyphs.readUInt16BE()); dy = withSign(flag >> 1, glyphs.readUInt16BE()); diff --git a/src/WOFFFont.js b/src/WOFFFont.js index 6a2399a1..23982d1b 100644 --- a/src/WOFFFont.js +++ b/src/WOFFFont.js @@ -24,7 +24,10 @@ export default class WOFFFont extends TTFFont { if (table.compLength < table.length) { this.stream.pos += 2; // skip deflate header let outBuffer = new Uint8Array(table.length); - let buf = inflate(this.stream.readBuffer(table.compLength - 2), outBuffer); + let buf = inflate( + this.stream.readBuffer(table.compLength - 2), + outBuffer, + ); return new r.DecodeStream(buf); } else { return this.stream; diff --git a/src/aat/AATFeatureMap.js b/src/aat/AATFeatureMap.js index 2aacffec..d249f4f5 100644 --- a/src/aat/AATFeatureMap.js +++ b/src/aat/AATFeatureMap.js @@ -4,7 +4,7 @@ const features = { allTypographicFeatures: { code: 0, exclusive: false, - allTypeFeatures: 0 + allTypeFeatures: 0, }, ligatures: { code: 1, @@ -19,34 +19,34 @@ const features = { abbrevSquaredLigatures: 14, symbolLigatures: 16, contextualLigatures: 18, - historicalLigatures: 20 + historicalLigatures: 20, }, cursiveConnection: { code: 2, exclusive: true, unconnected: 0, partiallyConnected: 1, - cursive: 2 + cursive: 2, }, letterCase: { code: 3, - exclusive: true - }, - // upperAndLowerCase: 0 # deprecated - // allCaps: 1 # deprecated - // allLowerCase: 2 # deprecated - // smallCaps: 3 # deprecated - // initialCaps: 4 # deprecated - // initialCapsAndSmallCaps: 5 # deprecated + exclusive: true, + }, + // upperAndLowerCase: 0 # deprecated + // allCaps: 1 # deprecated + // allLowerCase: 2 # deprecated + // smallCaps: 3 # deprecated + // initialCaps: 4 # deprecated + // initialCapsAndSmallCaps: 5 # deprecated verticalSubstitution: { code: 4, exclusive: false, - substituteVerticalForms: 0 + substituteVerticalForms: 0, }, linguisticRearrangement: { code: 5, exclusive: false, - linguisticRearrangement: 0 + linguisticRearrangement: 0, }, numberSpacing: { code: 6, @@ -54,7 +54,7 @@ const features = { monospacedNumbers: 0, proportionalNumbers: 1, thirdWidthNumbers: 2, - quarterWidthNumbers: 3 + quarterWidthNumbers: 3, }, smartSwash: { code: 8, @@ -63,14 +63,14 @@ const features = { wordFinalSwashes: 2, // lineInitialSwashes: 4 // lineFinalSwashes: 6 - nonFinalSwashes: 8 + nonFinalSwashes: 8, }, diacritics: { code: 9, exclusive: true, showDiacritics: 0, hideDiacritics: 1, - decomposeDiacritics: 2 + decomposeDiacritics: 2, }, verticalPosition: { code: 10, @@ -79,30 +79,30 @@ const features = { superiors: 1, inferiors: 2, ordinals: 3, - scientificInferiors: 4 + scientificInferiors: 4, }, fractions: { code: 11, exclusive: true, noFractions: 0, verticalFractions: 1, - diagonalFractions: 2 + diagonalFractions: 2, }, overlappingCharacters: { code: 13, exclusive: false, - preventOverlap: 0 + preventOverlap: 0, }, typographicExtras: { code: 14, exclusive: false, // hyphensToEmDash: 0 // hyphenToEnDash: 2 - slashedZero: 4 + slashedZero: 4, }, - // formInterrobang: 6 - // smartQuotes: 8 - // periodsToEllipsis: 10 + // formInterrobang: 6 + // smartQuotes: 8 + // periodsToEllipsis: 10 mathematicalExtras: { code: 15, exclusive: false, @@ -111,7 +111,7 @@ const features = { // slashToDivide: 4 // inequalityLigatures: 6 // exponents: 8 - mathematicalGreek: 10 + mathematicalGreek: 10, }, ornamentSets: { code: 16, @@ -122,14 +122,14 @@ const features = { fleurons: 3, decorativeBorders: 4, internationalSymbols: 5, - mathSymbols: 6 + mathSymbols: 6, }, characterAlternatives: { code: 17, exclusive: true, - noAlternates: 0 + noAlternates: 0, }, - // user defined options + // user defined options designComplexity: { code: 18, exclusive: true, @@ -137,7 +137,7 @@ const features = { designLevel2: 1, designLevel3: 2, designLevel4: 3, - designLevel5: 4 + designLevel5: 4, }, styleOptions: { code: 19, @@ -147,7 +147,7 @@ const features = { engravedText: 2, illuminatedCaps: 3, titlingCaps: 4, - tallCaps: 5 + tallCaps: 5, }, characterShape: { code: 20, @@ -166,13 +166,13 @@ const features = { JIS2004Characters: 11, hojoCharacters: 12, NLCCharacters: 13, - traditionalNamesCharacters: 14 + traditionalNamesCharacters: 14, }, numberCase: { code: 21, exclusive: true, lowerCaseNumbers: 0, - upperCaseNumbers: 1 + upperCaseNumbers: 1, }, textSpacing: { code: 22, @@ -183,22 +183,22 @@ const features = { thirdWidthText: 3, quarterWidthText: 4, altProportionalText: 5, - altHalfWidthText: 6 + altHalfWidthText: 6, }, transliteration: { code: 23, exclusive: true, - noTransliteration: 0 - }, - // hanjaToHangul: 1 - // hiraganaToKatakana: 2 - // katakanaToHiragana: 3 - // kanaToRomanization: 4 - // romanizationToHiragana: 5 - // romanizationToKatakana: 6 - // hanjaToHangulAltOne: 7 - // hanjaToHangulAltTwo: 8 - // hanjaToHangulAltThree: 9 + noTransliteration: 0, + }, + // hanjaToHangul: 1 + // hiraganaToKatakana: 2 + // katakanaToHiragana: 3 + // kanaToRomanization: 4 + // romanizationToHiragana: 5 + // romanizationToKatakana: 6 + // hanjaToHangulAltOne: 7 + // hanjaToHangulAltTwo: 8 + // hanjaToHangulAltThree: 9 annotation: { code: 24, exclusive: true, @@ -212,34 +212,34 @@ const features = { romanNumeralAnnotation: 7, diamondAnnotation: 8, invertedBoxAnnotation: 9, - invertedRoundedBoxAnnotation: 10 + invertedRoundedBoxAnnotation: 10, }, kanaSpacing: { code: 25, exclusive: true, fullWidthKana: 0, - proportionalKana: 1 + proportionalKana: 1, }, ideographicSpacing: { code: 26, exclusive: true, fullWidthIdeographs: 0, proportionalIdeographs: 1, - halfWidthIdeographs: 2 + halfWidthIdeographs: 2, }, unicodeDecomposition: { code: 27, exclusive: false, canonicalComposition: 0, compatibilityComposition: 2, - transcodingComposition: 4 + transcodingComposition: 4, }, rubyKana: { code: 28, exclusive: false, // noRubyKana: 0 # deprecated - use rubyKanaOff instead // rubyKana: 1 # deprecated - use rubyKanaOn instead - rubyKana: 2 + rubyKana: 2, }, CJKSymbolAlternatives: { code: 29, @@ -249,7 +249,7 @@ const features = { CJKSymbolAltTwo: 2, CJKSymbolAltThree: 3, CJKSymbolAltFour: 4, - CJKSymbolAltFive: 5 + CJKSymbolAltFive: 5, }, ideographicAlternatives: { code: 30, @@ -259,32 +259,32 @@ const features = { ideographicAltTwo: 2, ideographicAltThree: 3, ideographicAltFour: 4, - ideographicAltFive: 5 + ideographicAltFive: 5, }, CJKVerticalRomanPlacement: { code: 31, exclusive: true, CJKVerticalRomanCentered: 0, - CJKVerticalRomanHBaseline: 1 + CJKVerticalRomanHBaseline: 1, }, italicCJKRoman: { code: 32, exclusive: false, // noCJKItalicRoman: 0 # deprecated - use CJKItalicRomanOff instead // CJKItalicRoman: 1 # deprecated - use CJKItalicRomanOn instead - CJKItalicRoman: 2 + CJKItalicRoman: 2, }, caseSensitiveLayout: { code: 33, exclusive: false, caseSensitiveLayout: 0, - caseSensitiveSpacing: 2 + caseSensitiveSpacing: 2, }, alternateKana: { code: 34, exclusive: false, alternateHorizKana: 0, - alternateVertKana: 2 + alternateVertKana: 2, }, stylisticAlternatives: { code: 35, @@ -309,32 +309,33 @@ const features = { stylisticAltSeventeen: 34, stylisticAltEighteen: 36, stylisticAltNineteen: 38, - stylisticAltTwenty: 40 + stylisticAltTwenty: 40, }, contextualAlternates: { code: 36, exclusive: false, contextualAlternates: 0, swashAlternates: 2, - contextualSwashAlternates: 4 + contextualSwashAlternates: 4, }, lowerCase: { code: 37, exclusive: true, defaultLowerCase: 0, lowerCaseSmallCaps: 1, - lowerCasePetiteCaps: 2 + lowerCasePetiteCaps: 2, }, upperCase: { code: 38, exclusive: true, defaultUpperCase: 0, upperCaseSmallCaps: 1, - upperCasePetiteCaps: 2 + upperCasePetiteCaps: 2, }, - languageTag: { // indices into ltag table + languageTag: { + // indices into ltag table code: 39, - exclusive: true + exclusive: true, }, CJKRomanSpacing: { code: 103, @@ -342,11 +343,14 @@ const features = { halfWidthCJKRoman: 0, proportionalCJKRoman: 1, defaultCJKRoman: 2, - fullWidthCJKRoman: 3 - } + fullWidthCJKRoman: 3, + }, }; -const feature = (name, selector) => [features[name].code, features[name][selector]]; +const feature = (name, selector) => [ + features[name].code, + features[name][selector], +]; const OTMapping = { rlig: feature('ligatures', 'requiredLigatures'), @@ -453,14 +457,17 @@ const OTMapping = { ss17: feature('stylisticAlternatives', 'stylisticAltSeventeen'), ss18: feature('stylisticAlternatives', 'stylisticAltEighteen'), ss19: feature('stylisticAlternatives', 'stylisticAltNineteen'), - ss20: feature('stylisticAlternatives', 'stylisticAltTwenty') + ss20: feature('stylisticAlternatives', 'stylisticAltTwenty'), }; - // salt: feature 'stylisticAlternatives', 'stylisticAltOne' # hmm, which one to choose +// salt: feature 'stylisticAlternatives', 'stylisticAltOne' # hmm, which one to choose // Add cv01-cv99 features for (let i = 1; i <= 99; i++) { - OTMapping[`cv${`00${i}`.slice(-2)}`] = [features.characterAlternatives.code, i]; + OTMapping[`cv${`00${i}`.slice(-2)}`] = [ + features.characterAlternatives.code, + i, + ]; } // create inverse mapping @@ -480,7 +487,7 @@ export function mapOTToAAT(features) { let res = {}; for (let k in features) { let r; - if (r = OTMapping[k]) { + if ((r = OTMapping[k])) { if (res[r[0]] == null) { res[r[0]] = {}; } @@ -521,18 +528,20 @@ export function mapAATToOT(features) { for (let k = 0; k < features.length; k++) { let r; let f = mapFeatureStrings(features[k]); - if (r = AATMapping[f[0]] && AATMapping[f[0]][f[1]]) { + if ((r = AATMapping[f[0]] && AATMapping[f[0]][f[1]])) { res[r] = true; } } - } else if (typeof features === 'object') { for (let type in features) { let feature = features[type]; for (let setting in feature) { let r; let f = mapFeatureStrings([type, setting]); - if (feature[setting] && (r = AATMapping[f[0]] && AATMapping[f[0]][f[1]])) { + if ( + feature[setting] && + (r = AATMapping[f[0]] && AATMapping[f[0]][f[1]]) + ) { res[r] = true; } } diff --git a/src/aat/AATLayoutEngine.js b/src/aat/AATLayoutEngine.js index 1097e4a1..28cdaf75 100644 --- a/src/aat/AATLayoutEngine.js +++ b/src/aat/AATLayoutEngine.js @@ -16,7 +16,10 @@ export default class AATLayoutEngine { glyphRun.glyphs.reverse(); } - this.morxProcessor.process(glyphRun.glyphs, AATFeatureMap.mapOTToAAT(glyphRun.features)); + this.morxProcessor.process( + glyphRun.glyphs, + AATFeatureMap.mapOTToAAT(glyphRun.features), + ); } getAvailableFeatures(script, language) { @@ -25,7 +28,7 @@ export default class AATLayoutEngine { stringsForGlyph(gid) { let glyphStrings = this.morxProcessor.generateInputs(gid); - let result = new Set; + let result = new Set(); for (let glyphs of glyphStrings) { this._addStrings(glyphs, 0, result, ''); diff --git a/src/aat/AATLookupTable.js b/src/aat/AATLookupTable.js index 62ae190c..aa5f24c5 100644 --- a/src/aat/AATLookupTable.js +++ b/src/aat/AATLookupTable.js @@ -1,5 +1,5 @@ -import {cache} from '../cache'; -import {range} from '../utils'; +import { cache } from '../cache'; +import { range } from '../utils'; export default class AATLookupTable { constructor(table) { @@ -41,7 +41,8 @@ export default class AATLookupTable { return null; } - case 6: { // lookup single + case 6: { + // lookup single let min = 0; let max = this.table.binarySearchHeader.nUnits - 1; @@ -81,7 +82,7 @@ export default class AATLookupTable { case 2: // segment format case 4: { for (let segment of this.table.segments) { - if ((this.table.version === 2 && segment.value === classValue)) { + if (this.table.version === 2 && segment.value === classValue) { res.push(...range(segment.firstGlyph, segment.lastGlyph + 1)); } else { for (let index = 0; index < segment.values.length; index++) { @@ -95,7 +96,8 @@ export default class AATLookupTable { break; } - case 6: { // lookup single + case 6: { + // lookup single for (let segment of this.table.segments) { if (segment.value === classValue) { res.push(segment.glyph); @@ -105,7 +107,8 @@ export default class AATLookupTable { break; } - case 8: { // lookup trimmed + case 8: { + // lookup trimmed for (let i = 0; i < this.table.values.length; i++) { if (this.table.values[i] === classValue) { res.push(this.table.firstGlyph + i); @@ -124,5 +127,5 @@ export default class AATLookupTable { } cache(AATLookupTable, { - glyphsForValue: 'key' + glyphsForValue: 'key', }); diff --git a/src/aat/AATMorxProcessor.js b/src/aat/AATMorxProcessor.js index 2acf98c1..3db9f9fd 100644 --- a/src/aat/AATMorxProcessor.js +++ b/src/aat/AATMorxProcessor.js @@ -1,42 +1,44 @@ import AATStateMachine from './AATStateMachine'; import AATLookupTable from './AATLookupTable'; -import {cache} from '../cache'; +import { cache } from '../cache'; // indic replacement flags const MARK_FIRST = 0x8000; -const MARK_LAST = 0x2000; -const VERB = 0x000F; +const MARK_LAST = 0x2000; +const VERB = 0x000f; // contextual substitution and glyph insertion flag const SET_MARK = 0x8000; // ligature entry flags -const SET_COMPONENT = 0x8000; +const SET_COMPONENT = 0x8000; const PERFORM_ACTION = 0x2000; // ligature action masks -const LAST_MASK = 0x80000000; -const STORE_MASK = 0x40000000; -const OFFSET_MASK = 0x3FFFFFFF; +const LAST_MASK = 0x80000000; +const STORE_MASK = 0x40000000; +const OFFSET_MASK = 0x3fffffff; -const VERTICAL_ONLY = 0x800000; -const REVERSE_DIRECTION = 0x400000; +const VERTICAL_ONLY = 0x800000; +const REVERSE_DIRECTION = 0x400000; const HORIZONTAL_AND_VERTICAL = 0x200000; // glyph insertion flags const CURRENT_IS_KASHIDA_LIKE = 0x2000; -const MARKED_IS_KASHIDA_LIKE = 0x1000; -const CURRENT_INSERT_BEFORE = 0x0800; -const MARKED_INSERT_BEFORE = 0x0400; -const CURRENT_INSERT_COUNT = 0x03E0; -const MARKED_INSERT_COUNT = 0x001F; +const MARKED_IS_KASHIDA_LIKE = 0x1000; +const CURRENT_INSERT_BEFORE = 0x0800; +const MARKED_INSERT_BEFORE = 0x0400; +const CURRENT_INSERT_COUNT = 0x03e0; +const MARKED_INSERT_COUNT = 0x001f; export default class AATMorxProcessor { constructor(font) { this.processIndicRearragement = this.processIndicRearragement.bind(this); - this.processContextualSubstitution = this.processContextualSubstitution.bind(this); + this.processContextualSubstitution = + this.processContextualSubstitution.bind(this); this.processLigature = this.processLigature.bind(this); - this.processNoncontextualSubstitutions = this.processNoncontextualSubstitutions.bind(this); + this.processNoncontextualSubstitutions = + this.processNoncontextualSubstitutions.bind(this); this.processGlyphInsertion = this.processGlyphInsertion.bind(this); this.font = font; this.morx = font.morx; @@ -52,7 +54,7 @@ export default class AATMorxProcessor { // enable/disable the requested features for (let feature of chain.features) { let f; - if (f = features[feature.featureType]) { + if ((f = features[feature.featureType])) { if (f[feature.featureSetting]) { flags &= feature.disableFlags; flags |= feature.enableFlags; @@ -134,7 +136,12 @@ export default class AATMorxProcessor { this.lastGlyph = index; } - reorderGlyphs(this.glyphs, entry.flags & VERB, this.firstGlyph, this.lastGlyph); + reorderGlyphs( + this.glyphs, + entry.flags & VERB, + this.firstGlyph, + this.lastGlyph, + ); } processContextualSubstitution(glyph, entry, index) { @@ -145,7 +152,10 @@ export default class AATMorxProcessor { glyph = this.glyphs[this.markedGlyph]; var gid = lookupTable.lookup(glyph.id); if (gid) { - this.glyphs[this.markedGlyph] = this.font.getGlyph(gid, glyph.codePoints); + this.glyphs[this.markedGlyph] = this.font.getGlyph( + gid, + glyph.codePoints, + ); } } @@ -187,7 +197,7 @@ export default class AATMorxProcessor { let action = actions.getItem(actionIndex++); last = !!(action & LAST_MASK); let store = !!(action & STORE_MASK); - let offset = (action & OFFSET_MASK) << 2 >> 2; // sign extend 30 to 32 bits + let offset = ((action & OFFSET_MASK) << 2) >> 2; // sign extend 30 to 32 bits offset += this.glyphs[componentGlyph].id; let component = components.getItem(offset); @@ -195,7 +205,10 @@ export default class AATMorxProcessor { if (last || store) { let ligatureEntry = ligatureList.getItem(ligatureIndex); - this.glyphs[componentGlyph] = this.font.getGlyph(ligatureEntry, codePoints); + this.glyphs[componentGlyph] = this.font.getGlyph( + ligatureEntry, + codePoints, + ); ligatureGlyphs.push(componentGlyph); ligatureIndex = 0; codePoints = []; @@ -216,7 +229,8 @@ export default class AATMorxProcessor { let glyph = glyphs[index]; if (glyph.id !== 0xffff) { let gid = lookupTable.lookup(glyph.id); - if (gid) { // 0 means do nothing + if (gid) { + // 0 means do nothing glyphs[index] = this.font.getGlyph(gid, glyph.codePoints); } } @@ -226,7 +240,9 @@ export default class AATMorxProcessor { _insertGlyphs(glyphIndex, insertionActionIndex, count, isBefore) { let insertions = []; while (count--) { - let gid = this.subtable.table.insertionActions.getItem(insertionActionIndex++); + let gid = this.subtable.table.insertionActions.getItem( + insertionActionIndex++, + ); insertions.push(this.font.getGlyph(gid)); } @@ -245,7 +261,12 @@ export default class AATMorxProcessor { if (entry.markedInsertIndex !== 0xffff) { let count = (entry.flags & MARKED_INSERT_COUNT) >>> 5; let isBefore = !!(entry.flags & MARKED_INSERT_BEFORE); - this._insertGlyphs(this.markedIndex, entry.markedInsertIndex, count, isBefore); + this._insertGlyphs( + this.markedIndex, + entry.markedInsertIndex, + count, + isBefore, + ); } if (entry.currentInsertIndex !== 0xffff) { @@ -314,7 +335,7 @@ export default class AATMorxProcessor { let glyphs = this.glyphs; stack.push({ glyphs: glyphs.slice(), - ligatureStack: this.ligatureStack.slice() + ligatureStack: this.ligatureStack.slice(), }); // Add glyph to input and glyphs to process. @@ -336,7 +357,7 @@ export default class AATMorxProcessor { } if (count === 1) { - let result = input.map(g => g.id); + let result = input.map((g) => g.id); let cache = this.inputCache[found]; if (cache) { cache.push(result); @@ -347,15 +368,16 @@ export default class AATMorxProcessor { }, exit: () => { - ({glyphs: this.glyphs, ligatureStack: this.ligatureStack} = stack.pop()); + ({ glyphs: this.glyphs, ligatureStack: this.ligatureStack } = + stack.pop()); input.pop(); - } + }, }); } } cache(AATMorxProcessor, { - getStateMachine: 'key' + getStateMachine: 'key', }); // swaps the glyphs in rangeA with those in rangeB diff --git a/src/aat/AATStateMachine.js b/src/aat/AATStateMachine.js index 77d31ef0..ba81a28a 100644 --- a/src/aat/AATStateMachine.js +++ b/src/aat/AATStateMachine.js @@ -21,7 +21,10 @@ export default class AATStateMachine { let index = reverse ? glyphs.length - 1 : 0; let dir = reverse ? -1 : 1; - while ((dir === 1 && index <= glyphs.length) || (dir === -1 && index >= -1)) { + while ( + (dir === 1 && index <= glyphs.length) || + (dir === -1 && index >= -1) + ) { let glyph = null; let classCode = OUT_OF_BOUNDS_CLASS; let shouldAdvance = true; @@ -30,7 +33,8 @@ export default class AATStateMachine { classCode = END_OF_TEXT_CLASS; } else { glyph = glyphs[index]; - if (glyph.id === 0xffff) { // deleted glyph + if (glyph.id === 0xffff) { + // deleted glyph classCode = DELETED_GLYPH_CLASS; } else { classCode = this.lookupTable.lookup(glyph.id); @@ -44,7 +48,10 @@ export default class AATStateMachine { let entryIndex = row[classCode]; let entry = this.stateTable.entryTable.getItem(entryIndex); - if (classCode !== END_OF_TEXT_CLASS && classCode !== DELETED_GLYPH_CLASS) { + if ( + classCode !== END_OF_TEXT_CLASS && + classCode !== DELETED_GLYPH_CLASS + ) { processEntry(glyph, entry, index); shouldAdvance = !(entry.flags & DONT_ADVANCE); } @@ -62,14 +69,14 @@ export default class AATStateMachine { * Performs a depth-first traversal of the glyph strings * represented by the state machine. */ - traverse(opts, state = 0, visited = new Set) { + traverse(opts, state = 0, visited = new Set()) { if (visited.has(state)) { return; } visited.add(state); - let {nClasses, stateArray, entryTable} = this.stateTable; + let { nClasses, stateArray, entryTable } = this.stateTable; let row = stateArray.getItem(state); // Skip predefined classes diff --git a/src/base.js b/src/base.js index 1f9d40b8..f14e2cd2 100644 --- a/src/base.js +++ b/src/base.js @@ -1,11 +1,11 @@ -import {DecodeStream} from 'restructure'; +import { DecodeStream } from 'restructure'; export let logErrors = false; let formats = []; export function registerFormat(format) { formats.push(format); -}; +} export function create(buffer, postscriptName) { for (let i = 0; i < formats.length; i++) { @@ -21,9 +21,9 @@ export function create(buffer, postscriptName) { } throw new Error('Unknown font format'); -}; +} export let defaultLanguage = 'en'; export function setDefaultLanguage(lang = 'en') { defaultLanguage = lang; -}; +} diff --git a/src/cache.js b/src/cache.js index 338f61f6..b02a10ef 100644 --- a/src/cache.js +++ b/src/cache.js @@ -11,8 +11,13 @@ export function cache(Class, members) { throw new TypeError(`Unknown cache mode for ${key}: ${mode}`); } - if (!descriptor || (!descriptor.get && typeof descriptor.value !== 'function')) { - throw new TypeError(`Cannot cache ${key}: expected an own getter or method`); + if ( + !descriptor || + (!descriptor.get && typeof descriptor.value !== 'function') + ) { + throw new TypeError( + `Cannot cache ${key}: expected an own getter or method`, + ); } if (descriptor.get) { @@ -21,7 +26,7 @@ export function cache(Class, members) { } let get = descriptor.get; - descriptor.get = function() { + descriptor.get = function () { let value = get.call(this); Object.defineProperty(this, key, { value }); return value; @@ -36,7 +41,7 @@ export function cache(Class, members) { if (mode === 'once') { let computed = false; let value; - memoized = function() { + memoized = function () { if (!computed) { value = fn.call(this); computed = true; @@ -46,7 +51,7 @@ export function cache(Class, members) { }; } else { let values = new Map(); - memoized = function(arg) { + memoized = function (arg) { let value = values.get(arg); if (value !== undefined || values.has(arg)) { return value; @@ -60,7 +65,7 @@ export function cache(Class, members) { Object.defineProperty(this, key, { value: memoized }); return memoized; - } + }, }; } diff --git a/src/cff/CFFCharsets.js b/src/cff/CFFCharsets.js index b7a98741..cca7108c 100644 --- a/src/cff/CFFCharsets.js +++ b/src/cff/CFFCharsets.js @@ -1,99 +1,490 @@ export let ISOAdobeCharset = [ - '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', - 'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright', - 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', - 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', - 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', - 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', - 'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', - 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', - 'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft', - 'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl', - 'periodcentered', 'paragraph', 'bullet', 'quotesinglbase', - 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', - 'perthousand', 'questiondown', 'grave', 'acute', 'circumflex', 'tilde', - 'macron', 'breve', 'dotaccent', 'dieresis', 'ring', 'cedilla', - 'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine', - 'Lslash', 'Oslash', 'OE', 'ordmasculine', 'ae', 'dotlessi', 'lslash', - 'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu', - 'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter', - 'divide', 'brokenbar', 'degree', 'thorn', 'threequarters', 'twosuperior', - 'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright', - 'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde', - 'Ccedilla', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', 'Iacute', - 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex', - 'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex', - 'Udieresis', 'Ugrave', 'Yacute', 'Ydieresis', 'Zcaron', 'aacute', - 'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', 'ccedilla', - 'eacute', 'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex', - 'idieresis', 'igrave', 'ntilde', 'oacute', 'ocircumflex', 'odieresis', - 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', - 'ugrave', 'yacute', 'ydieresis', 'zcaron' + '.notdef', + 'space', + 'exclam', + 'quotedbl', + 'numbersign', + 'dollar', + 'percent', + 'ampersand', + 'quoteright', + 'parenleft', + 'parenright', + 'asterisk', + 'plus', + 'comma', + 'hyphen', + 'period', + 'slash', + 'zero', + 'one', + 'two', + 'three', + 'four', + 'five', + 'six', + 'seven', + 'eight', + 'nine', + 'colon', + 'semicolon', + 'less', + 'equal', + 'greater', + 'question', + 'at', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'bracketleft', + 'backslash', + 'bracketright', + 'asciicircum', + 'underscore', + 'quoteleft', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + 'braceleft', + 'bar', + 'braceright', + 'asciitilde', + 'exclamdown', + 'cent', + 'sterling', + 'fraction', + 'yen', + 'florin', + 'section', + 'currency', + 'quotesingle', + 'quotedblleft', + 'guillemotleft', + 'guilsinglleft', + 'guilsinglright', + 'fi', + 'fl', + 'endash', + 'dagger', + 'daggerdbl', + 'periodcentered', + 'paragraph', + 'bullet', + 'quotesinglbase', + 'quotedblbase', + 'quotedblright', + 'guillemotright', + 'ellipsis', + 'perthousand', + 'questiondown', + 'grave', + 'acute', + 'circumflex', + 'tilde', + 'macron', + 'breve', + 'dotaccent', + 'dieresis', + 'ring', + 'cedilla', + 'hungarumlaut', + 'ogonek', + 'caron', + 'emdash', + 'AE', + 'ordfeminine', + 'Lslash', + 'Oslash', + 'OE', + 'ordmasculine', + 'ae', + 'dotlessi', + 'lslash', + 'oslash', + 'oe', + 'germandbls', + 'onesuperior', + 'logicalnot', + 'mu', + 'trademark', + 'Eth', + 'onehalf', + 'plusminus', + 'Thorn', + 'onequarter', + 'divide', + 'brokenbar', + 'degree', + 'thorn', + 'threequarters', + 'twosuperior', + 'registered', + 'minus', + 'eth', + 'multiply', + 'threesuperior', + 'copyright', + 'Aacute', + 'Acircumflex', + 'Adieresis', + 'Agrave', + 'Aring', + 'Atilde', + 'Ccedilla', + 'Eacute', + 'Ecircumflex', + 'Edieresis', + 'Egrave', + 'Iacute', + 'Icircumflex', + 'Idieresis', + 'Igrave', + 'Ntilde', + 'Oacute', + 'Ocircumflex', + 'Odieresis', + 'Ograve', + 'Otilde', + 'Scaron', + 'Uacute', + 'Ucircumflex', + 'Udieresis', + 'Ugrave', + 'Yacute', + 'Ydieresis', + 'Zcaron', + 'aacute', + 'acircumflex', + 'adieresis', + 'agrave', + 'aring', + 'atilde', + 'ccedilla', + 'eacute', + 'ecircumflex', + 'edieresis', + 'egrave', + 'iacute', + 'icircumflex', + 'idieresis', + 'igrave', + 'ntilde', + 'oacute', + 'ocircumflex', + 'odieresis', + 'ograve', + 'otilde', + 'scaron', + 'uacute', + 'ucircumflex', + 'udieresis', + 'ugrave', + 'yacute', + 'ydieresis', + 'zcaron', ]; export let ExpertCharset = [ - '.notdef', 'space', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', - 'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', - 'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma', - 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', - 'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', - 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', - 'colon', 'semicolon', 'commasuperior', 'threequartersemdash', - 'periodsuperior', 'questionsmall', 'asuperior', 'bsuperior', - 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', - 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', - 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', - 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', - 'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', - 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', - 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', - 'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', - 'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall', 'centoldstyle', - 'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', - 'Brevesmall', 'Caronsmall', 'Dotaccentsmall', 'Macronsmall', - 'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall', - 'Cedillasmall', 'onequarter', 'onehalf', 'threequarters', - 'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', - 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', - 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', - 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', - 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', - 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', - 'periodinferior', 'commainferior', 'Agravesmall', 'Aacutesmall', - 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall', - 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall', - 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall', - 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', - 'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall', - 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall', - 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', - 'Ydieresissmall' + '.notdef', + 'space', + 'exclamsmall', + 'Hungarumlautsmall', + 'dollaroldstyle', + 'dollarsuperior', + 'ampersandsmall', + 'Acutesmall', + 'parenleftsuperior', + 'parenrightsuperior', + 'twodotenleader', + 'onedotenleader', + 'comma', + 'hyphen', + 'period', + 'fraction', + 'zerooldstyle', + 'oneoldstyle', + 'twooldstyle', + 'threeoldstyle', + 'fouroldstyle', + 'fiveoldstyle', + 'sixoldstyle', + 'sevenoldstyle', + 'eightoldstyle', + 'nineoldstyle', + 'colon', + 'semicolon', + 'commasuperior', + 'threequartersemdash', + 'periodsuperior', + 'questionsmall', + 'asuperior', + 'bsuperior', + 'centsuperior', + 'dsuperior', + 'esuperior', + 'isuperior', + 'lsuperior', + 'msuperior', + 'nsuperior', + 'osuperior', + 'rsuperior', + 'ssuperior', + 'tsuperior', + 'ff', + 'fi', + 'fl', + 'ffi', + 'ffl', + 'parenleftinferior', + 'parenrightinferior', + 'Circumflexsmall', + 'hyphensuperior', + 'Gravesmall', + 'Asmall', + 'Bsmall', + 'Csmall', + 'Dsmall', + 'Esmall', + 'Fsmall', + 'Gsmall', + 'Hsmall', + 'Ismall', + 'Jsmall', + 'Ksmall', + 'Lsmall', + 'Msmall', + 'Nsmall', + 'Osmall', + 'Psmall', + 'Qsmall', + 'Rsmall', + 'Ssmall', + 'Tsmall', + 'Usmall', + 'Vsmall', + 'Wsmall', + 'Xsmall', + 'Ysmall', + 'Zsmall', + 'colonmonetary', + 'onefitted', + 'rupiah', + 'Tildesmall', + 'exclamdownsmall', + 'centoldstyle', + 'Lslashsmall', + 'Scaronsmall', + 'Zcaronsmall', + 'Dieresissmall', + 'Brevesmall', + 'Caronsmall', + 'Dotaccentsmall', + 'Macronsmall', + 'figuredash', + 'hypheninferior', + 'Ogoneksmall', + 'Ringsmall', + 'Cedillasmall', + 'onequarter', + 'onehalf', + 'threequarters', + 'questiondownsmall', + 'oneeighth', + 'threeeighths', + 'fiveeighths', + 'seveneighths', + 'onethird', + 'twothirds', + 'zerosuperior', + 'onesuperior', + 'twosuperior', + 'threesuperior', + 'foursuperior', + 'fivesuperior', + 'sixsuperior', + 'sevensuperior', + 'eightsuperior', + 'ninesuperior', + 'zeroinferior', + 'oneinferior', + 'twoinferior', + 'threeinferior', + 'fourinferior', + 'fiveinferior', + 'sixinferior', + 'seveninferior', + 'eightinferior', + 'nineinferior', + 'centinferior', + 'dollarinferior', + 'periodinferior', + 'commainferior', + 'Agravesmall', + 'Aacutesmall', + 'Acircumflexsmall', + 'Atildesmall', + 'Adieresissmall', + 'Aringsmall', + 'AEsmall', + 'Ccedillasmall', + 'Egravesmall', + 'Eacutesmall', + 'Ecircumflexsmall', + 'Edieresissmall', + 'Igravesmall', + 'Iacutesmall', + 'Icircumflexsmall', + 'Idieresissmall', + 'Ethsmall', + 'Ntildesmall', + 'Ogravesmall', + 'Oacutesmall', + 'Ocircumflexsmall', + 'Otildesmall', + 'Odieresissmall', + 'OEsmall', + 'Oslashsmall', + 'Ugravesmall', + 'Uacutesmall', + 'Ucircumflexsmall', + 'Udieresissmall', + 'Yacutesmall', + 'Thornsmall', + 'Ydieresissmall', ]; export let ExpertSubsetCharset = [ - '.notdef', 'space', 'dollaroldstyle', 'dollarsuperior', - 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', - 'onedotenleader', 'comma', 'hyphen', 'period', 'fraction', - 'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle', - 'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', - 'eightoldstyle', 'nineoldstyle', 'colon', 'semicolon', 'commasuperior', - 'threequartersemdash', 'periodsuperior', 'asuperior', 'bsuperior', - 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', - 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', - 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', - 'parenrightinferior', 'hyphensuperior', 'colonmonetary', 'onefitted', - 'rupiah', 'centoldstyle', 'figuredash', 'hypheninferior', 'onequarter', - 'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', - 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', - 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', - 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', - 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', - 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', - 'periodinferior', 'commainferior' + '.notdef', + 'space', + 'dollaroldstyle', + 'dollarsuperior', + 'parenleftsuperior', + 'parenrightsuperior', + 'twodotenleader', + 'onedotenleader', + 'comma', + 'hyphen', + 'period', + 'fraction', + 'zerooldstyle', + 'oneoldstyle', + 'twooldstyle', + 'threeoldstyle', + 'fouroldstyle', + 'fiveoldstyle', + 'sixoldstyle', + 'sevenoldstyle', + 'eightoldstyle', + 'nineoldstyle', + 'colon', + 'semicolon', + 'commasuperior', + 'threequartersemdash', + 'periodsuperior', + 'asuperior', + 'bsuperior', + 'centsuperior', + 'dsuperior', + 'esuperior', + 'isuperior', + 'lsuperior', + 'msuperior', + 'nsuperior', + 'osuperior', + 'rsuperior', + 'ssuperior', + 'tsuperior', + 'ff', + 'fi', + 'fl', + 'ffi', + 'ffl', + 'parenleftinferior', + 'parenrightinferior', + 'hyphensuperior', + 'colonmonetary', + 'onefitted', + 'rupiah', + 'centoldstyle', + 'figuredash', + 'hypheninferior', + 'onequarter', + 'onehalf', + 'threequarters', + 'oneeighth', + 'threeeighths', + 'fiveeighths', + 'seveneighths', + 'onethird', + 'twothirds', + 'zerosuperior', + 'onesuperior', + 'twosuperior', + 'threesuperior', + 'foursuperior', + 'fivesuperior', + 'sixsuperior', + 'sevensuperior', + 'eightsuperior', + 'ninesuperior', + 'zeroinferior', + 'oneinferior', + 'twoinferior', + 'threeinferior', + 'fourinferior', + 'fiveinferior', + 'sixinferior', + 'seveninferior', + 'eightinferior', + 'nineinferior', + 'centinferior', + 'dollarinferior', + 'periodinferior', + 'commainferior', ]; diff --git a/src/cff/CFFDict.js b/src/cff/CFFDict.js index 569c1067..15b6e3e6 100644 --- a/src/cff/CFFDict.js +++ b/src/cff/CFFDict.js @@ -8,14 +8,18 @@ export default class CFFDict { this.ops = ops; this.fields = {}; for (let field of ops) { - let key = Array.isArray(field[0]) ? field[0][0] << 8 | field[0][1] : field[0]; + let key = Array.isArray(field[0]) + ? (field[0][0] << 8) | field[0][1] + : field[0]; this.fields[key] = field; } } decodeOperands(type, stream, ret, operands) { if (Array.isArray(type)) { - return operands.map((op, i) => this.decodeOperands(type[i], stream, ret, [op])); + return operands.map((op, i) => + this.decodeOperands(type[i], stream, ret, [op]), + ); } else if (type.decode != null) { return type.decode(stream, ret, operands); } else { @@ -34,7 +38,9 @@ export default class CFFDict { encodeOperands(type, stream, ctx, operands) { if (Array.isArray(type)) { - return operands.map((op, i) => this.encodeOperands(type[i], stream, ctx, op)[0]); + return operands.map( + (op, i) => this.encodeOperands(type[i], stream, ctx, op)[0], + ); } else if (type.encode != null) { return type.encode(stream, operands, ctx); } else if (typeof operands === 'number') { @@ -55,8 +61,8 @@ export default class CFFDict { // define hidden properties Object.defineProperties(ret, { - parent: { value: parent }, - _startOffset: { value: stream.pos } + parent: { value: parent }, + _startOffset: { value: stream.pos }, }); // fill in defaults @@ -100,7 +106,7 @@ export default class CFFDict { parent, val: dict, pointerSize: 0, - startOffset: parent.startOffset || 0 + startOffset: parent.startOffset || 0, }; let len = 0; @@ -134,7 +140,7 @@ export default class CFFDict { startOffset: stream.pos, parent, val: dict, - pointerSize: 0 + pointerSize: 0, }; ctx.pointerOffset = stream.pos + this.size(dict, ctx, false); diff --git a/src/cff/CFFEncodings.js b/src/cff/CFFEncodings.js index 5465bb4f..0f035cd2 100644 --- a/src/cff/CFFEncodings.js +++ b/src/cff/CFFEncodings.js @@ -1,48 +1,512 @@ export let StandardEncoding = [ - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'quoteright', - 'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', - 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', - 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', - 'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'exclamdown', 'cent', 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', 'quotesingle', - 'quotedblleft', 'guillemotleft', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', '', 'endash', 'dagger', - 'daggerdbl', 'periodcentered', '', 'paragraph', 'bullet', 'quotesinglbase', 'quotedblbase', 'quotedblright', - 'guillemotright', 'ellipsis', 'perthousand', '', 'questiondown', '', 'grave', 'acute', 'circumflex', 'tilde', - 'macron', 'breve', 'dotaccent', 'dieresis', '', 'ring', 'cedilla', '', 'hungarumlaut', 'ogonek', 'caron', - 'emdash', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'AE', '', 'ordfeminine', '', '', '', - '', 'Lslash', 'Oslash', 'OE', 'ordmasculine', '', '', '', '', '', 'ae', '', '', '', 'dotlessi', '', '', - 'lslash', 'oslash', 'oe', 'germandbls' + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + 'space', + 'exclam', + 'quotedbl', + 'numbersign', + 'dollar', + 'percent', + 'ampersand', + 'quoteright', + 'parenleft', + 'parenright', + 'asterisk', + 'plus', + 'comma', + 'hyphen', + 'period', + 'slash', + 'zero', + 'one', + 'two', + 'three', + 'four', + 'five', + 'six', + 'seven', + 'eight', + 'nine', + 'colon', + 'semicolon', + 'less', + 'equal', + 'greater', + 'question', + 'at', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'bracketleft', + 'backslash', + 'bracketright', + 'asciicircum', + 'underscore', + 'quoteleft', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + 'braceleft', + 'bar', + 'braceright', + 'asciitilde', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + 'exclamdown', + 'cent', + 'sterling', + 'fraction', + 'yen', + 'florin', + 'section', + 'currency', + 'quotesingle', + 'quotedblleft', + 'guillemotleft', + 'guilsinglleft', + 'guilsinglright', + 'fi', + 'fl', + '', + 'endash', + 'dagger', + 'daggerdbl', + 'periodcentered', + '', + 'paragraph', + 'bullet', + 'quotesinglbase', + 'quotedblbase', + 'quotedblright', + 'guillemotright', + 'ellipsis', + 'perthousand', + '', + 'questiondown', + '', + 'grave', + 'acute', + 'circumflex', + 'tilde', + 'macron', + 'breve', + 'dotaccent', + 'dieresis', + '', + 'ring', + 'cedilla', + '', + 'hungarumlaut', + 'ogonek', + 'caron', + 'emdash', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + 'AE', + '', + 'ordfeminine', + '', + '', + '', + '', + 'Lslash', + 'Oslash', + 'OE', + 'ordmasculine', + '', + '', + '', + '', + '', + 'ae', + '', + '', + '', + 'dotlessi', + '', + '', + 'lslash', + 'oslash', + 'oe', + 'germandbls', ]; export let ExpertEncoding = [ - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', 'space', 'exclamsmall', 'Hungarumlautsmall', '', 'dollaroldstyle', 'dollarsuperior', - 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', 'onedotenleader', - 'comma', 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle', - 'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'colon', - 'semicolon', 'commasuperior', 'threequartersemdash', 'periodsuperior', 'questionsmall', '', 'asuperior', - 'bsuperior', 'centsuperior', 'dsuperior', 'esuperior', '', '', 'isuperior', '', '', 'lsuperior', 'msuperior', - 'nsuperior', 'osuperior', '', '', 'rsuperior', 'ssuperior', 'tsuperior', '', 'ff', 'fi', 'fl', 'ffi', 'ffl', - 'parenleftinferior', '', 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', 'Asmall', - 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', - 'Msmall', 'Nsmall', 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall', - 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah', 'Tildesmall', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'exclamdownsmall', 'centoldstyle', 'Lslashsmall', '', '', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', - 'Brevesmall', 'Caronsmall', '', 'Dotaccentsmall', '', '', 'Macronsmall', '', '', 'figuredash', 'hypheninferior', - '', '', 'Ogoneksmall', 'Ringsmall', 'Cedillasmall', '', '', '', 'onequarter', 'onehalf', 'threequarters', - 'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', 'seveneighths', 'onethird', 'twothirds', '', - '', 'zerosuperior', 'onesuperior', 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', - 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', 'zeroinferior', 'oneinferior', 'twoinferior', - 'threeinferior', 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', 'eightinferior', - 'nineinferior', 'centinferior', 'dollarinferior', 'periodinferior', 'commainferior', 'Agravesmall', - 'Aacutesmall', 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall', 'AEsmall', 'Ccedillasmall', - 'Egravesmall', 'Eacutesmall', 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall', - 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', 'Ogravesmall', 'Oacutesmall', - 'Ocircumflexsmall', 'Otildesmall', 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall', - 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', 'Ydieresissmall' + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + 'space', + 'exclamsmall', + 'Hungarumlautsmall', + '', + 'dollaroldstyle', + 'dollarsuperior', + 'ampersandsmall', + 'Acutesmall', + 'parenleftsuperior', + 'parenrightsuperior', + 'twodotenleader', + 'onedotenleader', + 'comma', + 'hyphen', + 'period', + 'fraction', + 'zerooldstyle', + 'oneoldstyle', + 'twooldstyle', + 'threeoldstyle', + 'fouroldstyle', + 'fiveoldstyle', + 'sixoldstyle', + 'sevenoldstyle', + 'eightoldstyle', + 'nineoldstyle', + 'colon', + 'semicolon', + 'commasuperior', + 'threequartersemdash', + 'periodsuperior', + 'questionsmall', + '', + 'asuperior', + 'bsuperior', + 'centsuperior', + 'dsuperior', + 'esuperior', + '', + '', + 'isuperior', + '', + '', + 'lsuperior', + 'msuperior', + 'nsuperior', + 'osuperior', + '', + '', + 'rsuperior', + 'ssuperior', + 'tsuperior', + '', + 'ff', + 'fi', + 'fl', + 'ffi', + 'ffl', + 'parenleftinferior', + '', + 'parenrightinferior', + 'Circumflexsmall', + 'hyphensuperior', + 'Gravesmall', + 'Asmall', + 'Bsmall', + 'Csmall', + 'Dsmall', + 'Esmall', + 'Fsmall', + 'Gsmall', + 'Hsmall', + 'Ismall', + 'Jsmall', + 'Ksmall', + 'Lsmall', + 'Msmall', + 'Nsmall', + 'Osmall', + 'Psmall', + 'Qsmall', + 'Rsmall', + 'Ssmall', + 'Tsmall', + 'Usmall', + 'Vsmall', + 'Wsmall', + 'Xsmall', + 'Ysmall', + 'Zsmall', + 'colonmonetary', + 'onefitted', + 'rupiah', + 'Tildesmall', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + 'exclamdownsmall', + 'centoldstyle', + 'Lslashsmall', + '', + '', + 'Scaronsmall', + 'Zcaronsmall', + 'Dieresissmall', + 'Brevesmall', + 'Caronsmall', + '', + 'Dotaccentsmall', + '', + '', + 'Macronsmall', + '', + '', + 'figuredash', + 'hypheninferior', + '', + '', + 'Ogoneksmall', + 'Ringsmall', + 'Cedillasmall', + '', + '', + '', + 'onequarter', + 'onehalf', + 'threequarters', + 'questiondownsmall', + 'oneeighth', + 'threeeighths', + 'fiveeighths', + 'seveneighths', + 'onethird', + 'twothirds', + '', + '', + 'zerosuperior', + 'onesuperior', + 'twosuperior', + 'threesuperior', + 'foursuperior', + 'fivesuperior', + 'sixsuperior', + 'sevensuperior', + 'eightsuperior', + 'ninesuperior', + 'zeroinferior', + 'oneinferior', + 'twoinferior', + 'threeinferior', + 'fourinferior', + 'fiveinferior', + 'sixinferior', + 'seveninferior', + 'eightinferior', + 'nineinferior', + 'centinferior', + 'dollarinferior', + 'periodinferior', + 'commainferior', + 'Agravesmall', + 'Aacutesmall', + 'Acircumflexsmall', + 'Atildesmall', + 'Adieresissmall', + 'Aringsmall', + 'AEsmall', + 'Ccedillasmall', + 'Egravesmall', + 'Eacutesmall', + 'Ecircumflexsmall', + 'Edieresissmall', + 'Igravesmall', + 'Iacutesmall', + 'Icircumflexsmall', + 'Idieresissmall', + 'Ethsmall', + 'Ntildesmall', + 'Ogravesmall', + 'Oacutesmall', + 'Ocircumflexsmall', + 'Otildesmall', + 'Odieresissmall', + 'OEsmall', + 'Oslashsmall', + 'Ugravesmall', + 'Uacutesmall', + 'Ucircumflexsmall', + 'Udieresissmall', + 'Yacutesmall', + 'Thornsmall', + 'Ydieresissmall', ]; diff --git a/src/cff/CFFFont.js b/src/cff/CFFFont.js index c6c6809b..59e5969a 100644 --- a/src/cff/CFFFont.js +++ b/src/cff/CFFFont.js @@ -24,7 +24,7 @@ class CFFFont { if (this.version < 2) { if (this.topDictIndex.length !== 1) { - throw new Error("Only a single font is allowed in CFF"); + throw new Error('Only a single font is allowed in CFF'); } this.topDict = this.topDictIndex[0]; @@ -134,7 +134,9 @@ class CFFFont { } } default: - throw new Error(`Unknown FDSelect version: ${this.topDict.FDSelect.version}`); + throw new Error( + `Unknown FDSelect version: ${this.topDict.FDSelect.version}`, + ); } } diff --git a/src/cff/CFFIndex.js b/src/cff/CFFIndex.js index fea5eaf3..fbd70695 100644 --- a/src/cff/CFFIndex.js +++ b/src/cff/CFFIndex.js @@ -15,9 +15,7 @@ export default class CFFIndex { decode(stream, parent) { let version = this.getCFFVersion(parent); - let count = version >= 2 - ? stream.readUInt32BE() - : stream.readUInt16BE(); + let count = version >= 2 ? stream.readUInt32BE() : stream.readUInt16BE(); if (count === 0) { return []; @@ -38,7 +36,7 @@ export default class CFFIndex { } let ret = []; - let startPos = stream.pos + ((count + 1) * offSize) - 1; + let startPos = stream.pos + (count + 1) * offSize - 1; let start = offsetType.decode(stream); for (let i = 0; i < count; i++) { @@ -54,7 +52,7 @@ export default class CFFIndex { } else { ret.push({ offset: startPos + start, - length: end - start + length: end - start, }); } @@ -71,7 +69,7 @@ export default class CFFIndex { return size; } - let type = this.type || new r.Buffer; + let type = this.type || new r.Buffer(); // find maximum offset to detminine offset type let offset = 1; @@ -90,7 +88,7 @@ export default class CFFIndex { } else if (offset <= 0xffffffff) { offsetType = r.uint32; } else { - throw new Error("Bad offset in CFFIndex"); + throw new Error('Bad offset in CFFIndex'); } size += 1 + offsetType.size() * (arr.length + 1); @@ -105,7 +103,7 @@ export default class CFFIndex { return; } - let type = this.type || new r.Buffer; + let type = this.type || new r.Buffer(); // find maximum offset to detminine offset type let sizes = []; @@ -126,7 +124,7 @@ export default class CFFIndex { } else if (offset <= 0xffffffff) { offsetType = r.uint32; } else { - throw new Error("Bad offset in CFFIndex"); + throw new Error('Bad offset in CFFIndex'); } // write offset size diff --git a/src/cff/CFFOperand.js b/src/cff/CFFOperand.js index 28f858c1..08c963a8 100644 --- a/src/cff/CFFOperand.js +++ b/src/cff/CFFOperand.js @@ -1,14 +1,27 @@ const FLOAT_EOF = 0xf; const FLOAT_LOOKUP = [ - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '.', 'E', 'E-', null, '-' + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '.', + 'E', + 'E-', + null, + '-', ]; const FLOAT_ENCODE_LOOKUP = { '.': 10, - 'E': 11, + E: 11, 'E-': 12, - '-': 14 + '-': 14, }; export default class CFFOperand { @@ -39,11 +52,15 @@ export default class CFFOperand { let b = stream.readUInt8(); let n1 = b >> 4; - if (n1 === FLOAT_EOF) { break; } + if (n1 === FLOAT_EOF) { + break; + } str += FLOAT_LOOKUP[n1]; let n2 = b & 15; - if (n2 === FLOAT_EOF) { break; } + if (n2 === FLOAT_EOF) { + break; + } str += FLOAT_LOOKUP[n2]; } @@ -60,19 +77,19 @@ export default class CFFOperand { value = 32768; } - if ((value | 0) !== value) { // floating point + if ((value | 0) !== value) { + // floating point let str = '' + value; return 1 + Math.ceil((str.length + 1) / 2); - } else if (-107 <= value && value <= 107) { return 1; - - } else if (108 <= value && value <= 1131 || -1131 <= value && value <= -108) { + } else if ( + (108 <= value && value <= 1131) || + (-1131 <= value && value <= -108) + ) { return 2; - } else if (-32768 <= value && value <= 32767) { return 3; - } else { return 5; } @@ -86,8 +103,8 @@ export default class CFFOperand { if (value.forceLarge) { stream.writeUInt8(29); return stream.writeInt32BE(val); - - } else if ((val | 0) !== val) { // floating point + } else if ((val | 0) !== val) { + // floating point stream.writeUInt8(30); let str = '' + val; @@ -106,26 +123,21 @@ export default class CFFOperand { } if (n2 !== FLOAT_EOF) { - return stream.writeUInt8((FLOAT_EOF << 4)); + return stream.writeUInt8(FLOAT_EOF << 4); } - } else if (-107 <= val && val <= 107) { return stream.writeUInt8(val + 139); - } else if (108 <= val && val <= 1131) { val -= 108; stream.writeUInt8((val >> 8) + 247); return stream.writeUInt8(val & 0xff); - } else if (-1131 <= val && val <= -108) { val = -val - 108; stream.writeUInt8((val >> 8) + 251); return stream.writeUInt8(val & 0xff); - } else if (-32768 <= val && val <= 32767) { stream.writeUInt8(28); return stream.writeInt16BE(val); - } else { stream.writeUInt8(29); return stream.writeInt32BE(val); diff --git a/src/cff/CFFPointer.js b/src/cff/CFFPointer.js index 771e834b..613049f0 100644 --- a/src/cff/CFFPointer.js +++ b/src/cff/CFFPointer.js @@ -11,7 +11,7 @@ export default class CFFPointer extends r.Pointer { decode(stream, parent, operands) { this.offsetType = { - decode: () => operands[0] + decode: () => operands[0], }; return super.decode(stream, parent, operands); @@ -21,7 +21,7 @@ export default class CFFPointer extends r.Pointer { if (!stream) { // compute the size (so ctx.pointerSize is correct) this.offsetType = { - size: () => 0 + size: () => 0, }; this.size(value, ctx); @@ -30,7 +30,7 @@ export default class CFFPointer extends r.Pointer { let ptr = null; this.offsetType = { - encode: (stream, val) => ptr = val + encode: (stream, val) => (ptr = val), }; super.encode(stream, value, ctx); diff --git a/src/cff/CFFPrivateDict.js b/src/cff/CFFPrivateDict.js index 59fcab65..cf59b732 100644 --- a/src/cff/CFFPrivateDict.js +++ b/src/cff/CFFPrivateDict.js @@ -16,24 +16,24 @@ class CFFBlendOp { export default new CFFDict([ // key name type default - [6, 'BlueValues', 'delta', null], - [7, 'OtherBlues', 'delta', null], - [8, 'FamilyBlues', 'delta', null], - [9, 'FamilyOtherBlues', 'delta', null], - [[12, 9], 'BlueScale', 'number', 0.039625], - [[12, 10], 'BlueShift', 'number', 7], - [[12, 11], 'BlueFuzz', 'number', 1], - [10, 'StdHW', 'number', null], - [11, 'StdVW', 'number', null], - [[12, 12], 'StemSnapH', 'delta', null], - [[12, 13], 'StemSnapV', 'delta', null], - [[12, 14], 'ForceBold', 'boolean', false], - [[12, 17], 'LanguageGroup', 'number', 0], - [[12, 18], 'ExpansionFactor', 'number', 0.06], - [[12, 19], 'initialRandomSeed', 'number', 0], - [20, 'defaultWidthX', 'number', 0], - [21, 'nominalWidthX', 'number', 0], - [22, 'vsindex', 'number', 0], - [23, 'blend', CFFBlendOp, null], - [19, 'Subrs', new CFFPointer(new CFFIndex, {type: 'local'}), null] + [6, 'BlueValues', 'delta', null], + [7, 'OtherBlues', 'delta', null], + [8, 'FamilyBlues', 'delta', null], + [9, 'FamilyOtherBlues', 'delta', null], + [[12, 9], 'BlueScale', 'number', 0.039625], + [[12, 10], 'BlueShift', 'number', 7], + [[12, 11], 'BlueFuzz', 'number', 1], + [10, 'StdHW', 'number', null], + [11, 'StdVW', 'number', null], + [[12, 12], 'StemSnapH', 'delta', null], + [[12, 13], 'StemSnapV', 'delta', null], + [[12, 14], 'ForceBold', 'boolean', false], + [[12, 17], 'LanguageGroup', 'number', 0], + [[12, 18], 'ExpansionFactor', 'number', 0.06], + [[12, 19], 'initialRandomSeed', 'number', 0], + [20, 'defaultWidthX', 'number', 0], + [21, 'nominalWidthX', 'number', 0], + [22, 'vsindex', 'number', 0], + [23, 'blend', CFFBlendOp, null], + [19, 'Subrs', new CFFPointer(new CFFIndex(), { type: 'local' }), null], ]); diff --git a/src/cff/CFFStandardStrings.js b/src/cff/CFFStandardStrings.js index b5d59560..fdad39c6 100644 --- a/src/cff/CFFStandardStrings.js +++ b/src/cff/CFFStandardStrings.js @@ -1,71 +1,395 @@ // Automatically generated from Appendix A of the CFF specification; do // not edit. Length should be 391. export default [ - ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", - "percent", "ampersand", "quoteright", "parenleft", "parenright", - "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", - "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", - "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", - "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", - "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", - "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", - "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", - "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", - "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", - "florin", "section", "currency", "quotesingle", "quotedblleft", - "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", - "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", - "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", - "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", - "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", - "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", - "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", - "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", - "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", - "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", - "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", - "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", - "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", - "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", - "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", - "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", - "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", - "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", - "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", - "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", - "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", - "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", - "parenleftsuperior", "parenrightsuperior", "twodotenleader", - "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", - "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", - "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", - "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", - "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", - "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", - "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", - "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", - "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", - "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", - "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", - "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", - "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", - "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", - "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", - "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", - "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", - "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", - "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", - "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", - "threeinferior", "fourinferior", "fiveinferior", "sixinferior", - "seveninferior", "eightinferior", "nineinferior", "centinferior", - "dollarinferior", "periodinferior", "commainferior", "Agravesmall", - "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", - "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", - "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", - "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", - "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", - "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", - "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", - "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", - "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold" + '.notdef', + 'space', + 'exclam', + 'quotedbl', + 'numbersign', + 'dollar', + 'percent', + 'ampersand', + 'quoteright', + 'parenleft', + 'parenright', + 'asterisk', + 'plus', + 'comma', + 'hyphen', + 'period', + 'slash', + 'zero', + 'one', + 'two', + 'three', + 'four', + 'five', + 'six', + 'seven', + 'eight', + 'nine', + 'colon', + 'semicolon', + 'less', + 'equal', + 'greater', + 'question', + 'at', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'bracketleft', + 'backslash', + 'bracketright', + 'asciicircum', + 'underscore', + 'quoteleft', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + 'braceleft', + 'bar', + 'braceright', + 'asciitilde', + 'exclamdown', + 'cent', + 'sterling', + 'fraction', + 'yen', + 'florin', + 'section', + 'currency', + 'quotesingle', + 'quotedblleft', + 'guillemotleft', + 'guilsinglleft', + 'guilsinglright', + 'fi', + 'fl', + 'endash', + 'dagger', + 'daggerdbl', + 'periodcentered', + 'paragraph', + 'bullet', + 'quotesinglbase', + 'quotedblbase', + 'quotedblright', + 'guillemotright', + 'ellipsis', + 'perthousand', + 'questiondown', + 'grave', + 'acute', + 'circumflex', + 'tilde', + 'macron', + 'breve', + 'dotaccent', + 'dieresis', + 'ring', + 'cedilla', + 'hungarumlaut', + 'ogonek', + 'caron', + 'emdash', + 'AE', + 'ordfeminine', + 'Lslash', + 'Oslash', + 'OE', + 'ordmasculine', + 'ae', + 'dotlessi', + 'lslash', + 'oslash', + 'oe', + 'germandbls', + 'onesuperior', + 'logicalnot', + 'mu', + 'trademark', + 'Eth', + 'onehalf', + 'plusminus', + 'Thorn', + 'onequarter', + 'divide', + 'brokenbar', + 'degree', + 'thorn', + 'threequarters', + 'twosuperior', + 'registered', + 'minus', + 'eth', + 'multiply', + 'threesuperior', + 'copyright', + 'Aacute', + 'Acircumflex', + 'Adieresis', + 'Agrave', + 'Aring', + 'Atilde', + 'Ccedilla', + 'Eacute', + 'Ecircumflex', + 'Edieresis', + 'Egrave', + 'Iacute', + 'Icircumflex', + 'Idieresis', + 'Igrave', + 'Ntilde', + 'Oacute', + 'Ocircumflex', + 'Odieresis', + 'Ograve', + 'Otilde', + 'Scaron', + 'Uacute', + 'Ucircumflex', + 'Udieresis', + 'Ugrave', + 'Yacute', + 'Ydieresis', + 'Zcaron', + 'aacute', + 'acircumflex', + 'adieresis', + 'agrave', + 'aring', + 'atilde', + 'ccedilla', + 'eacute', + 'ecircumflex', + 'edieresis', + 'egrave', + 'iacute', + 'icircumflex', + 'idieresis', + 'igrave', + 'ntilde', + 'oacute', + 'ocircumflex', + 'odieresis', + 'ograve', + 'otilde', + 'scaron', + 'uacute', + 'ucircumflex', + 'udieresis', + 'ugrave', + 'yacute', + 'ydieresis', + 'zcaron', + 'exclamsmall', + 'Hungarumlautsmall', + 'dollaroldstyle', + 'dollarsuperior', + 'ampersandsmall', + 'Acutesmall', + 'parenleftsuperior', + 'parenrightsuperior', + 'twodotenleader', + 'onedotenleader', + 'zerooldstyle', + 'oneoldstyle', + 'twooldstyle', + 'threeoldstyle', + 'fouroldstyle', + 'fiveoldstyle', + 'sixoldstyle', + 'sevenoldstyle', + 'eightoldstyle', + 'nineoldstyle', + 'commasuperior', + 'threequartersemdash', + 'periodsuperior', + 'questionsmall', + 'asuperior', + 'bsuperior', + 'centsuperior', + 'dsuperior', + 'esuperior', + 'isuperior', + 'lsuperior', + 'msuperior', + 'nsuperior', + 'osuperior', + 'rsuperior', + 'ssuperior', + 'tsuperior', + 'ff', + 'ffi', + 'ffl', + 'parenleftinferior', + 'parenrightinferior', + 'Circumflexsmall', + 'hyphensuperior', + 'Gravesmall', + 'Asmall', + 'Bsmall', + 'Csmall', + 'Dsmall', + 'Esmall', + 'Fsmall', + 'Gsmall', + 'Hsmall', + 'Ismall', + 'Jsmall', + 'Ksmall', + 'Lsmall', + 'Msmall', + 'Nsmall', + 'Osmall', + 'Psmall', + 'Qsmall', + 'Rsmall', + 'Ssmall', + 'Tsmall', + 'Usmall', + 'Vsmall', + 'Wsmall', + 'Xsmall', + 'Ysmall', + 'Zsmall', + 'colonmonetary', + 'onefitted', + 'rupiah', + 'Tildesmall', + 'exclamdownsmall', + 'centoldstyle', + 'Lslashsmall', + 'Scaronsmall', + 'Zcaronsmall', + 'Dieresissmall', + 'Brevesmall', + 'Caronsmall', + 'Dotaccentsmall', + 'Macronsmall', + 'figuredash', + 'hypheninferior', + 'Ogoneksmall', + 'Ringsmall', + 'Cedillasmall', + 'questiondownsmall', + 'oneeighth', + 'threeeighths', + 'fiveeighths', + 'seveneighths', + 'onethird', + 'twothirds', + 'zerosuperior', + 'foursuperior', + 'fivesuperior', + 'sixsuperior', + 'sevensuperior', + 'eightsuperior', + 'ninesuperior', + 'zeroinferior', + 'oneinferior', + 'twoinferior', + 'threeinferior', + 'fourinferior', + 'fiveinferior', + 'sixinferior', + 'seveninferior', + 'eightinferior', + 'nineinferior', + 'centinferior', + 'dollarinferior', + 'periodinferior', + 'commainferior', + 'Agravesmall', + 'Aacutesmall', + 'Acircumflexsmall', + 'Atildesmall', + 'Adieresissmall', + 'Aringsmall', + 'AEsmall', + 'Ccedillasmall', + 'Egravesmall', + 'Eacutesmall', + 'Ecircumflexsmall', + 'Edieresissmall', + 'Igravesmall', + 'Iacutesmall', + 'Icircumflexsmall', + 'Idieresissmall', + 'Ethsmall', + 'Ntildesmall', + 'Ogravesmall', + 'Oacutesmall', + 'Ocircumflexsmall', + 'Otildesmall', + 'Odieresissmall', + 'OEsmall', + 'Oslashsmall', + 'Ugravesmall', + 'Uacutesmall', + 'Ucircumflexsmall', + 'Udieresissmall', + 'Yacutesmall', + 'Thornsmall', + 'Ydieresissmall', + '001.000', + '001.001', + '001.002', + '001.003', + 'Black', + 'Bold', + 'Book', + 'Light', + 'Medium', + 'Regular', + 'Roman', + 'Semibold', ]; diff --git a/src/cff/CFFTop.js b/src/cff/CFFTop.js index efdba720..8e3748ce 100644 --- a/src/cff/CFFTop.js +++ b/src/cff/CFFTop.js @@ -6,7 +6,11 @@ import CFFPointer from './CFFPointer'; import CFFPrivateDict from './CFFPrivateDict'; import StandardStrings from './CFFStandardStrings'; import { StandardEncoding, ExpertEncoding } from './CFFEncodings'; -import { ISOAdobeCharset, ExpertCharset, ExpertSubsetCharset } from './CFFCharsets'; +import { + ISOAdobeCharset, + ExpertCharset, + ExpertSubsetCharset, +} from './CFFCharsets'; import { ItemVariationStore } from '../tables/variations'; // Checks if an operand is an index of a predefined value, @@ -51,29 +55,32 @@ class CFFEncodingVersion extends r.Number { let Range1 = new r.Struct({ first: r.uint16, - nLeft: r.uint8 + nLeft: r.uint8, }); let Range2 = new r.Struct({ first: r.uint16, - nLeft: r.uint16 + nLeft: r.uint16, }); let CFFCustomEncoding = new r.VersionedStruct(new CFFEncodingVersion(), { 0: { nCodes: r.uint8, - codes: new r.Array(r.uint8, 'nCodes') + codes: new r.Array(r.uint8, 'nCodes'), }, 1: { nRanges: r.uint8, - ranges: new r.Array(Range1, 'nRanges') - } + ranges: new r.Array(Range1, 'nRanges'), + }, // TODO: supplement? }); -let CFFEncoding = new PredefinedOp([ StandardEncoding, ExpertEncoding ], new CFFPointer(CFFCustomEncoding, { lazy: true })); +let CFFEncoding = new PredefinedOp( + [StandardEncoding, ExpertEncoding], + new CFFPointer(CFFCustomEncoding, { lazy: true }), +); // Decodes an array of ranges until the total // length is equal to the provided length. @@ -95,46 +102,49 @@ class RangeArray extends r.Array { let CFFCustomCharset = new r.VersionedStruct(r.uint8, { 0: { - glyphs: new r.Array(r.uint16, t => t.parent.CharStrings.length - 1) + glyphs: new r.Array(r.uint16, (t) => t.parent.CharStrings.length - 1), }, 1: { - ranges: new RangeArray(Range1, t => t.parent.CharStrings.length - 1) + ranges: new RangeArray(Range1, (t) => t.parent.CharStrings.length - 1), }, 2: { - ranges: new RangeArray(Range2, t => t.parent.CharStrings.length - 1) - } + ranges: new RangeArray(Range2, (t) => t.parent.CharStrings.length - 1), + }, }); -let CFFCharset = new PredefinedOp([ ISOAdobeCharset, ExpertCharset, ExpertSubsetCharset ], new CFFPointer(CFFCustomCharset, {lazy: true})); +let CFFCharset = new PredefinedOp( + [ISOAdobeCharset, ExpertCharset, ExpertSubsetCharset], + new CFFPointer(CFFCustomCharset, { lazy: true }), +); let FDRange3 = new r.Struct({ first: r.uint16, - fd: r.uint8 + fd: r.uint8, }); let FDRange4 = new r.Struct({ first: r.uint32, - fd: r.uint16 + fd: r.uint16, }); let FDSelect = new r.VersionedStruct(r.uint8, { 0: { - fds: new r.Array(r.uint8, t => t.parent.CharStrings.length) + fds: new r.Array(r.uint8, (t) => t.parent.CharStrings.length), }, 3: { nRanges: r.uint16, ranges: new r.Array(FDRange3, 'nRanges'), - sentinel: r.uint16 + sentinel: r.uint16, }, 4: { nRanges: r.uint32, ranges: new r.Array(FDRange4, 'nRanges'), - sentinel: r.uint32 - } + sentinel: r.uint32, + }, }); let ptr = new CFFPointer(CFFPrivateDict); @@ -149,89 +159,92 @@ class CFFPrivateOp { } encode(stream, dict, ctx) { - return [CFFPrivateDict.size(dict, ctx, false), ptr.encode(stream, dict, ctx)[0]]; + return [ + CFFPrivateDict.size(dict, ctx, false), + ptr.encode(stream, dict, ctx)[0], + ]; } } let FontDict = new CFFDict([ // key name type(s) default - [18, 'Private', new CFFPrivateOp, null], - [[12, 38], 'FontName', 'sid', null], - [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]], - [[12, 5], 'PaintType', 'number', 0], + [18, 'Private', new CFFPrivateOp(), null], + [[12, 38], 'FontName', 'sid', null], + [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]], + [[12, 5], 'PaintType', 'number', 0], ]); let CFFTopDict = new CFFDict([ // key name type(s) default - [[12, 30], 'ROS', ['sid', 'sid', 'number'], null], - - [0, 'version', 'sid', null], - [1, 'Notice', 'sid', null], - [[12, 0], 'Copyright', 'sid', null], - [2, 'FullName', 'sid', null], - [3, 'FamilyName', 'sid', null], - [4, 'Weight', 'sid', null], - [[12, 1], 'isFixedPitch', 'boolean', false], - [[12, 2], 'ItalicAngle', 'number', 0], - [[12, 3], 'UnderlinePosition', 'number', -100], - [[12, 4], 'UnderlineThickness', 'number', 50], - [[12, 5], 'PaintType', 'number', 0], - [[12, 6], 'CharstringType', 'number', 2], - [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]], - [13, 'UniqueID', 'number', null], - [5, 'FontBBox', 'array', [0, 0, 0, 0]], - [[12, 8], 'StrokeWidth', 'number', 0], - [14, 'XUID', 'array', null], - [15, 'charset', CFFCharset, ISOAdobeCharset], - [16, 'Encoding', CFFEncoding, StandardEncoding], - [17, 'CharStrings', new CFFPointer(new CFFIndex), null], - [18, 'Private', new CFFPrivateOp, null], - [[12, 20], 'SyntheticBase', 'number', null], - [[12, 21], 'PostScript', 'sid', null], - [[12, 22], 'BaseFontName', 'sid', null], - [[12, 23], 'BaseFontBlend', 'delta', null], + [[12, 30], 'ROS', ['sid', 'sid', 'number'], null], + + [0, 'version', 'sid', null], + [1, 'Notice', 'sid', null], + [[12, 0], 'Copyright', 'sid', null], + [2, 'FullName', 'sid', null], + [3, 'FamilyName', 'sid', null], + [4, 'Weight', 'sid', null], + [[12, 1], 'isFixedPitch', 'boolean', false], + [[12, 2], 'ItalicAngle', 'number', 0], + [[12, 3], 'UnderlinePosition', 'number', -100], + [[12, 4], 'UnderlineThickness', 'number', 50], + [[12, 5], 'PaintType', 'number', 0], + [[12, 6], 'CharstringType', 'number', 2], + [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]], + [13, 'UniqueID', 'number', null], + [5, 'FontBBox', 'array', [0, 0, 0, 0]], + [[12, 8], 'StrokeWidth', 'number', 0], + [14, 'XUID', 'array', null], + [15, 'charset', CFFCharset, ISOAdobeCharset], + [16, 'Encoding', CFFEncoding, StandardEncoding], + [17, 'CharStrings', new CFFPointer(new CFFIndex()), null], + [18, 'Private', new CFFPrivateOp(), null], + [[12, 20], 'SyntheticBase', 'number', null], + [[12, 21], 'PostScript', 'sid', null], + [[12, 22], 'BaseFontName', 'sid', null], + [[12, 23], 'BaseFontBlend', 'delta', null], // CID font specific - [[12, 31], 'CIDFontVersion', 'number', 0], - [[12, 32], 'CIDFontRevision', 'number', 0], - [[12, 33], 'CIDFontType', 'number', 0], - [[12, 34], 'CIDCount', 'number', 8720], - [[12, 35], 'UIDBase', 'number', null], - [[12, 37], 'FDSelect', new CFFPointer(FDSelect), null], - [[12, 36], 'FDArray', new CFFPointer(new CFFIndex(FontDict)), null], - [[12, 38], 'FontName', 'sid', null] + [[12, 31], 'CIDFontVersion', 'number', 0], + [[12, 32], 'CIDFontRevision', 'number', 0], + [[12, 33], 'CIDFontType', 'number', 0], + [[12, 34], 'CIDCount', 'number', 8720], + [[12, 35], 'UIDBase', 'number', null], + [[12, 37], 'FDSelect', new CFFPointer(FDSelect), null], + [[12, 36], 'FDArray', new CFFPointer(new CFFIndex(FontDict)), null], + [[12, 38], 'FontName', 'sid', null], ]); let VariationStore = new r.Struct({ length: r.uint16, - itemVariationStore: ItemVariationStore -}) + itemVariationStore: ItemVariationStore, +}); let CFF2TopDict = new CFFDict([ - [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]], - [17, 'CharStrings', new CFFPointer(new CFFIndex), null], - [[12, 37], 'FDSelect', new CFFPointer(FDSelect), null], - [[12, 36], 'FDArray', new CFFPointer(new CFFIndex(FontDict)), null], - [24, 'vstore', new CFFPointer(VariationStore), null], - [25, 'maxstack', 'number', 193] + [[12, 7], 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0]], + [17, 'CharStrings', new CFFPointer(new CFFIndex()), null], + [[12, 37], 'FDSelect', new CFFPointer(FDSelect), null], + [[12, 36], 'FDArray', new CFFPointer(new CFFIndex(FontDict)), null], + [24, 'vstore', new CFFPointer(VariationStore), null], + [25, 'maxstack', 'number', 193], ]); let CFFTop = new r.VersionedStruct(r.fixed16, { 1: { - hdrSize: r.uint8, - offSize: r.uint8, - nameIndex: new CFFIndex(new r.String('length')), - topDictIndex: new CFFIndex(CFFTopDict), - stringIndex: new CFFIndex(new r.String('length')), - globalSubrIndex: new CFFIndex + hdrSize: r.uint8, + offSize: r.uint8, + nameIndex: new CFFIndex(new r.String('length')), + topDictIndex: new CFFIndex(CFFTopDict), + stringIndex: new CFFIndex(new r.String('length')), + globalSubrIndex: new CFFIndex(), }, 2: { - hdrSize: r.uint8, - length: r.uint16, - topDict: CFF2TopDict, - globalSubrIndex: new CFFIndex - } + hdrSize: r.uint8, + length: r.uint16, + topDict: CFF2TopDict, + globalSubrIndex: new CFFIndex(), + }, }); export default CFFTop; diff --git a/src/encodings.js b/src/encodings.js index 7e2230f0..438ad17d 100644 --- a/src/encodings.js +++ b/src/encodings.js @@ -6,20 +6,33 @@ export function getEncoding(platformID, encodingID, languageID = 0) { if (platformID === 1 && MAC_LANGUAGE_ENCODINGS[languageID]) { return MAC_LANGUAGE_ENCODINGS[languageID]; } - + return ENCODINGS[platformID][encodingID]; } -const SINGLE_BYTE_ENCODINGS = new Set(['x-mac-roman', 'x-mac-cyrillic', 'iso-8859-6', 'iso-8859-8']); +const SINGLE_BYTE_ENCODINGS = new Set([ + 'x-mac-roman', + 'x-mac-cyrillic', + 'iso-8859-6', + 'iso-8859-8', +]); const MAC_ENCODINGS = { - 'x-mac-croatian': 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈ƫȅ\u00A0ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ', - 'x-mac-gaelic': 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæøṁṖṗɼƒſṠ«»…\u00A0ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ', - 'x-mac-greek': 'Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»…\u00A0ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ\u00AD', - 'x-mac-icelandic': 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüݰ¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»…\u00A0ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ', - 'x-mac-inuit': 'ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗᓘᓚᓛᓪᔨᔩᔪᔫᔭ…\u00A0ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł', - 'x-mac-ce': 'ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»…\u00A0ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ', - 'x-mac-romanian': 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș¿¡¬√ƒ≈∆«»…\u00A0ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ', - 'x-mac-turkish': 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»…\u00A0ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ' + 'x-mac-croatian': + 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈ƫȅ\u00A0ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ', + 'x-mac-gaelic': + 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæøṁṖṗɼƒſṠ«»…\u00A0ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ', + 'x-mac-greek': + 'Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»…\u00A0ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ\u00AD', + 'x-mac-icelandic': + 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüݰ¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»…\u00A0ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ', + 'x-mac-inuit': + 'ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗᓘᓚᓛᓪᔨᔩᔪᔫᔭ…\u00A0ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł', + 'x-mac-ce': + 'ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»…\u00A0ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ', + 'x-mac-romanian': + 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș¿¡¬√ƒ≈∆«»…\u00A0ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ', + 'x-mac-turkish': + 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»…\u00A0ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ', }; const encodingCache = new Map(); @@ -66,8 +79,16 @@ export function getEncodingMapping(encoding) { // Map of platform ids to encoding ids. export const ENCODINGS = [ // unicode - ['utf-16be', 'utf-16be', 'utf-16be', 'utf-16be', 'utf-16be', 'utf-16be', 'utf-16be'], - + [ + 'utf-16be', + 'utf-16be', + 'utf-16be', + 'utf-16be', + 'utf-16be', + 'utf-16be', + 'utf-16be', + ], + // macintosh // Mappings available at http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/ // 0 Roman 17 Malayalam @@ -87,18 +108,59 @@ export const ENCODINGS = [ // 14 Tamil 31 Sindhi // 15 Telugu 32 (Uninterpreted) // 16 Kannada - ['x-mac-roman', 'shift-jis', 'big5', 'euc-kr', 'iso-8859-6', 'iso-8859-8', - 'x-mac-greek', 'x-mac-cyrillic', 'x-mac-symbol', 'x-mac-devanagari', 'x-mac-gurmukhi', 'x-mac-gujarati', - 'Oriya', 'Bengali', 'Tamil', 'Telugu', 'Kannada', 'Malayalam', 'Sinhalese', - 'Burmese', 'Khmer', 'iso-8859-11', 'Laotian', 'Georgian', 'Armenian', 'gbk', - 'Tibetan', 'Mongolian', 'Geez', 'x-mac-ce', 'Vietnamese', 'Sindhi'], - + [ + 'x-mac-roman', + 'shift-jis', + 'big5', + 'euc-kr', + 'iso-8859-6', + 'iso-8859-8', + 'x-mac-greek', + 'x-mac-cyrillic', + 'x-mac-symbol', + 'x-mac-devanagari', + 'x-mac-gurmukhi', + 'x-mac-gujarati', + 'Oriya', + 'Bengali', + 'Tamil', + 'Telugu', + 'Kannada', + 'Malayalam', + 'Sinhalese', + 'Burmese', + 'Khmer', + 'iso-8859-11', + 'Laotian', + 'Georgian', + 'Armenian', + 'gbk', + 'Tibetan', + 'Mongolian', + 'Geez', + 'x-mac-ce', + 'Vietnamese', + 'Sindhi', + ], + // ISO (deprecated) ['ascii', null, 'iso-8859-1'], - + // windows // Docs here: http://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx - ['symbol', 'utf-16be', 'shift-jis', 'gb18030', 'big5', 'euc-kr', 'johab', null, null, null, 'utf-16be'] + [ + 'symbol', + 'utf-16be', + 'shift-jis', + 'gb18030', + 'big5', + 'euc-kr', + 'johab', + null, + null, + null, + 'utf-16be', + ], ]; // Overrides for Mac scripts by language id. @@ -118,102 +180,346 @@ export const MAC_LANGUAGE_ENCODINGS = { 39: 'x-mac-ce', 40: 'x-mac-ce', 143: 'x-mac-inuit', - 146: 'x-mac-gaelic' + 146: 'x-mac-gaelic', }; // Map of platform ids to BCP-47 language codes. export const LANGUAGES = [ // unicode [], - - { // macintosh - 0: 'en', 30: 'fo', 60: 'ks', 90: 'rw', - 1: 'fr', 31: 'fa', 61: 'ku', 91: 'rn', - 2: 'de', 32: 'ru', 62: 'sd', 92: 'ny', - 3: 'it', 33: 'zh', 63: 'bo', 93: 'mg', - 4: 'nl', 34: 'nl-BE', 64: 'ne', 94: 'eo', - 5: 'sv', 35: 'ga', 65: 'sa', 128: 'cy', - 6: 'es', 36: 'sq', 66: 'mr', 129: 'eu', - 7: 'da', 37: 'ro', 67: 'bn', 130: 'ca', - 8: 'pt', 38: 'cz', 68: 'as', 131: 'la', - 9: 'no', 39: 'sk', 69: 'gu', 132: 'qu', - 10: 'he', 40: 'si', 70: 'pa', 133: 'gn', - 11: 'ja', 41: 'yi', 71: 'or', 134: 'ay', - 12: 'ar', 42: 'sr', 72: 'ml', 135: 'tt', - 13: 'fi', 43: 'mk', 73: 'kn', 136: 'ug', - 14: 'el', 44: 'bg', 74: 'ta', 137: 'dz', - 15: 'is', 45: 'uk', 75: 'te', 138: 'jv', - 16: 'mt', 46: 'be', 76: 'si', 139: 'su', - 17: 'tr', 47: 'uz', 77: 'my', 140: 'gl', - 18: 'hr', 48: 'kk', 78: 'km', 141: 'af', - 19: 'zh-Hant', 49: 'az-Cyrl', 79: 'lo', 142: 'br', - 20: 'ur', 50: 'az-Arab', 80: 'vi', 143: 'iu', - 21: 'hi', 51: 'hy', 81: 'id', 144: 'gd', - 22: 'th', 52: 'ka', 82: 'tl', 145: 'gv', - 23: 'ko', 53: 'mo', 83: 'ms', 146: 'ga', - 24: 'lt', 54: 'ky', 84: 'ms-Arab', 147: 'to', - 25: 'pl', 55: 'tg', 85: 'am', 148: 'el-polyton', - 26: 'hu', 56: 'tk', 86: 'ti', 149: 'kl', - 27: 'es', 57: 'mn-CN', 87: 'om', 150: 'az', - 28: 'lv', 58: 'mn', 88: 'so', 151: 'nn', - 29: 'se', 59: 'ps', 89: 'sw', + + { + // macintosh + 0: 'en', + 30: 'fo', + 60: 'ks', + 90: 'rw', + 1: 'fr', + 31: 'fa', + 61: 'ku', + 91: 'rn', + 2: 'de', + 32: 'ru', + 62: 'sd', + 92: 'ny', + 3: 'it', + 33: 'zh', + 63: 'bo', + 93: 'mg', + 4: 'nl', + 34: 'nl-BE', + 64: 'ne', + 94: 'eo', + 5: 'sv', + 35: 'ga', + 65: 'sa', + 128: 'cy', + 6: 'es', + 36: 'sq', + 66: 'mr', + 129: 'eu', + 7: 'da', + 37: 'ro', + 67: 'bn', + 130: 'ca', + 8: 'pt', + 38: 'cz', + 68: 'as', + 131: 'la', + 9: 'no', + 39: 'sk', + 69: 'gu', + 132: 'qu', + 10: 'he', + 40: 'si', + 70: 'pa', + 133: 'gn', + 11: 'ja', + 41: 'yi', + 71: 'or', + 134: 'ay', + 12: 'ar', + 42: 'sr', + 72: 'ml', + 135: 'tt', + 13: 'fi', + 43: 'mk', + 73: 'kn', + 136: 'ug', + 14: 'el', + 44: 'bg', + 74: 'ta', + 137: 'dz', + 15: 'is', + 45: 'uk', + 75: 'te', + 138: 'jv', + 16: 'mt', + 46: 'be', + 76: 'si', + 139: 'su', + 17: 'tr', + 47: 'uz', + 77: 'my', + 140: 'gl', + 18: 'hr', + 48: 'kk', + 78: 'km', + 141: 'af', + 19: 'zh-Hant', + 49: 'az-Cyrl', + 79: 'lo', + 142: 'br', + 20: 'ur', + 50: 'az-Arab', + 80: 'vi', + 143: 'iu', + 21: 'hi', + 51: 'hy', + 81: 'id', + 144: 'gd', + 22: 'th', + 52: 'ka', + 82: 'tl', + 145: 'gv', + 23: 'ko', + 53: 'mo', + 83: 'ms', + 146: 'ga', + 24: 'lt', + 54: 'ky', + 84: 'ms-Arab', + 147: 'to', + 25: 'pl', + 55: 'tg', + 85: 'am', + 148: 'el-polyton', + 26: 'hu', + 56: 'tk', + 86: 'ti', + 149: 'kl', + 27: 'es', + 57: 'mn-CN', + 87: 'om', + 150: 'az', + 28: 'lv', + 58: 'mn', + 88: 'so', + 151: 'nn', + 29: 'se', + 59: 'ps', + 89: 'sw', }, - + // ISO (deprecated) [], - - { // windows - 0x0436: 'af', 0x4009: 'en-IN', 0x0487: 'rw', 0x0432: 'tn', - 0x041C: 'sq', 0x1809: 'en-IE', 0x0441: 'sw', 0x045B: 'si', - 0x0484: 'gsw', 0x2009: 'en-JM', 0x0457: 'kok', 0x041B: 'sk', - 0x045E: 'am', 0x4409: 'en-MY', 0x0412: 'ko', 0x0424: 'sl', - 0x1401: 'ar-DZ', 0x1409: 'en-NZ', 0x0440: 'ky', 0x2C0A: 'es-AR', - 0x3C01: 'ar-BH', 0x3409: 'en-PH', 0x0454: 'lo', 0x400A: 'es-BO', - 0x0C01: 'ar', 0x4809: 'en-SG', 0x0426: 'lv', 0x340A: 'es-CL', - 0x0801: 'ar-IQ', 0x1C09: 'en-ZA', 0x0427: 'lt', 0x240A: 'es-CO', - 0x2C01: 'ar-JO', 0x2C09: 'en-TT', 0x082E: 'dsb', 0x140A: 'es-CR', - 0x3401: 'ar-KW', 0x0809: 'en-GB', 0x046E: 'lb', 0x1C0A: 'es-DO', - 0x3001: 'ar-LB', 0x0409: 'en', 0x042F: 'mk', 0x300A: 'es-EC', - 0x1001: 'ar-LY', 0x3009: 'en-ZW', 0x083E: 'ms-BN', 0x440A: 'es-SV', - 0x1801: 'ary', 0x0425: 'et', 0x043E: 'ms', 0x100A: 'es-GT', - 0x2001: 'ar-OM', 0x0438: 'fo', 0x044C: 'ml', 0x480A: 'es-HN', - 0x4001: 'ar-QA', 0x0464: 'fil', 0x043A: 'mt', 0x080A: 'es-MX', - 0x0401: 'ar-SA', 0x040B: 'fi', 0x0481: 'mi', 0x4C0A: 'es-NI', - 0x2801: 'ar-SY', 0x080C: 'fr-BE', 0x047A: 'arn', 0x180A: 'es-PA', - 0x1C01: 'aeb', 0x0C0C: 'fr-CA', 0x044E: 'mr', 0x3C0A: 'es-PY', - 0x3801: 'ar-AE', 0x040C: 'fr', 0x047C: 'moh', 0x280A: 'es-PE', - 0x2401: 'ar-YE', 0x140C: 'fr-LU', 0x0450: 'mn', 0x500A: 'es-PR', - 0x042B: 'hy', 0x180C: 'fr-MC', 0x0850: 'mn-CN', 0x0C0A: 'es', - 0x044D: 'as', 0x100C: 'fr-CH', 0x0461: 'ne', 0x040A: 'es', - 0x082C: 'az-Cyrl', 0x0462: 'fy', 0x0414: 'nb', 0x540A: 'es-US', - 0x042C: 'az', 0x0456: 'gl', 0x0814: 'nn', 0x380A: 'es-UY', - 0x046D: 'ba', 0x0437: 'ka', 0x0482: 'oc', 0x200A: 'es-VE', - 0x042D: 'eu', 0x0C07: 'de-AT', 0x0448: 'or', 0x081D: 'sv-FI', - 0x0423: 'be', 0x0407: 'de', 0x0463: 'ps', 0x041D: 'sv', - 0x0845: 'bn', 0x1407: 'de-LI', 0x0415: 'pl', 0x045A: 'syr', - 0x0445: 'bn-IN', 0x1007: 'de-LU', 0x0416: 'pt', 0x0428: 'tg', - 0x201A: 'bs-Cyrl', 0x0807: 'de-CH', 0x0816: 'pt-PT', 0x085F: 'tzm', - 0x141A: 'bs', 0x0408: 'el', 0x0446: 'pa', 0x0449: 'ta', - 0x047E: 'br', 0x046F: 'kl', 0x046B: 'qu-BO', 0x0444: 'tt', - 0x0402: 'bg', 0x0447: 'gu', 0x086B: 'qu-EC', 0x044A: 'te', - 0x0403: 'ca', 0x0468: 'ha', 0x0C6B: 'qu', 0x041E: 'th', - 0x0C04: 'zh-HK', 0x040D: 'he', 0x0418: 'ro', 0x0451: 'bo', - 0x1404: 'zh-MO', 0x0439: 'hi', 0x0417: 'rm', 0x041F: 'tr', - 0x0804: 'zh', 0x040E: 'hu', 0x0419: 'ru', 0x0442: 'tk', - 0x1004: 'zh-SG', 0x040F: 'is', 0x243B: 'smn', 0x0480: 'ug', - 0x0404: 'zh-TW', 0x0470: 'ig', 0x103B: 'smj-NO', 0x0422: 'uk', - 0x0483: 'co', 0x0421: 'id', 0x143B: 'smj', 0x042E: 'hsb', - 0x041A: 'hr', 0x045D: 'iu', 0x0C3B: 'se-FI', 0x0420: 'ur', - 0x101A: 'hr-BA', 0x085D: 'iu-Latn', 0x043B: 'se', 0x0843: 'uz-Cyrl', - 0x0405: 'cs', 0x083C: 'ga', 0x083B: 'se-SE', 0x0443: 'uz', - 0x0406: 'da', 0x0434: 'xh', 0x203B: 'sms', 0x042A: 'vi', - 0x048C: 'prs', 0x0435: 'zu', 0x183B: 'sma-NO', 0x0452: 'cy', - 0x0465: 'dv', 0x0410: 'it', 0x1C3B: 'sms', 0x0488: 'wo', - 0x0813: 'nl-BE', 0x0810: 'it-CH', 0x044F: 'sa', 0x0485: 'sah', - 0x0413: 'nl', 0x0411: 'ja', 0x1C1A: 'sr-Cyrl-BA', 0x0478: 'ii', - 0x0C09: 'en-AU', 0x044B: 'kn', 0x0C1A: 'sr', 0x046A: 'yo', - 0x2809: 'en-BZ', 0x043F: 'kk', 0x181A: 'sr-Latn-BA', - 0x1009: 'en-CA', 0x0453: 'km', 0x081A: 'sr-Latn', - 0x2409: 'en-029', 0x0486: 'quc', 0x046C: 'nso', - } + + { + // windows + 0x0436: 'af', + 0x4009: 'en-IN', + 0x0487: 'rw', + 0x0432: 'tn', + 0x041c: 'sq', + 0x1809: 'en-IE', + 0x0441: 'sw', + 0x045b: 'si', + 0x0484: 'gsw', + 0x2009: 'en-JM', + 0x0457: 'kok', + 0x041b: 'sk', + 0x045e: 'am', + 0x4409: 'en-MY', + 0x0412: 'ko', + 0x0424: 'sl', + 0x1401: 'ar-DZ', + 0x1409: 'en-NZ', + 0x0440: 'ky', + 0x2c0a: 'es-AR', + 0x3c01: 'ar-BH', + 0x3409: 'en-PH', + 0x0454: 'lo', + 0x400a: 'es-BO', + 0x0c01: 'ar', + 0x4809: 'en-SG', + 0x0426: 'lv', + 0x340a: 'es-CL', + 0x0801: 'ar-IQ', + 0x1c09: 'en-ZA', + 0x0427: 'lt', + 0x240a: 'es-CO', + 0x2c01: 'ar-JO', + 0x2c09: 'en-TT', + 0x082e: 'dsb', + 0x140a: 'es-CR', + 0x3401: 'ar-KW', + 0x0809: 'en-GB', + 0x046e: 'lb', + 0x1c0a: 'es-DO', + 0x3001: 'ar-LB', + 0x0409: 'en', + 0x042f: 'mk', + 0x300a: 'es-EC', + 0x1001: 'ar-LY', + 0x3009: 'en-ZW', + 0x083e: 'ms-BN', + 0x440a: 'es-SV', + 0x1801: 'ary', + 0x0425: 'et', + 0x043e: 'ms', + 0x100a: 'es-GT', + 0x2001: 'ar-OM', + 0x0438: 'fo', + 0x044c: 'ml', + 0x480a: 'es-HN', + 0x4001: 'ar-QA', + 0x0464: 'fil', + 0x043a: 'mt', + 0x080a: 'es-MX', + 0x0401: 'ar-SA', + 0x040b: 'fi', + 0x0481: 'mi', + 0x4c0a: 'es-NI', + 0x2801: 'ar-SY', + 0x080c: 'fr-BE', + 0x047a: 'arn', + 0x180a: 'es-PA', + 0x1c01: 'aeb', + 0x0c0c: 'fr-CA', + 0x044e: 'mr', + 0x3c0a: 'es-PY', + 0x3801: 'ar-AE', + 0x040c: 'fr', + 0x047c: 'moh', + 0x280a: 'es-PE', + 0x2401: 'ar-YE', + 0x140c: 'fr-LU', + 0x0450: 'mn', + 0x500a: 'es-PR', + 0x042b: 'hy', + 0x180c: 'fr-MC', + 0x0850: 'mn-CN', + 0x0c0a: 'es', + 0x044d: 'as', + 0x100c: 'fr-CH', + 0x0461: 'ne', + 0x040a: 'es', + 0x082c: 'az-Cyrl', + 0x0462: 'fy', + 0x0414: 'nb', + 0x540a: 'es-US', + 0x042c: 'az', + 0x0456: 'gl', + 0x0814: 'nn', + 0x380a: 'es-UY', + 0x046d: 'ba', + 0x0437: 'ka', + 0x0482: 'oc', + 0x200a: 'es-VE', + 0x042d: 'eu', + 0x0c07: 'de-AT', + 0x0448: 'or', + 0x081d: 'sv-FI', + 0x0423: 'be', + 0x0407: 'de', + 0x0463: 'ps', + 0x041d: 'sv', + 0x0845: 'bn', + 0x1407: 'de-LI', + 0x0415: 'pl', + 0x045a: 'syr', + 0x0445: 'bn-IN', + 0x1007: 'de-LU', + 0x0416: 'pt', + 0x0428: 'tg', + 0x201a: 'bs-Cyrl', + 0x0807: 'de-CH', + 0x0816: 'pt-PT', + 0x085f: 'tzm', + 0x141a: 'bs', + 0x0408: 'el', + 0x0446: 'pa', + 0x0449: 'ta', + 0x047e: 'br', + 0x046f: 'kl', + 0x046b: 'qu-BO', + 0x0444: 'tt', + 0x0402: 'bg', + 0x0447: 'gu', + 0x086b: 'qu-EC', + 0x044a: 'te', + 0x0403: 'ca', + 0x0468: 'ha', + 0x0c6b: 'qu', + 0x041e: 'th', + 0x0c04: 'zh-HK', + 0x040d: 'he', + 0x0418: 'ro', + 0x0451: 'bo', + 0x1404: 'zh-MO', + 0x0439: 'hi', + 0x0417: 'rm', + 0x041f: 'tr', + 0x0804: 'zh', + 0x040e: 'hu', + 0x0419: 'ru', + 0x0442: 'tk', + 0x1004: 'zh-SG', + 0x040f: 'is', + 0x243b: 'smn', + 0x0480: 'ug', + 0x0404: 'zh-TW', + 0x0470: 'ig', + 0x103b: 'smj-NO', + 0x0422: 'uk', + 0x0483: 'co', + 0x0421: 'id', + 0x143b: 'smj', + 0x042e: 'hsb', + 0x041a: 'hr', + 0x045d: 'iu', + 0x0c3b: 'se-FI', + 0x0420: 'ur', + 0x101a: 'hr-BA', + 0x085d: 'iu-Latn', + 0x043b: 'se', + 0x0843: 'uz-Cyrl', + 0x0405: 'cs', + 0x083c: 'ga', + 0x083b: 'se-SE', + 0x0443: 'uz', + 0x0406: 'da', + 0x0434: 'xh', + 0x203b: 'sms', + 0x042a: 'vi', + 0x048c: 'prs', + 0x0435: 'zu', + 0x183b: 'sma-NO', + 0x0452: 'cy', + 0x0465: 'dv', + 0x0410: 'it', + 0x1c3b: 'sms', + 0x0488: 'wo', + 0x0813: 'nl-BE', + 0x0810: 'it-CH', + 0x044f: 'sa', + 0x0485: 'sah', + 0x0413: 'nl', + 0x0411: 'ja', + 0x1c1a: 'sr-Cyrl-BA', + 0x0478: 'ii', + 0x0c09: 'en-AU', + 0x044b: 'kn', + 0x0c1a: 'sr', + 0x046a: 'yo', + 0x2809: 'en-BZ', + 0x043f: 'kk', + 0x181a: 'sr-Latn-BA', + 0x1009: 'en-CA', + 0x0453: 'km', + 0x081a: 'sr-Latn', + 0x2409: 'en-029', + 0x0486: 'quc', + 0x046c: 'nso', + }, ]; diff --git a/src/glyph/BBox.js b/src/glyph/BBox.js index bba72370..43207f33 100644 --- a/src/glyph/BBox.js +++ b/src/glyph/BBox.js @@ -2,7 +2,12 @@ * Represents a glyph bounding box */ export default class BBox { - constructor(minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity) { + constructor( + minX = Infinity, + minY = Infinity, + maxX = -Infinity, + maxY = -Infinity, + ) { /** * The minimum X position in the bounding box * @type {number} diff --git a/src/glyph/CFFGlyph.js b/src/glyph/CFFGlyph.js index 1ac182f1..f992a45f 100644 --- a/src/glyph/CFFGlyph.js +++ b/src/glyph/CFFGlyph.js @@ -32,13 +32,14 @@ export default class CFFGlyph extends Glyph { let end = str.offset + str.length; stream.pos = str.offset; - let path = new Path; + let path = new Path(); let stack = []; let trans = []; let width = null; let nStems = 0; - let x = 0, y = 0; + let x = 0, + y = 0; let usedGsubrs; let usedSubrs; let open = false; @@ -69,7 +70,7 @@ export default class CFFGlyph extends Glyph { } nStems += stack.length >> 1; - return stack.length = 0; + return (stack.length = 0); } function moveTo(x, y) { @@ -91,8 +92,8 @@ export default class CFFGlyph extends Glyph { let pts; switch (op) { - case 1: // hstem - case 3: // vstem + case 1: // hstem + case 3: // vstem case 18: // hstemhm case 23: // vstemhm parseStems(); @@ -178,7 +179,8 @@ export default class CFFGlyph extends Glyph { } break; - case 15: { // vsindex + case 15: { + // vsindex if (cff.version < 2) { throw new Error('vsindex operator not supported in CFF v1'); } @@ -187,7 +189,8 @@ export default class CFFGlyph extends Glyph { break; } - case 16: { // blend + case 16: { + // blend if (cff.version < 2) { throw new Error('blend operator not supported in CFF v1'); } @@ -196,7 +199,10 @@ export default class CFFGlyph extends Glyph { throw new Error('blend operator in non-variation font'); } - let blendVector = variationProcessor.getBlendVector(vstore, vsindex); + let blendVector = variationProcessor.getBlendVector( + vstore, + vsindex, + ); let numBlends = stack.pop(); let numOperands = numBlends * blendVector.length; let delta = stack.length - numOperands; @@ -557,7 +563,8 @@ export default class CFFGlyph extends Glyph { pts.push(x, y); } - if (Math.abs(x - startx) > Math.abs(y - starty)) { // horizontal + if (Math.abs(x - startx) > Math.abs(y - starty)) { + // horizontal x += stack.shift(); y = starty; } else { @@ -578,7 +585,6 @@ export default class CFFGlyph extends Glyph { default: throw new Error(`Unknown op: ${op}`); } - } else if (op < 247) { stack.push(op - 139); } else if (op < 251) { diff --git a/src/glyph/COLRGlyph.js b/src/glyph/COLRGlyph.js index 85d594b6..a448e686 100644 --- a/src/glyph/COLRGlyph.js +++ b/src/glyph/COLRGlyph.js @@ -17,7 +17,7 @@ export default class COLRGlyph extends Glyph { type = 'COLR'; _getBBox() { - let bbox = new BBox; + let bbox = new BBox(); for (let i = 0; i < this.layers.length; i++) { let layer = this.layers[i]; let b = layer.glyph.bbox; @@ -61,7 +61,7 @@ export default class COLRGlyph extends Glyph { red: 0, green: 0, blue: 0, - alpha: 255 + alpha: 255, }; return [new COLRLayer(g, color)]; @@ -69,7 +69,11 @@ export default class COLRGlyph extends Glyph { // otherwise, return an array of all the layers let layers = []; - for (let i = baseLayer.firstLayerIndex; i < baseLayer.firstLayerIndex + baseLayer.numLayers; i++) { + for ( + let i = baseLayer.firstLayerIndex; + i < baseLayer.firstLayerIndex + baseLayer.numLayers; + i++ + ) { var rec = colr.layerRecords[i]; var color = cpal.colorRecords[rec.paletteIndex]; var g = this._font._getBaseGlyph(rec.gid); @@ -80,8 +84,11 @@ export default class COLRGlyph extends Glyph { } render(ctx, size) { - for (let {glyph, color} of this.layers) { - ctx.fillColor([color.red, color.green, color.blue], color.alpha / 255 * 100); + for (let { glyph, color } of this.layers) { + ctx.fillColor( + [color.red, color.green, color.blue], + (color.alpha / 255) * 100, + ); glyph.render(ctx, size); } diff --git a/src/glyph/Glyph.js b/src/glyph/Glyph.js index 3eb7ed6f..845caa0f 100644 --- a/src/glyph/Glyph.js +++ b/src/glyph/Glyph.js @@ -1,6 +1,6 @@ import { cache } from '../cache'; import Path from './Path'; -import {isMark} from 'unicode-properties'; +import { isMark } from 'unicode-properties'; import StandardNames from './StandardNames'; /** @@ -53,29 +53,34 @@ export default class Glyph { let metric = table.metrics.get(table.metrics.length - 1); let res = { advance: metric ? metric.advance : 0, - bearing: table.bearings.get(this.id - table.metrics.length) || 0 + bearing: table.bearings.get(this.id - table.metrics.length) || 0, }; return res; } _getMetrics(cbox) { - if (this._metrics) { return this._metrics; } + if (this._metrics) { + return this._metrics; + } - let {advance:advanceWidth, bearing:leftBearing} = this._getTableMetrics(this._font.hmtx); + let { advance: advanceWidth, bearing: leftBearing } = this._getTableMetrics( + this._font.hmtx, + ); // For vertical metrics, use vmtx if available, or fall back to global data from OS/2 or hhea if (this._font.vmtx) { - var {advance:advanceHeight, bearing:topBearing} = this._getTableMetrics(this._font.vmtx); - + var { advance: advanceHeight, bearing: topBearing } = + this._getTableMetrics(this._font.vmtx); } else { let os2; - if (typeof cbox === 'undefined' || cbox === null) { ({ cbox } = this); } + if (typeof cbox === 'undefined' || cbox === null) { + ({ cbox } = this); + } if ((os2 = this._font['OS/2']) && os2.version > 0) { var advanceHeight = Math.abs(os2.typoAscender - os2.typoDescender); var topBearing = os2.typoAscender - cbox.maxY; - } else { let { hhea } = this._font; var advanceHeight = Math.abs(hhea.ascent - hhea.descent); @@ -84,10 +89,18 @@ export default class Glyph { } if (this._font._variationProcessor && this._font.HVAR) { - advanceWidth += this._font._variationProcessor.getAdvanceAdjustment(this.id, this._font.HVAR); + advanceWidth += this._font._variationProcessor.getAdvanceAdjustment( + this.id, + this._font.HVAR, + ); } - return this._metrics = { advanceWidth, advanceHeight, leftBearing, topBearing }; + return (this._metrics = { + advanceWidth, + advanceHeight, + leftBearing, + topBearing, + }); } /** @@ -130,7 +143,7 @@ export default class Glyph { * @return {Path} */ getScaledPath(size) { - let scale = 1 / this._font.unitsPerEm * size; + let scale = (1 / this._font.unitsPerEm) * size; return this.path.scale(scale); } @@ -194,7 +207,7 @@ export default class Glyph { render(ctx, size) { ctx.save(); - let scale = 1 / this._font.head.unitsPerEm * size; + let scale = (1 / this._font.head.unitsPerEm) * size; ctx.scale(scale, scale); let fn = this.path.toFunction(); @@ -211,5 +224,5 @@ cache(Glyph, { path: 'once', advanceWidth: 'once', advanceHeight: 'once', - name: 'once' + name: 'once', }); diff --git a/src/glyph/GlyphVariationProcessor.js b/src/glyph/GlyphVariationProcessor.js index 78662795..adbcda20 100644 --- a/src/glyph/GlyphVariationProcessor.js +++ b/src/glyph/GlyphVariationProcessor.js @@ -1,14 +1,14 @@ const TUPLES_SHARE_POINT_NUMBERS = 0x8000; -const TUPLE_COUNT_MASK = 0x0fff; -const EMBEDDED_TUPLE_COORD = 0x8000; -const INTERMEDIATE_TUPLE = 0x4000; -const PRIVATE_POINT_NUMBERS = 0x2000; -const TUPLE_INDEX_MASK = 0x0fff; -const POINTS_ARE_WORDS = 0x80; -const POINT_RUN_COUNT_MASK = 0x7f; -const DELTAS_ARE_ZERO = 0x80; -const DELTAS_ARE_WORDS = 0x40; -const DELTA_RUN_COUNT_MASK = 0x3f; +const TUPLE_COUNT_MASK = 0x0fff; +const EMBEDDED_TUPLE_COORD = 0x8000; +const INTERMEDIATE_TUPLE = 0x4000; +const PRIVATE_POINT_NUMBERS = 0x2000; +const TUPLE_INDEX_MASK = 0x0fff; +const POINTS_ARE_WORDS = 0x80; +const POINT_RUN_COUNT_MASK = 0x7f; +const DELTAS_ARE_ZERO = 0x80; +const DELTAS_ARE_WORDS = 0x40; +const DELTA_RUN_COUNT_MASK = 0x3f; /** * This class is transforms TrueType glyphs according to the data from @@ -25,7 +25,7 @@ export default class GlyphVariationProcessor { constructor(font, coords) { this.font = font; this.normalizedCoords = this.normalizeCoords(coords); - this.blendVectors = new Map; + this.blendVectors = new Map(); } normalizeCoords(coords) { @@ -35,9 +35,15 @@ export default class GlyphVariationProcessor { for (var i = 0; i < this.font.fvar.axis.length; i++) { let axis = this.font.fvar.axis[i]; if (coords[i] < axis.defaultValue) { - normalized.push((coords[i] - axis.defaultValue + Number.EPSILON) / (axis.defaultValue - axis.minValue + Number.EPSILON)); + normalized.push( + (coords[i] - axis.defaultValue + Number.EPSILON) / + (axis.defaultValue - axis.minValue + Number.EPSILON), + ); } else { - normalized.push((coords[i] - axis.defaultValue + Number.EPSILON) / (axis.maxValue - axis.defaultValue + Number.EPSILON)); + normalized.push( + (coords[i] - axis.defaultValue + Number.EPSILON) / + (axis.maxValue - axis.defaultValue + Number.EPSILON), + ); } } @@ -50,8 +56,11 @@ export default class GlyphVariationProcessor { let pair = segment.correspondence[j]; if (j >= 1 && normalized[i] < pair.fromCoord) { let prev = segment.correspondence[j - 1]; - normalized[i] = ((normalized[i] - prev.fromCoord) * (pair.toCoord - prev.toCoord) + Number.EPSILON) / - (pair.fromCoord - prev.fromCoord + Number.EPSILON) + + normalized[i] = + ((normalized[i] - prev.fromCoord) * + (pair.toCoord - prev.toCoord) + + Number.EPSILON) / + (pair.fromCoord - prev.fromCoord + Number.EPSILON) + prev.toCoord; break; @@ -64,13 +73,19 @@ export default class GlyphVariationProcessor { } transformPoints(gid, glyphPoints) { - if (!this.font.fvar || !this.font.gvar) { return; } + if (!this.font.fvar || !this.font.gvar) { + return; + } let { gvar } = this.font; - if (gid >= gvar.glyphCount) { return; } + if (gid >= gvar.glyphCount) { + return; + } let offset = gvar.offsets[gid]; - if (offset === gvar.offsets[gid + 1]) { return; } + if (offset === gvar.offsets[gid + 1]) { + return; + } // Read the gvar data for this glyph let { stream } = this.font; @@ -90,7 +105,7 @@ export default class GlyphVariationProcessor { stream.pos = here; } - let origPoints = glyphPoints.map(pt => pt.copy()); + let origPoints = glyphPoints.map((pt) => pt.copy()); tupleCount &= TUPLE_COUNT_MASK; for (let i = 0; i < tupleCount; i++) { @@ -102,7 +117,6 @@ export default class GlyphVariationProcessor { for (let a = 0; a < gvar.axisCount; a++) { tupleCoords.push(stream.readInt16BE() / 16384); } - } else { if ((tupleIndex & TUPLE_INDEX_MASK) >= gvar.globalCoordCount) { throw new Error('Invalid gvar table'); @@ -124,7 +138,12 @@ export default class GlyphVariationProcessor { } // Get the factor at which to apply this tuple - let factor = this.tupleFactor(tupleIndex, tupleCoords, startCoords, endCoords); + let factor = this.tupleFactor( + tupleIndex, + tupleCoords, + startCoords, + endCoords, + ); if (factor === 0) { offsetToData += tupleDataSize; continue; @@ -144,14 +163,15 @@ export default class GlyphVariationProcessor { let xDeltas = this.decodeDeltas(nPoints); let yDeltas = this.decodeDeltas(nPoints); - if (points.length === 0) { // all points + if (points.length === 0) { + // all points for (let i = 0; i < glyphPoints.length; i++) { var point = glyphPoints[i]; point.x += Math.round(xDeltas[i] * factor); point.y += Math.round(yDeltas[i] * factor); } } else { - let outPoints = origPoints.map(pt => pt.copy()); + let outPoints = origPoints.map((pt) => pt.copy()); let hasDelta = glyphPoints.map(() => false); for (let i = 0; i < points.length; i++) { @@ -186,7 +206,7 @@ export default class GlyphVariationProcessor { let count = stream.readUInt8(); if (count & POINTS_ARE_WORDS) { - count = (count & POINT_RUN_COUNT_MASK) << 8 | stream.readUInt8(); + count = ((count & POINT_RUN_COUNT_MASK) << 8) | stream.readUInt8(); } let points = new Uint16Array(count); @@ -217,7 +237,6 @@ export default class GlyphVariationProcessor { if (run & DELTAS_ARE_ZERO) { i += runCount; - } else { let fn = run & DELTAS_ARE_WORDS ? stream.readInt16BE : stream.readInt8; for (let j = 0; j < runCount && i < count; j++) { @@ -244,22 +263,27 @@ export default class GlyphVariationProcessor { } if ((tupleIndex & INTERMEDIATE_TUPLE) === 0) { - if ((normalized[i] < Math.min(0, tupleCoords[i])) || - (normalized[i] > Math.max(0, tupleCoords[i]))) { + if ( + normalized[i] < Math.min(0, tupleCoords[i]) || + normalized[i] > Math.max(0, tupleCoords[i]) + ) { return 0; } - factor = (factor * normalized[i] + Number.EPSILON) / (tupleCoords[i] + Number.EPSILON); + factor = + (factor * normalized[i] + Number.EPSILON) / + (tupleCoords[i] + Number.EPSILON); } else { - if ((normalized[i] < startCoords[i]) || - (normalized[i] > endCoords[i])) { + if (normalized[i] < startCoords[i] || normalized[i] > endCoords[i]) { return 0; - } else if (normalized[i] < tupleCoords[i]) { - factor = factor * (normalized[i] - startCoords[i] + Number.EPSILON) / (tupleCoords[i] - startCoords[i] + Number.EPSILON); - + factor = + (factor * (normalized[i] - startCoords[i] + Number.EPSILON)) / + (tupleCoords[i] - startCoords[i] + Number.EPSILON); } else { - factor = factor * (endCoords[i] - normalized[i] + Number.EPSILON) / (endCoords[i] - tupleCoords[i] + Number.EPSILON); + factor = + (factor * (endCoords[i] - normalized[i] + Number.EPSILON)) / + (endCoords[i] - tupleCoords[i] + Number.EPSILON); } } } @@ -302,7 +326,14 @@ export default class GlyphVariationProcessor { while (point <= endPoint) { // find the next point with a delta, and interpolate intermediate points if (hasDelta[point]) { - this.deltaInterpolate(curDelta + 1, point - 1, curDelta, point, inPoints, points); + this.deltaInterpolate( + curDelta + 1, + point - 1, + curDelta, + point, + inPoints, + points, + ); curDelta = point; } @@ -314,10 +345,24 @@ export default class GlyphVariationProcessor { this.deltaShift(firstPoint, endPoint, curDelta, inPoints, points); } else { // otherwise, handle the remaining points at the end and beginning of the contour - this.deltaInterpolate(curDelta + 1, endPoint, curDelta, firstDelta, inPoints, points); + this.deltaInterpolate( + curDelta + 1, + endPoint, + curDelta, + firstDelta, + inPoints, + points, + ); if (firstDelta > 0) { - this.deltaInterpolate(firstPoint, firstDelta - 1, curDelta, firstDelta, inPoints, points); + this.deltaInterpolate( + firstPoint, + firstDelta - 1, + curDelta, + firstDelta, + inPoints, + points, + ); } } @@ -392,7 +437,7 @@ export default class GlyphVariationProcessor { } let entryFormat = table.advanceWidthMapping.entryFormat; - ({outerIndex, innerIndex} = table.advanceWidthMapping.mapData[idx]); + ({ outerIndex, innerIndex } = table.advanceWidthMapping.mapData[idx]); } else { outerIndex = 0; innerIndex = gid; @@ -446,29 +491,40 @@ export default class GlyphVariationProcessor { // compute the scalar contribution of this axis // ignore invalid ranges - if (axis.startCoord > axis.peakCoord || axis.peakCoord > axis.endCoord) { + if ( + axis.startCoord > axis.peakCoord || + axis.peakCoord > axis.endCoord + ) { axisScalar = 1; - - } else if (axis.startCoord < 0 && axis.endCoord > 0 && axis.peakCoord !== 0) { + } else if ( + axis.startCoord < 0 && + axis.endCoord > 0 && + axis.peakCoord !== 0 + ) { axisScalar = 1; - // peak of 0 means ignore this axis + // peak of 0 means ignore this axis } else if (axis.peakCoord === 0) { axisScalar = 1; - // ignore this region if coords are out of range - } else if (normalizedCoords[j] < axis.startCoord || normalizedCoords[j] > axis.endCoord) { + // ignore this region if coords are out of range + } else if ( + normalizedCoords[j] < axis.startCoord || + normalizedCoords[j] > axis.endCoord + ) { axisScalar = 0; - // calculate a proportional factor + // calculate a proportional factor } else { if (normalizedCoords[j] === axis.peakCoord) { axisScalar = 1; } else if (normalizedCoords[j] < axis.peakCoord) { - axisScalar = (normalizedCoords[j] - axis.startCoord + Number.EPSILON) / + axisScalar = + (normalizedCoords[j] - axis.startCoord + Number.EPSILON) / (axis.peakCoord - axis.startCoord + Number.EPSILON); } else { - axisScalar = (axis.endCoord - normalizedCoords[j] + Number.EPSILON) / + axisScalar = + (axis.endCoord - normalizedCoords[j] + Number.EPSILON) / (axis.endCoord - axis.peakCoord + Number.EPSILON); } } diff --git a/src/glyph/Path.js b/src/glyph/Path.js index a119fb28..c97a022e 100644 --- a/src/glyph/Path.js +++ b/src/glyph/Path.js @@ -5,7 +5,7 @@ const SVG_COMMANDS = { lineTo: 'L', quadraticCurveTo: 'Q', bezierCurveTo: 'C', - closePath: 'Z' + closePath: 'Z', }; /** @@ -27,10 +27,10 @@ export default class Path { * @return {string} */ toFunction() { - return ctx => { - this.commands.forEach(c => { - return ctx[c.command].apply(ctx, c.args) - }) + return (ctx) => { + this.commands.forEach((c) => { + return ctx[c.command].apply(ctx, c.args); + }); }; } @@ -39,8 +39,8 @@ export default class Path { * @return {string} */ toSVG() { - let cmds = this.commands.map(c => { - let args = c.args.map(arg => Math.round(arg * 100) / 100); + let cmds = this.commands.map((c) => { + let args = c.args.map((arg) => Math.round(arg * 100) / 100); return `${SVG_COMMANDS[c.command]}${args.join(' ')}`; }); @@ -56,7 +56,7 @@ export default class Path { */ get cbox() { if (!this._cbox) { - let cbox = new BBox; + let cbox = new BBox(); for (let command of this.commands) { for (let i = 0; i < command.args.length; i += 2) { cbox.addPoint(command.args[i], command.args[i + 1]); @@ -79,15 +79,15 @@ export default class Path { return this._bbox; } - let bbox = new BBox; - let cx = 0, cy = 0; + let bbox = new BBox(); + let cx = 0, + cy = 0; - let f = t => ( - Math.pow(1 - t, 3) * p0[i] - + 3 * Math.pow(1 - t, 2) * t * p1[i] - + 3 * (1 - t) * Math.pow(t, 2) * p2[i] - + Math.pow(t, 3) * p3[i] - ); + let f = (t) => + Math.pow(1 - t, 3) * p0[i] + + 3 * Math.pow(1 - t, 2) * t * p1[i] + + 3 * (1 - t) * Math.pow(t, 2) * p2[i] + + Math.pow(t, 3) * p3[i]; for (let c of this.commands) { switch (c.command) { @@ -104,10 +104,10 @@ export default class Path { if (c.command === 'quadraticCurveTo') { // http://fontforge.org/bezier.html var [qp1x, qp1y, p3x, p3y] = c.args; - var cp1x = cx + 2 / 3 * (qp1x - cx); // CP1 = QP0 + 2/3 * (QP1-QP0) - var cp1y = cy + 2 / 3 * (qp1y - cy); - var cp2x = p3x + 2 / 3 * (qp1x - p3x); // CP2 = QP2 + 2/3 * (QP1-QP2) - var cp2y = p3y + 2 / 3 * (qp1y - p3y); + var cp1x = cx + (2 / 3) * (qp1x - cx); // CP1 = QP0 + 2/3 * (QP1-QP0) + var cp1y = cy + (2 / 3) * (qp1y - cy); + var cp2x = p3x + (2 / 3) * (qp1x - p3x); // CP2 = QP2 + 2/3 * (QP1-QP2) + var cp2y = p3y + (2 / 3) * (qp1y - p3y); } else { var [cp1x, cp1y, cp2x, cp2y, p3x, p3y] = c.args; } @@ -172,7 +172,7 @@ export default class Path { } } - return this._bbox = Object.freeze(bbox); + return (this._bbox = Object.freeze(bbox)); } /** @@ -181,7 +181,7 @@ export default class Path { * @return {Path} */ mapPoints(fn) { - let path = new Path; + let path = new Path(); for (let c of this.commands) { let args = []; @@ -231,12 +231,18 @@ export default class Path { } } -for (let command of ['moveTo', 'lineTo', 'quadraticCurveTo', 'bezierCurveTo', 'closePath']) { - Path.prototype[command] = function(...args) { +for (let command of [ + 'moveTo', + 'lineTo', + 'quadraticCurveTo', + 'bezierCurveTo', + 'closePath', +]) { + Path.prototype[command] = function (...args) { this._bbox = this._cbox = null; this.commands.push({ command, - args + args, }); return this; diff --git a/src/glyph/SBIXGlyph.js b/src/glyph/SBIXGlyph.js index fda3b890..56955238 100644 --- a/src/glyph/SBIXGlyph.js +++ b/src/glyph/SBIXGlyph.js @@ -5,7 +5,7 @@ let SBIXImage = new r.Struct({ originX: r.uint16, originY: r.uint16, type: new r.String(4), - data: new r.Buffer(t => t.parent.buflen - t._currentOffset) + data: new r.Buffer((t) => t.parent.buflen - t._currentOffset), }); /** @@ -25,7 +25,9 @@ export default class SBIXGlyph extends TTFGlyph { getImageForSize(size) { for (let i = 0; i < this._font.sbix.imageTables.length; i++) { var table = this._font.sbix.imageTables[i]; - if (table.ppem >= size) { break; } + if (table.ppem >= size) { + break; + } } let offsets = table.imageOffsets; @@ -37,14 +39,18 @@ export default class SBIXGlyph extends TTFGlyph { } this._font.stream.pos = start; - return SBIXImage.decode(this._font.stream, {buflen: end - start}); + return SBIXImage.decode(this._font.stream, { buflen: end - start }); } render(ctx, size) { let img = this.getImageForSize(size); if (img != null) { let scale = size / this._font.unitsPerEm; - ctx.image(img.data, {height: size, x: img.originX, y: (this.bbox.minY - img.originY) * scale}); + ctx.image(img.data, { + height: size, + x: img.originX, + y: (this.bbox.minY - img.originY) * scale, + }); } if (this._font.sbix.flags.renderOutlines) { diff --git a/src/glyph/StandardNames.js b/src/glyph/StandardNames.js index 7c024a1f..18071e71 100644 --- a/src/glyph/StandardNames.js +++ b/src/glyph/StandardNames.js @@ -1,27 +1,260 @@ export default [ - '.notdef', '.null', 'nonmarkingreturn', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', - 'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', - 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', - 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', - 'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', - 'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', 'Odieresis', 'Udieresis', 'aacute', 'agrave', - 'acircumflex', 'adieresis', 'atilde', 'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis', - 'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute', 'ograve', 'ocircumflex', 'odieresis', - 'otilde', 'uacute', 'ugrave', 'ucircumflex', 'udieresis', 'dagger', 'degree', 'cent', 'sterling', 'section', - 'bullet', 'paragraph', 'germandbls', 'registered', 'copyright', 'trademark', 'acute', 'dieresis', 'notequal', - 'AE', 'Oslash', 'infinity', 'plusminus', 'lessequal', 'greaterequal', 'yen', 'mu', 'partialdiff', 'summation', - 'product', 'pi', 'integral', 'ordfeminine', 'ordmasculine', 'Omega', 'ae', 'oslash', 'questiondown', - 'exclamdown', 'logicalnot', 'radical', 'florin', 'approxequal', 'Delta', 'guillemotleft', 'guillemotright', - 'ellipsis', 'nonbreakingspace', 'Agrave', 'Atilde', 'Otilde', 'OE', 'oe', 'endash', 'emdash', 'quotedblleft', - 'quotedblright', 'quoteleft', 'quoteright', 'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction', - 'currency', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl', 'periodcentered', 'quotesinglbase', - 'quotedblbase', 'perthousand', 'Acircumflex', 'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute', - 'Icircumflex', 'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple', 'Ograve', 'Uacute', 'Ucircumflex', - 'Ugrave', 'dotlessi', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut', - 'ogonek', 'caron', 'Lslash', 'lslash', 'Scaron', 'scaron', 'Zcaron', 'zcaron', 'brokenbar', 'Eth', 'eth', - 'Yacute', 'yacute', 'Thorn', 'thorn', 'minus', 'multiply', 'onesuperior', 'twosuperior', 'threesuperior', - 'onehalf', 'onequarter', 'threequarters', 'franc', 'Gbreve', 'gbreve', 'Idotaccent', 'Scedilla', 'scedilla', - 'Cacute', 'cacute', 'Ccaron', 'ccaron', 'dcroat' + '.notdef', + '.null', + 'nonmarkingreturn', + 'space', + 'exclam', + 'quotedbl', + 'numbersign', + 'dollar', + 'percent', + 'ampersand', + 'quotesingle', + 'parenleft', + 'parenright', + 'asterisk', + 'plus', + 'comma', + 'hyphen', + 'period', + 'slash', + 'zero', + 'one', + 'two', + 'three', + 'four', + 'five', + 'six', + 'seven', + 'eight', + 'nine', + 'colon', + 'semicolon', + 'less', + 'equal', + 'greater', + 'question', + 'at', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'bracketleft', + 'backslash', + 'bracketright', + 'asciicircum', + 'underscore', + 'grave', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + 'braceleft', + 'bar', + 'braceright', + 'asciitilde', + 'Adieresis', + 'Aring', + 'Ccedilla', + 'Eacute', + 'Ntilde', + 'Odieresis', + 'Udieresis', + 'aacute', + 'agrave', + 'acircumflex', + 'adieresis', + 'atilde', + 'aring', + 'ccedilla', + 'eacute', + 'egrave', + 'ecircumflex', + 'edieresis', + 'iacute', + 'igrave', + 'icircumflex', + 'idieresis', + 'ntilde', + 'oacute', + 'ograve', + 'ocircumflex', + 'odieresis', + 'otilde', + 'uacute', + 'ugrave', + 'ucircumflex', + 'udieresis', + 'dagger', + 'degree', + 'cent', + 'sterling', + 'section', + 'bullet', + 'paragraph', + 'germandbls', + 'registered', + 'copyright', + 'trademark', + 'acute', + 'dieresis', + 'notequal', + 'AE', + 'Oslash', + 'infinity', + 'plusminus', + 'lessequal', + 'greaterequal', + 'yen', + 'mu', + 'partialdiff', + 'summation', + 'product', + 'pi', + 'integral', + 'ordfeminine', + 'ordmasculine', + 'Omega', + 'ae', + 'oslash', + 'questiondown', + 'exclamdown', + 'logicalnot', + 'radical', + 'florin', + 'approxequal', + 'Delta', + 'guillemotleft', + 'guillemotright', + 'ellipsis', + 'nonbreakingspace', + 'Agrave', + 'Atilde', + 'Otilde', + 'OE', + 'oe', + 'endash', + 'emdash', + 'quotedblleft', + 'quotedblright', + 'quoteleft', + 'quoteright', + 'divide', + 'lozenge', + 'ydieresis', + 'Ydieresis', + 'fraction', + 'currency', + 'guilsinglleft', + 'guilsinglright', + 'fi', + 'fl', + 'daggerdbl', + 'periodcentered', + 'quotesinglbase', + 'quotedblbase', + 'perthousand', + 'Acircumflex', + 'Ecircumflex', + 'Aacute', + 'Edieresis', + 'Egrave', + 'Iacute', + 'Icircumflex', + 'Idieresis', + 'Igrave', + 'Oacute', + 'Ocircumflex', + 'apple', + 'Ograve', + 'Uacute', + 'Ucircumflex', + 'Ugrave', + 'dotlessi', + 'circumflex', + 'tilde', + 'macron', + 'breve', + 'dotaccent', + 'ring', + 'cedilla', + 'hungarumlaut', + 'ogonek', + 'caron', + 'Lslash', + 'lslash', + 'Scaron', + 'scaron', + 'Zcaron', + 'zcaron', + 'brokenbar', + 'Eth', + 'eth', + 'Yacute', + 'yacute', + 'Thorn', + 'thorn', + 'minus', + 'multiply', + 'onesuperior', + 'twosuperior', + 'threesuperior', + 'onehalf', + 'onequarter', + 'threequarters', + 'franc', + 'Gbreve', + 'gbreve', + 'Idotaccent', + 'Scedilla', + 'scedilla', + 'Cacute', + 'cacute', + 'Ccaron', + 'ccaron', + 'dcroat', ]; diff --git a/src/glyph/TTFGlyph.js b/src/glyph/TTFGlyph.js index 9ebd441a..ed253076 100644 --- a/src/glyph/TTFGlyph.js +++ b/src/glyph/TTFGlyph.js @@ -6,32 +6,32 @@ import * as r from 'restructure'; // The header for both simple and composite glyphs let GlyfHeader = new r.Struct({ numberOfContours: r.int16, // if negative, this is a composite glyph - xMin: r.int16, - yMin: r.int16, - xMax: r.int16, - yMax: r.int16 + xMin: r.int16, + yMin: r.int16, + xMax: r.int16, + yMax: r.int16, }); // Flags for simple glyphs -const ON_CURVE = 1 << 0; -const X_SHORT_VECTOR = 1 << 1; -const Y_SHORT_VECTOR = 1 << 2; -const REPEAT = 1 << 3; -const SAME_X = 1 << 4; -const SAME_Y = 1 << 5; +const ON_CURVE = 1 << 0; +const X_SHORT_VECTOR = 1 << 1; +const Y_SHORT_VECTOR = 1 << 2; +const REPEAT = 1 << 3; +const SAME_X = 1 << 4; +const SAME_Y = 1 << 5; // Flags for composite glyphs -const ARG_1_AND_2_ARE_WORDS = 1 << 0; -const ARGS_ARE_XY_VALUES = 1 << 1; -const ROUND_XY_TO_GRID = 1 << 2; -const WE_HAVE_A_SCALE = 1 << 3; -const MORE_COMPONENTS = 1 << 5; -const WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6; -const WE_HAVE_A_TWO_BY_TWO = 1 << 7; -const WE_HAVE_INSTRUCTIONS = 1 << 8; -const USE_MY_METRICS = 1 << 9; -const OVERLAP_COMPOUND = 1 << 10; -const SCALED_COMPONENT_OFFSET = 1 << 11; +const ARG_1_AND_2_ARE_WORDS = 1 << 0; +const ARGS_ARE_XY_VALUES = 1 << 1; +const ROUND_XY_TO_GRID = 1 << 2; +const WE_HAVE_A_SCALE = 1 << 3; +const MORE_COMPONENTS = 1 << 5; +const WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6; +const WE_HAVE_A_TWO_BY_TWO = 1 << 7; +const WE_HAVE_INSTRUCTIONS = 1 << 8; +const USE_MY_METRICS = 1 << 9; +const OVERLAP_COMPOUND = 1 << 10; +const SCALED_COMPONENT_OFFSET = 1 << 11; const UNSCALED_COMPONENT_OFFSET = 1 << 12; // Represents a point in a simple glyph @@ -109,7 +109,9 @@ export default class TTFGlyph extends Glyph { let nextPos = this._font.loca.offsets[this.id + 1]; // Nothing to do if there is no data for this glyph - if (glyfPos === nextPos) { return null; } + if (glyfPos === nextPos) { + return null; + } let stream = this._font._getTableStream('glyf'); stream.pos += glyfPos; @@ -119,7 +121,6 @@ export default class TTFGlyph extends Glyph { if (glyph.numberOfContours > 0) { this._decodeSimple(glyph, stream); - } else if (glyph.numberOfContours < 0) { this._decodeComposite(glyph, stream, startPos); } @@ -131,7 +132,9 @@ export default class TTFGlyph extends Glyph { // this is a simple glyph glyph.points = []; - let endPtsOfContours = new r.Array(r.uint16, glyph.numberOfContours).decode(stream); + let endPtsOfContours = new r.Array(r.uint16, glyph.numberOfContours).decode( + stream, + ); glyph.instructions = new r.Array(r.uint8, r.uint16).decode(stream); let flags = []; @@ -152,20 +155,35 @@ export default class TTFGlyph extends Glyph { for (var i = 0; i < flags.length; i++) { var flag = flags[i]; - let point = new Point(!!(flag & ON_CURVE), endPtsOfContours.indexOf(i) >= 0, 0, 0); + let point = new Point( + !!(flag & ON_CURVE), + endPtsOfContours.indexOf(i) >= 0, + 0, + 0, + ); glyph.points.push(point); } let px = 0; for (var i = 0; i < flags.length; i++) { var flag = flags[i]; - glyph.points[i].x = px = this._parseGlyphCoord(stream, px, flag & X_SHORT_VECTOR, flag & SAME_X); + glyph.points[i].x = px = this._parseGlyphCoord( + stream, + px, + flag & X_SHORT_VECTOR, + flag & SAME_X, + ); } let py = 0; for (var i = 0; i < flags.length; i++) { var flag = flags[i]; - glyph.points[i].y = py = this._parseGlyphCoord(stream, py, flag & Y_SHORT_VECTOR, flag & SAME_Y); + glyph.points[i].y = py = this._parseGlyphCoord( + stream, + py, + flag & Y_SHORT_VECTOR, + flag & SAME_Y, + ); } if (this._font._variationProcessor) { @@ -206,18 +224,29 @@ export default class TTFGlyph extends Glyph { if (flags & WE_HAVE_A_SCALE) { // fixed number with 14 bits of fraction - component.scaleX = - component.scaleY = ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / 1073741824; - + component.scaleX = component.scaleY = + ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / + 1073741824; } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { - component.scaleX = ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / 1073741824; - component.scaleY = ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / 1073741824; - + component.scaleX = + ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / + 1073741824; + component.scaleY = + ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / + 1073741824; } else if (flags & WE_HAVE_A_TWO_BY_TWO) { - component.scaleX = ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / 1073741824; - component.scale01 = ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / 1073741824; - component.scale10 = ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / 1073741824; - component.scaleY = ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / 1073741824; + component.scaleX = + ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / + 1073741824; + component.scale01 = + ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / + 1073741824; + component.scale10 = + ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / + 1073741824; + component.scaleY = + ((stream.readUInt8() << 24) | (stream.readUInt8() << 16)) / + 1073741824; } glyph.components.push(component); @@ -257,13 +286,14 @@ export default class TTFGlyph extends Glyph { this._defaultMetrics = Object.assign({}, this._metrics); } - let { advanceWidth, advanceHeight, leftBearing, topBearing } = this._defaultMetrics; + let { advanceWidth, advanceHeight, leftBearing, topBearing } = + this._defaultMetrics; return [ new Point(false, true, glyph.xMin - leftBearing, 0), new Point(false, true, glyph.xMin - leftBearing + advanceWidth, 0), new Point(false, true, 0, glyph.yMax + topBearing), - new Point(false, true, 0, glyph.yMax + topBearing + advanceHeight) + new Point(false, true, 0, glyph.yMax + topBearing + advanceHeight), ]; } @@ -284,8 +314,14 @@ export default class TTFGlyph extends Glyph { let contour = contours[i]; for (let j = 0; j < contour.length; j++) { let point = contour[j]; - let x = point.x * component.scaleX + point.y * component.scale10 + component.dx; - let y = point.y * component.scaleY + point.x * component.scale01 + component.dy; + let x = + point.x * component.scaleX + + point.y * component.scale10 + + component.dx; + let y = + point.y * component.scaleY + + point.x * component.scale01 + + component.dy; points.push(new Point(point.onCurve, point.endContour, x, y)); } } @@ -296,10 +332,12 @@ export default class TTFGlyph extends Glyph { // Recompute and cache metrics if we performed variation processing, and don't have an HVAR table if (glyph.phantomPoints && !this._font.directory.tables.HVAR) { - this._metrics.advanceWidth = glyph.phantomPoints[1].x - glyph.phantomPoints[0].x; - this._metrics.advanceHeight = glyph.phantomPoints[3].y - glyph.phantomPoints[2].y; - this._metrics.leftBearing = glyph.xMin - glyph.phantomPoints[0].x; - this._metrics.topBearing = glyph.phantomPoints[2].y - glyph.yMax; + this._metrics.advanceWidth = + glyph.phantomPoints[1].x - glyph.phantomPoints[0].x; + this._metrics.advanceHeight = + glyph.phantomPoints[3].y - glyph.phantomPoints[2].y; + this._metrics.leftBearing = glyph.xMin - glyph.phantomPoints[0].x; + this._metrics.topBearing = glyph.phantomPoints[2].y - glyph.yMax; } let contours = []; @@ -335,7 +373,7 @@ export default class TTFGlyph extends Glyph { // Converts contours to a Path object that can be rendered _getPath() { let contours = this._getContours(); - let path = new Path; + let path = new Path(); for (let i = 0; i < contours.length; i++) { let contour = contours[i]; @@ -353,7 +391,12 @@ export default class TTFGlyph extends Glyph { firstPt = lastPt; } else { // Start at the middle if both the first and last points are off curve - firstPt = new Point(false, false, (firstPt.x + lastPt.x) / 2, (firstPt.y + lastPt.y) / 2); + firstPt = new Point( + false, + false, + (firstPt.x + lastPt.x) / 2, + (firstPt.y + lastPt.y) / 2, + ); } var curvePt = firstPt; @@ -367,22 +410,18 @@ export default class TTFGlyph extends Glyph { if (prevPt.onCurve && pt.onCurve) { path.lineTo(pt.x, pt.y); - } else if (prevPt.onCurve && !pt.onCurve) { var curvePt = pt; - } else if (!prevPt.onCurve && !pt.onCurve) { let midX = (prevPt.x + pt.x) / 2; let midY = (prevPt.y + pt.y) / 2; path.quadraticCurveTo(prevPt.x, prevPt.y, midX, midY); var curvePt = pt; - } else if (!prevPt.onCurve && pt.onCurve) { path.quadraticCurveTo(curvePt.x, curvePt.y, pt.x, pt.y); var curvePt = null; - } else { - throw new Error("Unknown TTF path state"); + throw new Error('Unknown TTF path state'); } } diff --git a/src/glyph/TTFGlyphEncoder.js b/src/glyph/TTFGlyphEncoder.js index 6ab8b73c..b26692b8 100644 --- a/src/glyph/TTFGlyphEncoder.js +++ b/src/glyph/TTFGlyphEncoder.js @@ -1,18 +1,18 @@ import * as r from 'restructure'; // Flags for simple glyphs -const ON_CURVE = 1 << 0; -const X_SHORT_VECTOR = 1 << 1; -const Y_SHORT_VECTOR = 1 << 2; -const REPEAT = 1 << 3; -const SAME_X = 1 << 4; -const SAME_Y = 1 << 5; +const ON_CURVE = 1 << 0; +const X_SHORT_VECTOR = 1 << 1; +const Y_SHORT_VECTOR = 1 << 2; +const REPEAT = 1 << 3; +const SAME_X = 1 << 4; +const SAME_Y = 1 << 5; class Point { static size(val) { return val >= 0 && val <= 255 ? 1 : 2; } - + static encode(stream, value) { if (value >= 0 && value <= 255) { stream.writeUInt8(value); @@ -32,7 +32,7 @@ let Glyf = new r.Struct({ instructions: new r.Array(r.uint8, r.uint16), flags: new r.Array(r.uint8, 0), xPoints: new r.Array(Point, 0), - yPoints: new r.Array(Point, 0) + yPoints: new r.Array(Point, 0), }); /** @@ -45,17 +45,19 @@ export default class TTFGlyphEncoder { let yPoints = []; let flags = []; let same = 0; - let lastX = 0, lastY = 0, lastFlag = 0; + let lastX = 0, + lastY = 0, + lastFlag = 0; let pointCount = 0; - + for (let i = 0; i < path.commands.length; i++) { let c = path.commands[i]; - + for (let j = 0; j < c.args.length; j += 2) { let x = c.args[j]; let y = c.args[j + 1]; let flag = 0; - + // If the ending point of a quadratic curve is the midpoint // between the control point and the control point of the next // quadratic curve, we can omit the ending point. @@ -64,21 +66,35 @@ export default class TTFGlyphEncoder { if (next && next.command === 'quadraticCurveTo') { let midX = (lastX + next.args[0]) / 2; let midY = (lastY + next.args[1]) / 2; - + if (x === midX && y === midY) { continue; } } } - + // All points except control points are on curve. if (!(c.command === 'quadraticCurveTo' && j === 0)) { flag |= ON_CURVE; } - - flag = this._encodePoint(x, lastX, xPoints, flag, X_SHORT_VECTOR, SAME_X); - flag = this._encodePoint(y, lastY, yPoints, flag, Y_SHORT_VECTOR, SAME_Y); - + + flag = this._encodePoint( + x, + lastX, + xPoints, + flag, + X_SHORT_VECTOR, + SAME_X, + ); + flag = this._encodePoint( + y, + lastY, + yPoints, + flag, + Y_SHORT_VECTOR, + SAME_Y, + ); + if (flag === lastFlag && same < 255) { flags[flags.length - 1] |= REPEAT; same++; @@ -87,26 +103,29 @@ export default class TTFGlyphEncoder { flags.push(same); same = 0; } - + flags.push(flag); lastFlag = flag; } - + lastX = x; lastY = y; pointCount++; } - + if (c.command === 'closePath') { endPtsOfContours.push(pointCount - 1); } } // Close the path if the last command didn't already - if (path.commands.length > 1 && path.commands[path.commands.length - 1].command !== 'closePath') { + if ( + path.commands.length > 1 && + path.commands[path.commands.length - 1].command !== 'closePath' + ) { endPtsOfContours.push(pointCount - 1); } - + let bbox = path.bbox; let glyf = { numberOfContours: endPtsOfContours.length, @@ -118,26 +137,26 @@ export default class TTFGlyphEncoder { instructions: instructions, flags: flags, xPoints: xPoints, - yPoints: yPoints + yPoints: yPoints, }; - + let size = Glyf.size(glyf); let tail = 4 - (size % 4); - + let stream = new r.EncodeStream(size + tail); Glyf.encode(stream, glyf); - + // Align to 4-byte length if (tail !== 0) { stream.fill(0, tail); } - + return stream.buffer; } - + _encodePoint(value, last, points, flag, shortFlag, sameFlag) { let diff = value - last; - + if (value === last) { flag |= sameFlag; } else { @@ -149,10 +168,10 @@ export default class TTFGlyphEncoder { flag |= sameFlag; } } - + points.push(diff); } - + return flag; } } diff --git a/src/index.js b/src/index.js index e27a7b25..03c0303c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,9 @@ -import { registerFormat, create, defaultLanguage, setDefaultLanguage } from './base'; +import { + registerFormat, + create, + defaultLanguage, + setDefaultLanguage, +} from './base'; import TTFFont from './TTFFont'; import WOFFFont from './WOFFFont'; import WOFF2Font from './WOFF2Font'; diff --git a/src/layout/GlyphRun.js b/src/layout/GlyphRun.js index 18e2f236..2303c095 100644 --- a/src/layout/GlyphRun.js +++ b/src/layout/GlyphRun.js @@ -69,10 +69,10 @@ export default class GlyphRun { return width; } - /** - * The total advance height of the run. - * @type {number} - */ + /** + * The total advance height of the run. + * @type {number} + */ get advanceHeight() { let height = 0; for (let position of this.positions) { @@ -82,12 +82,12 @@ export default class GlyphRun { return height; } - /** - * The bounding box containing all glyphs in the run. - * @type {BBox} - */ + /** + * The bounding box containing all glyphs in the run. + * @type {BBox} + */ get bbox() { - let bbox = new BBox; + let bbox = new BBox(); let x = 0; let y = 0; diff --git a/src/layout/KernProcessor.js b/src/layout/KernProcessor.js index 4d4f6db5..199cbde4 100644 --- a/src/layout/KernProcessor.js +++ b/src/layout/KernProcessor.js @@ -1,4 +1,4 @@ -import {binarySearch} from '../utils'; +import { binarySearch } from '../utils'; export default class KernProcessor { constructor(font) { @@ -43,7 +43,7 @@ export default class KernProcessor { switch (table.format) { case 0: let pairIdx = binarySearch(s.pairs, function (pair) { - return (left - pair.left) || (right - pair.right); + return left - pair.left || right - pair.right; }); if (pairIdx >= 0) { @@ -53,14 +53,21 @@ export default class KernProcessor { break; case 2: - let leftOffset = 0, rightOffset = 0; - if (left >= s.leftTable.firstGlyph && left < s.leftTable.firstGlyph + s.leftTable.nGlyphs) { + let leftOffset = 0, + rightOffset = 0; + if ( + left >= s.leftTable.firstGlyph && + left < s.leftTable.firstGlyph + s.leftTable.nGlyphs + ) { leftOffset = s.leftTable.offsets[left - s.leftTable.firstGlyph]; } else { leftOffset = s.array.off; } - if (right >= s.rightTable.firstGlyph && right < s.rightTable.firstGlyph + s.rightTable.nGlyphs) { + if ( + right >= s.rightTable.firstGlyph && + right < s.rightTable.firstGlyph + s.rightTable.nGlyphs + ) { rightOffset = s.rightTable.offsets[right - s.rightTable.firstGlyph]; } @@ -73,11 +80,18 @@ export default class KernProcessor { return 0; } - val = s.kernValue[s.kernIndex[s.leftClass[left] * s.rightClassCount + s.rightClass[right]]]; + val = + s.kernValue[ + s.kernIndex[ + s.leftClass[left] * s.rightClassCount + s.rightClass[right] + ] + ]; break; default: - throw new Error(`Unsupported kerning sub-table format ${table.format}`); + throw new Error( + `Unsupported kerning sub-table format ${table.format}`, + ); } // Microsoft supports the override flag, which resets the result diff --git a/src/layout/LayoutEngine.js b/src/layout/LayoutEngine.js index 1b035a72..47652d92 100644 --- a/src/layout/LayoutEngine.js +++ b/src/layout/LayoutEngine.js @@ -16,7 +16,6 @@ export default class LayoutEngine { // scripts are currently supported because the shaping logic is built into the font. if (this.font.morx) { this.engine = new AATLayoutEngine(this.font); - } else if (this.font.GSUB || this.font.GPOS) { this.engine = new OTLayoutEngine(this.font); } @@ -89,7 +88,9 @@ export default class LayoutEngine { position(glyphRun) { // Get initial glyph positions - glyphRun.positions = glyphRun.glyphs.map(glyph => new GlyphPosition(glyph.advanceWidth)); + glyphRun.positions = glyphRun.glyphs.map( + (glyph) => new GlyphPosition(glyph.advanceWidth), + ); let positioned = null; // Call the advanced layout engine. Returns the features applied. @@ -103,11 +104,18 @@ export default class LayoutEngine { this.unicodeLayoutEngine = new UnicodeLayoutEngine(this.font); } - this.unicodeLayoutEngine.positionGlyphs(glyphRun.glyphs, glyphRun.positions); + this.unicodeLayoutEngine.positionGlyphs( + glyphRun.glyphs, + glyphRun.positions, + ); } // if kerning is not supported by GPOS, do kerning with the TrueType/AAT kern table - if ((!positioned || !positioned.kern) && glyphRun.features.kern !== false && this.font.kern) { + if ( + (!positioned || !positioned.kern) && + glyphRun.features.kern !== false && + this.font.kern + ) { if (!this.kernProcessor) { this.kernProcessor = new KernProcessor(this.font); } @@ -136,22 +144,40 @@ export default class LayoutEngine { if (plane === 0) { // BMP switch (ch >> 8) { - case 0x00: return ch === 0x00AD; - case 0x03: return ch === 0x034F; - case 0x06: return ch === 0x061C; - case 0x17: return 0x17B4 <= ch && ch <= 0x17B5; - case 0x18: return 0x180B <= ch && ch <= 0x180E; - case 0x20: return (0x200B <= ch && ch <= 0x200F) || (0x202A <= ch && ch <= 0x202E) || (0x2060 <= ch && ch <= 0x206F); - case 0xFE: return (0xFE00 <= ch && ch <= 0xFE0F) || ch === 0xFEFF; - case 0xFF: return 0xFFF0 <= ch && ch <= 0xFFF8; - default: return false; + case 0x00: + return ch === 0x00ad; + case 0x03: + return ch === 0x034f; + case 0x06: + return ch === 0x061c; + case 0x17: + return 0x17b4 <= ch && ch <= 0x17b5; + case 0x18: + return 0x180b <= ch && ch <= 0x180e; + case 0x20: + return ( + (0x200b <= ch && ch <= 0x200f) || + (0x202a <= ch && ch <= 0x202e) || + (0x2060 <= ch && ch <= 0x206f) + ); + case 0xfe: + return (0xfe00 <= ch && ch <= 0xfe0f) || ch === 0xfeff; + case 0xff: + return 0xfff0 <= ch && ch <= 0xfff8; + default: + return false; } } else { // Other planes switch (plane) { - case 0x01: return (0x1BCA0 <= ch && ch <= 0x1BCA3) || (0x1D173 <= ch && ch <= 0x1D17A); - case 0x0E: return 0xE0000 <= ch && ch <= 0xE0FFF; - default: return false; + case 0x01: + return ( + (0x1bca0 <= ch && ch <= 0x1bca3) || (0x1d173 <= ch && ch <= 0x1d17a) + ); + case 0x0e: + return 0xe0000 <= ch && ch <= 0xe0fff; + default: + return false; } } } @@ -171,7 +197,7 @@ export default class LayoutEngine { } stringsForGlyph(gid) { - let result = new Set; + let result = new Set(); let codePoints = this.font._cmapProcessor.codePointsForGlyph(gid); for (let codePoint of codePoints) { diff --git a/src/layout/Script.js b/src/layout/Script.js index 80106b64..98a3bc1a 100644 --- a/src/layout/Script.js +++ b/src/layout/Script.js @@ -1,4 +1,4 @@ -import {getScript} from 'unicode-properties'; +import { getScript } from 'unicode-properties'; // This maps the Unicode Script property to an OpenType script tag // Data from http://www.microsoft.com/typography/otspec/scripttags.htm @@ -130,7 +130,7 @@ const UNICODE_SCRIPTS = { Yi: 'yi ', Inherited: 'zinh', Common: 'zyyy', - Unknown: 'zzzz' + Unknown: 'zzzz', }; const OPENTYPE_SCRIPTS = {}; @@ -166,7 +166,7 @@ export function forString(string) { // Check if this is a low surrogate if (0xdc00 <= next && next <= 0xdfff) { idx++; - code = ((code & 0x3FF) << 10) + (next & 0x3FF) + 0x10000; + code = ((code & 0x3ff) << 10) + (next & 0x3ff) + 0x10000; } } @@ -193,33 +193,33 @@ export function forCodePoints(codePoints) { // The scripts in this map are written from right to left const RTL = { - arab: true, // Arabic - hebr: true, // Hebrew - syrc: true, // Syriac - thaa: true, // Thaana - cprt: true, // Cypriot Syllabary - khar: true, // Kharosthi - phnx: true, // Phoenician + arab: true, // Arabic + hebr: true, // Hebrew + syrc: true, // Syriac + thaa: true, // Thaana + cprt: true, // Cypriot Syllabary + khar: true, // Kharosthi + phnx: true, // Phoenician 'nko ': true, // N'Ko - lydi: true, // Lydian - avst: true, // Avestan - armi: true, // Imperial Aramaic - phli: true, // Inscriptional Pahlavi - prti: true, // Inscriptional Parthian - sarb: true, // Old South Arabian - orkh: true, // Old Turkic, Orkhon Runic - samr: true, // Samaritan - mand: true, // Mandaic, Mandaean - merc: true, // Meroitic Cursive - mero: true, // Meroitic Hieroglyphs + lydi: true, // Lydian + avst: true, // Avestan + armi: true, // Imperial Aramaic + phli: true, // Inscriptional Pahlavi + prti: true, // Inscriptional Parthian + sarb: true, // Old South Arabian + orkh: true, // Old Turkic, Orkhon Runic + samr: true, // Samaritan + mand: true, // Mandaic, Mandaean + merc: true, // Meroitic Cursive + mero: true, // Meroitic Hieroglyphs // Unicode 7.0 (not listed on http://www.microsoft.com/typography/otspec/scripttags.htm) - mani: true, // Manichaean - mend: true, // Mende Kikakui - nbat: true, // Nabataean - narb: true, // Old North Arabian - palm: true, // Palmyrene - phlp: true // Psalter Pahlavi + mani: true, // Manichaean + mend: true, // Mende Kikakui + nbat: true, // Nabataean + narb: true, // Old North Arabian + palm: true, // Palmyrene + phlp: true, // Psalter Pahlavi }; export function direction(script) { diff --git a/src/layout/UnicodeLayoutEngine.js b/src/layout/UnicodeLayoutEngine.js index 68d5b9a0..ed0145e5 100644 --- a/src/layout/UnicodeLayoutEngine.js +++ b/src/layout/UnicodeLayoutEngine.js @@ -1,4 +1,4 @@ -import {getCombiningClass} from 'unicode-properties'; +import { getCombiningClass } from 'unicode-properties'; /** * This class is used when GPOS does not define 'mark' or 'mkmk' features @@ -19,7 +19,8 @@ export default class UnicodeLayoutEngine { let clusterEnd = 0; for (let index = 0; index < glyphs.length; index++) { let glyph = glyphs[index]; - if (glyph.isMark) { // TODO: handle ligatures + if (glyph.isMark) { + // TODO: handle ligatures clusterEnd = index; } else { if (clusterStart !== clusterEnd) { @@ -44,7 +45,8 @@ export default class UnicodeLayoutEngine { // adjust bounding box for ligature glyphs if (base.codePoints.length > 1) { // LTR. TODO: RTL support. - baseBox.minX += ((base.codePoints.length - 1) * baseBox.width) / base.codePoints.length; + baseBox.minX += + ((base.codePoints.length - 1) * baseBox.width) / base.codePoints.length; } let xOffset = -positions[clusterStart].xAdvance; @@ -86,7 +88,8 @@ export default class UnicodeLayoutEngine { default: // Attached_Below, Attached_Above, Below, Above, other // center align - position.xOffset += baseBox.minX + (baseBox.width - markBox.width) / 2 - markBox.minX; + position.xOffset += + baseBox.minX + (baseBox.width - markBox.width) / 2 - markBox.minX; } // y positioning @@ -98,7 +101,10 @@ export default class UnicodeLayoutEngine { case 'Attached_Below_Left': case 'Attached_Below': // add a small gap between the glyphs if they are not attached - if (combiningClass === 'Attached_Below_Left' || combiningClass === 'Attached_Below') { + if ( + combiningClass === 'Attached_Below_Left' || + combiningClass === 'Attached_Below' + ) { baseBox.minY += yGap; } @@ -113,7 +119,10 @@ export default class UnicodeLayoutEngine { case 'Attached_Above': case 'Attached_Above_Right': // add a small gap between the glyphs if they are not attached - if (combiningClass === 'Attached_Above' || combiningClass === 'Attached_Above_Right') { + if ( + combiningClass === 'Attached_Above' || + combiningClass === 'Attached_Above_Right' + ) { baseBox.maxY += yGap; } @@ -125,7 +134,6 @@ export default class UnicodeLayoutEngine { position.xAdvance = position.yAdvance = 0; position.xOffset += xOffset; position.yOffset += yOffset; - } else { xOffset -= position.xAdvance; yOffset -= position.yAdvance; @@ -166,7 +174,8 @@ export default class UnicodeLayoutEngine { case 0x0ebc: return 'Below'; } - } else if (codePoint === 0x0e3a) { // virama + } else if (codePoint === 0x0e3a) { + // virama return 'Below_Right'; } } diff --git a/src/node.js b/src/node.js index f496ea02..8e04cf3e 100644 --- a/src/node.js +++ b/src/node.js @@ -1,4 +1,9 @@ -import { registerFormat, create, defaultLanguage, setDefaultLanguage } from './base'; +import { + registerFormat, + create, + defaultLanguage, + setDefaultLanguage, +} from './base'; import { open, openSync } from './fs'; import TTFFont from './TTFFont'; import WOFFFont from './WOFFFont'; diff --git a/src/opentype/GPOSProcessor.js b/src/opentype/GPOSProcessor.js index 6a2c1f9f..352adfe8 100644 --- a/src/opentype/GPOSProcessor.js +++ b/src/opentype/GPOSProcessor.js @@ -24,19 +24,35 @@ export default class GPOSProcessor extends OTProcessor { let variationStore = this.font.GDEF && this.font.GDEF.itemVariationStore; if (variationProcessor && variationStore) { if (value.xPlaDevice) { - position.xOffset += variationProcessor.getDelta(variationStore, value.xPlaDevice.a, value.xPlaDevice.b); + position.xOffset += variationProcessor.getDelta( + variationStore, + value.xPlaDevice.a, + value.xPlaDevice.b, + ); } if (value.yPlaDevice) { - position.yOffset += variationProcessor.getDelta(variationStore, value.yPlaDevice.a, value.yPlaDevice.b); + position.yOffset += variationProcessor.getDelta( + variationStore, + value.yPlaDevice.a, + value.yPlaDevice.b, + ); } if (value.xAdvDevice) { - position.xAdvance += variationProcessor.getDelta(variationStore, value.xAdvDevice.a, value.xAdvDevice.b); + position.xAdvance += variationProcessor.getDelta( + variationStore, + value.xAdvDevice.a, + value.xAdvDevice.b, + ); } if (value.yAdvDevice) { - position.yAdvance += variationProcessor.getDelta(variationStore, value.yAdvDevice.a, value.yAdvDevice.b); + position.yAdvance += variationProcessor.getDelta( + variationStore, + value.yAdvDevice.a, + value.yAdvDevice.b, + ); } } @@ -45,7 +61,8 @@ export default class GPOSProcessor extends OTProcessor { applyLookup(lookupType, table) { switch (lookupType) { - case 1: { // Single positioning value + case 1: { + // Single positioning value let index = this.coverageIndex(table.coverage); if (index === -1) { return false; @@ -64,7 +81,8 @@ export default class GPOSProcessor extends OTProcessor { return true; } - case 2: { // Pair Adjustment Positioning + case 2: { + // Pair Adjustment Positioning let nextGlyph = this.glyphIterator.peek(); if (!nextGlyph) { return false; @@ -90,7 +108,10 @@ export default class GPOSProcessor extends OTProcessor { return false; case 2: // Class pair adjustment - let class1 = this.getClassID(this.glyphIterator.cur.id, table.classDef1); + let class1 = this.getClassID( + this.glyphIterator.cur.id, + table.classDef1, + ); let class2 = this.getClassID(nextGlyph.id, table.classDef2); if (class1 === -1 || class2 === -1) { return false; @@ -103,19 +124,24 @@ export default class GPOSProcessor extends OTProcessor { } } - case 3: { // Cursive Attachment Positioning + case 3: { + // Cursive Attachment Positioning let nextIndex = this.glyphIterator.peekIndex(); let nextGlyph = this.glyphs[nextIndex]; if (!nextGlyph) { return false; } - let curRecord = table.entryExitRecords[this.coverageIndex(table.coverage)]; + let curRecord = + table.entryExitRecords[this.coverageIndex(table.coverage)]; if (!curRecord || !curRecord.exitAnchor) { return false; } - let nextRecord = table.entryExitRecords[this.coverageIndex(table.coverage, nextGlyph.id)]; + let nextRecord = + table.entryExitRecords[ + this.coverageIndex(table.coverage, nextGlyph.id) + ]; if (!nextRecord || !nextRecord.entryAnchor) { return false; } @@ -155,7 +181,8 @@ export default class GPOSProcessor extends OTProcessor { return true; } - case 4: { // Mark to base positioning + case 4: { + // Mark to base positioning let markIndex = this.coverageIndex(table.markCoverage); if (markIndex === -1) { return false; @@ -163,13 +190,20 @@ export default class GPOSProcessor extends OTProcessor { // search backward for a base glyph let baseGlyphIndex = this.glyphIterator.index; - while (--baseGlyphIndex >= 0 && (this.glyphs[baseGlyphIndex].isMark || this.glyphs[baseGlyphIndex].ligatureComponent > 0)); + while ( + --baseGlyphIndex >= 0 && + (this.glyphs[baseGlyphIndex].isMark || + this.glyphs[baseGlyphIndex].ligatureComponent > 0) + ); if (baseGlyphIndex < 0) { return false; } - let baseIndex = this.coverageIndex(table.baseCoverage, this.glyphs[baseGlyphIndex].id); + let baseIndex = this.coverageIndex( + table.baseCoverage, + this.glyphs[baseGlyphIndex].id, + ); if (baseIndex === -1) { return false; } @@ -180,7 +214,8 @@ export default class GPOSProcessor extends OTProcessor { return true; } - case 5: { // Mark to ligature positioning + case 5: { + // Mark to ligature positioning let markIndex = this.coverageIndex(table.markCoverage); if (markIndex === -1) { return false; @@ -194,7 +229,10 @@ export default class GPOSProcessor extends OTProcessor { return false; } - let ligIndex = this.coverageIndex(table.ligatureCoverage, this.glyphs[baseGlyphIndex].id); + let ligIndex = this.coverageIndex( + table.ligatureCoverage, + this.glyphs[baseGlyphIndex].id, + ); if (ligIndex === -1) { return false; } @@ -202,9 +240,15 @@ export default class GPOSProcessor extends OTProcessor { let ligAttach = table.ligatureArray[ligIndex]; let markGlyph = this.glyphIterator.cur; let ligGlyph = this.glyphs[baseGlyphIndex]; - let compIndex = ligGlyph.ligatureID && ligGlyph.ligatureID === markGlyph.ligatureID && (markGlyph.ligatureComponent > 0) - ? Math.min(markGlyph.ligatureComponent, ligGlyph.codePoints.length) - 1 - : ligGlyph.codePoints.length - 1; + let compIndex = + ligGlyph.ligatureID && + ligGlyph.ligatureID === markGlyph.ligatureID && + markGlyph.ligatureComponent > 0 + ? Math.min( + markGlyph.ligatureComponent, + ligGlyph.codePoints.length, + ) - 1 + : ligGlyph.codePoints.length - 1; let markRecord = table.markArray[markIndex]; let baseAnchor = ligAttach[compIndex][markRecord.class]; @@ -212,7 +256,8 @@ export default class GPOSProcessor extends OTProcessor { return true; } - case 6: { // Mark to mark positioning + case 6: { + // Mark to mark positioning let mark1Index = this.coverageIndex(table.mark1Coverage); if (mark1Index === -1) { return false; @@ -230,15 +275,20 @@ export default class GPOSProcessor extends OTProcessor { // The following logic was borrowed from Harfbuzz let good = false; if (cur.ligatureID === prev.ligatureID) { - if (!cur.ligatureID) { // Marks belonging to the same base + if (!cur.ligatureID) { + // Marks belonging to the same base good = true; - } else if (cur.ligatureComponent === prev.ligatureComponent) { // Marks belonging to the same ligature component + } else if (cur.ligatureComponent === prev.ligatureComponent) { + // Marks belonging to the same ligature component good = true; } } else { // If ligature ids don't match, it may be the case that one of the marks // itself is a ligature, in which case match. - if ((cur.ligatureID && !cur.ligatureComponent) || (prev.ligatureID && !prev.ligatureComponent)) { + if ( + (cur.ligatureID && !cur.ligatureComponent) || + (prev.ligatureID && !prev.ligatureComponent) + ) { good = true; } } @@ -294,11 +344,19 @@ export default class GPOSProcessor extends OTProcessor { let variationStore = this.font.GDEF && this.font.GDEF.itemVariationStore; if (variationProcessor && variationStore) { if (anchor.xDeviceTable) { - x += variationProcessor.getDelta(variationStore, anchor.xDeviceTable.a, anchor.xDeviceTable.b); + x += variationProcessor.getDelta( + variationStore, + anchor.xDeviceTable.a, + anchor.xDeviceTable.b, + ); } if (anchor.yDeviceTable) { - y += variationProcessor.getDelta(variationStore, anchor.yDeviceTable.a, anchor.yDeviceTable.b); + y += variationProcessor.getDelta( + variationStore, + anchor.yDeviceTable.a, + anchor.yDeviceTable.b, + ); } } diff --git a/src/opentype/GSUBProcessor.js b/src/opentype/GSUBProcessor.js index f5672d5d..a9b48c1a 100644 --- a/src/opentype/GSUBProcessor.js +++ b/src/opentype/GSUBProcessor.js @@ -4,7 +4,8 @@ import GlyphInfo from './GlyphInfo'; export default class GSUBProcessor extends OTProcessor { applyLookup(lookupType, table) { switch (lookupType) { - case 1: { // Single Substitution + case 1: { + // Single Substitution let index = this.coverageIndex(table.coverage); if (index === -1) { return false; @@ -24,7 +25,8 @@ export default class GSUBProcessor extends OTProcessor { return true; } - case 2: { // Multiple Substitution + case 2: { + // Multiple Substitution let index = this.coverageIndex(table.coverage); if (index !== -1) { let sequence = table.sequences.get(index); @@ -58,7 +60,8 @@ export default class GSUBProcessor extends OTProcessor { return false; } - case 3: { // Alternate Substitution + case 3: { + // Alternate Substitution let index = this.coverageIndex(table.coverage); if (index !== -1) { let USER_INDEX = 0; // TODO @@ -69,7 +72,8 @@ export default class GSUBProcessor extends OTProcessor { return false; } - case 4: { // Ligature Substitution + case 4: { + // Ligature Substitution let index = this.coverageIndex(table.coverage); if (index === -1) { return false; @@ -90,7 +94,12 @@ export default class GSUBProcessor extends OTProcessor { } // Create the replacement ligature glyph - let ligatureGlyph = new GlyphInfo(this.font, ligature.glyph, characters, curGlyph.features); + let ligatureGlyph = new GlyphInfo( + this.font, + ligature.glyph, + characters, + curGlyph.features, + ); ligatureGlyph.shaperInfo = curGlyph.shaperInfo; ligatureGlyph.isLigated = true; ligatureGlyph.substituted = true; @@ -139,7 +148,13 @@ export default class GSUBProcessor extends OTProcessor { idx = matchIndex; } else { while (idx < matchIndex) { - var ligatureComponent = curComps - lastNumComps + Math.min(this.glyphs[idx].ligatureComponent || 1, lastNumComps); + var ligatureComponent = + curComps - + lastNumComps + + Math.min( + this.glyphs[idx].ligatureComponent || 1, + lastNumComps, + ); this.glyphs[idx].ligatureID = ligatureGlyph.ligatureID; this.glyphs[idx].ligatureComponent = ligatureComponent; idx++; @@ -156,7 +171,10 @@ export default class GSUBProcessor extends OTProcessor { if (lastLigID && !isMarkLigature) { for (let i = idx; i < this.glyphs.length; i++) { if (this.glyphs[i].ligatureID === lastLigID) { - var ligatureComponent = curComps - lastNumComps + Math.min(this.glyphs[i].ligatureComponent || 1, lastNumComps); + var ligatureComponent = + curComps - + lastNumComps + + Math.min(this.glyphs[i].ligatureComponent || 1, lastNumComps); this.glyphs[i].ligatureComponent = ligatureComponent; } else { break; diff --git a/src/opentype/GlyphInfo.js b/src/opentype/GlyphInfo.js index 644a3a8e..24692f92 100644 --- a/src/opentype/GlyphInfo.js +++ b/src/opentype/GlyphInfo.js @@ -1,4 +1,4 @@ -import {isMark} from 'unicode-properties'; +import { isMark } from 'unicode-properties'; import OTProcessor from './OTProcessor'; export default class GlyphInfo { @@ -42,7 +42,9 @@ export default class GlyphInfo { this.isBase = classID === 1; this.isLigature = classID === 2; this.isMark = classID === 3; - this.markAttachmentType = GDEF.markAttachClassDef ? OTProcessor.prototype.getClassID(id, GDEF.markAttachClassDef) : 0; + this.markAttachmentType = GDEF.markAttachClassDef + ? OTProcessor.prototype.getClassID(id, GDEF.markAttachClassDef) + : 0; } else { this.isMark = this.codePoints.length > 0 && this.codePoints.every(isMark); this.isBase = !this.isMark; diff --git a/src/opentype/GlyphIterator.js b/src/opentype/GlyphIterator.js index b22ad30b..de7e89e3 100644 --- a/src/opentype/GlyphIterator.js +++ b/src/opentype/GlyphIterator.js @@ -16,15 +16,23 @@ export default class GlyphIterator { } shouldIgnore(glyph) { - return (this.flags.ignoreMarks && glyph.isMark) || - (this.flags.ignoreBaseGlyphs && glyph.isBase) || - (this.flags.ignoreLigatures && glyph.isLigature) || - (this.markAttachmentType && glyph.isMark && glyph.markAttachmentType !== this.markAttachmentType); + return ( + (this.flags.ignoreMarks && glyph.isMark) || + (this.flags.ignoreBaseGlyphs && glyph.isBase) || + (this.flags.ignoreLigatures && glyph.isLigature) || + (this.markAttachmentType && + glyph.isMark && + glyph.markAttachmentType !== this.markAttachmentType) + ); } move(dir) { this.index += dir; - while (0 <= this.index && this.index < this.glyphs.length && this.shouldIgnore(this.glyphs[this.index])) { + while ( + 0 <= this.index && + this.index < this.glyphs.length && + this.shouldIgnore(this.glyphs[this.index]) + ) { this.index += dir; } diff --git a/src/opentype/OTLayoutEngine.js b/src/opentype/OTLayoutEngine.js index 15cf3627..736d43f5 100644 --- a/src/opentype/OTLayoutEngine.js +++ b/src/opentype/OTLayoutEngine.js @@ -25,16 +25,26 @@ export default class OTLayoutEngine { setup(glyphRun) { // Map glyphs to GlyphInfo objects so data can be passed between // GSUB and GPOS without mutating the real (shared) Glyph objects. - this.glyphInfos = glyphRun.glyphs.map(glyph => new GlyphInfo(this.font, glyph.id, [...glyph.codePoints])); + this.glyphInfos = glyphRun.glyphs.map( + (glyph) => new GlyphInfo(this.font, glyph.id, [...glyph.codePoints]), + ); // Select a script based on what is available in GSUB/GPOS. let script = null; if (this.GPOSProcessor) { - script = this.GPOSProcessor.selectScript(glyphRun.script, glyphRun.language, glyphRun.direction); + script = this.GPOSProcessor.selectScript( + glyphRun.script, + glyphRun.language, + glyphRun.direction, + ); } if (this.GSUBProcessor) { - script = this.GSUBProcessor.selectScript(glyphRun.script, glyphRun.language, glyphRun.direction); + script = this.GSUBProcessor.selectScript( + glyphRun.script, + glyphRun.language, + glyphRun.direction, + ); } // Choose a shaper based on the script, and setup a shaping plan. @@ -54,7 +64,9 @@ export default class OTLayoutEngine { this.plan.process(this.GSUBProcessor, this.glyphInfos); // Map glyph infos back to normal Glyph objects - glyphRun.glyphs = this.glyphInfos.map(glyphInfo => this.font.getGlyph(glyphInfo.id, glyphInfo.codePoints)); + glyphRun.glyphs = this.glyphInfos.map((glyphInfo) => + this.font.getGlyph(glyphInfo.id, glyphInfo.codePoints), + ); } } @@ -64,7 +76,11 @@ export default class OTLayoutEngine { } if (this.GPOSProcessor) { - this.plan.process(this.GPOSProcessor, this.glyphInfos, glyphRun.positions); + this.plan.process( + this.GPOSProcessor, + this.glyphInfos, + glyphRun.positions, + ); } if (this.shaper.zeroMarkWidths === 'AFTER_GPOS') { diff --git a/src/opentype/OTProcessor.js b/src/opentype/OTProcessor.js index 80d1ce69..c38653c6 100644 --- a/src/opentype/OTProcessor.js +++ b/src/opentype/OTProcessor.js @@ -105,7 +105,8 @@ export default class OTProcessor { if (this.language) { for (let featureIndex of this.language.featureIndexes) { let record = this.table.featureList[featureIndex]; - let substituteFeature = this.substituteFeatureForVariations(featureIndex); + let substituteFeature = + this.substituteFeatureForVariations(featureIndex); this.features[record.tag] = substituteFeature || record.feature; } } @@ -130,7 +131,7 @@ export default class OTProcessor { lookups.push({ feature: tag, index: lookupIndex, - lookup: this.table.lookupList.get(lookupIndex) + lookup: this.table.lookupList.get(lookupIndex), }); } } @@ -144,7 +145,10 @@ export default class OTProcessor { return null; } - let record = this.table.featureVariations.featureVariationRecords[this.variationsIndex]; + let record = + this.table.featureVariations.featureVariationRecords[ + this.variationsIndex + ]; let substitutions = record.featureTableSubstitution.substitutions; for (let substitution of substitutions) { if (substitution.featureIndex === featureIndex) { @@ -173,9 +177,13 @@ export default class OTProcessor { } variationConditionsMatch(conditions, coords) { - return conditions.every(condition => { - let coord = condition.axisIndex < coords.length ? coords[condition.axisIndex] : 0; - return condition.filterRangeMinValue <= coord && coord <= condition.filterRangeMaxValue; + return conditions.every((condition) => { + let coord = + condition.axisIndex < coords.length ? coords[condition.axisIndex] : 0; + return ( + condition.filterRangeMinValue <= coord && + coord <= condition.filterRangeMaxValue + ); }); } @@ -212,7 +220,7 @@ export default class OTProcessor { } applyLookup(lookup, table) { - throw new Error("applyLookup must be implemented by subclasses"); + throw new Error('applyLookup must be implemented by subclasses'); } applyLookupList(lookupRecords) { @@ -285,23 +293,34 @@ export default class OTProcessor { } sequenceMatches(sequenceIndex, sequence) { - return this.match(sequenceIndex, sequence, (component, glyph) => component === glyph.id); + return this.match( + sequenceIndex, + sequence, + (component, glyph) => component === glyph.id, + ); } sequenceMatchIndices(sequenceIndex, sequence) { - return this.match(sequenceIndex, sequence, (component, glyph) => { - // If the current feature doesn't apply to this glyph, - if (!(this.currentFeature in glyph.features)) { - return false; - } + return this.match( + sequenceIndex, + sequence, + (component, glyph) => { + // If the current feature doesn't apply to this glyph, + if (!(this.currentFeature in glyph.features)) { + return false; + } - return component === glyph.id; - }, []); + return component === glyph.id; + }, + [], + ); } coverageSequenceMatches(sequenceIndex, sequence) { - return this.match(sequenceIndex, sequence, (coverage, glyph) => - this.coverageIndex(coverage, glyph.id) >= 0 + return this.match( + sequenceIndex, + sequence, + (coverage, glyph) => this.coverageIndex(coverage, glyph.id) >= 0, ); } @@ -329,8 +348,10 @@ export default class OTProcessor { } classSequenceMatches(sequenceIndex, sequence, classDef) { - return this.match(sequenceIndex, sequence, (classID, glyph) => - classID === this.getClassID(glyph.id, classDef) + return this.match( + sequenceIndex, + sequence, + (classID, glyph) => classID === this.getClassID(glyph.id, classDef), ); } @@ -393,9 +414,11 @@ export default class OTProcessor { let set = table.chainRuleSets[index]; for (let rule of set) { - if (this.sequenceMatches(-rule.backtrack.length, rule.backtrack) - && this.sequenceMatches(1, rule.input) - && this.sequenceMatches(1 + rule.input.length, rule.lookahead)) { + if ( + this.sequenceMatches(-rule.backtrack.length, rule.backtrack) && + this.sequenceMatches(1, rule.input) && + this.sequenceMatches(1 + rule.input.length, rule.lookahead) + ) { return this.applyLookupList(rule.lookupRecords); } } @@ -414,9 +437,19 @@ export default class OTProcessor { } for (let rule of rules) { - if (this.classSequenceMatches(-rule.backtrack.length, rule.backtrack, table.backtrackClassDef) && + if ( + this.classSequenceMatches( + -rule.backtrack.length, + rule.backtrack, + table.backtrackClassDef, + ) && this.classSequenceMatches(1, rule.input, table.inputClassDef) && - this.classSequenceMatches(1 + rule.input.length, rule.lookahead, table.lookaheadClassDef)) { + this.classSequenceMatches( + 1 + rule.input.length, + rule.lookahead, + table.lookaheadClassDef, + ) + ) { return this.applyLookupList(rule.lookupRecords); } } @@ -424,9 +457,17 @@ export default class OTProcessor { break; case 3: - if (this.coverageSequenceMatches(-table.backtrackGlyphCount, table.backtrackCoverage) && + if ( + this.coverageSequenceMatches( + -table.backtrackGlyphCount, + table.backtrackCoverage, + ) && this.coverageSequenceMatches(0, table.inputCoverage) && - this.coverageSequenceMatches(table.inputGlyphCount, table.lookaheadCoverage)) { + this.coverageSequenceMatches( + table.inputGlyphCount, + table.lookaheadCoverage, + ) + ) { return this.applyLookupList(table.lookupRecords); } diff --git a/src/opentype/ShapingPlan.js b/src/opentype/ShapingPlan.js index 121a7934..d6fa8a98 100644 --- a/src/opentype/ShapingPlan.js +++ b/src/opentype/ShapingPlan.js @@ -56,7 +56,7 @@ export default class ShapingPlan { this._addFeatures(arg.global || [], true); this._addFeatures(arg.local || [], false); } else { - throw new Error("Unsupported argument to ShapingPlan#add"); + throw new Error('Unsupported argument to ShapingPlan#add'); } } @@ -109,7 +109,6 @@ export default class ShapingPlan { if (!positions) { stage(this.font, glyphs, this); } - } else if (stage.length > 0) { processor.applyFeatures(stage, glyphs, positions); } diff --git a/src/opentype/shapers/ArabicShaper.js b/src/opentype/shapers/ArabicShaper.js index 6b8d289f..52023494 100644 --- a/src/opentype/shapers/ArabicShaper.js +++ b/src/opentype/shapers/ArabicShaper.js @@ -3,7 +3,9 @@ import { getCategory } from 'unicode-properties'; import { UnicodeTrie } from 'unicode-trie'; import { decodeBase64 } from '../../utils'; -const trie = new UnicodeTrie(decodeBase64(require('fs').readFileSync(__dirname + '/data.trie', 'base64'))); +const trie = new UnicodeTrie( + decodeBase64(require('fs').readFileSync(__dirname + '/data.trie', 'base64')), +); const FEATURES = ['isol', 'fina', 'fin2', 'fin3', 'medi', 'med2', 'init']; const ShapingClasses = { @@ -14,7 +16,7 @@ const ShapingClasses = { Join_Causing: 3, ALAPH: 4, 'DALATH RISH': 5, - Transparent: 6 + Transparent: 6, }; const ISOL = 'isol'; @@ -30,25 +32,74 @@ const NONE = null; const STATE_TABLE = [ // Non_Joining, Left_Joining, Right_Joining, Dual_Joining, ALAPH, DALATH RISH // State 0: prev was U, not willing to join. - [ [ NONE, NONE, 0 ], [ NONE, ISOL, 2 ], [ NONE, ISOL, 1 ], [ NONE, ISOL, 2 ], [ NONE, ISOL, 1 ], [ NONE, ISOL, 6 ] ], + [ + [NONE, NONE, 0], + [NONE, ISOL, 2], + [NONE, ISOL, 1], + [NONE, ISOL, 2], + [NONE, ISOL, 1], + [NONE, ISOL, 6], + ], // State 1: prev was R or ISOL/ALAPH, not willing to join. - [ [ NONE, NONE, 0 ], [ NONE, ISOL, 2 ], [ NONE, ISOL, 1 ], [ NONE, ISOL, 2 ], [ NONE, FIN2, 5 ], [ NONE, ISOL, 6 ] ], + [ + [NONE, NONE, 0], + [NONE, ISOL, 2], + [NONE, ISOL, 1], + [NONE, ISOL, 2], + [NONE, FIN2, 5], + [NONE, ISOL, 6], + ], // State 2: prev was D/L in ISOL form, willing to join. - [ [ NONE, NONE, 0 ], [ NONE, ISOL, 2 ], [ INIT, FINA, 1 ], [ INIT, FINA, 3 ], [ INIT, FINA, 4 ], [ INIT, FINA, 6 ] ], + [ + [NONE, NONE, 0], + [NONE, ISOL, 2], + [INIT, FINA, 1], + [INIT, FINA, 3], + [INIT, FINA, 4], + [INIT, FINA, 6], + ], // State 3: prev was D in FINA form, willing to join. - [ [ NONE, NONE, 0 ], [ NONE, ISOL, 2 ], [ MEDI, FINA, 1 ], [ MEDI, FINA, 3 ], [ MEDI, FINA, 4 ], [ MEDI, FINA, 6 ] ], + [ + [NONE, NONE, 0], + [NONE, ISOL, 2], + [MEDI, FINA, 1], + [MEDI, FINA, 3], + [MEDI, FINA, 4], + [MEDI, FINA, 6], + ], // State 4: prev was FINA ALAPH, not willing to join. - [ [ NONE, NONE, 0 ], [ NONE, ISOL, 2 ], [ MED2, ISOL, 1 ], [ MED2, ISOL, 2 ], [ MED2, FIN2, 5 ], [ MED2, ISOL, 6 ] ], + [ + [NONE, NONE, 0], + [NONE, ISOL, 2], + [MED2, ISOL, 1], + [MED2, ISOL, 2], + [MED2, FIN2, 5], + [MED2, ISOL, 6], + ], // State 5: prev was FIN2/FIN3 ALAPH, not willing to join. - [ [ NONE, NONE, 0 ], [ NONE, ISOL, 2 ], [ ISOL, ISOL, 1 ], [ ISOL, ISOL, 2 ], [ ISOL, FIN2, 5 ], [ ISOL, ISOL, 6 ] ], + [ + [NONE, NONE, 0], + [NONE, ISOL, 2], + [ISOL, ISOL, 1], + [ISOL, ISOL, 2], + [ISOL, FIN2, 5], + [ISOL, ISOL, 6], + ], // State 6: prev was DALATH/RISH, not willing to join. - [ [ NONE, NONE, 0 ], [ NONE, ISOL, 2 ], [ NONE, ISOL, 1 ], [ NONE, ISOL, 2 ], [ NONE, FIN3, 5 ], [ NONE, ISOL, 6 ] ] + [ + [NONE, NONE, 0], + [NONE, ISOL, 2], + [NONE, ISOL, 1], + [NONE, ISOL, 2], + [NONE, FIN3, 5], + [NONE, ISOL, 6], + ], ]; /** @@ -101,7 +152,7 @@ export default class ArabicShaper extends DefaultShaper { for (let index = 0; index < glyphs.length; index++) { let feature; var glyph = glyphs[index]; - if (feature = actions[index]) { + if ((feature = actions[index])) { glyph.features[feature] = true; } } diff --git a/src/opentype/shapers/DefaultShaper.js b/src/opentype/shapers/DefaultShaper.js index e02e4d36..7d80fe44 100644 --- a/src/opentype/shapers/DefaultShaper.js +++ b/src/opentype/shapers/DefaultShaper.js @@ -1,4 +1,4 @@ -import {isDigit} from 'unicode-properties'; +import { isDigit } from 'unicode-properties'; const VARIATION_FEATURES = ['rvrn']; const COMMON_FEATURES = ['ccmp', 'locl', 'rlig', 'mark', 'mkmk']; @@ -7,7 +7,7 @@ const HORIZONTAL_FEATURES = ['calt', 'clig', 'liga', 'rclt', 'curs', 'kern']; const VERTICAL_FEATURES = ['vert']; const DIRECTIONAL_FEATURES = { ltr: ['ltra', 'ltrm'], - rtl: ['rtla', 'rtlm'] + rtl: ['rtla', 'rtlm'], }; export default class DefaultShaper { @@ -28,7 +28,7 @@ export default class DefaultShaper { static planPreprocessing(plan) { plan.add({ global: [...VARIATION_FEATURES, ...DIRECTIONAL_FEATURES[plan.direction]], - local: FRACTIONAL_FEATURES + local: FRACTIONAL_FEATURES, }); } @@ -45,7 +45,8 @@ export default class DefaultShaper { // Enable contextual fractions for (let i = 0; i < glyphs.length; i++) { let glyph = glyphs[i]; - if (glyph.codePoints[0] === 0x2044) { // fraction slash + if (glyph.codePoints[0] === 0x2044) { + // fraction slash let start = i; let end = i + 1; diff --git a/src/opentype/shapers/HangulShaper.js b/src/opentype/shapers/HangulShaper.js index 789fb76f..cd9013b8 100644 --- a/src/opentype/shapers/HangulShaper.js +++ b/src/opentype/shapers/HangulShaper.js @@ -38,7 +38,7 @@ export default class HangulShaper extends DefaultShaper { let code = glyph.codePoints[0]; let type = getType(code); - [ action, state ] = STATE_TABLE[state][type]; + [action, state] = STATE_TABLE[state][type]; switch (action) { case DECOMPOSE: @@ -69,72 +69,120 @@ export default class HangulShaper extends DefaultShaper { } } -const HANGUL_BASE = 0xac00; -const HANGUL_END = 0xd7a4; +const HANGUL_BASE = 0xac00; +const HANGUL_END = 0xd7a4; const HANGUL_COUNT = HANGUL_END - HANGUL_BASE + 1; -const L_BASE = 0x1100; // lead -const V_BASE = 0x1161; // vowel -const T_BASE = 0x11a7; // trail +const L_BASE = 0x1100; // lead +const V_BASE = 0x1161; // vowel +const T_BASE = 0x11a7; // trail const L_COUNT = 19; const V_COUNT = 21; const T_COUNT = 28; -const L_END = L_BASE + L_COUNT - 1; -const V_END = V_BASE + V_COUNT - 1; -const T_END = T_BASE + T_COUNT - 1; +const L_END = L_BASE + L_COUNT - 1; +const V_END = V_BASE + V_COUNT - 1; +const T_END = T_BASE + T_COUNT - 1; const DOTTED_CIRCLE = 0x25cc; -const isL = code => 0x1100 <= code && code <= 0x115f || 0xa960 <= code && code <= 0xa97c; -const isV = code => 0x1160 <= code && code <= 0x11a7 || 0xd7b0 <= code && code <= 0xd7c6; -const isT = code => 0x11a8 <= code && code <= 0x11ff || 0xd7cb <= code && code <= 0xd7fb; -const isTone = code => 0x302e <= code && code <= 0x302f; -const isLVT = code => HANGUL_BASE <= code && code <= HANGUL_END; -const isLV = code => (code - HANGUL_BASE) < HANGUL_COUNT && (code - HANGUL_BASE) % T_COUNT === 0; -const isCombiningL = code => L_BASE <= code && code <= L_END; -const isCombiningV = code => V_BASE <= code && code <= V_END; -const isCombiningT = code => T_BASE + 1 && 1 <= code && code <= T_END; +const isL = (code) => + (0x1100 <= code && code <= 0x115f) || (0xa960 <= code && code <= 0xa97c); +const isV = (code) => + (0x1160 <= code && code <= 0x11a7) || (0xd7b0 <= code && code <= 0xd7c6); +const isT = (code) => + (0x11a8 <= code && code <= 0x11ff) || (0xd7cb <= code && code <= 0xd7fb); +const isTone = (code) => 0x302e <= code && code <= 0x302f; +const isLVT = (code) => HANGUL_BASE <= code && code <= HANGUL_END; +const isLV = (code) => + code - HANGUL_BASE < HANGUL_COUNT && (code - HANGUL_BASE) % T_COUNT === 0; +const isCombiningL = (code) => L_BASE <= code && code <= L_END; +const isCombiningV = (code) => V_BASE <= code && code <= V_END; +const isCombiningT = (code) => T_BASE + 1 && 1 <= code && code <= T_END; // Character categories -const X = 0; // Other character -const L = 1; // Leading consonant -const V = 2; // Medial vowel -const T = 3; // Trailing consonant -const LV = 4; // Composed syllable +const X = 0; // Other character +const L = 1; // Leading consonant +const V = 2; // Medial vowel +const T = 3; // Trailing consonant +const LV = 4; // Composed syllable const LVT = 5; // Composed syllable -const M = 6; // Tone mark +const M = 6; // Tone mark // This function classifies a character using the above categories. function getType(code) { - if (isL(code)) { return L; } - if (isV(code)) { return V; } - if (isT(code)) { return T; } - if (isLV(code)) { return LV; } - if (isLVT(code)) { return LVT; } - if (isTone(code)) { return M; } + if (isL(code)) { + return L; + } + if (isV(code)) { + return V; + } + if (isT(code)) { + return T; + } + if (isLV(code)) { + return LV; + } + if (isLVT(code)) { + return LVT; + } + if (isTone(code)) { + return M; + } return X; } // State machine actions const NO_ACTION = 0; const DECOMPOSE = 1; -const COMPOSE = 2; +const COMPOSE = 2; const TONE_MARK = 4; -const INVALID = 5; +const INVALID = 5; // Build a state machine that accepts valid syllables, and applies actions along the way. // The logic this is implementing is documented at the top of the file. const STATE_TABLE = [ // X L V T LV LVT M // State 0: start state - [ [ NO_ACTION, 0 ], [ NO_ACTION, 1 ], [ NO_ACTION, 0 ], [ NO_ACTION, 0 ], [ DECOMPOSE, 2 ], [ DECOMPOSE, 3 ], [ INVALID, 0 ] ], + [ + [NO_ACTION, 0], + [NO_ACTION, 1], + [NO_ACTION, 0], + [NO_ACTION, 0], + [DECOMPOSE, 2], + [DECOMPOSE, 3], + [INVALID, 0], + ], // State 1: - [ [ NO_ACTION, 0 ], [ NO_ACTION, 1 ], [ COMPOSE, 2 ], [ NO_ACTION, 0 ], [ DECOMPOSE, 2 ], [ DECOMPOSE, 3 ], [ INVALID, 0 ] ], + [ + [NO_ACTION, 0], + [NO_ACTION, 1], + [COMPOSE, 2], + [NO_ACTION, 0], + [DECOMPOSE, 2], + [DECOMPOSE, 3], + [INVALID, 0], + ], // State 2: or - [ [ NO_ACTION, 0 ], [ NO_ACTION, 1 ], [ NO_ACTION, 0 ], [ COMPOSE, 3 ], [ DECOMPOSE, 2 ], [ DECOMPOSE, 3 ], [ TONE_MARK, 0 ] ], + [ + [NO_ACTION, 0], + [NO_ACTION, 1], + [NO_ACTION, 0], + [COMPOSE, 3], + [DECOMPOSE, 2], + [DECOMPOSE, 3], + [TONE_MARK, 0], + ], // State 3: or - [ [ NO_ACTION, 0 ], [ NO_ACTION, 1 ], [ NO_ACTION, 0 ], [ NO_ACTION, 0 ], [ DECOMPOSE, 2 ], [ DECOMPOSE, 3 ], [ TONE_MARK, 0 ] ] + [ + [NO_ACTION, 0], + [NO_ACTION, 1], + [NO_ACTION, 0], + [NO_ACTION, 0], + [DECOMPOSE, 2], + [DECOMPOSE, 3], + [TONE_MARK, 0], + ], ]; function getGlyph(font, code, features) { @@ -146,15 +194,17 @@ function decompose(glyphs, i, font) { let code = glyph.codePoints[0]; let s = code - HANGUL_BASE; - let t = T_BASE + s % T_COUNT; - s = s / T_COUNT | 0; - let l = L_BASE + s / V_COUNT | 0; - let v = V_BASE + s % V_COUNT; + let t = T_BASE + (s % T_COUNT); + s = (s / T_COUNT) | 0; + let l = (L_BASE + s / V_COUNT) | 0; + let v = V_BASE + (s % V_COUNT); // Don't decompose if all of the components are not available - if (!font.hasGlyphForCodePoint(l) || - !font.hasGlyphForCodePoint(v) || - (t !== T_BASE && !font.hasGlyphForCodePoint(t))) { + if ( + !font.hasGlyphForCodePoint(l) || + !font.hasGlyphForCodePoint(v) || + (t !== T_BASE && !font.hasGlyphForCodePoint(t)) + ) { return i; } @@ -166,7 +216,7 @@ function decompose(glyphs, i, font) { let vjmo = getGlyph(font, v, glyph.features); vjmo.features.vjmo = true; - let insert = [ ljmo, vjmo ]; + let insert = [ljmo, vjmo]; if (t > T_BASE) { let tjmo = getGlyph(font, t, glyph.features); @@ -214,7 +264,7 @@ function compose(glyphs, i, font) { } let t = (tjmo && tjmo.codePoints[0]) || T_BASE; - if ((lv != null) && (t === T_BASE || isCombiningT(t))) { + if (lv != null && (t === T_BASE || isCombiningT(t))) { let s = lv + (t - T_BASE); // Replace with a composed glyph if supported by the font, @@ -227,9 +277,15 @@ function compose(glyphs, i, font) { } // Didn't compose (either a non-combining component or unsupported by font). - if (ljmo) { ljmo.features.ljmo = true; } - if (vjmo) { vjmo.features.vjmo = true; } - if (tjmo) { tjmo.features.tjmo = true; } + if (ljmo) { + ljmo.features.ljmo = true; + } + if (vjmo) { + vjmo.features.vjmo = true; + } + if (tjmo) { + tjmo.features.tjmo = true; + } if (prevType === LV) { // Sequence was originally , which got combined earlier. @@ -259,7 +315,9 @@ function reorderToneMark(glyphs, i, font) { let code = glyphs[i].codePoints[0]; // Move tone mark to the beginning of the previous syllable, unless it is zero width - if (font.glyphForCodePoint(code).advanceWidth === 0) { return; } + if (font.glyphForCodePoint(code).advanceWidth === 0) { + return; + } let prev = glyphs[i - 1].codePoints[0]; let len = getLength(prev); diff --git a/src/opentype/shapers/IndicShaper.js b/src/opentype/shapers/IndicShaper.js index 77793b38..49ce6909 100644 --- a/src/opentype/shapers/IndicShaper.js +++ b/src/opentype/shapers/IndicShaper.js @@ -11,13 +11,16 @@ import { POSITIONS, CONSONANT_FLAGS, JOINER_FLAGS, - HALANT_OR_COENG_FLAGS, INDIC_CONFIGS, - INDIC_DECOMPOSITIONS + HALANT_OR_COENG_FLAGS, + INDIC_CONFIGS, + INDIC_DECOMPOSITIONS, } from './indic-data'; import { decodeBase64 } from '../../utils'; -const {decompositions} = useData; -const trie = new UnicodeTrie(decodeBase64(require('fs').readFileSync(__dirname + '/indic.trie', 'base64'))); +const { decompositions } = useData; +const trie = new UnicodeTrie( + decodeBase64(require('fs').readFileSync(__dirname + '/indic.trie', 'base64')), +); const stateMachine = new StateMachine(indicMachine); /** @@ -50,13 +53,27 @@ export default class IndicShaper extends DefaultShaper { plan.addStage({ local: ['init'], - global: ['pres', 'abvs', 'blws', 'psts', 'haln', 'dist', 'abvm', 'blwm', 'calt', 'clig'] + global: [ + 'pres', + 'abvs', + 'blws', + 'psts', + 'haln', + 'dist', + 'abvm', + 'blwm', + 'calt', + 'clig', + ], }); // Setup the indic config for the selected script plan.unicodeScript = Script.fromOpenType(plan.script); - plan.indicConfig = INDIC_CONFIGS[plan.unicodeScript] || INDIC_CONFIGS.Default; - plan.isOldSpec = plan.indicConfig.hasOldSpec && plan.script[plan.script.length - 1] !== '2'; + plan.indicConfig = + INDIC_CONFIGS[plan.unicodeScript] || INDIC_CONFIGS.Default; + plan.isOldSpec = + plan.indicConfig.hasOldSpec && + plan.script[plan.script.length - 1] !== '2'; // TODO: turn off kern (Khmer) and liga features. } @@ -68,7 +85,7 @@ export default class IndicShaper extends DefaultShaper { let codepoint = glyphs[i].codePoints[0]; let d = INDIC_DECOMPOSITIONS[codepoint] || decompositions[codepoint]; if (d) { - let decomposed = d.map(c => { + let decomposed = d.map((c) => { let g = plan.font.glyphForCodePoint(c); return new GlyphInfo(plan.font, g.id, [c], glyphs[i].features); }); @@ -99,11 +116,18 @@ class IndicInfo { function setupSyllables(font, glyphs) { let syllable = 0; let last = 0; - for (let [start, end, tags] of stateMachine.match(glyphs.map(indicCategory))) { + for (let [start, end, tags] of stateMachine.match( + glyphs.map(indicCategory), + )) { if (start > last) { ++syllable; for (let i = last; i < start; i++) { - glyphs[i].shaperInfo = new IndicInfo(CATEGORIES.X, POSITIONS.End, 'non_indic_cluster', syllable); + glyphs[i].shaperInfo = new IndicInfo( + CATEGORIES.X, + POSITIONS.End, + 'non_indic_cluster', + syllable, + ); } } @@ -115,7 +139,7 @@ function setupSyllables(font, glyphs) { 1 << indicCategory(glyphs[i]), indicPosition(glyphs[i]), tags[0], - syllable + syllable, ); } @@ -125,7 +149,12 @@ function setupSyllables(font, glyphs) { if (last < glyphs.length) { ++syllable; for (let i = last; i < glyphs.length; i++) { - glyphs[i].shaperInfo = new IndicInfo(CATEGORIES.X, POSITIONS.End, 'non_indic_cluster', syllable); + glyphs[i].shaperInfo = new IndicInfo( + CATEGORIES.X, + POSITIONS.End, + 'non_indic_cluster', + syllable, + ); } } } @@ -144,7 +173,7 @@ function isHalantOrCoeng(glyph) { function wouldSubstitute(glyphs, feature) { for (let glyph of glyphs) { - glyph.features = {[feature]: true}; + glyph.features = { [feature]: true }; } let GSUB = glyphs[0]._font._layoutEngine.engine.GSUBProcessor; @@ -155,11 +184,20 @@ function wouldSubstitute(glyphs, feature) { function consonantPosition(font, consonant, virama) { let glyphs = [virama, consonant, virama]; - if (wouldSubstitute(glyphs.slice(0, 2), 'blwf') || wouldSubstitute(glyphs.slice(1, 3), 'blwf')) { + if ( + wouldSubstitute(glyphs.slice(0, 2), 'blwf') || + wouldSubstitute(glyphs.slice(1, 3), 'blwf') + ) { return POSITIONS.Below_C; - } else if (wouldSubstitute(glyphs.slice(0, 2), 'pstf') || wouldSubstitute(glyphs.slice(1, 3), 'pstf')) { + } else if ( + wouldSubstitute(glyphs.slice(0, 2), 'pstf') || + wouldSubstitute(glyphs.slice(1, 3), 'pstf') + ) { return POSITIONS.Post_C; - } else if (wouldSubstitute(glyphs.slice(0, 2), 'pref') || wouldSubstitute(glyphs.slice(1, 3), 'pref')) { + } else if ( + wouldSubstitute(glyphs.slice(0, 2), 'pref') || + wouldSubstitute(glyphs.slice(1, 3), 'pref') + ) { return POSITIONS.Post_C; } @@ -176,15 +214,26 @@ function initialReordering(font, glyphs, plan) { let info = new GlyphInfo(font, virama, [indicConfig.virama]); for (let i = 0; i < glyphs.length; i++) { if (glyphs[i].shaperInfo.position === POSITIONS.Base_C) { - glyphs[i].shaperInfo.position = consonantPosition(font, glyphs[i].copy(), info); + glyphs[i].shaperInfo.position = consonantPosition( + font, + glyphs[i].copy(), + info, + ); } } } - for (let start = 0, end = nextSyllable(glyphs, 0); start < glyphs.length; start = end, end = nextSyllable(glyphs, start)) { - let {category, syllableType} = glyphs[start].shaperInfo; + for ( + let start = 0, end = nextSyllable(glyphs, 0); + start < glyphs.length; + start = end, end = nextSyllable(glyphs, start) + ) { + let { category, syllableType } = glyphs[start].shaperInfo; - if (syllableType === 'symbol_cluster' || syllableType === 'non_indic_cluster') { + if ( + syllableType === 'symbol_cluster' || + syllableType === 'non_indic_cluster' + ) { continue; } @@ -194,7 +243,7 @@ function initialReordering(font, glyphs, plan) { 1 << indicCategory(g), indicPosition(g), glyphs[start].shaperInfo.syllableType, - glyphs[start].shaperInfo.syllable + glyphs[start].shaperInfo.syllable, ); // Insert after possible Repha. @@ -223,16 +272,24 @@ function initialReordering(font, glyphs, plan) { // If the syllable starts with Ra + Halant (in a script that has Reph) // and has more than one consonant, Ra is excluded from candidates for // base consonants. - if (indicConfig.rephPos !== POSITIONS.Ra_To_Become_Reph && + if ( + indicConfig.rephPos !== POSITIONS.Ra_To_Become_Reph && features.rphf && - start + 3 <= end && ( - (indicConfig.rephMode === 'Implicit' && !isJoiner(glyphs[start + 2])) || - (indicConfig.rephMode === 'Explicit' && glyphs[start + 2].shaperInfo.category === CATEGORIES.ZWJ) - ) + start + 3 <= end && + ((indicConfig.rephMode === 'Implicit' && !isJoiner(glyphs[start + 2])) || + (indicConfig.rephMode === 'Explicit' && + glyphs[start + 2].shaperInfo.category === CATEGORIES.ZWJ)) ) { // See if it matches the 'rphf' feature. - let g = [glyphs[start].copy(), glyphs[start + 1].copy(), glyphs[start + 2].copy()]; - if (wouldSubstitute(g.slice(0, 2), 'rphf') || (indicConfig.rephMode === 'Explicit' && wouldSubstitute(g, 'rphf'))) { + let g = [ + glyphs[start].copy(), + glyphs[start + 1].copy(), + glyphs[start + 2].copy(), + ]; + if ( + wouldSubstitute(g.slice(0, 2), 'rphf') || + (indicConfig.rephMode === 'Explicit' && wouldSubstitute(g, 'rphf')) + ) { limit += 2; while (limit < end && isJoiner(glyphs[limit])) { limit++; @@ -240,7 +297,10 @@ function initialReordering(font, glyphs, plan) { base = start; hasReph = true; } - } else if (indicConfig.rephMode === 'Log_Repha' && glyphs[start].shaperInfo.category === CATEGORIES.Repha) { + } else if ( + indicConfig.rephMode === 'Log_Repha' && + glyphs[start].shaperInfo.category === CATEGORIES.Repha + ) { limit++; while (limit < end && isJoiner(glyphs[limit])) { limit++; @@ -262,7 +322,10 @@ function initialReordering(font, glyphs, plan) { if (isConsonant(glyphs[i])) { // that does not have a below-base or post-base form // (post-base forms have to follow below-base forms), - if (info.position !== POSITIONS.Below_C && (info.position !== POSITIONS.Post_C || seenBelow)) { + if ( + info.position !== POSITIONS.Below_C && + (info.position !== POSITIONS.Post_C || seenBelow) + ) { base = i; break; } @@ -282,7 +345,11 @@ function initialReordering(font, glyphs, plan) { } base = i; - } else if (start < i && info.category === CATEGORIES.ZWJ && glyphs[i - 1].shaperInfo.category === CATEGORIES.H) { + } else if ( + start < i && + info.category === CATEGORIES.ZWJ && + glyphs[i - 1].shaperInfo.category === CATEGORIES.H + ) { // A ZWJ after a Halant stops the base search, and requests an explicit // half form. // A ZWJ before a Halant, requests a subjoined form instead, and hence @@ -396,7 +463,11 @@ function initialReordering(font, glyphs, plan) { if (glyphs[i].shaperInfo.category === CATEGORIES.H) { let j; for (j = end - 1; j > i; j--) { - if (isConsonant(glyphs[j]) || (disallowDoubleHalants && glyphs[j].shaperInfo.category === CATEGORIES.H)) { + if ( + isConsonant(glyphs[j]) || + (disallowDoubleHalants && + glyphs[j].shaperInfo.category === CATEGORIES.H) + ) { break; } } @@ -417,9 +488,19 @@ function initialReordering(font, glyphs, plan) { let lastPos = POSITIONS.Start; for (let i = start; i < end; i++) { let info = glyphs[i].shaperInfo; - if (info.category & (JOINER_FLAGS | CATEGORIES.N | CATEGORIES.RS | CATEGORIES.CM | HALANT_OR_COENG_FLAGS & info.category)) { + if ( + info.category & + (JOINER_FLAGS | + CATEGORIES.N | + CATEGORIES.RS | + CATEGORIES.CM | + (HALANT_OR_COENG_FLAGS & info.category)) + ) { info.position = lastPos; - if (info.category === CATEGORIES.H && info.position === POSITIONS.Pre_M) { + if ( + info.category === CATEGORIES.H && + info.position === POSITIONS.Pre_M + ) { // Uniscribe doesn't move the Halant with Left Matra. // TEST: U+092B,U+093F,U+094DE // We follow. This is important for the Sinhala @@ -470,7 +551,11 @@ function initialReordering(font, glyphs, plan) { // Setup features now // Reph - for (let i = start; i < end && glyphs[i].shaperInfo.position === POSITIONS.Ra_To_Become_Reph; i++) { + for ( + let i = start; + i < end && glyphs[i].shaperInfo.position === POSITIONS.Ra_To_Become_Reph; + i++ + ) { glyphs[i].features.rphf = true; } @@ -509,9 +594,11 @@ function initialReordering(font, glyphs, plan) { // // Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915 for (let i = start; i + 1 < base; i++) { - if (glyphs[i].shaperInfo.category === CATEGORIES.Ra && + if ( + glyphs[i].shaperInfo.category === CATEGORIES.Ra && glyphs[i + 1].shaperInfo.category === CATEGORIES.H && - (i + 1 === base || glyphs[i + 2].shaperInfo.category === CATEGORIES.ZWJ) + (i + 1 === base || + glyphs[i + 2].shaperInfo.category === CATEGORIES.ZWJ) ) { glyphs[i].features.blwf = true; glyphs[i + 1].features.blwf = true; @@ -572,7 +659,11 @@ function finalReordering(font, glyphs, plan) { let indicConfig = plan.indicConfig; let features = font._layoutEngine.engine.GSUBProcessor.features; - for (let start = 0, end = nextSyllable(glyphs, 0); start < glyphs.length; start = end, end = nextSyllable(glyphs, start)) { + for ( + let start = 0, end = nextSyllable(glyphs, 0); + start < glyphs.length; + start = end, end = nextSyllable(glyphs, start) + ) { // 4. Final reordering: // // After the localized forms and basic shaping forms GSUB features have been @@ -589,7 +680,11 @@ function finalReordering(font, glyphs, plan) { if (tryPref && base + 1 < end) { for (let i = base + 1; i < end; i++) { if (glyphs[i].features.pref) { - if (!(glyphs[i].substituted && glyphs[i].isLigated && !glyphs[i].isMultiplied)) { + if (!( + glyphs[i].substituted && + glyphs[i].isLigated && + !glyphs[i].isMultiplied + )) { // Ok, this was a 'pref' candidate but didn't form any. // Base is around here... base = i; @@ -620,26 +715,41 @@ function finalReordering(font, glyphs, plan) { i++; } - if (i < end && isConsonant(glyphs[i]) && glyphs[i].shaperInfo.position === POSITIONS.Below_C) { + if ( + i < end && + isConsonant(glyphs[i]) && + glyphs[i].shaperInfo.position === POSITIONS.Below_C + ) { base = i; glyphs[base].shaperInfo.position = POSITIONS.Base_C; } } } - if (start < base && glyphs[base].shaperInfo.position > POSITIONS.Base_C) { + if ( + start < base && + glyphs[base].shaperInfo.position > POSITIONS.Base_C + ) { base--; } break; } } - if (base === end && start < base && glyphs[base - 1].shaperInfo.category === CATEGORIES.ZWJ) { + if ( + base === end && + start < base && + glyphs[base - 1].shaperInfo.category === CATEGORIES.ZWJ + ) { base--; } if (base < end) { - while (start < base && glyphs[base].shaperInfo.category & (CATEGORIES.N | HALANT_OR_COENG_FLAGS)) { + while ( + start < base && + glyphs[base].shaperInfo.category & + (CATEGORIES.N | HALANT_OR_COENG_FLAGS) + ) { base--; } } @@ -654,22 +764,35 @@ function finalReordering(font, glyphs, plan) { // halant, position is moved after it. // - if (start + 1 < end && start < base) { // Otherwise there can't be any pre-base matra characters. + if (start + 1 < end && start < base) { + // Otherwise there can't be any pre-base matra characters. // If we lost track of base, alas, position before last thingy. let newPos = base === end ? base - 2 : base - 1; // Malayalam / Tamil do not have "half" forms or explicit virama forms. // The glyphs formed by 'half' are Chillus or ligated explicit viramas. // We want to position matra after them. - if (plan.unicodeScript !== 'Malayalam' && plan.unicodeScript !== 'Tamil') { - while (newPos > start && !(glyphs[newPos].shaperInfo.category & (CATEGORIES.M | HALANT_OR_COENG_FLAGS))) { + if ( + plan.unicodeScript !== 'Malayalam' && + plan.unicodeScript !== 'Tamil' + ) { + while ( + newPos > start && + !( + glyphs[newPos].shaperInfo.category & + (CATEGORIES.M | HALANT_OR_COENG_FLAGS) + ) + ) { newPos--; } // If we found no Halant we are done. // Otherwise only proceed if the Halant does // not belong to the Matra itself! - if (isHalantOrCoeng(glyphs[newPos]) && glyphs[newPos].shaperInfo.position !== POSITIONS.Pre_M) { + if ( + isHalantOrCoeng(glyphs[newPos]) && + glyphs[newPos].shaperInfo.position !== POSITIONS.Pre_M + ) { // If ZWJ or ZWNJ follow this halant, position is moved after it. if (newPos + 1 < end && isJoiner(glyphs[newPos + 1])) { newPos++; @@ -679,17 +802,25 @@ function finalReordering(font, glyphs, plan) { } } - if (start < newPos && glyphs[newPos].shaperInfo.position !== POSITIONS.Pre_M) { + if ( + start < newPos && + glyphs[newPos].shaperInfo.position !== POSITIONS.Pre_M + ) { // Now go see if there's actually any matras... for (let i = newPos; i > start; i--) { if (glyphs[i - 1].shaperInfo.position === POSITIONS.Pre_M) { let oldPos = i - 1; - if (oldPos < base && base <= newPos) { // Shouldn't actually happen. + if (oldPos < base && base <= newPos) { + // Shouldn't actually happen. base--; } let tmp = glyphs[oldPos]; - glyphs.splice(oldPos, 0, ...glyphs.splice(oldPos + 1, newPos - oldPos)); + glyphs.splice( + oldPos, + 0, + ...glyphs.splice(oldPos + 1, newPos - oldPos), + ); glyphs[newPos] = tmp; newPos--; @@ -714,9 +845,11 @@ function finalReordering(font, glyphs, plan) { // - If repha is encoded separately and in the logical position, we should only // move it if it did NOT ligate. If it ligated, it's probably the font trying // to make it work without the reordering. - if (start + 1 < end && + if ( + start + 1 < end && glyphs[start].shaperInfo.position === POSITIONS.Ra_To_Become_Reph && - (glyphs[start].shaperInfo.category === CATEGORIES.Repha) !== (glyphs[start].isLigated && !glyphs[start].isMultiplied) + (glyphs[start].shaperInfo.category === CATEGORIES.Repha) !== + (glyphs[start].isLigated && !glyphs[start].isMultiplied) ) { let newRephPos; let rephPos = indicConfig.rephPos; @@ -754,7 +887,10 @@ function finalReordering(font, glyphs, plan) { // consonant that is not a potential pre-base reordering Ra. if (!found && rephPos === POSITIONS.After_Main) { newRephPos = base; - while (newRephPos + 1 < end && glyphs[newRephPos + 1].shaperInfo.position <= POSITIONS.After_Main) { + while ( + newRephPos + 1 < end && + glyphs[newRephPos + 1].shaperInfo.position <= POSITIONS.After_Main + ) { newRephPos++; } @@ -769,7 +905,13 @@ function finalReordering(font, glyphs, plan) { // This is our take on what step 4 is trying to say (and failing, BADLY). if (!found && rephPos === POSITIONS.After_Sub) { newRephPos = base; - while (newRephPos + 1 < end && !(glyphs[newRephPos + 1].shaperInfo.position & (POSITIONS.Post_C | POSITIONS.After_Post | POSITIONS.SMVD))) { + while ( + newRephPos + 1 < end && + !( + glyphs[newRephPos + 1].shaperInfo.position & + (POSITIONS.Post_C | POSITIONS.After_Post | POSITIONS.SMVD) + ) + ) { newRephPos++; } @@ -803,7 +945,10 @@ function finalReordering(font, glyphs, plan) { // 6. Otherwise, reorder reph to the end of the syllable. if (!found) { newRephPos = end - 1; - while (newRephPos > start && glyphs[newRephPos].shaperInfo.position === POSITIONS.SMVD) { + while ( + newRephPos > start && + glyphs[newRephPos].shaperInfo.position === POSITIONS.SMVD + ) { newRephPos--; } @@ -837,9 +982,9 @@ function finalReordering(font, glyphs, plan) { if (tryPref && base + 1 < end) { for (let i = base + 1; i < end; i++) { if (glyphs[i].features.pref) { - // 1. Only reorder a glyph produced by substitution during application - // of the feature. (Note that a font may shape a Ra consonant with - // the feature generally but block it in certain contexts.) + // 1. Only reorder a glyph produced by substitution during application + // of the feature. (Note that a font may shape a Ra consonant with + // the feature generally but block it in certain contexts.) // Note: We just check that something got substituted. We don't check that // the feature actually did it... @@ -856,14 +1001,26 @@ function finalReordering(font, glyphs, plan) { // Malayalam / Tamil do not have "half" forms or explicit virama forms. // The glyphs formed by 'half' are Chillus or ligated explicit viramas. // We want to position matra after them. - if (plan.unicodeScript !== 'Malayalam' && plan.unicodeScript !== 'Tamil') { - while (newPos > start && !(glyphs[newPos - 1].shaperInfo.category & (CATEGORIES.M | HALANT_OR_COENG_FLAGS))) { + if ( + plan.unicodeScript !== 'Malayalam' && + plan.unicodeScript !== 'Tamil' + ) { + while ( + newPos > start && + !( + glyphs[newPos - 1].shaperInfo.category & + (CATEGORIES.M | HALANT_OR_COENG_FLAGS) + ) + ) { newPos--; } // In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a // split matra, it should be reordered to *before* the left part of such matra. - if (newPos > start && glyphs[newPos - 1].shaperInfo.category === CATEGORIES.M) { + if ( + newPos > start && + glyphs[newPos - 1].shaperInfo.category === CATEGORIES.M + ) { let oldPos = i; for (let j = base + 1; j < oldPos; j++) { if (glyphs[j].shaperInfo.category === CATEGORIES.M) { @@ -883,7 +1040,11 @@ function finalReordering(font, glyphs, plan) { let oldPos = i; let tmp = glyphs[oldPos]; - glyphs.splice(newPos + 1, 0, ...glyphs.splice(newPos, oldPos - newPos)); + glyphs.splice( + newPos + 1, + 0, + ...glyphs.splice(newPos, oldPos - newPos), + ); glyphs[newPos] = tmp; if (newPos <= base && base < oldPos) { @@ -897,7 +1058,10 @@ function finalReordering(font, glyphs, plan) { } // Apply 'init' to the Left Matra if it's a word start. - if (glyphs[start].shaperInfo.position === POSITIONS.Pre_M && (!start || !/Cf|Mn/.test(getCategory(glyphs[start - 1].codePoints[0])))) { + if ( + glyphs[start].shaperInfo.position === POSITIONS.Pre_M && + (!start || !/Cf|Mn/.test(getCategory(glyphs[start - 1].codePoints[0]))) + ) { glyphs[start].features.init = true; } } @@ -906,6 +1070,9 @@ function finalReordering(font, glyphs, plan) { function nextSyllable(glyphs, start) { if (start >= glyphs.length) return start; let syllable = glyphs[start].shaperInfo.syllable; - while (++start < glyphs.length && glyphs[start].shaperInfo.syllable === syllable); + while ( + ++start < glyphs.length && + glyphs[start].shaperInfo.syllable === syllable + ); return start; } diff --git a/src/opentype/shapers/UniversalShaper.js b/src/opentype/shapers/UniversalShaper.js index 15434b8d..e6a6a372 100644 --- a/src/opentype/shapers/UniversalShaper.js +++ b/src/opentype/shapers/UniversalShaper.js @@ -5,8 +5,10 @@ import GlyphInfo from '../GlyphInfo'; import useData from './use.json'; import { decodeBase64 } from '../../utils'; -const {categories, decompositions} = useData; -const trie = new UnicodeTrie(decodeBase64(require('fs').readFileSync(__dirname + '/use.trie', 'base64'))); +const { categories, decompositions } = useData; +const trie = new UnicodeTrie( + decodeBase64(require('fs').readFileSync(__dirname + '/use.trie', 'base64')), +); const stateMachine = new StateMachine(useData); /** @@ -48,7 +50,7 @@ export default class UniversalShaper extends DefaultShaper { for (let i = glyphs.length - 1; i >= 0; i--) { let codepoint = glyphs[i].codePoints[0]; if (decompositions[codepoint]) { - let decomposed = decompositions[codepoint].map(c => { + let decomposed = decompositions[codepoint].map((c) => { let g = plan.font.glyphForCodePoint(c); return new GlyphInfo(plan.font, g.id, [c], glyphs[i].features); }); @@ -78,11 +80,16 @@ function setupSyllables(font, glyphs) { // Create shaper info for (let i = start; i <= end; i++) { - glyphs[i].shaperInfo = new USEInfo(categories[useCategory(glyphs[i])], tags[0], syllable); + glyphs[i].shaperInfo = new USEInfo( + categories[useCategory(glyphs[i])], + tags[0], + syllable, + ); } // Assign rphf feature - let limit = glyphs[start].shaperInfo.category === 'R' ? 1 : Math.min(3, end - start); + let limit = + glyphs[start].shaperInfo.category === 'R' ? 1 : Math.min(3, end - start); for (let i = start; i < start + limit; i++) { glyphs[i].features.rphf = true; } @@ -116,13 +123,21 @@ function recordPref(font, glyphs) { function reorder(font, glyphs) { let dottedCircle = font.glyphForCodePoint(0x25cc).id; - for (let start = 0, end = nextSyllable(glyphs, 0); start < glyphs.length; start = end, end = nextSyllable(glyphs, start)) { + for ( + let start = 0, end = nextSyllable(glyphs, 0); + start < glyphs.length; + start = end, end = nextSyllable(glyphs, start) + ) { let i, j; let info = glyphs[start].shaperInfo; let type = info.syllableType; // Only a few syllable types need reordering. - if (type !== 'virama_terminated_cluster' && type !== 'standard_cluster' && type !== 'broken_cluster') { + if ( + type !== 'virama_terminated_cluster' && + type !== 'standard_cluster' && + type !== 'broken_cluster' + ) { continue; } @@ -149,7 +164,12 @@ function reorder(font, glyphs) { i--; } - glyphs.splice(start, 0, ...glyphs.splice(start + 1, i - start), glyphs[i]); + glyphs.splice( + start, + 0, + ...glyphs.splice(start + 1, i - start), + glyphs[i], + ); break; } } @@ -162,7 +182,10 @@ function reorder(font, glyphs) { // If we hit a halant, move after it; otherwise it's a base: move to it's // place, and shift things in between backward. j = isHalant(glyphs[i]) ? i + 1 : i; - } else if ((info.category === 'VPre' || info.category === 'VMPre') && j < i) { + } else if ( + (info.category === 'VPre' || info.category === 'VMPre') && + j < i + ) { glyphs.splice(j, 1, glyphs[i], ...glyphs.splice(j, i - j)); } } @@ -172,7 +195,10 @@ function reorder(font, glyphs) { function nextSyllable(glyphs, start) { if (start >= glyphs.length) return start; let syllable = glyphs[start].shaperInfo.syllable; - while (++start < glyphs.length && glyphs[start].shaperInfo.syllable === syllable); + while ( + ++start < glyphs.length && + glyphs[start].shaperInfo.syllable === syllable + ); return start; } diff --git a/src/opentype/shapers/gen-indic.js b/src/opentype/shapers/gen-indic.js index d8b46b6b..ce50e4f2 100644 --- a/src/opentype/shapers/gen-indic.js +++ b/src/opentype/shapers/gen-indic.js @@ -40,56 +40,56 @@ const CATEGORY_MAP = { Visarga: 'SM', Vowel: 'V', Vowel_Dependent: 'M', - Vowel_Independent: 'V' + Vowel_Independent: 'V', }; const OVERRIDES = { 0x0953: 'SM', 0x0954: 'SM', - 0x0A72: 'C', - 0x0A73: 'C', - 0x1CF5: 'C', - 0x1CF6: 'C', - 0x1CE2: 'A', - 0x1CE3: 'A', - 0x1CE4: 'A', - 0x1CE5: 'A', - 0x1CE6: 'A', - 0x1CE7: 'A', - 0x1CE8: 'A', - 0x1CED: 'A', - 0xA8F2: 'Symbol', - 0xA8F3: 'Symbol', - 0xA8F4: 'Symbol', - 0xA8F5: 'Symbol', - 0xA8F6: 'Symbol', - 0xA8F7: 'Symbol', - 0x1CE9: 'Symbol', - 0x1CEA: 'Symbol', - 0x1CEB: 'Symbol', - 0x1CEC: 'Symbol', - 0x1CEE: 'Symbol', - 0x1CEF: 'Symbol', - 0x1CF0: 'Symbol', - 0x1CF1: 'Symbol', - 0x17C6: 'N', + 0x0a72: 'C', + 0x0a73: 'C', + 0x1cf5: 'C', + 0x1cf6: 'C', + 0x1ce2: 'A', + 0x1ce3: 'A', + 0x1ce4: 'A', + 0x1ce5: 'A', + 0x1ce6: 'A', + 0x1ce7: 'A', + 0x1ce8: 'A', + 0x1ced: 'A', + 0xa8f2: 'Symbol', + 0xa8f3: 'Symbol', + 0xa8f4: 'Symbol', + 0xa8f5: 'Symbol', + 0xa8f6: 'Symbol', + 0xa8f7: 'Symbol', + 0x1ce9: 'Symbol', + 0x1cea: 'Symbol', + 0x1ceb: 'Symbol', + 0x1cec: 'Symbol', + 0x1cee: 'Symbol', + 0x1cef: 'Symbol', + 0x1cf0: 'Symbol', + 0x1cf1: 'Symbol', + 0x17c6: 'N', 0x2010: 'Placeholder', 0x2011: 'Placeholder', - 0x25CC: 'Dotted_Circle', + 0x25cc: 'Dotted_Circle', // Ra 0x0930: 'Ra', // Devanagari - 0x09B0: 'Ra', // Bengali - 0x09F0: 'Ra', // Bengali - 0x0A30: 'Ra', // Gurmukhi - No Reph - 0x0AB0: 'Ra', // Gujarati - 0x0B30: 'Ra', // Oriya - 0x0BB0: 'Ra', // Tamil - No Reph - 0x0C30: 'Ra', // Telugu - Reph formed only with ZWJ - 0x0CB0: 'Ra', // Kannada - 0x0D30: 'Ra', // Malayalam - No Reph, Logical Repha - 0x0DBB: 'Ra', // Sinhala - Reph formed only with ZWJ - 0x179A: 'Ra', // Khmer - No Reph, Visual Repha + 0x09b0: 'Ra', // Bengali + 0x09f0: 'Ra', // Bengali + 0x0a30: 'Ra', // Gurmukhi - No Reph + 0x0ab0: 'Ra', // Gujarati + 0x0b30: 'Ra', // Oriya + 0x0bb0: 'Ra', // Tamil - No Reph + 0x0c30: 'Ra', // Telugu - Reph formed only with ZWJ + 0x0cb0: 'Ra', // Kannada + 0x0d30: 'Ra', // Malayalam - No Reph, Logical Repha + 0x0dbb: 'Ra', // Sinhala - Reph formed only with ZWJ + 0x179a: 'Ra', // Khmer - No Reph, Visual Repha }; const POSITION_MAP = { @@ -108,7 +108,7 @@ const POSITION_MAP = { Top_And_Right: 'Post_C', Overstruck: 'After_Main', - Visual_Order_Left: 'Pre_M' + Visual_Order_Left: 'Pre_M', }; function matraPosition(c, pos) { @@ -118,48 +118,82 @@ function matraPosition(c, pos) { case 'Post_C': switch (c.block) { - case 'Devanagari': return 'After_Sub'; - case 'Bengali': return 'After_Post'; - case 'Gurmukhi': return 'After_Post'; - case 'Gujarati': return 'After_Post'; - case 'Oriya': return 'After_Post'; - case 'Tamil': return 'After_Post'; - case 'Telugu': return c.code <= 0x0C42 ? 'Before_Sub' : 'After_Sub'; - case 'Kannada': return c.code < 0x0CC3 || c.code > 0xCD6 ? 'Before_Sub' : 'After_Sub'; - case 'Malayalam': return 'After_Post'; - case 'Sinhala': return 'After_Sub'; - case 'Khmer': return 'After_Post'; - default: return 'After_Sub'; + case 'Devanagari': + return 'After_Sub'; + case 'Bengali': + return 'After_Post'; + case 'Gurmukhi': + return 'After_Post'; + case 'Gujarati': + return 'After_Post'; + case 'Oriya': + return 'After_Post'; + case 'Tamil': + return 'After_Post'; + case 'Telugu': + return c.code <= 0x0c42 ? 'Before_Sub' : 'After_Sub'; + case 'Kannada': + return c.code < 0x0cc3 || c.code > 0xcd6 ? 'Before_Sub' : 'After_Sub'; + case 'Malayalam': + return 'After_Post'; + case 'Sinhala': + return 'After_Sub'; + case 'Khmer': + return 'After_Post'; + default: + return 'After_Sub'; } case 'Above_C': switch (c.block) { - case 'Devanagari': return 'After_Sub'; - case 'Gurmukhi': return 'After_Post'; // Deviate from spec - case 'Gujarati': return 'After_Sub'; - case 'Oriya': return 'After_Main'; - case 'Tamil': return 'After_Sub'; - case 'Telugu': return 'Before_Sub'; - case 'Kannada': return 'Before_Sub'; - case 'Sinhala': return 'After_Sub'; - case 'Khmer': return 'After_Post'; - default: return 'After_Sub'; + case 'Devanagari': + return 'After_Sub'; + case 'Gurmukhi': + return 'After_Post'; // Deviate from spec + case 'Gujarati': + return 'After_Sub'; + case 'Oriya': + return 'After_Main'; + case 'Tamil': + return 'After_Sub'; + case 'Telugu': + return 'Before_Sub'; + case 'Kannada': + return 'Before_Sub'; + case 'Sinhala': + return 'After_Sub'; + case 'Khmer': + return 'After_Post'; + default: + return 'After_Sub'; } case 'Below_C': switch (c.block) { - case 'Devanagari': return 'After_Sub'; - case 'Bengali': return 'After_Sub'; - case 'Gurmukhi': return 'After_Post'; - case 'Gujarati': return 'After_Post'; - case 'Oriya': return 'After_Sub'; - case 'Tamil': return 'After_Post'; - case 'Telugu': return 'Before_Sub'; - case 'Kannada': return 'Before_Sub'; - case 'Malayalam': return 'After_Post'; - case 'Sinhala': return 'After_Sub'; - case 'Khmer': return 'After_Post'; - default: return 'After_Sub'; + case 'Devanagari': + return 'After_Sub'; + case 'Bengali': + return 'After_Sub'; + case 'Gurmukhi': + return 'After_Post'; + case 'Gujarati': + return 'After_Post'; + case 'Oriya': + return 'After_Sub'; + case 'Tamil': + return 'After_Post'; + case 'Telugu': + return 'Before_Sub'; + case 'Kannada': + return 'Before_Sub'; + case 'Malayalam': + return 'After_Post'; + case 'Sinhala': + return 'After_Sub'; + case 'Khmer': + return 'After_Post'; + default: + return 'After_Sub'; } default: @@ -174,12 +208,17 @@ function getPosition(codepoint, category) { position = 'Base_C'; } else if (category === 'M') { position = matraPosition(codepoint, position); - } else if (category === 'SM' || category === 'VD' || category === 'A' || category === 'Symbol') { + } else if ( + category === 'SM' || + category === 'VD' || + category === 'A' || + category === 'Symbol' + ) { position = 'SMVD'; } // Oriya Bindu is Before_Sub in the spec. - if (codepoint.code === 0x0B01) { + if (codepoint.code === 0x0b01) { position = 'Before_Sub'; } @@ -191,11 +230,14 @@ for (let c in CATEGORIES) { symbols[c] = Math.log2(CATEGORIES[c]); } -let trie = new UnicodeTrieBuilder; +let trie = new UnicodeTrieBuilder(); for (let i = 0; i < codepoints.length; i++) { let codepoint = codepoints[i]; if (codepoint) { - let category = OVERRIDES[codepoint.code] || CATEGORY_MAP[codepoint.indicSyllabicCategory] || 'X'; + let category = + OVERRIDES[codepoint.code] || + CATEGORY_MAP[codepoint.indicSyllabicCategory] || + 'X'; let position = getPosition(codepoint, category); trie.set(codepoint.code, (symbols[category] << 8) | position); @@ -204,5 +246,11 @@ for (let i = 0; i < codepoints.length; i++) { fs.writeFileSync(new URL('indic.trie', import.meta.url), trie.toBuffer()); -let stateMachine = compile(fs.readFileSync(new URL('indic.machine', import.meta.url), 'utf8'), symbols); -fs.writeFileSync(new URL('indic.json', import.meta.url), JSON.stringify(stateMachine)); +let stateMachine = compile( + fs.readFileSync(new URL('indic.machine', import.meta.url), 'utf8'), + symbols, +); +fs.writeFileSync( + new URL('indic.json', import.meta.url), + JSON.stringify(stateMachine), +); diff --git a/src/opentype/shapers/gen-use.js b/src/opentype/shapers/gen-use.js index 3c5cb5f4..3af591d3 100644 --- a/src/opentype/shapers/gen-use.js +++ b/src/opentype/shapers/gen-use.js @@ -7,113 +7,64 @@ const compile = dfa.default; const CATEGORIES = { B: [ - {UISC: 'Number'}, - {UISC: 'Avagraha', UGC: 'Lo'}, - {UISC: 'Bindu', UGC: 'Lo'}, - {UISC: 'Consonant'}, - {UISC: 'Consonant_Final', UGC: 'Lo'}, - {UISC: 'Consonant_Head_Letter'}, - {UISC: 'Consonant_Medial', UGC: 'Lo'}, - {UISC: 'Consonant_Subjoined', UGC: 'Lo'}, - {UISC: 'Tone_Letter'}, - {UISC: 'Vowel', UGC: 'Lo'}, - {UISC: 'Vowel_Independent'}, - {UISC: 'Vowel_Dependent', UGC: 'Lo'} + { UISC: 'Number' }, + { UISC: 'Avagraha', UGC: 'Lo' }, + { UISC: 'Bindu', UGC: 'Lo' }, + { UISC: 'Consonant' }, + { UISC: 'Consonant_Final', UGC: 'Lo' }, + { UISC: 'Consonant_Head_Letter' }, + { UISC: 'Consonant_Medial', UGC: 'Lo' }, + { UISC: 'Consonant_Subjoined', UGC: 'Lo' }, + { UISC: 'Tone_Letter' }, + { UISC: 'Vowel', UGC: 'Lo' }, + { UISC: 'Vowel_Independent' }, + { UISC: 'Vowel_Dependent', UGC: 'Lo' }, ], CGJ: [0x034f], - CM: [ - 'Nukta', - 'Gemination_Mark', - 'Consonant_Killer' - ], - CS: [ - 'Consonant_With_Stacker' - ], + CM: ['Nukta', 'Gemination_Mark', 'Consonant_Killer'], + CS: ['Consonant_With_Stacker'], F: [ - {UISC: 'Consonant_Final', UGC: {not: 'Lo'}}, - {UISC: 'Consonant_Succeeding_Repha'} - ], - FM: [ - 'Syllable_Modifier' - ], - GB: [ - 'Consonant_Placeholder', - 0x2015, - 0x2022, - 0x25fb, - 0x25fc, - 0x25fd, - 0x25fe - ], - H: [ - 'Virama', - 'Invisible_Stacker' - ], - HN: [ - 'Number_Joiner' + { UISC: 'Consonant_Final', UGC: { not: 'Lo' } }, + { UISC: 'Consonant_Succeeding_Repha' }, ], + FM: ['Syllable_Modifier'], + GB: ['Consonant_Placeholder', 0x2015, 0x2022, 0x25fb, 0x25fc, 0x25fd, 0x25fe], + H: ['Virama', 'Invisible_Stacker'], + HN: ['Number_Joiner'], IND: [ 'Consonant_Dead', 'Modifying_Letter', - {UGC: 'Po', U: {not: [0x104e, 0x2022]}} - ], - M: [ - {UISC: 'Consonant_Medial', UGC: {not: 'Lo'}} - ], - N: [ - 'Brahmi_Joining_Number' - ], - R: [ - 'Consonant_Preceding_Repha', - 'Consonant_Prefixed' + { UGC: 'Po', U: { not: [0x104e, 0x2022] } }, ], + M: [{ UISC: 'Consonant_Medial', UGC: { not: 'Lo' } }], + N: ['Brahmi_Joining_Number'], + R: ['Consonant_Preceding_Repha', 'Consonant_Prefixed'], Rsv: [ - {UGC: 'Cn'} // TODO - ], - S: [ - {UGC: 'So', U: {not: 0x25cc}}, - {UGC: 'Sc'} - ], - SM: [ - 0x1b6b, - 0x1b6c, - 0x1b6d, - 0x1b6e, - 0x1b6f, - 0x1b70, - 0x1b71, - 0x1b72, - 0x1b73 - ], - SUB: [ - {UISC: 'Consonant_Subjoined', UGC: {not: 'Lo'}} + { UGC: 'Cn' }, // TODO ], + S: [{ UGC: 'So', U: { not: 0x25cc } }, { UGC: 'Sc' }], + SM: [0x1b6b, 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b70, 0x1b71, 0x1b72, 0x1b73], + SUB: [{ UISC: 'Consonant_Subjoined', UGC: { not: 'Lo' } }], V: [ - {UISC: 'Vowel', UGC: {not: 'Lo'}}, - {UISC: 'Vowel_Dependent', UGC: {not: 'Lo'}}, - {UISC: 'Pure_Killer'} + { UISC: 'Vowel', UGC: { not: 'Lo' } }, + { UISC: 'Vowel_Dependent', UGC: { not: 'Lo' } }, + { UISC: 'Pure_Killer' }, ], VM: [ - {UISC: 'Bindu', UGC: {not: 'Lo'}}, + { UISC: 'Bindu', UGC: { not: 'Lo' } }, 'Tone_Mark', 'Cantillation_Mark', 'Register_Shifter', - 'Visarga' + 'Visarga', ], VS: [ - 0xfe00, 0xfe01, 0xfe02, 0xfe03, 0xfe04, 0xfe05, 0xfe06, 0xfe07, - 0xfe08, 0xfe09, 0xfe0a, 0xfe0b, 0xfe0c, 0xfe0d, 0xfe0e, 0xfe0f + 0xfe00, 0xfe01, 0xfe02, 0xfe03, 0xfe04, 0xfe05, 0xfe06, 0xfe07, 0xfe08, + 0xfe09, 0xfe0a, 0xfe0b, 0xfe0c, 0xfe0d, 0xfe0e, 0xfe0f, ], WJ: [0x2060], - ZWJ: [ - 'Joiner' - ], - ZWNJ: [ - 'Non_Joiner' - ], - O: [ - 'Other' - ] + ZWJ: ['Joiner'], + ZWNJ: ['Non_Joiner'], + O: ['Other'], }; const USE_POSITIONS = { @@ -147,7 +98,7 @@ const USE_POSITIONS = { SM: { Abv: ['Top'], Blw: ['Bottom'], - } + }, }; const UISC_OVERRIDE = { @@ -159,7 +110,7 @@ const UISC_OVERRIDE = { 0x1ce6: 'Cantillation_Mark', 0x1ce7: 'Cantillation_Mark', 0x1ce8: 'Cantillation_Mark', - 0x1ced: 'Tone_Mark' + 0x1ced: 'Tone_Mark', }; const UIPC_OVERRIDE = { @@ -179,7 +130,7 @@ const UIPC_OVERRIDE = { 0x1cf2: 'Right', 0x1cf3: 'Right', 0x1cf8: 'Top', - 0x1cf9: 'Top' + 0x1cf9: 'Top', }; function check(pattern, value) { @@ -196,9 +147,9 @@ function check(pattern, value) { function matches(pattern, code) { if (typeof pattern === 'number') { - pattern = {U: pattern}; + pattern = { U: pattern }; } else if (typeof pattern === 'string') { - pattern = {UISC: pattern}; + pattern = { UISC: pattern }; } for (let key in pattern) { @@ -235,7 +186,13 @@ function getPositionalCategory(code, USE) { function getCategory(code) { for (let category in CATEGORIES) { for (let pattern of CATEGORIES[category]) { - if (matches(pattern, {UISC: getUISC(code), UGC: code.category, U: code.code})) { + if ( + matches(pattern, { + UISC: getUISC(code), + UGC: code.category, + U: code.code, + }) + ) { return getPositionalCategory(code, category); } } @@ -244,7 +201,7 @@ function getCategory(code) { return null; } -let trie = new UnicodeTrieBuilder; +let trie = new UnicodeTrieBuilder(); let symbols = {}; let numSymbols = 0; let decompositions = {}; @@ -258,7 +215,10 @@ for (let i = 0; i < codepoints.length; i++) { trie.set(codepoint.code, symbols[category]); - if (codepoint.indicSyllabicCategory === 'Vowel_Dependent' && codepoint.decomposition.length > 0) { + if ( + codepoint.indicSyllabicCategory === 'Vowel_Dependent' && + codepoint.decomposition.length > 0 + ) { decompositions[codepoint.code] = decompose(codepoint.code); } } @@ -278,10 +238,16 @@ function decompose(code) { fs.writeFileSync(new URL('use.trie', import.meta.url), trie.toBuffer()); -let stateMachine = compile(fs.readFileSync(new URL('use.machine', import.meta.url), 'utf8'), symbols); -let json = Object.assign({ - categories: Object.keys(symbols), - decompositions: decompositions -}, stateMachine); +let stateMachine = compile( + fs.readFileSync(new URL('use.machine', import.meta.url), 'utf8'), + symbols, +); +let json = Object.assign( + { + categories: Object.keys(symbols), + decompositions: decompositions, + }, + stateMachine, +); fs.writeFileSync(new URL('use.json', import.meta.url), JSON.stringify(json)); diff --git a/src/opentype/shapers/generate-data.js b/src/opentype/shapers/generate-data.js index f7634952..400fe6b0 100644 --- a/src/opentype/shapers/generate-data.js +++ b/src/opentype/shapers/generate-data.js @@ -14,16 +14,18 @@ let ShapingClasses = { Join_Causing: 3, ALAPH: 4, 'DALATH RISH': 5, - Transparent: 6 + Transparent: 6, }; let trie = new UnicodeTrieBuilder(); for (let i = 0; i < codepoints.length; i++) { let codepoint = codepoints[i]; if (codepoint) { - if (codepoint.joiningGroup === 'ALAPH' || codepoint.joiningGroup === 'DALATH RISH') { + if ( + codepoint.joiningGroup === 'ALAPH' || + codepoint.joiningGroup === 'DALATH RISH' + ) { trie.set(codepoint.code, ShapingClasses[codepoint.joiningGroup] + 1); - } else if (codepoint.joiningType) { trie.set(codepoint.code, ShapingClasses[codepoint.joiningType] + 1); } diff --git a/src/opentype/shapers/index.js b/src/opentype/shapers/index.js index b22ebdd3..67b37978 100644 --- a/src/opentype/shapers/index.js +++ b/src/opentype/shapers/index.js @@ -5,36 +5,36 @@ import IndicShaper from './IndicShaper'; import UniversalShaper from './UniversalShaper'; const SHAPERS = { - arab: ArabicShaper, // Arabic - mong: ArabicShaper, // Mongolian - syrc: ArabicShaper, // Syriac - 'nko ': ArabicShaper, // N'Ko - phag: ArabicShaper, // Phags Pa - mand: ArabicShaper, // Mandaic - mani: ArabicShaper, // Manichaean - phlp: ArabicShaper, // Psalter Pahlavi + arab: ArabicShaper, // Arabic + mong: ArabicShaper, // Mongolian + syrc: ArabicShaper, // Syriac + 'nko ': ArabicShaper, // N'Ko + phag: ArabicShaper, // Phags Pa + mand: ArabicShaper, // Mandaic + mani: ArabicShaper, // Manichaean + phlp: ArabicShaper, // Psalter Pahlavi - hang: HangulShaper, // Hangul + hang: HangulShaper, // Hangul - bng2: IndicShaper, // Bengali - beng: IndicShaper, // Bengali - dev2: IndicShaper, // Devanagari - deva: IndicShaper, // Devanagari - gjr2: IndicShaper, // Gujarati - gujr: IndicShaper, // Gujarati - guru: IndicShaper, // Gurmukhi - gur2: IndicShaper, // Gurmukhi - knda: IndicShaper, // Kannada - knd2: IndicShaper, // Kannada - mlm2: IndicShaper, // Malayalam - mlym: IndicShaper, // Malayalam - ory2: IndicShaper, // Oriya - orya: IndicShaper, // Oriya - taml: IndicShaper, // Tamil - tml2: IndicShaper, // Tamil - telu: IndicShaper, // Telugu - tel2: IndicShaper, // Telugu - khmr: IndicShaper, // Khmer + bng2: IndicShaper, // Bengali + beng: IndicShaper, // Bengali + dev2: IndicShaper, // Devanagari + deva: IndicShaper, // Devanagari + gjr2: IndicShaper, // Gujarati + gujr: IndicShaper, // Gujarati + guru: IndicShaper, // Gurmukhi + gur2: IndicShaper, // Gurmukhi + knda: IndicShaper, // Kannada + knd2: IndicShaper, // Kannada + mlm2: IndicShaper, // Malayalam + mlym: IndicShaper, // Malayalam + ory2: IndicShaper, // Oriya + orya: IndicShaper, // Oriya + taml: IndicShaper, // Tamil + tml2: IndicShaper, // Tamil + telu: IndicShaper, // Telugu + tel2: IndicShaper, // Telugu + khmr: IndicShaper, // Khmer bali: UniversalShaper, // Balinese batk: UniversalShaper, // Batak @@ -82,8 +82,8 @@ const SHAPERS = { tfng: UniversalShaper, // Tifinagh tirh: UniversalShaper, // Tirhuta - latn: DefaultShaper, // Latin - DFLT: DefaultShaper // Default + latn: DefaultShaper, // Latin + DFLT: DefaultShaper, // Default }; export function choose(script) { diff --git a/src/opentype/shapers/indic-data.js b/src/opentype/shapers/indic-data.js index 30feff2b..f4841de6 100644 --- a/src/opentype/shapers/indic-data.js +++ b/src/opentype/shapers/indic-data.js @@ -14,12 +14,12 @@ export const CATEGORIES = { A: 1 << 10, Placeholder: 1 << 11, Dotted_Circle: 1 << 12, - RS: 1 << 13, // Register Shifter, used in Khmer OT spec. + RS: 1 << 13, // Register Shifter, used in Khmer OT spec. Coeng: 1 << 14, // Khmer-style Virama. Repha: 1 << 15, // Atomically-encoded logical or visual repha. Ra: 1 << 16, - CM: 1 << 17, // Consonant-Medial. - Symbol: 1 << 18 // Avagraha, etc that take marks (SM,A,VD). + CM: 1 << 17, // Consonant-Medial. + Symbol: 1 << 18, // Avagraha, etc that take marks (SM,A,VD). }; // Visual positions in a syllable from left to right. @@ -46,10 +46,16 @@ export const POSITIONS = { Final_C: 1 << 13, SMVD: 1 << 14, - End: 1 << 15 + End: 1 << 15, }; -export const CONSONANT_FLAGS = CATEGORIES.C | CATEGORIES.Ra | CATEGORIES.CM | CATEGORIES.V | CATEGORIES.Placeholder | CATEGORIES.Dotted_Circle; +export const CONSONANT_FLAGS = + CATEGORIES.C | + CATEGORIES.Ra | + CATEGORIES.CM | + CATEGORIES.V | + CATEGORIES.Placeholder | + CATEGORIES.Dotted_Circle; export const JOINER_FLAGS = CATEGORIES.ZWJ | CATEGORIES.ZWNJ; export const HALANT_OR_COENG_FLAGS = CATEGORIES.H | CATEGORIES.Coeng; @@ -60,88 +66,88 @@ export const INDIC_CONFIGS = { basePos: 'Last', rephPos: POSITIONS.Before_Post, rephMode: 'Implicit', - blwfMode: 'Pre_And_Post' + blwfMode: 'Pre_And_Post', }, Devanagari: { hasOldSpec: true, - virama: 0x094D, + virama: 0x094d, basePos: 'Last', rephPos: POSITIONS.Before_Post, rephMode: 'Implicit', - blwfMode: 'Pre_And_Post' + blwfMode: 'Pre_And_Post', }, Bengali: { hasOldSpec: true, - virama: 0x09CD, + virama: 0x09cd, basePos: 'Last', rephPos: POSITIONS.After_Sub, rephMode: 'Implicit', - blwfMode: 'Pre_And_Post' + blwfMode: 'Pre_And_Post', }, Gurmukhi: { hasOldSpec: true, - virama: 0x0A4D, + virama: 0x0a4d, basePos: 'Last', rephPos: POSITIONS.Before_Sub, rephMode: 'Implicit', - blwfMode: 'Pre_And_Post' + blwfMode: 'Pre_And_Post', }, Gujarati: { hasOldSpec: true, - virama: 0x0ACD, + virama: 0x0acd, basePos: 'Last', rephPos: POSITIONS.Before_Post, rephMode: 'Implicit', - blwfMode: 'Pre_And_Post' + blwfMode: 'Pre_And_Post', }, Oriya: { hasOldSpec: true, - virama: 0x0B4D, + virama: 0x0b4d, basePos: 'Last', rephPos: POSITIONS.After_Main, rephMode: 'Implicit', - blwfMode: 'Pre_And_Post' + blwfMode: 'Pre_And_Post', }, Tamil: { hasOldSpec: true, - virama: 0x0BCD, + virama: 0x0bcd, basePos: 'Last', rephPos: POSITIONS.After_Post, rephMode: 'Implicit', - blwfMode: 'Pre_And_Post' + blwfMode: 'Pre_And_Post', }, Telugu: { hasOldSpec: true, - virama: 0x0C4D, + virama: 0x0c4d, basePos: 'Last', rephPos: POSITIONS.After_Post, rephMode: 'Explicit', - blwfMode: 'Post_Only' + blwfMode: 'Post_Only', }, Kannada: { hasOldSpec: true, - virama: 0x0CCD, + virama: 0x0ccd, basePos: 'Last', rephPos: POSITIONS.After_Post, rephMode: 'Implicit', - blwfMode: 'Post_Only' + blwfMode: 'Post_Only', }, Malayalam: { hasOldSpec: true, - virama: 0x0D4D, + virama: 0x0d4d, basePos: 'Last', rephPos: POSITIONS.After_Main, rephMode: 'Log_Repha', - blwfMode: 'Pre_And_Post' + blwfMode: 'Pre_And_Post', }, // Handled by UniversalShaper @@ -156,20 +162,20 @@ export const INDIC_CONFIGS = { Khmer: { hasOldSpec: false, - virama: 0x17D2, + virama: 0x17d2, basePos: 'First', rephPos: POSITIONS.Ra_To_Become_Reph, rephMode: 'Vis_Repha', - blwfMode: 'Pre_And_Post' - } + blwfMode: 'Pre_And_Post', + }, }; // Additional decompositions that aren't in Unicode export const INDIC_DECOMPOSITIONS = { // Khmer - 0x17BE: [0x17C1, 0x17BE], - 0x17BF: [0x17C1, 0x17BF], - 0x17C0: [0x17C1, 0x17C0], - 0x17C4: [0x17C1, 0x17C4], - 0x17C5: [0x17C1, 0x17C5] + 0x17be: [0x17c1, 0x17be], + 0x17bf: [0x17c1, 0x17bf], + 0x17c0: [0x17c1, 0x17c0], + 0x17c4: [0x17c1, 0x17c4], + 0x17c5: [0x17c1, 0x17c5], }; diff --git a/src/subset/CFFSubset.js b/src/subset/CFFSubset.js index d4506e7b..ac220c67 100644 --- a/src/subset/CFFSubset.js +++ b/src/subset/CFFSubset.js @@ -50,7 +50,7 @@ export default class CFFSubset extends Subset { topDict.FDArray = []; topDict.FDSelect = { version: 0, - fds: [] + fds: [], }; let used_fds = {}; @@ -83,7 +83,10 @@ export default class CFFSubset extends Subset { delete dict.FontName; if (dict.Private && dict.Private.Subrs) { dict.Private = Object.assign({}, dict.Private); - dict.Private.Subrs = this.subsetSubrs(dict.Private.Subrs, used_subrs[i]); + dict.Private.Subrs = this.subsetSubrs( + dict.Private.Subrs, + used_subrs[i], + ); } } @@ -103,16 +106,19 @@ export default class CFFSubset extends Subset { let privateDict = Object.assign({}, this.cff.topDict.Private); if (this.cff.topDict.Private && this.cff.topDict.Private.Subrs) { - privateDict.Subrs = this.subsetSubrs(this.cff.topDict.Private.Subrs, used_subrs); + privateDict.Subrs = this.subsetSubrs( + this.cff.topDict.Private.Subrs, + used_subrs, + ); } topDict.FDArray = [{ Private: privateDict }]; - return topDict.FDSelect = { + return (topDict.FDSelect = { version: 3, nRanges: 1, ranges: [{ first: 0, fd: 0 }], - sentinel: this.charstrings.length - }; + sentinel: this.charstrings.length, + }); } addString(string) { @@ -133,7 +139,7 @@ export default class CFFSubset extends Subset { let charset = { version: this.charstrings.length > 255 ? 2 : 1, - ranges: [{ first: 1, nLeft: this.charstrings.length - 2 }] + ranges: [{ first: 1, nLeft: this.charstrings.length - 2 }], }; let topDict = Object.assign({}, this.cff.topDict); @@ -142,7 +148,17 @@ export default class CFFSubset extends Subset { topDict.Encoding = null; topDict.CharStrings = this.charstrings; - for (let key of ['version', 'Notice', 'Copyright', 'FullName', 'FamilyName', 'Weight', 'PostScript', 'BaseFontName', 'FontName']) { + for (let key of [ + 'version', + 'Notice', + 'Copyright', + 'FullName', + 'FamilyName', + 'Weight', + 'PostScript', + 'BaseFontName', + 'FontName', + ]) { topDict[key] = this.addString(this.cff.string(topDict[key])); } @@ -163,7 +179,7 @@ export default class CFFSubset extends Subset { nameIndex: [this.cff.postscriptName], topDictIndex: [topDict], stringIndex: this.strings, - globalSubrIndex: this.gsubrs + globalSubrIndex: this.gsubrs, }; return CFFTop.toBuffer(top); diff --git a/src/subset/TTFSubset.js b/src/subset/TTFSubset.js index f13e5ce5..ae8a4803 100644 --- a/src/subset/TTFSubset.js +++ b/src/subset/TTFSubset.js @@ -7,7 +7,7 @@ import TTFGlyphEncoder from '../glyph/TTFGlyphEncoder'; export default class TTFSubset extends Subset { constructor(font) { super(font); - this.glyphEncoder = new TTFGlyphEncoder; + this.glyphEncoder = new TTFGlyphEncoder(); } _addGlyph(gid) { @@ -41,7 +41,7 @@ export default class TTFSubset extends Subset { this.hmtx.metrics.push({ advance: glyph.advanceWidth, - bearing: glyph._getMetrics().leftBearing + bearing: glyph._getMetrics().leftBearing, }); this.offset += buffer.length; @@ -59,12 +59,12 @@ export default class TTFSubset extends Subset { this.offset = 0; this.loca = { offsets: [], - version: this.font.loca.version + version: this.font.loca.version, }; this.hmtx = { metrics: [], - bearings: [] + bearings: [], }; // include all the glyphs @@ -119,13 +119,13 @@ export default class TTFSubset extends Subset { prep: this.font.prep, glyf: this.glyf, hmtx: this.hmtx, - fpgm: this.font.fpgm + fpgm: this.font.fpgm, // name: clone @font.name // 'OS/2': clone @font['OS/2'] // post: clone @font.post // cmap: cmap - } + }, }); } } diff --git a/src/tables/BASE.js b/src/tables/BASE.js index bbb84cfb..3bef1081 100644 --- a/src/tables/BASE.js +++ b/src/tables/BASE.js @@ -1,58 +1,68 @@ import * as r from 'restructure'; -import {ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device} from './opentype'; -import {ItemVariationStore} from './variations'; +import { + ScriptList, + FeatureList, + LookupList, + Coverage, + ClassDef, + Device, +} from './opentype'; +import { ItemVariationStore } from './variations'; let BaseCoord = new r.VersionedStruct(r.uint16, { - 1: { // Design units only - coordinate: r.int16 // X or Y value, in design units + 1: { + // Design units only + coordinate: r.int16, // X or Y value, in design units }, - 2: { // Design units plus contour point - coordinate: r.int16, // X or Y value, in design units - referenceGlyph: r.uint16, // GlyphID of control glyph - baseCoordPoint: r.uint16 // Index of contour point on the referenceGlyph + 2: { + // Design units plus contour point + coordinate: r.int16, // X or Y value, in design units + referenceGlyph: r.uint16, // GlyphID of control glyph + baseCoordPoint: r.uint16, // Index of contour point on the referenceGlyph }, - 3: { // Design units plus Device table - coordinate: r.int16, // X or Y value, in design units - deviceTable: new r.Pointer(r.uint16, Device) // Device table for X or Y value - } + 3: { + // Design units plus Device table + coordinate: r.int16, // X or Y value, in design units + deviceTable: new r.Pointer(r.uint16, Device), // Device table for X or Y value + }, }); let BaseValues = new r.Struct({ - defaultIndex: r.uint16, // Index of default baseline for this script-same index in the BaseTagList + defaultIndex: r.uint16, // Index of default baseline for this script-same index in the BaseTagList baseCoordCount: r.uint16, - baseCoords: new r.Array(new r.Pointer(r.uint16, BaseCoord), 'baseCoordCount') + baseCoords: new r.Array(new r.Pointer(r.uint16, BaseCoord), 'baseCoordCount'), }); let FeatMinMaxRecord = new r.Struct({ - tag: new r.String(4), // 4-byte feature identification tag-must match FeatureTag in FeatureList - minCoord: new r.Pointer(r.uint16, BaseCoord, {type: 'parent'}), // May be NULL - maxCoord: new r.Pointer(r.uint16, BaseCoord, {type: 'parent'}) // May be NULL + tag: new r.String(4), // 4-byte feature identification tag-must match FeatureTag in FeatureList + minCoord: new r.Pointer(r.uint16, BaseCoord, { type: 'parent' }), // May be NULL + maxCoord: new r.Pointer(r.uint16, BaseCoord, { type: 'parent' }), // May be NULL }); let MinMax = new r.Struct({ - minCoord: new r.Pointer(r.uint16, BaseCoord), // May be NULL - maxCoord: new r.Pointer(r.uint16, BaseCoord), // May be NULL - featMinMaxCount: r.uint16, // May be 0 - featMinMaxRecords: new r.Array(FeatMinMaxRecord, 'featMinMaxCount') // In alphabetical order + minCoord: new r.Pointer(r.uint16, BaseCoord), // May be NULL + maxCoord: new r.Pointer(r.uint16, BaseCoord), // May be NULL + featMinMaxCount: r.uint16, // May be 0 + featMinMaxRecords: new r.Array(FeatMinMaxRecord, 'featMinMaxCount'), // In alphabetical order }); let BaseLangSysRecord = new r.Struct({ - tag: new r.String(4), // 4-byte language system identification tag - minMax: new r.Pointer(r.uint16, MinMax, {type: 'parent'}) + tag: new r.String(4), // 4-byte language system identification tag + minMax: new r.Pointer(r.uint16, MinMax, { type: 'parent' }), }); let BaseScript = new r.Struct({ - baseValues: new r.Pointer(r.uint16, BaseValues), // May be NULL - defaultMinMax: new r.Pointer(r.uint16, MinMax), // May be NULL - baseLangSysCount: r.uint16, // May be 0 - baseLangSysRecords: new r.Array(BaseLangSysRecord, 'baseLangSysCount') // in alphabetical order by BaseLangSysTag + baseValues: new r.Pointer(r.uint16, BaseValues), // May be NULL + defaultMinMax: new r.Pointer(r.uint16, MinMax), // May be NULL + baseLangSysCount: r.uint16, // May be 0 + baseLangSysRecords: new r.Array(BaseLangSysRecord, 'baseLangSysCount'), // in alphabetical order by BaseLangSysTag }); let BaseScriptRecord = new r.Struct({ - tag: new r.String(4), // 4-byte script identification tag - script: new r.Pointer(r.uint16, BaseScript, {type: 'parent'}) + tag: new r.String(4), // 4-byte script identification tag + script: new r.Pointer(r.uint16, BaseScript, { type: 'parent' }), }); let BaseScriptList = new r.Array(BaseScriptRecord, r.uint16); @@ -61,18 +71,18 @@ let BaseScriptList = new r.Array(BaseScriptRecord, r.uint16); let BaseTagList = new r.Array(new r.String(4), r.uint16); let Axis = new r.Struct({ - baseTagList: new r.Pointer(r.uint16, BaseTagList), // May be NULL - baseScriptList: new r.Pointer(r.uint16, BaseScriptList) + baseTagList: new r.Pointer(r.uint16, BaseTagList), // May be NULL + baseScriptList: new r.Pointer(r.uint16, BaseScriptList), }); export default new r.VersionedStruct(r.uint32, { header: { - horizAxis: new r.Pointer(r.uint16, Axis), // May be NULL - vertAxis: new r.Pointer(r.uint16, Axis) // May be NULL + horizAxis: new r.Pointer(r.uint16, Axis), // May be NULL + vertAxis: new r.Pointer(r.uint16, Axis), // May be NULL }, 0x00010000: {}, 0x00010001: { - itemVariationStore: new r.Pointer(r.uint32, ItemVariationStore) - } + itemVariationStore: new r.Pointer(r.uint32, ItemVariationStore), + }, }); diff --git a/src/tables/COLR.js b/src/tables/COLR.js index 6a4b1697..f5fece64 100644 --- a/src/tables/COLR.js +++ b/src/tables/COLR.js @@ -1,25 +1,32 @@ import * as r from 'restructure'; let LayerRecord = new r.Struct({ - gid: r.uint16, // Glyph ID of layer glyph (must be in z-order from bottom to top). - paletteIndex: r.uint16 // Index value to use in the appropriate palette. This value must -}); // be less than numPaletteEntries in the CPAL table, except for - // the special case noted below. Each palette entry is 16 bits. - // A palette index of 0xFFFF is a special case indicating that - // the text foreground color should be used. + gid: r.uint16, // Glyph ID of layer glyph (must be in z-order from bottom to top). + paletteIndex: r.uint16, // Index value to use in the appropriate palette. This value must +}); // be less than numPaletteEntries in the CPAL table, except for +// the special case noted below. Each palette entry is 16 bits. +// A palette index of 0xFFFF is a special case indicating that +// the text foreground color should be used. let BaseGlyphRecord = new r.Struct({ - gid: r.uint16, // Glyph ID of reference glyph. This glyph is for reference only - // and is not rendered for color. + gid: r.uint16, // Glyph ID of reference glyph. This glyph is for reference only + // and is not rendered for color. firstLayerIndex: r.uint16, // Index (from beginning of the Layer Records) to the layer record. - // There will be numLayers consecutive entries for this base glyph. - numLayers: r.uint16 + // There will be numLayers consecutive entries for this base glyph. + numLayers: r.uint16, }); export default new r.Struct({ version: r.uint16, numBaseGlyphRecords: r.uint16, - baseGlyphRecord: new r.Pointer(r.uint32, new r.Array(BaseGlyphRecord, 'numBaseGlyphRecords')), - layerRecords: new r.Pointer(r.uint32, new r.Array(LayerRecord, 'numLayerRecords'), { lazy: true }), - numLayerRecords: r.uint16 + baseGlyphRecord: new r.Pointer( + r.uint32, + new r.Array(BaseGlyphRecord, 'numBaseGlyphRecords'), + ), + layerRecords: new r.Pointer( + r.uint32, + new r.Array(LayerRecord, 'numLayerRecords'), + { lazy: true }, + ), + numLayerRecords: r.uint16, }); diff --git a/src/tables/CPAL.js b/src/tables/CPAL.js index 2b4fd9ee..f3902e3e 100644 --- a/src/tables/CPAL.js +++ b/src/tables/CPAL.js @@ -4,7 +4,7 @@ let ColorRecord = new r.Struct({ blue: r.uint8, green: r.uint8, red: r.uint8, - alpha: r.uint8 + alpha: r.uint8, }); export default new r.VersionedStruct(r.uint16, { @@ -12,13 +12,25 @@ export default new r.VersionedStruct(r.uint16, { numPaletteEntries: r.uint16, numPalettes: r.uint16, numColorRecords: r.uint16, - colorRecords: new r.Pointer(r.uint32, new r.Array(ColorRecord, 'numColorRecords')), + colorRecords: new r.Pointer( + r.uint32, + new r.Array(ColorRecord, 'numColorRecords'), + ), colorRecordIndices: new r.Array(r.uint16, 'numPalettes'), }, 0: {}, 1: { - offsetPaletteTypeArray: new r.Pointer(r.uint32, new r.Array(r.uint32, 'numPalettes')), - offsetPaletteLabelArray: new r.Pointer(r.uint32, new r.Array(r.uint16, 'numPalettes')), - offsetPaletteEntryLabelArray: new r.Pointer(r.uint32, new r.Array(r.uint16, 'numPaletteEntries')) - } + offsetPaletteTypeArray: new r.Pointer( + r.uint32, + new r.Array(r.uint32, 'numPalettes'), + ), + offsetPaletteLabelArray: new r.Pointer( + r.uint32, + new r.Array(r.uint16, 'numPalettes'), + ), + offsetPaletteEntryLabelArray: new r.Pointer( + r.uint32, + new r.Array(r.uint16, 'numPaletteEntries'), + ), + }, }); diff --git a/src/tables/DSIG.js b/src/tables/DSIG.js index 660be0c9..f8007119 100644 --- a/src/tables/DSIG.js +++ b/src/tables/DSIG.js @@ -3,19 +3,19 @@ import * as r from 'restructure'; let Signature = new r.Struct({ format: r.uint32, length: r.uint32, - offset: r.uint32 + offset: r.uint32, }); let SignatureBlock = new r.Struct({ - reserved: new r.Reserved(r.uint16, 2), - cbSignature: r.uint32, // Length (in bytes) of the PKCS#7 packet in pbSignature - signature: new r.Buffer('cbSignature') + reserved: new r.Reserved(r.uint16, 2), + cbSignature: r.uint32, // Length (in bytes) of the PKCS#7 packet in pbSignature + signature: new r.Buffer('cbSignature'), }); export default new r.Struct({ - ulVersion: r.uint32, // Version number of the DSIG table (0x00000001) - usNumSigs: r.uint16, // Number of signatures in the table - usFlag: r.uint16, // Permission flags - signatures: new r.Array(Signature, 'usNumSigs'), - signatureBlocks: new r.Array(SignatureBlock, 'usNumSigs') + ulVersion: r.uint32, // Version number of the DSIG table (0x00000001) + usNumSigs: r.uint16, // Number of signatures in the table + usFlag: r.uint16, // Permission flags + signatures: new r.Array(Signature, 'usNumSigs'), + signatureBlocks: new r.Array(SignatureBlock, 'usNumSigs'), }); diff --git a/src/tables/EBDT.js b/src/tables/EBDT.js index c4aa5967..14ee3daf 100644 --- a/src/tables/EBDT.js +++ b/src/tables/EBDT.js @@ -8,7 +8,7 @@ export let BigMetrics = new r.Struct({ horiAdvance: r.uint8, vertBearingX: r.int8, vertBearingY: r.int8, - vertAdvance: r.uint8 + vertAdvance: r.uint8, }); export let SmallMetrics = new r.Struct({ @@ -16,13 +16,13 @@ export let SmallMetrics = new r.Struct({ width: r.uint8, bearingX: r.int8, bearingY: r.int8, - advance: r.uint8 + advance: r.uint8, }); let EBDTComponent = new r.Struct({ glyph: r.uint16, xOffset: r.int8, - yOffset: r.int8 + yOffset: r.int8, }); class ByteAligned {} @@ -32,60 +32,59 @@ class BitAligned {} export let glyph = new r.VersionedStruct('version', { 1: { metrics: SmallMetrics, - data: ByteAligned + data: ByteAligned, }, 2: { metrics: SmallMetrics, - data: BitAligned + data: BitAligned, }, // format 3 is deprecated // format 4 is not supported by Microsoft 5: { - data: BitAligned + data: BitAligned, }, 6: { metrics: BigMetrics, - data: ByteAligned + data: ByteAligned, }, 7: { metrics: BigMetrics, - data: BitAligned + data: BitAligned, }, 8: { metrics: SmallMetrics, pad: new r.Reserved(r.uint8), numComponents: r.uint16, - components: new r.Array(EBDTComponent, 'numComponents') + components: new r.Array(EBDTComponent, 'numComponents'), }, 9: { metrics: BigMetrics, pad: new r.Reserved(r.uint8), numComponents: r.uint16, - components: new r.Array(EBDTComponent, 'numComponents') + components: new r.Array(EBDTComponent, 'numComponents'), }, 17: { metrics: SmallMetrics, dataLen: r.uint32, - data: new r.Buffer('dataLen') + data: new r.Buffer('dataLen'), }, 18: { metrics: BigMetrics, dataLen: r.uint32, - data: new r.Buffer('dataLen') + data: new r.Buffer('dataLen'), }, 19: { dataLen: r.uint32, - data: new r.Buffer('dataLen') - } + data: new r.Buffer('dataLen'), + }, }); - diff --git a/src/tables/EBLC.js b/src/tables/EBLC.js index 90705ef9..0b67cd87 100644 --- a/src/tables/EBLC.js +++ b/src/tables/EBLC.js @@ -1,5 +1,5 @@ import * as r from 'restructure'; -import {BigMetrics} from './EBDT'; +import { BigMetrics } from './EBDT'; let SBitLineMetrics = new r.Struct({ ascender: r.int8, @@ -12,54 +12,64 @@ let SBitLineMetrics = new r.Struct({ minAdvanceSB: r.int8, maxBeforeBL: r.int8, minAfterBL: r.int8, - pad: new r.Reserved(r.int8, 2) + pad: new r.Reserved(r.int8, 2), }); let CodeOffsetPair = new r.Struct({ glyphCode: r.uint16, - offset: r.uint16 + offset: r.uint16, }); let IndexSubtable = new r.VersionedStruct(r.uint16, { header: { imageFormat: r.uint16, - imageDataOffset: r.uint32 + imageDataOffset: r.uint32, }, 1: { - offsetArray: new r.Array(r.uint32, t => t.parent.lastGlyphIndex - t.parent.firstGlyphIndex + 1) + offsetArray: new r.Array( + r.uint32, + (t) => t.parent.lastGlyphIndex - t.parent.firstGlyphIndex + 1, + ), }, 2: { imageSize: r.uint32, - bigMetrics: BigMetrics + bigMetrics: BigMetrics, }, 3: { - offsetArray: new r.Array(r.uint16, t => t.parent.lastGlyphIndex - t.parent.firstGlyphIndex + 1) + offsetArray: new r.Array( + r.uint16, + (t) => t.parent.lastGlyphIndex - t.parent.firstGlyphIndex + 1, + ), }, 4: { numGlyphs: r.uint32, - glyphArray: new r.Array(CodeOffsetPair, t => t.numGlyphs + 1) + glyphArray: new r.Array(CodeOffsetPair, (t) => t.numGlyphs + 1), }, 5: { imageSize: r.uint32, bigMetrics: BigMetrics, numGlyphs: r.uint32, - glyphCodeArray: new r.Array(r.uint16, 'numGlyphs') - } + glyphCodeArray: new r.Array(r.uint16, 'numGlyphs'), + }, }); let IndexSubtableArray = new r.Struct({ firstGlyphIndex: r.uint16, lastGlyphIndex: r.uint16, - subtable: new r.Pointer(r.uint32, IndexSubtable) + subtable: new r.Pointer(r.uint32, IndexSubtable), }); let BitmapSizeTable = new r.Struct({ - indexSubTableArray: new r.Pointer(r.uint32, new r.Array(IndexSubtableArray, 1), { type: 'parent' }), + indexSubTableArray: new r.Pointer( + r.uint32, + new r.Array(IndexSubtableArray, 1), + { type: 'parent' }, + ), indexTablesSize: r.uint32, numberOfIndexSubTables: r.uint32, colorRef: r.uint32, @@ -70,11 +80,11 @@ let BitmapSizeTable = new r.Struct({ ppemX: r.uint8, ppemY: r.uint8, bitDepth: r.uint8, - flags: new r.Bitfield(r.uint8, ['horizontal', 'vertical']) + flags: new r.Bitfield(r.uint8, ['horizontal', 'vertical']), }); export default new r.Struct({ - version: r.uint32, // 0x00020000 + version: r.uint32, // 0x00020000 numSizes: r.uint32, - sizes: new r.Array(BitmapSizeTable, 'numSizes') + sizes: new r.Array(BitmapSizeTable, 'numSizes'), }); diff --git a/src/tables/GDEF.js b/src/tables/GDEF.js index a1be8630..0452b088 100644 --- a/src/tables/GDEF.js +++ b/src/tables/GDEF.js @@ -1,57 +1,67 @@ import * as r from 'restructure'; -import {ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device} from './opentype'; -import {ItemVariationStore} from './variations'; +import { + ScriptList, + FeatureList, + LookupList, + Coverage, + ClassDef, + Device, +} from './opentype'; +import { ItemVariationStore } from './variations'; let AttachPoint = new r.Array(r.uint16, r.uint16); let AttachList = new r.Struct({ - coverage: new r.Pointer(r.uint16, Coverage), - glyphCount: r.uint16, - attachPoints: new r.Array(new r.Pointer(r.uint16, AttachPoint), 'glyphCount') + coverage: new r.Pointer(r.uint16, Coverage), + glyphCount: r.uint16, + attachPoints: new r.Array(new r.Pointer(r.uint16, AttachPoint), 'glyphCount'), }); let CaretValue = new r.VersionedStruct(r.uint16, { - 1: { // Design units only - coordinate: r.int16 + 1: { + // Design units only + coordinate: r.int16, }, - 2: { // Contour point - caretValuePoint: r.uint16 + 2: { + // Contour point + caretValuePoint: r.uint16, }, - 3: { // Design units plus Device table - coordinate: r.int16, - deviceTable: new r.Pointer(r.uint16, Device) - } + 3: { + // Design units plus Device table + coordinate: r.int16, + deviceTable: new r.Pointer(r.uint16, Device), + }, }); let LigGlyph = new r.Array(new r.Pointer(r.uint16, CaretValue), r.uint16); let LigCaretList = new r.Struct({ - coverage: new r.Pointer(r.uint16, Coverage), - ligGlyphCount: r.uint16, - ligGlyphs: new r.Array(new r.Pointer(r.uint16, LigGlyph), 'ligGlyphCount') + coverage: new r.Pointer(r.uint16, Coverage), + ligGlyphCount: r.uint16, + ligGlyphs: new r.Array(new r.Pointer(r.uint16, LigGlyph), 'ligGlyphCount'), }); let MarkGlyphSetsDef = new r.Struct({ markSetTableFormat: r.uint16, - markSetCount: r.uint16, - coverage: new r.Array(new r.Pointer(r.uint32, Coverage), 'markSetCount') + markSetCount: r.uint16, + coverage: new r.Array(new r.Pointer(r.uint32, Coverage), 'markSetCount'), }); export default new r.VersionedStruct(r.uint32, { header: { - glyphClassDef: new r.Pointer(r.uint16, ClassDef), - attachList: new r.Pointer(r.uint16, AttachList), - ligCaretList: new r.Pointer(r.uint16, LigCaretList), - markAttachClassDef: new r.Pointer(r.uint16, ClassDef) + glyphClassDef: new r.Pointer(r.uint16, ClassDef), + attachList: new r.Pointer(r.uint16, AttachList), + ligCaretList: new r.Pointer(r.uint16, LigCaretList), + markAttachClassDef: new r.Pointer(r.uint16, ClassDef), }, 0x00010000: {}, 0x00010002: { - markGlyphSetsDef: new r.Pointer(r.uint16, MarkGlyphSetsDef) + markGlyphSetsDef: new r.Pointer(r.uint16, MarkGlyphSetsDef), }, 0x00010003: { - markGlyphSetsDef: new r.Pointer(r.uint16, MarkGlyphSetsDef), - itemVariationStore: new r.Pointer(r.uint32, ItemVariationStore) - } + markGlyphSetsDef: new r.Pointer(r.uint16, MarkGlyphSetsDef), + itemVariationStore: new r.Pointer(r.uint32, ItemVariationStore), + }, }); diff --git a/src/tables/GPOS.js b/src/tables/GPOS.js index 3fc7cc33..00cdedef 100644 --- a/src/tables/GPOS.js +++ b/src/tables/GPOS.js @@ -1,23 +1,48 @@ import * as r from 'restructure'; -import {ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device, Context, ChainingContext} from './opentype'; -import {FeatureVariations} from './variations'; +import { + ScriptList, + FeatureList, + LookupList, + Coverage, + ClassDef, + Device, + Context, + ChainingContext, +} from './opentype'; +import { FeatureVariations } from './variations'; let ValueFormat = new r.Bitfield(r.uint16, [ - 'xPlacement', 'yPlacement', - 'xAdvance', 'yAdvance', - 'xPlaDevice', 'yPlaDevice', - 'xAdvDevice', 'yAdvDevice' + 'xPlacement', + 'yPlacement', + 'xAdvance', + 'yAdvance', + 'xPlaDevice', + 'yPlaDevice', + 'xAdvDevice', + 'yAdvDevice', ]); let types = { xPlacement: r.int16, yPlacement: r.int16, - xAdvance: r.int16, - yAdvance: r.int16, - xPlaDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }), - yPlaDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }), - xAdvDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }), - yAdvDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }) + xAdvance: r.int16, + yAdvance: r.int16, + xPlaDevice: new r.Pointer(r.uint16, Device, { + type: 'global', + relativeTo: (ctx) => ctx.rel, + }), + yPlaDevice: new r.Pointer(r.uint16, Device, { + type: 'global', + relativeTo: (ctx) => ctx.rel, + }), + xAdvDevice: new r.Pointer(r.uint16, Device, { + type: 'global', + relativeTo: (ctx) => ctx.rel, + }), + yAdvDevice: new r.Pointer(r.uint16, Device, { + type: 'global', + relativeTo: (ctx) => ctx.rel, + }), }; class ValueRecord { @@ -58,135 +83,163 @@ class ValueRecord { } let PairValueRecord = new r.Struct({ - secondGlyph: r.uint16, - value1: new ValueRecord('valueFormat1'), - value2: new ValueRecord('valueFormat2') + secondGlyph: r.uint16, + value1: new ValueRecord('valueFormat1'), + value2: new ValueRecord('valueFormat2'), }); let PairSet = new r.Array(PairValueRecord, r.uint16); let Class2Record = new r.Struct({ value1: new ValueRecord('valueFormat1'), - value2: new ValueRecord('valueFormat2') + value2: new ValueRecord('valueFormat2'), }); let Anchor = new r.VersionedStruct(r.uint16, { - 1: { // Design units only - xCoordinate: r.int16, - yCoordinate: r.int16 + 1: { + // Design units only + xCoordinate: r.int16, + yCoordinate: r.int16, }, - 2: { // Design units plus contour point - xCoordinate: r.int16, - yCoordinate: r.int16, - anchorPoint: r.uint16 + 2: { + // Design units plus contour point + xCoordinate: r.int16, + yCoordinate: r.int16, + anchorPoint: r.uint16, }, - 3: { // Design units plus Device tables - xCoordinate: r.int16, - yCoordinate: r.int16, - xDeviceTable: new r.Pointer(r.uint16, Device), - yDeviceTable: new r.Pointer(r.uint16, Device) - } + 3: { + // Design units plus Device tables + xCoordinate: r.int16, + yCoordinate: r.int16, + xDeviceTable: new r.Pointer(r.uint16, Device), + yDeviceTable: new r.Pointer(r.uint16, Device), + }, }); let EntryExitRecord = new r.Struct({ - entryAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'}), - exitAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'}) + entryAnchor: new r.Pointer(r.uint16, Anchor, { type: 'parent' }), + exitAnchor: new r.Pointer(r.uint16, Anchor, { type: 'parent' }), }); let MarkRecord = new r.Struct({ - class: r.uint16, - markAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'}) + class: r.uint16, + markAnchor: new r.Pointer(r.uint16, Anchor, { type: 'parent' }), }); let MarkArray = new r.Array(MarkRecord, r.uint16); -let BaseRecord = new r.Array(new r.Pointer(r.uint16, Anchor), t => t.parent.classCount); -let BaseArray = new r.Array(BaseRecord, r.uint16); - -let ComponentRecord = new r.Array(new r.Pointer(r.uint16, Anchor), t => t.parent.parent.classCount); -let LigatureAttach = new r.Array(ComponentRecord, r.uint16); -let LigatureArray = new r.Array(new r.Pointer(r.uint16, LigatureAttach), r.uint16); +let BaseRecord = new r.Array( + new r.Pointer(r.uint16, Anchor), + (t) => t.parent.classCount, +); +let BaseArray = new r.Array(BaseRecord, r.uint16); + +let ComponentRecord = new r.Array( + new r.Pointer(r.uint16, Anchor), + (t) => t.parent.parent.classCount, +); +let LigatureAttach = new r.Array(ComponentRecord, r.uint16); +let LigatureArray = new r.Array( + new r.Pointer(r.uint16, LigatureAttach), + r.uint16, +); let GPOSLookup = new r.VersionedStruct('lookupType', { - 1: new r.VersionedStruct(r.uint16, { // Single Adjustment - 1: { // Single positioning value - coverage: new r.Pointer(r.uint16, Coverage), - valueFormat: ValueFormat, - value: new ValueRecord() + 1: new r.VersionedStruct(r.uint16, { + // Single Adjustment + 1: { + // Single positioning value + coverage: new r.Pointer(r.uint16, Coverage), + valueFormat: ValueFormat, + value: new ValueRecord(), }, 2: { - coverage: new r.Pointer(r.uint16, Coverage), - valueFormat: ValueFormat, - valueCount: r.uint16, - values: new r.LazyArray(new ValueRecord(), 'valueCount') - } + coverage: new r.Pointer(r.uint16, Coverage), + valueFormat: ValueFormat, + valueCount: r.uint16, + values: new r.LazyArray(new ValueRecord(), 'valueCount'), + }, }), - 2: new r.VersionedStruct(r.uint16, { // Pair Adjustment Positioning - 1: { // Adjustments for glyph pairs - coverage: new r.Pointer(r.uint16, Coverage), - valueFormat1: ValueFormat, - valueFormat2: ValueFormat, - pairSetCount: r.uint16, - pairSets: new r.LazyArray(new r.Pointer(r.uint16, PairSet), 'pairSetCount') + 2: new r.VersionedStruct(r.uint16, { + // Pair Adjustment Positioning + 1: { + // Adjustments for glyph pairs + coverage: new r.Pointer(r.uint16, Coverage), + valueFormat1: ValueFormat, + valueFormat2: ValueFormat, + pairSetCount: r.uint16, + pairSets: new r.LazyArray( + new r.Pointer(r.uint16, PairSet), + 'pairSetCount', + ), }, - 2: { // Class pair adjustment - coverage: new r.Pointer(r.uint16, Coverage), - valueFormat1: ValueFormat, - valueFormat2: ValueFormat, - classDef1: new r.Pointer(r.uint16, ClassDef), - classDef2: new r.Pointer(r.uint16, ClassDef), - class1Count: r.uint16, - class2Count: r.uint16, - classRecords: new r.LazyArray(new r.LazyArray(Class2Record, 'class2Count'), 'class1Count') - } + 2: { + // Class pair adjustment + coverage: new r.Pointer(r.uint16, Coverage), + valueFormat1: ValueFormat, + valueFormat2: ValueFormat, + classDef1: new r.Pointer(r.uint16, ClassDef), + classDef2: new r.Pointer(r.uint16, ClassDef), + class1Count: r.uint16, + class2Count: r.uint16, + classRecords: new r.LazyArray( + new r.LazyArray(Class2Record, 'class2Count'), + 'class1Count', + ), + }, }), - 3: { // Cursive Attachment Positioning - format: r.uint16, - coverage: new r.Pointer(r.uint16, Coverage), - entryExitCount: r.uint16, - entryExitRecords: new r.Array(EntryExitRecord, 'entryExitCount') + 3: { + // Cursive Attachment Positioning + format: r.uint16, + coverage: new r.Pointer(r.uint16, Coverage), + entryExitCount: r.uint16, + entryExitRecords: new r.Array(EntryExitRecord, 'entryExitCount'), }, - 4: { // MarkToBase Attachment Positioning - format: r.uint16, - markCoverage: new r.Pointer(r.uint16, Coverage), - baseCoverage: new r.Pointer(r.uint16, Coverage), - classCount: r.uint16, - markArray: new r.Pointer(r.uint16, MarkArray), - baseArray: new r.Pointer(r.uint16, BaseArray) + 4: { + // MarkToBase Attachment Positioning + format: r.uint16, + markCoverage: new r.Pointer(r.uint16, Coverage), + baseCoverage: new r.Pointer(r.uint16, Coverage), + classCount: r.uint16, + markArray: new r.Pointer(r.uint16, MarkArray), + baseArray: new r.Pointer(r.uint16, BaseArray), }, - 5: { // MarkToLigature Attachment Positioning - format: r.uint16, - markCoverage: new r.Pointer(r.uint16, Coverage), - ligatureCoverage: new r.Pointer(r.uint16, Coverage), - classCount: r.uint16, - markArray: new r.Pointer(r.uint16, MarkArray), - ligatureArray: new r.Pointer(r.uint16, LigatureArray) + 5: { + // MarkToLigature Attachment Positioning + format: r.uint16, + markCoverage: new r.Pointer(r.uint16, Coverage), + ligatureCoverage: new r.Pointer(r.uint16, Coverage), + classCount: r.uint16, + markArray: new r.Pointer(r.uint16, MarkArray), + ligatureArray: new r.Pointer(r.uint16, LigatureArray), }, - 6: { // MarkToMark Attachment Positioning - format: r.uint16, - mark1Coverage: new r.Pointer(r.uint16, Coverage), - mark2Coverage: new r.Pointer(r.uint16, Coverage), - classCount: r.uint16, - mark1Array: new r.Pointer(r.uint16, MarkArray), - mark2Array: new r.Pointer(r.uint16, BaseArray) + 6: { + // MarkToMark Attachment Positioning + format: r.uint16, + mark1Coverage: new r.Pointer(r.uint16, Coverage), + mark2Coverage: new r.Pointer(r.uint16, Coverage), + classCount: r.uint16, + mark1Array: new r.Pointer(r.uint16, MarkArray), + mark2Array: new r.Pointer(r.uint16, BaseArray), }, - 7: Context, // Contextual positioning - 8: ChainingContext, // Chaining contextual positioning + 7: Context, // Contextual positioning + 8: ChainingContext, // Chaining contextual positioning - 9: { // Extension Positioning - posFormat: r.uint16, - lookupType: r.uint16, // cannot also be 9 - extension: new r.Pointer(r.uint32, null) - } + 9: { + // Extension Positioning + posFormat: r.uint16, + lookupType: r.uint16, // cannot also be 9 + extension: new r.Pointer(r.uint32, null), + }, }); // Fix circular reference @@ -194,15 +247,15 @@ GPOSLookup.versions[9].extension.type = GPOSLookup; export default new r.VersionedStruct(r.uint32, { header: { - scriptList: new r.Pointer(r.uint16, ScriptList), - featureList: new r.Pointer(r.uint16, FeatureList), - lookupList: new r.Pointer(r.uint16, new LookupList(GPOSLookup)) + scriptList: new r.Pointer(r.uint16, ScriptList), + featureList: new r.Pointer(r.uint16, FeatureList), + lookupList: new r.Pointer(r.uint16, new LookupList(GPOSLookup)), }, 0x00010000: {}, 0x00010001: { - featureVariations: new r.Pointer(r.uint32, FeatureVariations) - } + featureVariations: new r.Pointer(r.uint32, FeatureVariations), + }, }); // export GPOSLookup for JSTF table diff --git a/src/tables/GSUB.js b/src/tables/GSUB.js index 757bf5a1..071c2186 100644 --- a/src/tables/GSUB.js +++ b/src/tables/GSUB.js @@ -1,70 +1,97 @@ import * as r from 'restructure'; -import {ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device, Context, ChainingContext} from './opentype'; -import {FeatureVariations} from './variations'; +import { + ScriptList, + FeatureList, + LookupList, + Coverage, + ClassDef, + Device, + Context, + ChainingContext, +} from './opentype'; +import { FeatureVariations } from './variations'; let Sequence = new r.Array(r.uint16, r.uint16); let AlternateSet = Sequence; let Ligature = new r.Struct({ - glyph: r.uint16, - compCount: r.uint16, - components: new r.Array(r.uint16, t => t.compCount - 1) + glyph: r.uint16, + compCount: r.uint16, + components: new r.Array(r.uint16, (t) => t.compCount - 1), }); let LigatureSet = new r.Array(new r.Pointer(r.uint16, Ligature), r.uint16); let GSUBLookup = new r.VersionedStruct('lookupType', { - 1: new r.VersionedStruct(r.uint16, {// Single Substitution + 1: new r.VersionedStruct(r.uint16, { + // Single Substitution 1: { - coverage: new r.Pointer(r.uint16, Coverage), - deltaGlyphID: r.int16 + coverage: new r.Pointer(r.uint16, Coverage), + deltaGlyphID: r.int16, }, 2: { - coverage: new r.Pointer(r.uint16, Coverage), - glyphCount: r.uint16, - substitute: new r.LazyArray(r.uint16, 'glyphCount') - } + coverage: new r.Pointer(r.uint16, Coverage), + glyphCount: r.uint16, + substitute: new r.LazyArray(r.uint16, 'glyphCount'), + }, }), - 2: { // Multiple Substitution - substFormat: r.uint16, - coverage: new r.Pointer(r.uint16, Coverage), - count: r.uint16, - sequences: new r.LazyArray(new r.Pointer(r.uint16, Sequence), 'count') + 2: { + // Multiple Substitution + substFormat: r.uint16, + coverage: new r.Pointer(r.uint16, Coverage), + count: r.uint16, + sequences: new r.LazyArray(new r.Pointer(r.uint16, Sequence), 'count'), }, - 3: { // Alternate Substitution - substFormat: r.uint16, - coverage: new r.Pointer(r.uint16, Coverage), - count: r.uint16, - alternateSet: new r.LazyArray(new r.Pointer(r.uint16, AlternateSet), 'count') + 3: { + // Alternate Substitution + substFormat: r.uint16, + coverage: new r.Pointer(r.uint16, Coverage), + count: r.uint16, + alternateSet: new r.LazyArray( + new r.Pointer(r.uint16, AlternateSet), + 'count', + ), }, - 4: { // Ligature Substitution - substFormat: r.uint16, - coverage: new r.Pointer(r.uint16, Coverage), - count: r.uint16, - ligatureSets: new r.LazyArray(new r.Pointer(r.uint16, LigatureSet), 'count') + 4: { + // Ligature Substitution + substFormat: r.uint16, + coverage: new r.Pointer(r.uint16, Coverage), + count: r.uint16, + ligatureSets: new r.LazyArray( + new r.Pointer(r.uint16, LigatureSet), + 'count', + ), }, - 5: Context, // Contextual Substitution + 5: Context, // Contextual Substitution 6: ChainingContext, // Chaining Contextual Substitution - 7: { // Extension Substitution - substFormat: r.uint16, - lookupType: r.uint16, // cannot also be 7 - extension: new r.Pointer(r.uint32, null) + 7: { + // Extension Substitution + substFormat: r.uint16, + lookupType: r.uint16, // cannot also be 7 + extension: new r.Pointer(r.uint32, null), }, - 8: { // Reverse Chaining Contextual Single Substitution - substFormat: r.uint16, - coverage: new r.Pointer(r.uint16, Coverage), - backtrackCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'backtrackGlyphCount'), - lookaheadGlyphCount: r.uint16, - lookaheadCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'lookaheadGlyphCount'), - glyphCount: r.uint16, - substitutes: new r.Array(r.uint16, 'glyphCount') - } + 8: { + // Reverse Chaining Contextual Single Substitution + substFormat: r.uint16, + coverage: new r.Pointer(r.uint16, Coverage), + backtrackCoverage: new r.Array( + new r.Pointer(r.uint16, Coverage), + 'backtrackGlyphCount', + ), + lookaheadGlyphCount: r.uint16, + lookaheadCoverage: new r.Array( + new r.Pointer(r.uint16, Coverage), + 'lookaheadGlyphCount', + ), + glyphCount: r.uint16, + substitutes: new r.Array(r.uint16, 'glyphCount'), + }, }); // Fix circular reference @@ -72,13 +99,13 @@ GSUBLookup.versions[7].extension.type = GSUBLookup; export default new r.VersionedStruct(r.uint32, { header: { - scriptList: new r.Pointer(r.uint16, ScriptList), - featureList: new r.Pointer(r.uint16, FeatureList), - lookupList: new r.Pointer(r.uint16, new LookupList(GSUBLookup)) + scriptList: new r.Pointer(r.uint16, ScriptList), + featureList: new r.Pointer(r.uint16, FeatureList), + lookupList: new r.Pointer(r.uint16, new LookupList(GSUBLookup)), }, 0x00010000: {}, 0x00010001: { - featureVariations: new r.Pointer(r.uint32, FeatureVariations) - } + featureVariations: new r.Pointer(r.uint32, FeatureVariations), + }, }); diff --git a/src/tables/HVAR.js b/src/tables/HVAR.js index 0b45e958..6d6bd3f8 100644 --- a/src/tables/HVAR.js +++ b/src/tables/HVAR.js @@ -10,10 +10,14 @@ class VariableSizeNumber { decode(stream, parent) { switch (this.size(0, parent)) { - case 1: return stream.readUInt8(); - case 2: return stream.readUInt16BE(); - case 3: return stream.readUInt24BE(); - case 4: return stream.readUInt32BE(); + case 1: + return stream.readUInt8(); + case 2: + return stream.readUInt16BE(); + case 3: + return stream.readUInt24BE(); + case 4: + return stream.readUInt32BE(); } } @@ -23,15 +27,18 @@ class VariableSizeNumber { } let MapDataEntry = new r.Struct({ - entry: new VariableSizeNumber(t => ((t.parent.entryFormat & 0x0030) >> 4) + 1), - outerIndex: t => t.entry >> ((t.parent.entryFormat & 0x000F) + 1), - innerIndex: t => t.entry & ((1 << ((t.parent.entryFormat & 0x000F) + 1)) - 1) + entry: new VariableSizeNumber( + (t) => ((t.parent.entryFormat & 0x0030) >> 4) + 1, + ), + outerIndex: (t) => t.entry >> ((t.parent.entryFormat & 0x000f) + 1), + innerIndex: (t) => + t.entry & ((1 << ((t.parent.entryFormat & 0x000f) + 1)) - 1), }); let DeltaSetIndexMap = new r.Struct({ entryFormat: r.uint16, mapCount: r.uint16, - mapData: new r.Array(MapDataEntry, 'mapCount') + mapData: new r.Array(MapDataEntry, 'mapCount'), }); export default new r.Struct({ @@ -40,5 +47,5 @@ export default new r.Struct({ itemVariationStore: new r.Pointer(r.uint32, ItemVariationStore), advanceWidthMapping: new r.Pointer(r.uint32, DeltaSetIndexMap), LSBMapping: new r.Pointer(r.uint32, DeltaSetIndexMap), - RSBMapping: new r.Pointer(r.uint32, DeltaSetIndexMap) + RSBMapping: new r.Pointer(r.uint32, DeltaSetIndexMap), }); diff --git a/src/tables/JSTF.js b/src/tables/JSTF.js index abfbe948..66902a40 100644 --- a/src/tables/JSTF.js +++ b/src/tables/JSTF.js @@ -1,43 +1,50 @@ import * as r from 'restructure'; -import { ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device } from './opentype'; +import { + ScriptList, + FeatureList, + LookupList, + Coverage, + ClassDef, + Device, +} from './opentype'; import { GPOSLookup } from './GPOS'; let JstfGSUBModList = new r.Array(r.uint16, r.uint16); let JstfPriority = new r.Struct({ - shrinkageEnableGSUB: new r.Pointer(r.uint16, JstfGSUBModList), - shrinkageDisableGSUB: new r.Pointer(r.uint16, JstfGSUBModList), - shrinkageEnableGPOS: new r.Pointer(r.uint16, JstfGSUBModList), - shrinkageDisableGPOS: new r.Pointer(r.uint16, JstfGSUBModList), - shrinkageJstfMax: new r.Pointer(r.uint16, new LookupList(GPOSLookup)), - extensionEnableGSUB: new r.Pointer(r.uint16, JstfGSUBModList), - extensionDisableGSUB: new r.Pointer(r.uint16, JstfGSUBModList), - extensionEnableGPOS: new r.Pointer(r.uint16, JstfGSUBModList), - extensionDisableGPOS: new r.Pointer(r.uint16, JstfGSUBModList), - extensionJstfMax: new r.Pointer(r.uint16, new LookupList(GPOSLookup)) + shrinkageEnableGSUB: new r.Pointer(r.uint16, JstfGSUBModList), + shrinkageDisableGSUB: new r.Pointer(r.uint16, JstfGSUBModList), + shrinkageEnableGPOS: new r.Pointer(r.uint16, JstfGSUBModList), + shrinkageDisableGPOS: new r.Pointer(r.uint16, JstfGSUBModList), + shrinkageJstfMax: new r.Pointer(r.uint16, new LookupList(GPOSLookup)), + extensionEnableGSUB: new r.Pointer(r.uint16, JstfGSUBModList), + extensionDisableGSUB: new r.Pointer(r.uint16, JstfGSUBModList), + extensionEnableGPOS: new r.Pointer(r.uint16, JstfGSUBModList), + extensionDisableGPOS: new r.Pointer(r.uint16, JstfGSUBModList), + extensionJstfMax: new r.Pointer(r.uint16, new LookupList(GPOSLookup)), }); let JstfLangSys = new r.Array(new r.Pointer(r.uint16, JstfPriority), r.uint16); let JstfLangSysRecord = new r.Struct({ - tag: new r.String(4), - jstfLangSys: new r.Pointer(r.uint16, JstfLangSys) + tag: new r.String(4), + jstfLangSys: new r.Pointer(r.uint16, JstfLangSys), }); let JstfScript = new r.Struct({ extenderGlyphs: new r.Pointer(r.uint16, new r.Array(r.uint16, r.uint16)), // array of glyphs to extend line length defaultLangSys: new r.Pointer(r.uint16, JstfLangSys), - langSysCount: r.uint16, - langSysRecords: new r.Array(JstfLangSysRecord, 'langSysCount') + langSysCount: r.uint16, + langSysRecords: new r.Array(JstfLangSysRecord, 'langSysCount'), }); let JstfScriptRecord = new r.Struct({ - tag: new r.String(4), - script: new r.Pointer(r.uint16, JstfScript, {type: 'parent'}) + tag: new r.String(4), + script: new r.Pointer(r.uint16, JstfScript, { type: 'parent' }), }); export default new r.Struct({ - version: r.uint32, // should be 0x00010000 + version: r.uint32, // should be 0x00010000 scriptCount: r.uint16, - scriptList: new r.Array(JstfScriptRecord, 'scriptCount') + scriptList: new r.Array(JstfScriptRecord, 'scriptCount'), }); diff --git a/src/tables/LTSH.js b/src/tables/LTSH.js index 8a7c29a8..05760941 100644 --- a/src/tables/LTSH.js +++ b/src/tables/LTSH.js @@ -4,7 +4,7 @@ import * as r from 'restructure'; // Records the ppem for each glyph at which the scaling becomes linear again, // despite instructions effecting the advance width export default new r.Struct({ - version: r.uint16, - numGlyphs: r.uint16, - yPels: new r.Array(r.uint8, 'numGlyphs') + version: r.uint16, + numGlyphs: r.uint16, + yPels: new r.Array(r.uint8, 'numGlyphs'), }); diff --git a/src/tables/OS2.js b/src/tables/OS2.js index 931a0e98..d16a115d 100644 --- a/src/tables/OS2.js +++ b/src/tables/OS2.js @@ -2,80 +2,98 @@ import * as r from 'restructure'; var OS2 = new r.VersionedStruct(r.uint16, { header: { - xAvgCharWidth: r.int16, // average weighted advance width of lower case letters and space - usWeightClass: r.uint16, // visual weight of stroke in glyphs - usWidthClass: r.uint16, // relative change from the normal aspect ratio (width to height ratio) - fsType: new r.Bitfield(r.uint16, [ // Indicates font embedding licensing rights - null, 'noEmbedding', 'viewOnly', 'editable', null, - null, null, null, 'noSubsetting', 'bitmapOnly' + xAvgCharWidth: r.int16, // average weighted advance width of lower case letters and space + usWeightClass: r.uint16, // visual weight of stroke in glyphs + usWidthClass: r.uint16, // relative change from the normal aspect ratio (width to height ratio) + fsType: new r.Bitfield(r.uint16, [ + // Indicates font embedding licensing rights + null, + 'noEmbedding', + 'viewOnly', + 'editable', + null, + null, + null, + null, + 'noSubsetting', + 'bitmapOnly', ]), - ySubscriptXSize: r.int16, // recommended horizontal size in pixels for subscripts - ySubscriptYSize: r.int16, // recommended vertical size in pixels for subscripts - ySubscriptXOffset: r.int16, // recommended horizontal offset for subscripts - ySubscriptYOffset: r.int16, // recommended vertical offset form the baseline for subscripts - ySuperscriptXSize: r.int16, // recommended horizontal size in pixels for superscripts - ySuperscriptYSize: r.int16, // recommended vertical size in pixels for superscripts - ySuperscriptXOffset: r.int16, // recommended horizontal offset for superscripts - ySuperscriptYOffset: r.int16, // recommended vertical offset from the baseline for superscripts - yStrikeoutSize: r.int16, // width of the strikeout stroke - yStrikeoutPosition: r.int16, // position of the strikeout stroke relative to the baseline - sFamilyClass: r.int16, // classification of font-family design - panose: new r.Array(r.uint8, 10), // describe the visual characteristics of a given typeface - ulCharRange: new r.Array(r.uint32, 4), - vendorID: new r.String(4), // four character identifier for the font vendor - fsSelection: new r.Bitfield(r.uint16, [ // bit field containing information about the font - 'italic', 'underscore', 'negative', 'outlined', 'strikeout', - 'bold', 'regular', 'useTypoMetrics', 'wws', 'oblique' + ySubscriptXSize: r.int16, // recommended horizontal size in pixels for subscripts + ySubscriptYSize: r.int16, // recommended vertical size in pixels for subscripts + ySubscriptXOffset: r.int16, // recommended horizontal offset for subscripts + ySubscriptYOffset: r.int16, // recommended vertical offset form the baseline for subscripts + ySuperscriptXSize: r.int16, // recommended horizontal size in pixels for superscripts + ySuperscriptYSize: r.int16, // recommended vertical size in pixels for superscripts + ySuperscriptXOffset: r.int16, // recommended horizontal offset for superscripts + ySuperscriptYOffset: r.int16, // recommended vertical offset from the baseline for superscripts + yStrikeoutSize: r.int16, // width of the strikeout stroke + yStrikeoutPosition: r.int16, // position of the strikeout stroke relative to the baseline + sFamilyClass: r.int16, // classification of font-family design + panose: new r.Array(r.uint8, 10), // describe the visual characteristics of a given typeface + ulCharRange: new r.Array(r.uint32, 4), + vendorID: new r.String(4), // four character identifier for the font vendor + fsSelection: new r.Bitfield(r.uint16, [ + // bit field containing information about the font + 'italic', + 'underscore', + 'negative', + 'outlined', + 'strikeout', + 'bold', + 'regular', + 'useTypoMetrics', + 'wws', + 'oblique', ]), - usFirstCharIndex: r.uint16, // The minimum Unicode index in this font - usLastCharIndex: r.uint16 // The maximum Unicode index in this font + usFirstCharIndex: r.uint16, // The minimum Unicode index in this font + usLastCharIndex: r.uint16, // The maximum Unicode index in this font }, // The Apple version of this table ends here, but the Microsoft one continues on... 0: {}, 1: { - typoAscender: r.int16, - typoDescender: r.int16, - typoLineGap: r.int16, - winAscent: r.uint16, - winDescent: r.uint16, - codePageRange: new r.Array(r.uint32, 2) + typoAscender: r.int16, + typoDescender: r.int16, + typoLineGap: r.int16, + winAscent: r.uint16, + winDescent: r.uint16, + codePageRange: new r.Array(r.uint32, 2), }, 2: { // these should be common with version 1 somehow - typoAscender: r.int16, - typoDescender: r.int16, - typoLineGap: r.int16, - winAscent: r.uint16, - winDescent: r.uint16, - codePageRange: new r.Array(r.uint32, 2), + typoAscender: r.int16, + typoDescender: r.int16, + typoLineGap: r.int16, + winAscent: r.uint16, + winDescent: r.uint16, + codePageRange: new r.Array(r.uint32, 2), - xHeight: r.int16, - capHeight: r.int16, - defaultChar: r.uint16, - breakChar: r.uint16, - maxContent: r.uint16 + xHeight: r.int16, + capHeight: r.int16, + defaultChar: r.uint16, + breakChar: r.uint16, + maxContent: r.uint16, }, 5: { - typoAscender: r.int16, - typoDescender: r.int16, - typoLineGap: r.int16, - winAscent: r.uint16, - winDescent: r.uint16, - codePageRange: new r.Array(r.uint32, 2), + typoAscender: r.int16, + typoDescender: r.int16, + typoLineGap: r.int16, + winAscent: r.uint16, + winDescent: r.uint16, + codePageRange: new r.Array(r.uint32, 2), - xHeight: r.int16, - capHeight: r.int16, - defaultChar: r.uint16, - breakChar: r.uint16, - maxContent: r.uint16, + xHeight: r.int16, + capHeight: r.int16, + defaultChar: r.uint16, + breakChar: r.uint16, + maxContent: r.uint16, usLowerOpticalPointSize: r.uint16, - usUpperOpticalPointSize: r.uint16 - } + usUpperOpticalPointSize: r.uint16, + }, }); let versions = OS2.versions; diff --git a/src/tables/PCLT.js b/src/tables/PCLT.js index 5df584d9..bfcd634c 100644 --- a/src/tables/PCLT.js +++ b/src/tables/PCLT.js @@ -3,19 +3,19 @@ import * as r from 'restructure'; // PCL 5 Table // NOTE: The PCLT table is strongly discouraged for OpenType fonts with TrueType outlines export default new r.Struct({ - version: r.uint16, - fontNumber: r.uint32, - pitch: r.uint16, - xHeight: r.uint16, - style: r.uint16, - typeFamily: r.uint16, - capHeight: r.uint16, - symbolSet: r.uint16, - typeface: new r.String(16), - characterComplement: new r.String(8), - fileName: new r.String(6), - strokeWeight: new r.String(1), - widthType: new r.String(1), - serifStyle: r.uint8, - reserved: new r.Reserved(r.uint8) + version: r.uint16, + fontNumber: r.uint32, + pitch: r.uint16, + xHeight: r.uint16, + style: r.uint16, + typeFamily: r.uint16, + capHeight: r.uint16, + symbolSet: r.uint16, + typeface: new r.String(16), + characterComplement: new r.String(8), + fileName: new r.String(6), + strokeWeight: new r.String(1), + widthType: new r.String(1), + serifStyle: r.uint8, + reserved: new r.Reserved(r.uint8), }); diff --git a/src/tables/VDMX.js b/src/tables/VDMX.js index c65e6584..8e440e3b 100644 --- a/src/tables/VDMX.js +++ b/src/tables/VDMX.js @@ -4,30 +4,30 @@ import * as r from 'restructure'; // sizes. This is needed in order to match font metrics on Windows. let Ratio = new r.Struct({ - bCharSet: r.uint8, // Character set - xRatio: r.uint8, // Value to use for x-Ratio - yStartRatio: r.uint8, // Starting y-Ratio value - yEndRatio: r.uint8 // Ending y-Ratio value + bCharSet: r.uint8, // Character set + xRatio: r.uint8, // Value to use for x-Ratio + yStartRatio: r.uint8, // Starting y-Ratio value + yEndRatio: r.uint8, // Ending y-Ratio value }); let vTable = new r.Struct({ - yPelHeight: r.uint16, // yPelHeight to which values apply - yMax: r.int16, // Maximum value (in pels) for this yPelHeight - yMin: r.int16 // Minimum value (in pels) for this yPelHeight + yPelHeight: r.uint16, // yPelHeight to which values apply + yMax: r.int16, // Maximum value (in pels) for this yPelHeight + yMin: r.int16, // Minimum value (in pels) for this yPelHeight }); let VdmxGroup = new r.Struct({ - recs: r.uint16, // Number of height records in this group - startsz: r.uint8, // Starting yPelHeight - endsz: r.uint8, // Ending yPelHeight - entries: new r.Array(vTable, 'recs') // The VDMX records + recs: r.uint16, // Number of height records in this group + startsz: r.uint8, // Starting yPelHeight + endsz: r.uint8, // Ending yPelHeight + entries: new r.Array(vTable, 'recs'), // The VDMX records }); export default new r.Struct({ - version: r.uint16, // Version number (0 or 1) - numRecs: r.uint16, // Number of VDMX groups present - numRatios: r.uint16, // Number of aspect ratio groupings - ratioRanges: new r.Array(Ratio, 'numRatios'), // Ratio ranges - offsets: new r.Array(r.uint16, 'numRatios'), // Offset to the VDMX group for this ratio range - groups: new r.Array(VdmxGroup, 'numRecs') // The actual VDMX groupings + version: r.uint16, // Version number (0 or 1) + numRecs: r.uint16, // Number of VDMX groups present + numRatios: r.uint16, // Number of aspect ratio groupings + ratioRanges: new r.Array(Ratio, 'numRatios'), // Ratio ranges + offsets: new r.Array(r.uint16, 'numRatios'), // Offset to the VDMX group for this ratio range + groups: new r.Array(VdmxGroup, 'numRecs'), // The actual VDMX groupings }); diff --git a/src/tables/VORG.js b/src/tables/VORG.js index 2a4f4406..21cdfc87 100644 --- a/src/tables/VORG.js +++ b/src/tables/VORG.js @@ -1,14 +1,14 @@ import * as r from 'restructure'; let VerticalOrigin = new r.Struct({ - glyphIndex: r.uint16, - vertOriginY: r.int16 + glyphIndex: r.uint16, + vertOriginY: r.int16, }); export default new r.Struct({ - majorVersion: r.uint16, - minorVersion: r.uint16, - defaultVertOriginY: r.int16, - numVertOriginYMetrics: r.uint16, - metrics: new r.Array(VerticalOrigin, 'numVertOriginYMetrics') + majorVersion: r.uint16, + minorVersion: r.uint16, + defaultVertOriginY: r.int16, + numVertOriginYMetrics: r.uint16, + metrics: new r.Array(VerticalOrigin, 'numVertOriginYMetrics'), }); diff --git a/src/tables/WOFF2Directory.js b/src/tables/WOFF2Directory.js index 91b10531..d5415d71 100644 --- a/src/tables/WOFF2Directory.js +++ b/src/tables/WOFF2Directory.js @@ -20,27 +20,86 @@ const Base128 = { } throw new Error('Bad base 128 number'); - } + }, }; let knownTags = [ - 'cmap', 'head', 'hhea', 'hmtx', 'maxp', 'name', 'OS/2', 'post', 'cvt ', - 'fpgm', 'glyf', 'loca', 'prep', 'CFF ', 'VORG', 'EBDT', 'EBLC', 'gasp', - 'hdmx', 'kern', 'LTSH', 'PCLT', 'VDMX', 'vhea', 'vmtx', 'BASE', 'GDEF', - 'GPOS', 'GSUB', 'EBSC', 'JSTF', 'MATH', 'CBDT', 'CBLC', 'COLR', 'CPAL', - 'SVG ', 'sbix', 'acnt', 'avar', 'bdat', 'bloc', 'bsln', 'cvar', 'fdsc', - 'feat', 'fmtx', 'fvar', 'gvar', 'hsty', 'just', 'lcar', 'mort', 'morx', - 'opbd', 'prop', 'trak', 'Zapf', 'Silf', 'Glat', 'Gloc', 'Feat', 'Sill' + 'cmap', + 'head', + 'hhea', + 'hmtx', + 'maxp', + 'name', + 'OS/2', + 'post', + 'cvt ', + 'fpgm', + 'glyf', + 'loca', + 'prep', + 'CFF ', + 'VORG', + 'EBDT', + 'EBLC', + 'gasp', + 'hdmx', + 'kern', + 'LTSH', + 'PCLT', + 'VDMX', + 'vhea', + 'vmtx', + 'BASE', + 'GDEF', + 'GPOS', + 'GSUB', + 'EBSC', + 'JSTF', + 'MATH', + 'CBDT', + 'CBLC', + 'COLR', + 'CPAL', + 'SVG ', + 'sbix', + 'acnt', + 'avar', + 'bdat', + 'bloc', + 'bsln', + 'cvar', + 'fdsc', + 'feat', + 'fmtx', + 'fvar', + 'gvar', + 'hsty', + 'just', + 'lcar', + 'mort', + 'morx', + 'opbd', + 'prop', + 'trak', + 'Zapf', + 'Silf', + 'Glat', + 'Gloc', + 'Feat', + 'Sill', ]; let WOFF2DirectoryEntry = new r.Struct({ flags: r.uint8, - customTag: new r.Optional(new r.String(4), t => (t.flags & 0x3f) === 0x3f), - tag: t => t.customTag || knownTags[t.flags & 0x3f],// || (() => { throw new Error(`Bad tag: ${flags & 0x3f}`); })(); }, + customTag: new r.Optional(new r.String(4), (t) => (t.flags & 0x3f) === 0x3f), + tag: (t) => t.customTag || knownTags[t.flags & 0x3f], // || (() => { throw new Error(`Bad tag: ${flags & 0x3f}`); })(); }, length: Base128, - transformVersion: t => (t.flags >>> 6) & 0x03, - transformed: t => (t.tag === 'glyf' || t.tag === 'loca') ? t.transformVersion === 0 : t.transformVersion !== 0, - transformLength: new r.Optional(Base128, t => t.transformed) + transformVersion: (t) => (t.flags >>> 6) & 0x03, + transformed: (t) => + t.tag === 'glyf' || t.tag === 'loca' + ? t.transformVersion === 0 + : t.transformVersion !== 0, + transformLength: new r.Optional(Base128, (t) => t.transformed), }); let WOFF2Directory = new r.Struct({ @@ -58,17 +117,17 @@ let WOFF2Directory = new r.Struct({ metaOrigLength: r.uint32, privOffset: r.uint32, privLength: r.uint32, - tables: new r.Array(WOFF2DirectoryEntry, 'numTables') + tables: new r.Array(WOFF2DirectoryEntry, 'numTables'), }); -WOFF2Directory.process = function() { +WOFF2Directory.process = function () { let tables = {}; for (let i = 0; i < this.tables.length; i++) { let table = this.tables[i]; tables[table.tag] = table; } - return this.tables = tables; + return (this.tables = tables); }; export default WOFF2Directory; diff --git a/src/tables/WOFFDirectory.js b/src/tables/WOFFDirectory.js index dfd5d55d..26599c7a 100644 --- a/src/tables/WOFFDirectory.js +++ b/src/tables/WOFFDirectory.js @@ -2,31 +2,31 @@ import * as r from 'restructure'; import tables from './'; let WOFFDirectoryEntry = new r.Struct({ - tag: new r.String(4), - offset: new r.Pointer(r.uint32, 'void', {type: 'global'}), - compLength: r.uint32, - length: r.uint32, - origChecksum: r.uint32 + tag: new r.String(4), + offset: new r.Pointer(r.uint32, 'void', { type: 'global' }), + compLength: r.uint32, + length: r.uint32, + origChecksum: r.uint32, }); let WOFFDirectory = new r.Struct({ - tag: new r.String(4), // should be 'wOFF' - flavor: r.uint32, - length: r.uint32, - numTables: r.uint16, - reserved: new r.Reserved(r.uint16), - totalSfntSize: r.uint32, - majorVersion: r.uint16, - minorVersion: r.uint16, - metaOffset: r.uint32, - metaLength: r.uint32, + tag: new r.String(4), // should be 'wOFF' + flavor: r.uint32, + length: r.uint32, + numTables: r.uint16, + reserved: new r.Reserved(r.uint16), + totalSfntSize: r.uint32, + majorVersion: r.uint16, + minorVersion: r.uint16, + metaOffset: r.uint32, + metaLength: r.uint32, metaOrigLength: r.uint32, - privOffset: r.uint32, - privLength: r.uint32, - tables: new r.Array(WOFFDirectoryEntry, 'numTables') + privOffset: r.uint32, + privLength: r.uint32, + tables: new r.Array(WOFFDirectoryEntry, 'numTables'), }); -WOFFDirectory.process = function() { +WOFFDirectory.process = function () { let tables = {}; for (let table of this.tables) { tables[table.tag] = table; diff --git a/src/tables/aat.js b/src/tables/aat.js index 299621ba..b5a5aaab 100644 --- a/src/tables/aat.js +++ b/src/tables/aat.js @@ -35,7 +35,7 @@ export class UnboundedArray extends r.Array { } } -export let LookupTable = function(ValueType = r.uint16) { +export let LookupTable = function (ValueType = r.uint16) { // Helper class that makes internal structures invisible to pointers class Shadow { constructor(type) { @@ -65,64 +65,77 @@ export let LookupTable = function(ValueType = r.uint16) { nUnits: r.uint16, searchRange: r.uint16, entrySelector: r.uint16, - rangeShift: r.uint16 + rangeShift: r.uint16, }); let LookupSegmentSingle = new r.Struct({ lastGlyph: r.uint16, firstGlyph: r.uint16, - value: ValueType + value: ValueType, }); let LookupSegmentArray = new r.Struct({ lastGlyph: r.uint16, firstGlyph: r.uint16, - values: new r.Pointer(r.uint16, new r.Array(ValueType, t => t.lastGlyph - t.firstGlyph + 1), {type: 'parent'}) + values: new r.Pointer( + r.uint16, + new r.Array(ValueType, (t) => t.lastGlyph - t.firstGlyph + 1), + { type: 'parent' }, + ), }); let LookupSingle = new r.Struct({ glyph: r.uint16, - value: ValueType + value: ValueType, }); return new r.VersionedStruct(r.uint16, { 0: { - values: new UnboundedArray(ValueType) // length == number of glyphs maybe? + values: new UnboundedArray(ValueType), // length == number of glyphs maybe? }, 2: { binarySearchHeader: BinarySearchHeader, - segments: new r.Array(LookupSegmentSingle, t => t.binarySearchHeader.nUnits) + segments: new r.Array( + LookupSegmentSingle, + (t) => t.binarySearchHeader.nUnits, + ), }, 4: { binarySearchHeader: BinarySearchHeader, - segments: new r.Array(LookupSegmentArray, t => t.binarySearchHeader.nUnits) + segments: new r.Array( + LookupSegmentArray, + (t) => t.binarySearchHeader.nUnits, + ), }, 6: { binarySearchHeader: BinarySearchHeader, - segments: new r.Array(LookupSingle, t => t.binarySearchHeader.nUnits) + segments: new r.Array(LookupSingle, (t) => t.binarySearchHeader.nUnits), }, 8: { firstGlyph: r.uint16, count: r.uint16, - values: new r.Array(ValueType, 'count') - } + values: new r.Array(ValueType, 'count'), + }, }); }; export function StateTable(entryData = {}, lookupType = r.uint16) { - let entry = Object.assign({ - newState: r.uint16, - flags: r.uint16 - }, entryData); + let entry = Object.assign( + { + newState: r.uint16, + flags: r.uint16, + }, + entryData, + ); let Entry = new r.Struct(entry); - let StateArray = new UnboundedArray(new r.Array(r.uint16, t => t.nClasses)); + let StateArray = new UnboundedArray(new r.Array(r.uint16, (t) => t.nClasses)); let StateHeader = new r.Struct({ nClasses: r.uint32, classTable: new r.Pointer(r.uint32, new LookupTable(lookupType)), stateArray: new r.Pointer(r.uint32, StateArray), - entryTable: new r.Pointer(r.uint32, new UnboundedArray(Entry)) + entryTable: new r.Pointer(r.uint32, new UnboundedArray(Entry)), }); return StateHeader; @@ -131,26 +144,34 @@ export function StateTable(entryData = {}, lookupType = r.uint16) { // This is the old version of the StateTable structure export function StateTable1(entryData = {}, lookupType = r.uint16) { let ClassLookupTable = new r.Struct({ - version() { return 8; }, // simulate LookupTable + version() { + return 8; + }, // simulate LookupTable firstGlyph: r.uint16, - values: new r.Array(r.uint8, r.uint16) + values: new r.Array(r.uint8, r.uint16), }); - let entry = Object.assign({ - newStateOffset: r.uint16, - // convert offset to stateArray index - newState: t => (t.newStateOffset - (t.parent.stateArray.base - t.parent._startOffset)) / t.parent.nClasses, - flags: r.uint16 - }, entryData); + let entry = Object.assign( + { + newStateOffset: r.uint16, + // convert offset to stateArray index + newState: (t) => + (t.newStateOffset - + (t.parent.stateArray.base - t.parent._startOffset)) / + t.parent.nClasses, + flags: r.uint16, + }, + entryData, + ); let Entry = new r.Struct(entry); - let StateArray = new UnboundedArray(new r.Array(r.uint8, t => t.nClasses)); + let StateArray = new UnboundedArray(new r.Array(r.uint8, (t) => t.nClasses)); let StateHeader1 = new r.Struct({ nClasses: r.uint16, classTable: new r.Pointer(r.uint16, ClassLookupTable), stateArray: new r.Pointer(r.uint16, StateArray), - entryTable: new r.Pointer(r.uint16, new UnboundedArray(Entry)) + entryTable: new r.Pointer(r.uint16, new UnboundedArray(Entry)), }); return StateHeader1; diff --git a/src/tables/avar.js b/src/tables/avar.js index d2e5aef1..0b4310bb 100644 --- a/src/tables/avar.js +++ b/src/tables/avar.js @@ -4,16 +4,16 @@ let shortFrac = new r.Fixed(16, 'BE', 14); let Correspondence = new r.Struct({ fromCoord: shortFrac, - toCoord: shortFrac + toCoord: shortFrac, }); let Segment = new r.Struct({ pairCount: r.uint16, - correspondence: new r.Array(Correspondence, 'pairCount') + correspondence: new r.Array(Correspondence, 'pairCount'), }); export default new r.Struct({ version: r.fixed32, axisCount: r.uint32, - segment: new r.Array(Segment, 'axisCount') + segment: new r.Array(Segment, 'axisCount'), }); diff --git a/src/tables/bsln.js b/src/tables/bsln.js index 21d57547..054964e4 100644 --- a/src/tables/bsln.js +++ b/src/tables/bsln.js @@ -2,30 +2,34 @@ import * as r from 'restructure'; import { LookupTable } from './aat'; let BslnSubtable = new r.VersionedStruct('format', { - 0: { // Distance-based, no mapping - deltas: new r.Array(r.int16, 32) + 0: { + // Distance-based, no mapping + deltas: new r.Array(r.int16, 32), }, - 1: { // Distance-based, with mapping + 1: { + // Distance-based, with mapping deltas: new r.Array(r.int16, 32), - mappingData: new LookupTable(r.uint16) + mappingData: new LookupTable(r.uint16), }, - 2: { // Control point-based, no mapping + 2: { + // Control point-based, no mapping standardGlyph: r.uint16, - controlPoints: new r.Array(r.uint16, 32) + controlPoints: new r.Array(r.uint16, 32), }, - 3: { // Control point-based, with mapping + 3: { + // Control point-based, with mapping standardGlyph: r.uint16, controlPoints: new r.Array(r.uint16, 32), - mappingData: new LookupTable(r.uint16) - } + mappingData: new LookupTable(r.uint16), + }, }); export default new r.Struct({ version: r.fixed32, format: r.uint16, defaultBaseline: r.uint16, - subtable: BslnSubtable + subtable: BslnSubtable, }); diff --git a/src/tables/cmap.js b/src/tables/cmap.js index 5335ba80..6a3913bc 100644 --- a/src/tables/cmap.js +++ b/src/tables/cmap.js @@ -1,127 +1,139 @@ import * as r from 'restructure'; let SubHeader = new r.Struct({ - firstCode: r.uint16, - entryCount: r.uint16, - idDelta: r.int16, - idRangeOffset: r.uint16 + firstCode: r.uint16, + entryCount: r.uint16, + idDelta: r.int16, + idRangeOffset: r.uint16, }); let CmapGroup = new r.Struct({ - startCharCode: r.uint32, - endCharCode: r.uint32, - glyphID: r.uint32 + startCharCode: r.uint32, + endCharCode: r.uint32, + glyphID: r.uint32, }); let UnicodeValueRange = new r.Struct({ - startUnicodeValue: r.uint24, - additionalCount: r.uint8 + startUnicodeValue: r.uint24, + additionalCount: r.uint8, }); let UVSMapping = new r.Struct({ unicodeValue: r.uint24, - glyphID: r.uint16 + glyphID: r.uint16, }); let DefaultUVS = new r.Array(UnicodeValueRange, r.uint32); let NonDefaultUVS = new r.Array(UVSMapping, r.uint32); let VarSelectorRecord = new r.Struct({ - varSelector: r.uint24, - defaultUVS: new r.Pointer(r.uint32, DefaultUVS, {type: 'parent'}), - nonDefaultUVS: new r.Pointer(r.uint32, NonDefaultUVS, {type: 'parent'}) + varSelector: r.uint24, + defaultUVS: new r.Pointer(r.uint32, DefaultUVS, { type: 'parent' }), + nonDefaultUVS: new r.Pointer(r.uint32, NonDefaultUVS, { type: 'parent' }), }); let CmapSubtable = new r.VersionedStruct(r.uint16, { - 0: { // Byte encoding - length: r.uint16, // Total table length in bytes (set to 262 for format 0) - language: r.uint16, // Language code for this encoding subtable, or zero if language-independent - codeMap: new r.LazyArray(r.uint8, 256) + 0: { + // Byte encoding + length: r.uint16, // Total table length in bytes (set to 262 for format 0) + language: r.uint16, // Language code for this encoding subtable, or zero if language-independent + codeMap: new r.LazyArray(r.uint8, 256), }, - 2: { // High-byte mapping (CJK) - length: r.uint16, - language: r.uint16, - subHeaderKeys: new r.Array(r.uint16, 256), - subHeaderCount: t => Math.max.apply(Math, t.subHeaderKeys), - subHeaders: new r.LazyArray(SubHeader, 'subHeaderCount'), - glyphIndexArray: new r.LazyArray(r.uint16, 'subHeaderCount') + 2: { + // High-byte mapping (CJK) + length: r.uint16, + language: r.uint16, + subHeaderKeys: new r.Array(r.uint16, 256), + subHeaderCount: (t) => Math.max.apply(Math, t.subHeaderKeys), + subHeaders: new r.LazyArray(SubHeader, 'subHeaderCount'), + glyphIndexArray: new r.LazyArray(r.uint16, 'subHeaderCount'), }, - 4: { // Segment mapping to delta values - length: r.uint16, // Total table length in bytes - language: r.uint16, // Language code - segCountX2: r.uint16, - segCount: t => t.segCountX2 >> 1, - searchRange: r.uint16, - entrySelector: r.uint16, - rangeShift: r.uint16, - endCode: new r.LazyArray(r.uint16, 'segCount'), - reservedPad: new r.Reserved(r.uint16), // This value should be zero - startCode: new r.LazyArray(r.uint16, 'segCount'), - idDelta: new r.LazyArray(r.int16, 'segCount'), - idRangeOffset: new r.LazyArray(r.uint16, 'segCount'), - glyphIndexArray: new r.LazyArray(r.uint16, t => (t.length - t._currentOffset) / 2) + 4: { + // Segment mapping to delta values + length: r.uint16, // Total table length in bytes + language: r.uint16, // Language code + segCountX2: r.uint16, + segCount: (t) => t.segCountX2 >> 1, + searchRange: r.uint16, + entrySelector: r.uint16, + rangeShift: r.uint16, + endCode: new r.LazyArray(r.uint16, 'segCount'), + reservedPad: new r.Reserved(r.uint16), // This value should be zero + startCode: new r.LazyArray(r.uint16, 'segCount'), + idDelta: new r.LazyArray(r.int16, 'segCount'), + idRangeOffset: new r.LazyArray(r.uint16, 'segCount'), + glyphIndexArray: new r.LazyArray( + r.uint16, + (t) => (t.length - t._currentOffset) / 2, + ), }, - 6: { // Trimmed table - length: r.uint16, - language: r.uint16, - firstCode: r.uint16, - entryCount: r.uint16, - glyphIndices: new r.LazyArray(r.uint16, 'entryCount') + 6: { + // Trimmed table + length: r.uint16, + language: r.uint16, + firstCode: r.uint16, + entryCount: r.uint16, + glyphIndices: new r.LazyArray(r.uint16, 'entryCount'), }, - 8: { // mixed 16-bit and 32-bit coverage + 8: { + // mixed 16-bit and 32-bit coverage reserved: new r.Reserved(r.uint16), - length: r.uint32, + length: r.uint32, language: r.uint16, - is32: new r.LazyArray(r.uint8, 8192), - nGroups: r.uint32, - groups: new r.LazyArray(CmapGroup, 'nGroups') + is32: new r.LazyArray(r.uint8, 8192), + nGroups: r.uint32, + groups: new r.LazyArray(CmapGroup, 'nGroups'), }, - 10: { // Trimmed Array - reserved: new r.Reserved(r.uint16), - length: r.uint32, - language: r.uint32, - firstCode: r.uint32, - entryCount: r.uint32, - glyphIndices: new r.LazyArray(r.uint16, 'entryCount') + 10: { + // Trimmed Array + reserved: new r.Reserved(r.uint16), + length: r.uint32, + language: r.uint32, + firstCode: r.uint32, + entryCount: r.uint32, + glyphIndices: new r.LazyArray(r.uint16, 'entryCount'), }, - 12: { // Segmented coverage + 12: { + // Segmented coverage reserved: new r.Reserved(r.uint16), - length: r.uint32, + length: r.uint32, language: r.uint32, - nGroups: r.uint32, - groups: new r.LazyArray(CmapGroup, 'nGroups') + nGroups: r.uint32, + groups: new r.LazyArray(CmapGroup, 'nGroups'), }, - 13: { // Many-to-one range mappings (same as 12 except for group.startGlyphID) + 13: { + // Many-to-one range mappings (same as 12 except for group.startGlyphID) reserved: new r.Reserved(r.uint16), - length: r.uint32, + length: r.uint32, language: r.uint32, - nGroups: r.uint32, - groups: new r.LazyArray(CmapGroup, 'nGroups') + nGroups: r.uint32, + groups: new r.LazyArray(CmapGroup, 'nGroups'), }, - 14: { // Unicode Variation Sequences - length: r.uint32, - numRecords: r.uint32, - varSelectors: new r.LazyArray(VarSelectorRecord, 'numRecords') - } + 14: { + // Unicode Variation Sequences + length: r.uint32, + numRecords: r.uint32, + varSelectors: new r.LazyArray(VarSelectorRecord, 'numRecords'), + }, }); let CmapEntry = new r.Struct({ - platformID: r.uint16, // Platform identifier - encodingID: r.uint16, // Platform-specific encoding identifier - table: new r.Pointer(r.uint32, CmapSubtable, {type: 'parent', lazy: true}) + platformID: r.uint16, // Platform identifier + encodingID: r.uint16, // Platform-specific encoding identifier + table: new r.Pointer(r.uint32, CmapSubtable, { type: 'parent', lazy: true }), }); // character to glyph mapping export default new r.Struct({ - version: r.uint16, + version: r.uint16, numSubtables: r.uint16, - tables: new r.Array(CmapEntry, 'numSubtables') + tables: new r.Array(CmapEntry, 'numSubtables'), }); diff --git a/src/tables/cvt.js b/src/tables/cvt.js index 48eecc38..21da316a 100644 --- a/src/tables/cvt.js +++ b/src/tables/cvt.js @@ -2,5 +2,5 @@ import * as r from 'restructure'; // An array of predefined values accessible by instructions export default new r.Struct({ - controlValues: new r.Array(r.int16) + controlValues: new r.Array(r.int16), }); diff --git a/src/tables/directory.js b/src/tables/directory.js index c95b8c6a..2892bd2c 100644 --- a/src/tables/directory.js +++ b/src/tables/directory.js @@ -2,22 +2,22 @@ import * as r from 'restructure'; import Tables from './'; let TableEntry = new r.Struct({ - tag: new r.String(4), - checkSum: r.uint32, - offset: new r.Pointer(r.uint32, 'void', { type: 'global' }), - length: r.uint32 + tag: new r.String(4), + checkSum: r.uint32, + offset: new r.Pointer(r.uint32, 'void', { type: 'global' }), + length: r.uint32, }); let Directory = new r.Struct({ - tag: new r.String(4), - numTables: r.uint16, - searchRange: r.uint16, - entrySelector: r.uint16, - rangeShift: r.uint16, - tables: new r.Array(TableEntry, 'numTables') + tag: new r.String(4), + numTables: r.uint16, + searchRange: r.uint16, + entrySelector: r.uint16, + rangeShift: r.uint16, + tables: new r.Array(TableEntry, 'numTables'), }); -Directory.process = function() { +Directory.process = function () { let tables = {}; for (let table of this.tables) { tables[table.tag] = table; @@ -26,7 +26,7 @@ Directory.process = function() { this.tables = tables; }; -Directory.preEncode = function() { +Directory.preEncode = function () { if (!Array.isArray(this.tables)) { let tables = []; for (let tag in this.tables) { @@ -36,21 +36,21 @@ Directory.preEncode = function() { tag: tag, checkSum: 0, offset: new r.VoidPointer(Tables[tag], table), - length: Tables[tag].size(table) + length: Tables[tag].size(table), }); } } - + this.tables = tables; } this.tag = 'true'; this.numTables = this.tables.length; - let maxExponentFor2 = Math.floor((Math.log(this.numTables) / Math.LN2)); + let maxExponentFor2 = Math.floor(Math.log(this.numTables) / Math.LN2); let maxPowerOf2 = Math.pow(2, maxExponentFor2); - this.searchRange = maxPowerOf2 * 16; + this.searchRange = maxPowerOf2 * 16; this.entrySelector = Math.log(maxPowerOf2) / Math.LN2; this.rangeShift = this.numTables * 16 - this.searchRange; }; diff --git a/src/tables/feat.js b/src/tables/feat.js index bfbbfb27..11c8fdac 100644 --- a/src/tables/feat.js +++ b/src/tables/feat.js @@ -3,20 +3,28 @@ import * as r from 'restructure'; let Setting = new r.Struct({ setting: r.uint16, nameIndex: r.int16, - name: t => t.parent.parent.parent.name.records.fontFeatures[t.nameIndex] + name: (t) => t.parent.parent.parent.name.records.fontFeatures[t.nameIndex], }); let FeatureName = new r.Struct({ feature: r.uint16, nSettings: r.uint16, - settingTable: new r.Pointer(r.uint32, new r.Array(Setting, 'nSettings'), { type: 'parent' }), + settingTable: new r.Pointer(r.uint32, new r.Array(Setting, 'nSettings'), { + type: 'parent', + }), featureFlags: new r.Bitfield(r.uint8, [ - null, null, null, null, null, null, - 'hasDefault', 'exclusive' + null, + null, + null, + null, + null, + null, + 'hasDefault', + 'exclusive', ]), defaultSetting: r.uint8, nameIndex: r.int16, - name: t => t.parent.parent.name.records.fontFeatures[t.nameIndex] + name: (t) => t.parent.parent.name.records.fontFeatures[t.nameIndex], }); export default new r.Struct({ @@ -24,5 +32,5 @@ export default new r.Struct({ featureNameCount: r.uint16, reserved1: new r.Reserved(r.uint16), reserved2: new r.Reserved(r.uint32), - featureNames: new r.Array(FeatureName, 'featureNameCount') + featureNames: new r.Array(FeatureName, 'featureNameCount'), }); diff --git a/src/tables/fpgm.js b/src/tables/fpgm.js index fde3e4df..bf30d485 100644 --- a/src/tables/fpgm.js +++ b/src/tables/fpgm.js @@ -4,5 +4,5 @@ import * as r from 'restructure'; // These instructions are known as the font program. The main use of this table // is for the definition of functions that are used in many different glyph programs. export default new r.Struct({ - instructions: new r.Array(r.uint8) + instructions: new r.Array(r.uint8), }); diff --git a/src/tables/fvar.js b/src/tables/fvar.js index d4187ed4..a40bc8e5 100644 --- a/src/tables/fvar.js +++ b/src/tables/fvar.js @@ -7,15 +7,18 @@ let Axis = new r.Struct({ maxValue: r.fixed32, flags: r.uint16, nameID: r.uint16, - name: t => t.parent.parent.name.records.fontFeatures[t.nameID] + name: (t) => t.parent.parent.name.records.fontFeatures[t.nameID], }); let Instance = new r.Struct({ nameID: r.uint16, - name: t => t.parent.parent.name.records.fontFeatures[t.nameID], + name: (t) => t.parent.parent.name.records.fontFeatures[t.nameID], flags: r.uint16, - coord: new r.Array(r.fixed32, t => t.parent.axisCount), - postscriptNameID: new r.Optional(r.uint16, t => t.parent.instanceSize - t._currentOffset > 0) + coord: new r.Array(r.fixed32, (t) => t.parent.axisCount), + postscriptNameID: new r.Optional( + r.uint16, + (t) => t.parent.instanceSize - t._currentOffset > 0, + ), }); export default new r.Struct({ @@ -27,5 +30,5 @@ export default new r.Struct({ instanceCount: r.uint16, instanceSize: r.uint16, axis: new r.Array(Axis, 'axisCount'), - instance: new r.Array(Instance, 'instanceCount') + instance: new r.Array(Instance, 'instanceCount'), }); diff --git a/src/tables/gasp.js b/src/tables/gasp.js index d0925b23..91aa5ad4 100644 --- a/src/tables/gasp.js +++ b/src/tables/gasp.js @@ -1,15 +1,18 @@ import * as r from 'restructure'; let GaspRange = new r.Struct({ - rangeMaxPPEM: r.uint16, // Upper limit of range, in ppem - rangeGaspBehavior: new r.Bitfield(r.uint16, [ // Flags describing desired rasterizer behavior - 'grayscale', 'gridfit', - 'symmetricSmoothing', 'symmetricGridfit' // only in version 1, for ClearType - ]) + rangeMaxPPEM: r.uint16, // Upper limit of range, in ppem + rangeGaspBehavior: new r.Bitfield(r.uint16, [ + // Flags describing desired rasterizer behavior + 'grayscale', + 'gridfit', + 'symmetricSmoothing', + 'symmetricGridfit', // only in version 1, for ClearType + ]), }); export default new r.Struct({ - version: r.uint16, // set to 0 - numRanges: r.uint16, - gaspRanges: new r.Array(GaspRange, 'numRanges') // Sorted by ppem + version: r.uint16, // set to 0 + numRanges: r.uint16, + gaspRanges: new r.Array(GaspRange, 'numRanges'), // Sorted by ppem }); diff --git a/src/tables/glyf.js b/src/tables/glyf.js index 207bb3ca..d7857270 100644 --- a/src/tables/glyf.js +++ b/src/tables/glyf.js @@ -1,4 +1,4 @@ import * as r from 'restructure'; // only used for encoding -export default new r.Array(new r.Buffer); +export default new r.Array(new r.Buffer()); diff --git a/src/tables/gvar.js b/src/tables/gvar.js index 8b4b1a48..33c27f44 100644 --- a/src/tables/gvar.js +++ b/src/tables/gvar.js @@ -6,9 +6,7 @@ class Offset { // In short format, offsets are multiplied by 2. // This doesn't seem to be documented by Apple, but it // is implemented this way in Freetype. - return parent.flags - ? stream.readUInt32BE() - : stream.readUInt16BE() * 2; + return parent.flags ? stream.readUInt32BE() : stream.readUInt16BE() * 2; } } @@ -17,11 +15,20 @@ let gvar = new r.Struct({ reserved: new r.Reserved(r.uint16), axisCount: r.uint16, globalCoordCount: r.uint16, - globalCoords: new r.Pointer(r.uint32, new r.Array(new r.Array(shortFrac, 'axisCount'), 'globalCoordCount')), + globalCoords: new r.Pointer( + r.uint32, + new r.Array(new r.Array(shortFrac, 'axisCount'), 'globalCoordCount'), + ), glyphCount: r.uint16, flags: r.uint16, offsetToData: r.uint32, - offsets: new r.Array(new r.Pointer(Offset, 'void', { relativeTo: ctx => ctx.offsetToData, allowNull: false }), t => t.glyphCount + 1) + offsets: new r.Array( + new r.Pointer(Offset, 'void', { + relativeTo: (ctx) => ctx.offsetToData, + allowNull: false, + }), + (t) => t.glyphCount + 1, + ), }); export default gvar; diff --git a/src/tables/hdmx.js b/src/tables/hdmx.js index 511f089b..5f441f88 100644 --- a/src/tables/hdmx.js +++ b/src/tables/hdmx.js @@ -1,15 +1,15 @@ import * as r from 'restructure'; let DeviceRecord = new r.Struct({ - pixelSize: r.uint8, - maximumWidth: r.uint8, - widths: new r.Array(r.uint8, t => t.parent.parent.maxp.numGlyphs) + pixelSize: r.uint8, + maximumWidth: r.uint8, + widths: new r.Array(r.uint8, (t) => t.parent.parent.maxp.numGlyphs), }); // The Horizontal Device Metrics table stores integer advance widths scaled to particular pixel sizes export default new r.Struct({ - version: r.uint16, - numRecords: r.int16, - sizeDeviceRecord: r.int32, - records: new r.Array(DeviceRecord, 'numRecords') + version: r.uint16, + numRecords: r.int16, + sizeDeviceRecord: r.int32, + records: new r.Array(DeviceRecord, 'numRecords'), }); diff --git a/src/tables/head.js b/src/tables/head.js index 88f7a51b..72ca7404 100644 --- a/src/tables/head.js +++ b/src/tables/head.js @@ -2,24 +2,29 @@ import * as r from 'restructure'; // font header export default new r.Struct({ - version: r.int32, // 0x00010000 (version 1.0) - revision: r.int32, // set by font manufacturer + version: r.int32, // 0x00010000 (version 1.0) + revision: r.int32, // set by font manufacturer checkSumAdjustment: r.uint32, - magicNumber: r.uint32, // set to 0x5F0F3CF5 - flags: r.uint16, - unitsPerEm: r.uint16, // range from 64 to 16384 - created: new r.Array(r.int32, 2), - modified: new r.Array(r.int32, 2), - xMin: r.int16, // for all glyph bounding boxes - yMin: r.int16, // for all glyph bounding boxes - xMax: r.int16, // for all glyph bounding boxes - yMax: r.int16, // for all glyph bounding boxes - macStyle: new r.Bitfield(r.uint16, [ - 'bold', 'italic', 'underline', 'outline', - 'shadow', 'condensed', 'extended' + magicNumber: r.uint32, // set to 0x5F0F3CF5 + flags: r.uint16, + unitsPerEm: r.uint16, // range from 64 to 16384 + created: new r.Array(r.int32, 2), + modified: new r.Array(r.int32, 2), + xMin: r.int16, // for all glyph bounding boxes + yMin: r.int16, // for all glyph bounding boxes + xMax: r.int16, // for all glyph bounding boxes + yMax: r.int16, // for all glyph bounding boxes + macStyle: new r.Bitfield(r.uint16, [ + 'bold', + 'italic', + 'underline', + 'outline', + 'shadow', + 'condensed', + 'extended', ]), - lowestRecPPEM: r.uint16, // smallest readable size in pixels - fontDirectionHint: r.int16, - indexToLocFormat: r.int16, // 0 for short offsets, 1 for long - glyphDataFormat: r.int16 // 0 for current format + lowestRecPPEM: r.uint16, // smallest readable size in pixels + fontDirectionHint: r.int16, + indexToLocFormat: r.int16, // 0 for short offsets, 1 for long + glyphDataFormat: r.int16, // 0 for current format }); diff --git a/src/tables/hhea.js b/src/tables/hhea.js index af47604e..9ca2ddae 100644 --- a/src/tables/hhea.js +++ b/src/tables/hhea.js @@ -2,18 +2,18 @@ import * as r from 'restructure'; // horizontal header export default new r.Struct({ - version: r.int32, - ascent: r.int16, // Distance from baseline of highest ascender - descent: r.int16, // Distance from baseline of lowest descender - lineGap: r.int16, // Typographic line gap - advanceWidthMax: r.uint16, // Maximum advance width value in 'hmtx' table - minLeftSideBearing: r.int16, // Maximum advance width value in 'hmtx' table - minRightSideBearing: r.int16, // Minimum right sidebearing value - xMaxExtent: r.int16, - caretSlopeRise: r.int16, // Used to calculate the slope of the cursor (rise/run); 1 for vertical - caretSlopeRun: r.int16, // 0 for vertical - caretOffset: r.int16, // Set to 0 for non-slanted fonts - reserved: new r.Reserved(r.int16, 4), - metricDataFormat: r.int16, // 0 for current format - numberOfMetrics: r.uint16 // Number of advance widths in 'hmtx' table + version: r.int32, + ascent: r.int16, // Distance from baseline of highest ascender + descent: r.int16, // Distance from baseline of lowest descender + lineGap: r.int16, // Typographic line gap + advanceWidthMax: r.uint16, // Maximum advance width value in 'hmtx' table + minLeftSideBearing: r.int16, // Maximum advance width value in 'hmtx' table + minRightSideBearing: r.int16, // Minimum right sidebearing value + xMaxExtent: r.int16, + caretSlopeRise: r.int16, // Used to calculate the slope of the cursor (rise/run); 1 for vertical + caretSlopeRun: r.int16, // 0 for vertical + caretOffset: r.int16, // Set to 0 for non-slanted fonts + reserved: new r.Reserved(r.int16, 4), + metricDataFormat: r.int16, // 0 for current format + numberOfMetrics: r.uint16, // Number of advance widths in 'hmtx' table }); diff --git a/src/tables/hmtx.js b/src/tables/hmtx.js index 6df2ae52..3ba45106 100644 --- a/src/tables/hmtx.js +++ b/src/tables/hmtx.js @@ -2,10 +2,13 @@ import * as r from 'restructure'; let HmtxEntry = new r.Struct({ advance: r.uint16, - bearing: r.int16 + bearing: r.int16, }); export default new r.Struct({ - metrics: new r.LazyArray(HmtxEntry, t => t.parent.hhea.numberOfMetrics), - bearings: new r.LazyArray(r.int16, t => t.parent.maxp.numGlyphs - t.parent.hhea.numberOfMetrics) + metrics: new r.LazyArray(HmtxEntry, (t) => t.parent.hhea.numberOfMetrics), + bearings: new r.LazyArray( + r.int16, + (t) => t.parent.maxp.numGlyphs - t.parent.hhea.numberOfMetrics, + ), }); diff --git a/src/tables/index.js b/src/tables/index.js index 438bb48c..4bd799d8 100644 --- a/src/tables/index.js +++ b/src/tables/index.js @@ -20,7 +20,6 @@ tables.name = name; tables['OS/2'] = OS2; tables.post = post; - // TrueType Outlines import cvt from './cvt'; import fpgm from './fpgm'; @@ -34,7 +33,6 @@ tables.prep = prep; tables['cvt '] = cvt; tables.glyf = glyf; - // PostScript Outlines import CFFFont from '../cff/CFFFont'; import VORG from './VORG'; @@ -43,7 +41,6 @@ tables['CFF '] = CFFFont; tables['CFF2'] = CFFFont; tables.VORG = VORG; - // Bitmap Glyphs import EBLC from './EBLC'; import sbix from './sbix'; @@ -56,7 +53,6 @@ tables.sbix = sbix; tables.COLR = COLR; tables.CPAL = CPAL; - // Advanced OpenType Tables import BASE from './BASE'; import GDEF from './GDEF'; @@ -96,7 +92,6 @@ tables.VDMX = VDMX; tables.vhea = vhea; tables.vmtx = vmtx; - // Apple Advanced Typography Tables import avar from './avar'; import bsln from './bsln'; diff --git a/src/tables/just.js b/src/tables/just.js index 198be1bf..39cf28e7 100644 --- a/src/tables/just.js +++ b/src/tables/just.js @@ -5,7 +5,7 @@ let ClassTable = new r.Struct({ length: r.uint16, coverage: r.uint16, subFeatureFlags: r.uint32, - stateTable: new StateTable1 + stateTable: new StateTable1(), }); let WidthDeltaRecord = new r.Struct({ @@ -15,42 +15,47 @@ let WidthDeltaRecord = new r.Struct({ afterGrowLimit: r.fixed32, afterShrinkLimit: r.fixed32, growFlags: r.uint16, - shrinkFlags: r.uint16 + shrinkFlags: r.uint16, }); let WidthDeltaCluster = new r.Array(WidthDeltaRecord, r.uint32); let ActionData = new r.VersionedStruct('actionType', { - 0: { // Decomposition action + 0: { + // Decomposition action lowerLimit: r.fixed32, upperLimit: r.fixed32, order: r.uint16, - glyphs: new r.Array(r.uint16, r.uint16) + glyphs: new r.Array(r.uint16, r.uint16), }, - 1: { // Unconditional add glyph action - addGlyph: r.uint16 + 1: { + // Unconditional add glyph action + addGlyph: r.uint16, }, - 2: { // Conditional add glyph action + 2: { + // Conditional add glyph action substThreshold: r.fixed32, addGlyph: r.uint16, - substGlyph: r.uint16 + substGlyph: r.uint16, }, 3: {}, // Stretch glyph action (no data, not supported by CoreText) - 4: { // Ductile glyph action (not supported by CoreText) + 4: { + // Ductile glyph action (not supported by CoreText) variationAxis: r.uint32, minimumLimit: r.fixed32, noStretchValue: r.fixed32, - maximumLimit: r.fixed32 + maximumLimit: r.fixed32, }, - 5: { // Repeated add glyph action + 5: { + // Repeated add glyph action flags: r.uint16, - glyph: r.uint16 - } + glyph: r.uint16, + }, }); let Action = new r.Struct({ @@ -58,24 +63,31 @@ let Action = new r.Struct({ actionType: r.uint16, actionLength: r.uint32, actionData: ActionData, - padding: new r.Reserved(r.uint8, t => t.actionLength - t._currentOffset) + padding: new r.Reserved(r.uint8, (t) => t.actionLength - t._currentOffset), }); let PostcompensationAction = new r.Array(Action, r.uint32); let PostCompensationTable = new r.Struct({ - lookupTable: new LookupTable(new r.Pointer(r.uint16, PostcompensationAction)) + lookupTable: new LookupTable(new r.Pointer(r.uint16, PostcompensationAction)), }); let JustificationTable = new r.Struct({ classTable: new r.Pointer(r.uint16, ClassTable, { type: 'parent' }), wdcOffset: r.uint16, - postCompensationTable: new r.Pointer(r.uint16, PostCompensationTable, { type: 'parent' }), - widthDeltaClusters: new LookupTable(new r.Pointer(r.uint16, WidthDeltaCluster, { type: 'parent', relativeTo: ctx => ctx.wdcOffset })) + postCompensationTable: new r.Pointer(r.uint16, PostCompensationTable, { + type: 'parent', + }), + widthDeltaClusters: new LookupTable( + new r.Pointer(r.uint16, WidthDeltaCluster, { + type: 'parent', + relativeTo: (ctx) => ctx.wdcOffset, + }), + ), }); export default new r.Struct({ version: r.uint32, format: r.uint16, horizontal: new r.Pointer(r.uint16, JustificationTable), - vertical: new r.Pointer(r.uint16, JustificationTable) + vertical: new r.Pointer(r.uint16, JustificationTable), }); diff --git a/src/tables/kern.js b/src/tables/kern.js index 9ce4d902..89897e16 100644 --- a/src/tables/kern.js +++ b/src/tables/kern.js @@ -1,91 +1,104 @@ import * as r from 'restructure'; let KernPair = new r.Struct({ - left: r.uint16, - right: r.uint16, - value: r.int16 + left: r.uint16, + right: r.uint16, + value: r.int16, }); let ClassTable = new r.Struct({ firstGlyph: r.uint16, nGlyphs: r.uint16, offsets: new r.Array(r.uint16, 'nGlyphs'), - max: t => t.offsets.length && Math.max.apply(Math, t.offsets) + max: (t) => t.offsets.length && Math.max.apply(Math, t.offsets), }); let Kern2Array = new r.Struct({ - off: t => t._startOffset - t.parent.parent._startOffset, - len: t => (((t.parent.leftTable.max - t.off) / t.parent.rowWidth) + 1) * (t.parent.rowWidth / 2), - values: new r.LazyArray(r.int16, 'len') + off: (t) => t._startOffset - t.parent.parent._startOffset, + len: (t) => + ((t.parent.leftTable.max - t.off) / t.parent.rowWidth + 1) * + (t.parent.rowWidth / 2), + values: new r.LazyArray(r.int16, 'len'), }); let KernSubtable = new r.VersionedStruct('format', { 0: { - nPairs: r.uint16, - searchRange: r.uint16, - entrySelector: r.uint16, - rangeShift: r.uint16, - pairs: new r.Array(KernPair, 'nPairs') + nPairs: r.uint16, + searchRange: r.uint16, + entrySelector: r.uint16, + rangeShift: r.uint16, + pairs: new r.Array(KernPair, 'nPairs'), }, 2: { - rowWidth: r.uint16, - leftTable: new r.Pointer(r.uint16, ClassTable, {type: 'parent'}), - rightTable: new r.Pointer(r.uint16, ClassTable, {type: 'parent'}), - array: new r.Pointer(r.uint16, Kern2Array, {type: 'parent'}) + rowWidth: r.uint16, + leftTable: new r.Pointer(r.uint16, ClassTable, { type: 'parent' }), + rightTable: new r.Pointer(r.uint16, ClassTable, { type: 'parent' }), + array: new r.Pointer(r.uint16, Kern2Array, { type: 'parent' }), }, 3: { - glyphCount: r.uint16, - kernValueCount: r.uint8, - leftClassCount: r.uint8, - rightClassCount: r.uint8, - flags: r.uint8, - kernValue: new r.Array(r.int16, 'kernValueCount'), - leftClass: new r.Array(r.uint8, 'glyphCount'), - rightClass: new r.Array(r.uint8, 'glyphCount'), - kernIndex: new r.Array(r.uint8, t => t.leftClassCount * t.rightClassCount) - } + glyphCount: r.uint16, + kernValueCount: r.uint8, + leftClassCount: r.uint8, + rightClassCount: r.uint8, + flags: r.uint8, + kernValue: new r.Array(r.int16, 'kernValueCount'), + leftClass: new r.Array(r.uint8, 'glyphCount'), + rightClass: new r.Array(r.uint8, 'glyphCount'), + kernIndex: new r.Array( + r.uint8, + (t) => t.leftClassCount * t.rightClassCount, + ), + }, }); let KernTable = new r.VersionedStruct('version', { - 0: { // Microsoft uses this format - subVersion: r.uint16, // Microsoft has an extra sub-table version number - length: r.uint16, // Length of the subtable, in bytes - format: r.uint8, // Format of subtable - coverage: new r.Bitfield(r.uint8, [ - 'horizontal', // 1 if table has horizontal data, 0 if vertical - 'minimum', // If set to 1, the table has minimum values. If set to 0, the table has kerning values. - 'crossStream', // If set to 1, kerning is perpendicular to the flow of the text - 'override' // If set to 1 the value in this table replaces the accumulated value + 0: { + // Microsoft uses this format + subVersion: r.uint16, // Microsoft has an extra sub-table version number + length: r.uint16, // Length of the subtable, in bytes + format: r.uint8, // Format of subtable + coverage: new r.Bitfield(r.uint8, [ + 'horizontal', // 1 if table has horizontal data, 0 if vertical + 'minimum', // If set to 1, the table has minimum values. If set to 0, the table has kerning values. + 'crossStream', // If set to 1, kerning is perpendicular to the flow of the text + 'override', // If set to 1 the value in this table replaces the accumulated value ]), - subtable: KernSubtable, - padding: new r.Reserved(r.uint8, t => t.length - t._currentOffset) + subtable: KernSubtable, + padding: new r.Reserved(r.uint8, (t) => t.length - t._currentOffset), }, - 1: { // Apple uses this format - length: r.uint32, - coverage: new r.Bitfield(r.uint8, [ - null, null, null, null, null, - 'variation', // Set if table has variation kerning values - 'crossStream', // Set if table has cross-stream kerning values - 'vertical' // Set if table has vertical kerning values + 1: { + // Apple uses this format + length: r.uint32, + coverage: new r.Bitfield(r.uint8, [ + null, + null, + null, + null, + null, + 'variation', // Set if table has variation kerning values + 'crossStream', // Set if table has cross-stream kerning values + 'vertical', // Set if table has vertical kerning values ]), - format: r.uint8, + format: r.uint8, tupleIndex: r.uint16, - subtable: KernSubtable, - padding: new r.Reserved(r.uint8, t => t.length - t._currentOffset) - } + subtable: KernSubtable, + padding: new r.Reserved(r.uint8, (t) => t.length - t._currentOffset), + }, }); export default new r.VersionedStruct(r.uint16, { - 0: { // Microsoft Version - nTables: r.uint16, - tables: new r.Array(KernTable, 'nTables') + 0: { + // Microsoft Version + nTables: r.uint16, + tables: new r.Array(KernTable, 'nTables'), }, - 1: { // Apple Version - reserved: new r.Reserved(r.uint16), // the other half of the version number - nTables: r.uint32, - tables: new r.Array(KernTable, 'nTables') - } + 1: { + // Apple Version + reserved: new r.Reserved(r.uint16), // the other half of the version number + nTables: r.uint32, + tables: new r.Array(KernTable, 'nTables'), + }, }); diff --git a/src/tables/loca.js b/src/tables/loca.js index 8d1ea6a2..2a3b5871 100644 --- a/src/tables/loca.js +++ b/src/tables/loca.js @@ -2,14 +2,14 @@ import * as r from 'restructure'; let loca = new r.VersionedStruct('head.indexToLocFormat', { 0: { - offsets: new r.Array(r.uint16) + offsets: new r.Array(r.uint16), }, 1: { - offsets: new r.Array(r.uint32) - } + offsets: new r.Array(r.uint32), + }, }); -loca.process = function() { +loca.process = function () { if (this.version === 0 && !this._processed) { for (let i = 0; i < this.offsets.length; i++) { this.offsets[i] <<= 1; @@ -18,7 +18,7 @@ loca.process = function() { } }; -loca.preEncode = function() { +loca.preEncode = function () { if (this.version === 0 && this._processed !== false) { for (let i = 0; i < this.offsets.length; i++) { this.offsets[i] >>>= 1; diff --git a/src/tables/maxp.js b/src/tables/maxp.js index 3e211388..a8aa3eea 100644 --- a/src/tables/maxp.js +++ b/src/tables/maxp.js @@ -2,19 +2,19 @@ import * as r from 'restructure'; // maxiumum profile export default new r.Struct({ - version: r.int32, - numGlyphs: r.uint16, // The number of glyphs in the font - maxPoints: r.uint16, // Maximum points in a non-composite glyph - maxContours: r.uint16, // Maximum contours in a non-composite glyph - maxComponentPoints: r.uint16, // Maximum points in a composite glyph - maxComponentContours: r.uint16, // Maximum contours in a composite glyph - maxZones: r.uint16, // 1 if instructions do not use the twilight zone, 2 otherwise - maxTwilightPoints: r.uint16, // Maximum points used in Z0 - maxStorage: r.uint16, // Number of Storage Area locations - maxFunctionDefs: r.uint16, // Number of FDEFs - maxInstructionDefs: r.uint16, // Number of IDEFs - maxStackElements: r.uint16, // Maximum stack depth - maxSizeOfInstructions: r.uint16, // Maximum byte count for glyph instructions - maxComponentElements: r.uint16, // Maximum number of components referenced at “top level” for any composite glyph - maxComponentDepth: r.uint16 // Maximum levels of recursion; 1 for simple components + version: r.int32, + numGlyphs: r.uint16, // The number of glyphs in the font + maxPoints: r.uint16, // Maximum points in a non-composite glyph + maxContours: r.uint16, // Maximum contours in a non-composite glyph + maxComponentPoints: r.uint16, // Maximum points in a composite glyph + maxComponentContours: r.uint16, // Maximum contours in a composite glyph + maxZones: r.uint16, // 1 if instructions do not use the twilight zone, 2 otherwise + maxTwilightPoints: r.uint16, // Maximum points used in Z0 + maxStorage: r.uint16, // Number of Storage Area locations + maxFunctionDefs: r.uint16, // Number of FDEFs + maxInstructionDefs: r.uint16, // Number of IDEFs + maxStackElements: r.uint16, // Maximum stack depth + maxSizeOfInstructions: r.uint16, // Maximum byte count for glyph instructions + maxComponentElements: r.uint16, // Maximum number of components referenced at “top level” for any composite glyph + maxComponentDepth: r.uint16, // Maximum levels of recursion; 1 for simple components }); diff --git a/src/tables/morx.js b/src/tables/morx.js index 73bc2962..e33065fd 100644 --- a/src/tables/morx.js +++ b/src/tables/morx.js @@ -2,48 +2,53 @@ import * as r from 'restructure'; import { UnboundedArray, LookupTable, StateTable } from './aat'; let LigatureData = { - action: r.uint16 + action: r.uint16, }; let ContextualData = { markIndex: r.uint16, - currentIndex: r.uint16 + currentIndex: r.uint16, }; let InsertionData = { currentInsertIndex: r.uint16, - markedInsertIndex: r.uint16 + markedInsertIndex: r.uint16, }; let SubstitutionTable = new r.Struct({ - items: new UnboundedArray(new r.Pointer(r.uint32, new LookupTable)) + items: new UnboundedArray(new r.Pointer(r.uint32, new LookupTable())), }); let SubtableData = new r.VersionedStruct('type', { - 0: { // Indic Rearrangement Subtable - stateTable: new StateTable + 0: { + // Indic Rearrangement Subtable + stateTable: new StateTable(), }, - 1: { // Contextual Glyph Substitution Subtable + 1: { + // Contextual Glyph Substitution Subtable stateTable: new StateTable(ContextualData), - substitutionTable: new r.Pointer(r.uint32, SubstitutionTable) + substitutionTable: new r.Pointer(r.uint32, SubstitutionTable), }, - 2: { // Ligature subtable + 2: { + // Ligature subtable stateTable: new StateTable(LigatureData), ligatureActions: new r.Pointer(r.uint32, new UnboundedArray(r.uint32)), components: new r.Pointer(r.uint32, new UnboundedArray(r.uint16)), - ligatureList: new r.Pointer(r.uint32, new UnboundedArray(r.uint16)) + ligatureList: new r.Pointer(r.uint32, new UnboundedArray(r.uint16)), }, - 4: { // Non-contextual Glyph Substitution Subtable - lookupTable: new LookupTable + 4: { + // Non-contextual Glyph Substitution Subtable + lookupTable: new LookupTable(), }, - 5: { // Glyph Insertion Subtable + 5: { + // Glyph Insertion Subtable stateTable: new StateTable(InsertionData), - insertionActions: new r.Pointer(r.uint32, new UnboundedArray(r.uint16)) - } + insertionActions: new r.Pointer(r.uint32, new UnboundedArray(r.uint16)), + }, }); let Subtable = new r.Struct({ @@ -52,28 +57,28 @@ let Subtable = new r.Struct({ type: r.uint8, subFeatureFlags: r.uint32, table: SubtableData, - padding: new r.Reserved(r.uint8, t => t.length - t._currentOffset) + padding: new r.Reserved(r.uint8, (t) => t.length - t._currentOffset), }); let FeatureEntry = new r.Struct({ - featureType: r.uint16, + featureType: r.uint16, featureSetting: r.uint16, - enableFlags: r.uint32, - disableFlags: r.uint32 + enableFlags: r.uint32, + disableFlags: r.uint32, }); let MorxChain = new r.Struct({ - defaultFlags: r.uint32, - chainLength: r.uint32, - nFeatureEntries: r.uint32, - nSubtables: r.uint32, - features: new r.Array(FeatureEntry, 'nFeatureEntries'), - subtables: new r.Array(Subtable, 'nSubtables') + defaultFlags: r.uint32, + chainLength: r.uint32, + nFeatureEntries: r.uint32, + nSubtables: r.uint32, + features: new r.Array(FeatureEntry, 'nFeatureEntries'), + subtables: new r.Array(Subtable, 'nSubtables'), }); export default new r.Struct({ - version: r.uint16, - unused: new r.Reserved(r.uint16), - nChains: r.uint32, - chains: new r.Array(MorxChain, 'nChains') + version: r.uint16, + unused: new r.Reserved(r.uint16), + nChains: r.uint32, + chains: new r.Array(MorxChain, 'nChains'), }); diff --git a/src/tables/name.js b/src/tables/name.js index c5542d22..c2e1976e 100644 --- a/src/tables/name.js +++ b/src/tables/name.js @@ -1,36 +1,46 @@ import * as r from 'restructure'; -import {getEncoding, LANGUAGES} from '../encodings'; +import { getEncoding, LANGUAGES } from '../encodings'; let NameRecord = new r.Struct({ platformID: r.uint16, encodingID: r.uint16, languageID: r.uint16, - nameID: r.uint16, - length: r.uint16, - string: new r.Pointer(r.uint16, - new r.String('length', t => getEncoding(t.platformID, t.encodingID, t.languageID)), - { type: 'parent', relativeTo: ctx => ctx.parent.stringOffset, allowNull: false } - ) + nameID: r.uint16, + length: r.uint16, + string: new r.Pointer( + r.uint16, + new r.String('length', (t) => + getEncoding(t.platformID, t.encodingID, t.languageID), + ), + { + type: 'parent', + relativeTo: (ctx) => ctx.parent.stringOffset, + allowNull: false, + }, + ), }); let LangTagRecord = new r.Struct({ - length: r.uint16, - tag: new r.Pointer(r.uint16, new r.String('length', 'utf16be'), {type: 'parent', relativeTo: ctx => ctx.stringOffset}) + length: r.uint16, + tag: new r.Pointer(r.uint16, new r.String('length', 'utf16be'), { + type: 'parent', + relativeTo: (ctx) => ctx.stringOffset, + }), }); var NameTable = new r.VersionedStruct(r.uint16, { 0: { - count: r.uint16, - stringOffset: r.uint16, - records: new r.Array(NameRecord, 'count') + count: r.uint16, + stringOffset: r.uint16, + records: new r.Array(NameRecord, 'count'), }, 1: { - count: r.uint16, - stringOffset: r.uint16, - records: new r.Array(NameRecord, 'count'), - langTagCount: r.uint16, - langTags: new r.Array(LangTagRecord, 'langTagCount') - } + count: r.uint16, + stringOffset: r.uint16, + records: new r.Array(NameRecord, 'count'), + langTagCount: r.uint16, + langTags: new r.Array(LangTagRecord, 'langTagCount'), + }, }); export default NameTable; @@ -58,16 +68,20 @@ const NAMES = [ 'sampleText', 'postscriptCIDFontName', 'wwsFamilyName', - 'wwsSubfamilyName' + 'wwsSubfamilyName', ]; -NameTable.process = function(stream) { +NameTable.process = function (stream) { var records = {}; for (let record of this.records) { // find out what language this is for let language = LANGUAGES[record.platformID][record.languageID]; - if (language == null && this.langTags != null && record.languageID >= 0x8000) { + if ( + language == null && + this.langTags != null && + record.languageID >= 0x8000 + ) { language = this.langTags[record.languageID - 0x8000].tag; } @@ -76,7 +90,10 @@ NameTable.process = function(stream) { } // if the nameID is >= 256, it is a font feature record (AAT) - let key = record.nameID >= 256 ? 'fontFeatures' : (NAMES[record.nameID] || record.nameID); + let key = + record.nameID >= 256 + ? 'fontFeatures' + : NAMES[record.nameID] || record.nameID; if (records[key] == null) { records[key] = {}; } @@ -86,7 +103,10 @@ NameTable.process = function(stream) { obj = obj[record.nameID] || (obj[record.nameID] = {}); } - if (typeof record.string === 'string' || typeof obj[language] !== 'string') { + if ( + typeof record.string === 'string' || + typeof obj[language] !== 'string' + ) { obj[language] = record.string; } } @@ -94,7 +114,7 @@ NameTable.process = function(stream) { this.records = records; }; -NameTable.preEncode = function() { +NameTable.preEncode = function () { if (Array.isArray(this.records)) return; this.version = 0; @@ -109,7 +129,7 @@ NameTable.preEncode = function() { languageID: 0x409, nameID: NAMES.indexOf(key), length: val.en.length * 2, - string: val.en + string: val.en, }); if (key === 'postscriptName') { @@ -119,7 +139,7 @@ NameTable.preEncode = function() { languageID: 0, nameID: NAMES.indexOf(key), length: val.en.length, - string: val.en + string: val.en, }); } } diff --git a/src/tables/opbd.js b/src/tables/opbd.js index 7c614f21..fec421a6 100644 --- a/src/tables/opbd.js +++ b/src/tables/opbd.js @@ -5,11 +5,11 @@ let OpticalBounds = new r.Struct({ left: r.int16, top: r.int16, right: r.int16, - bottom: r.int16 + bottom: r.int16, }); export default new r.Struct({ version: r.fixed32, format: r.uint16, - lookupTable: new LookupTable(OpticalBounds) + lookupTable: new LookupTable(OpticalBounds), }); diff --git a/src/tables/opentype.js b/src/tables/opentype.js index 867cf5cb..05de8087 100644 --- a/src/tables/opentype.js +++ b/src/tables/opentype.js @@ -5,26 +5,26 @@ import * as r from 'restructure'; //######################## let LangSysTable = new r.Struct({ - reserved: new r.Reserved(r.uint16), - reqFeatureIndex: r.uint16, - featureCount: r.uint16, - featureIndexes: new r.Array(r.uint16, 'featureCount') + reserved: new r.Reserved(r.uint16), + reqFeatureIndex: r.uint16, + featureCount: r.uint16, + featureIndexes: new r.Array(r.uint16, 'featureCount'), }); let LangSysRecord = new r.Struct({ - tag: new r.String(4), - langSys: new r.Pointer(r.uint16, LangSysTable, { type: 'parent' }) + tag: new r.String(4), + langSys: new r.Pointer(r.uint16, LangSysTable, { type: 'parent' }), }); let Script = new r.Struct({ defaultLangSys: new r.Pointer(r.uint16, LangSysTable), - count: r.uint16, - langSysRecords: new r.Array(LangSysRecord, 'count') + count: r.uint16, + langSysRecords: new r.Array(LangSysRecord, 'count'), }); let ScriptRecord = new r.Struct({ - tag: new r.String(4), - script: new r.Pointer(r.uint16, Script, { type: 'parent' }) + tag: new r.String(4), + script: new r.Pointer(r.uint16, Script, { type: 'parent' }), }); export let ScriptList = new r.Array(ScriptRecord, r.uint16); @@ -34,19 +34,19 @@ export let ScriptList = new r.Array(ScriptRecord, r.uint16); //####################### let FeatureParams = new r.Struct({ - version: r.uint16, // should be set to 0 according OT spec - nameID: r.uint16, //OT spec: UI Name ID or uiLabelNameId + version: r.uint16, // should be set to 0 according OT spec + nameID: r.uint16, //OT spec: UI Name ID or uiLabelNameId }); export let Feature = new r.Struct({ - featureParams: new r.Pointer(r.uint16, FeatureParams), - lookupCount: r.uint16, - lookupListIndexes: new r.Array(r.uint16, 'lookupCount') + featureParams: new r.Pointer(r.uint16, FeatureParams), + lookupCount: r.uint16, + lookupListIndexes: new r.Array(r.uint16, 'lookupCount'), }); let FeatureRecord = new r.Struct({ - tag: new r.String(4), - feature: new r.Pointer(r.uint16, Feature, { type: 'parent' }) + tag: new r.String(4), + feature: new r.Pointer(r.uint16, Feature, { type: 'parent' }), }); export let FeatureList = new r.Array(FeatureRecord, r.uint16); @@ -54,18 +54,24 @@ export let FeatureList = new r.Array(FeatureRecord, r.uint16); let LookupFlags = new r.Struct({ markAttachmentType: r.uint8, flags: new r.Bitfield(r.uint8, [ - 'rightToLeft', 'ignoreBaseGlyphs', 'ignoreLigatures', - 'ignoreMarks', 'useMarkFilteringSet' - ]) + 'rightToLeft', + 'ignoreBaseGlyphs', + 'ignoreLigatures', + 'ignoreMarks', + 'useMarkFilteringSet', + ]), }); export function LookupList(SubTable) { let Lookup = new r.Struct({ - lookupType: r.uint16, - flags: LookupFlags, - subTableCount: r.uint16, - subTables: new r.Array(new r.Pointer(r.uint16, SubTable), 'subTableCount'), - markFilteringSet: new r.Optional(r.uint16, t => t.flags.flags.useMarkFilteringSet) + lookupType: r.uint16, + flags: LookupFlags, + subTableCount: r.uint16, + subTables: new r.Array(new r.Pointer(r.uint16, SubTable), 'subTableCount'), + markFilteringSet: new r.Optional( + r.uint16, + (t) => t.flags.flags.useMarkFilteringSet, + ), }); return new r.LazyArray(new r.Pointer(r.uint16, Lookup), r.uint16); @@ -76,20 +82,20 @@ export function LookupList(SubTable) { //################# let RangeRecord = new r.Struct({ - start: r.uint16, - end: r.uint16, - startCoverageIndex: r.uint16 + start: r.uint16, + end: r.uint16, + startCoverageIndex: r.uint16, }); export let Coverage = new r.VersionedStruct(r.uint16, { 1: { - glyphCount: r.uint16, - glyphs: new r.Array(r.uint16, 'glyphCount') + glyphCount: r.uint16, + glyphs: new r.Array(r.uint16, 'glyphCount'), }, 2: { - rangeCount: r.uint16, - rangeRecords: new r.Array(RangeRecord, 'rangeCount') - } + rangeCount: r.uint16, + rangeRecords: new r.Array(RangeRecord, 'rangeCount'), + }, }); //######################### @@ -97,21 +103,23 @@ export let Coverage = new r.VersionedStruct(r.uint16, { //######################### let ClassRangeRecord = new r.Struct({ - start: r.uint16, - end: r.uint16, - class: r.uint16 + start: r.uint16, + end: r.uint16, + class: r.uint16, }); export let ClassDef = new r.VersionedStruct(r.uint16, { - 1: { // Class array - startGlyph: r.uint16, - glyphCount: r.uint16, - classValueArray: new r.Array(r.uint16, 'glyphCount') + 1: { + // Class array + startGlyph: r.uint16, + glyphCount: r.uint16, + classValueArray: new r.Array(r.uint16, 'glyphCount'), + }, + 2: { + // Class ranges + classRangeCount: r.uint16, + classRangeRecord: new r.Array(ClassRangeRecord, 'classRangeCount'), }, - 2: { // Class ranges - classRangeCount: r.uint16, - classRangeRecord: new r.Array(ClassRangeRecord, 'classRangeCount') - } }); //############### @@ -121,7 +129,7 @@ export let ClassDef = new r.VersionedStruct(r.uint16, { export let Device = new r.Struct({ a: r.uint16, // startSize for hinting Device, outerIndex for VariationIndex b: r.uint16, // endSize for Device, innerIndex for VariationIndex - deltaFormat: r.uint16 + deltaFormat: r.uint16, }); //############################################# @@ -129,46 +137,48 @@ export let Device = new r.Struct({ //############################################# let LookupRecord = new r.Struct({ - sequenceIndex: r.uint16, - lookupListIndex: r.uint16 + sequenceIndex: r.uint16, + lookupListIndex: r.uint16, }); let Rule = new r.Struct({ - glyphCount: r.uint16, - lookupCount: r.uint16, - input: new r.Array(r.uint16, t => t.glyphCount - 1), - lookupRecords: new r.Array(LookupRecord, 'lookupCount') + glyphCount: r.uint16, + lookupCount: r.uint16, + input: new r.Array(r.uint16, (t) => t.glyphCount - 1), + lookupRecords: new r.Array(LookupRecord, 'lookupCount'), }); let RuleSet = new r.Array(new r.Pointer(r.uint16, Rule), r.uint16); let ClassRule = new r.Struct({ - glyphCount: r.uint16, - lookupCount: r.uint16, - classes: new r.Array(r.uint16, t => t.glyphCount - 1), - lookupRecords: new r.Array(LookupRecord, 'lookupCount') + glyphCount: r.uint16, + lookupCount: r.uint16, + classes: new r.Array(r.uint16, (t) => t.glyphCount - 1), + lookupRecords: new r.Array(LookupRecord, 'lookupCount'), }); let ClassSet = new r.Array(new r.Pointer(r.uint16, ClassRule), r.uint16); export let Context = new r.VersionedStruct(r.uint16, { - 1: { // Simple context - coverage: new r.Pointer(r.uint16, Coverage), - ruleSetCount: r.uint16, - ruleSets: new r.Array(new r.Pointer(r.uint16, RuleSet), 'ruleSetCount') + 1: { + // Simple context + coverage: new r.Pointer(r.uint16, Coverage), + ruleSetCount: r.uint16, + ruleSets: new r.Array(new r.Pointer(r.uint16, RuleSet), 'ruleSetCount'), }, - 2: { // Class-based context - coverage: new r.Pointer(r.uint16, Coverage), - classDef: new r.Pointer(r.uint16, ClassDef), - classSetCnt: r.uint16, - classSet: new r.Array(new r.Pointer(r.uint16, ClassSet), 'classSetCnt') + 2: { + // Class-based context + coverage: new r.Pointer(r.uint16, Coverage), + classDef: new r.Pointer(r.uint16, ClassDef), + classSetCnt: r.uint16, + classSet: new r.Array(new r.Pointer(r.uint16, ClassSet), 'classSetCnt'), }, 3: { - glyphCount: r.uint16, - lookupCount: r.uint16, - coverages: new r.Array(new r.Pointer(r.uint16, Coverage), 'glyphCount'), - lookupRecords: new r.Array(LookupRecord, 'lookupCount') - } + glyphCount: r.uint16, + lookupCount: r.uint16, + coverages: new r.Array(new r.Pointer(r.uint16, Coverage), 'glyphCount'), + lookupRecords: new r.Array(LookupRecord, 'lookupCount'), + }, }); //###################################################### @@ -176,42 +186,60 @@ export let Context = new r.VersionedStruct(r.uint16, { //###################################################### let ChainRule = new r.Struct({ - backtrackGlyphCount: r.uint16, - backtrack: new r.Array(r.uint16, 'backtrackGlyphCount'), - inputGlyphCount: r.uint16, - input: new r.Array(r.uint16, t => t.inputGlyphCount - 1), - lookaheadGlyphCount: r.uint16, - lookahead: new r.Array(r.uint16, 'lookaheadGlyphCount'), - lookupCount: r.uint16, - lookupRecords: new r.Array(LookupRecord, 'lookupCount') + backtrackGlyphCount: r.uint16, + backtrack: new r.Array(r.uint16, 'backtrackGlyphCount'), + inputGlyphCount: r.uint16, + input: new r.Array(r.uint16, (t) => t.inputGlyphCount - 1), + lookaheadGlyphCount: r.uint16, + lookahead: new r.Array(r.uint16, 'lookaheadGlyphCount'), + lookupCount: r.uint16, + lookupRecords: new r.Array(LookupRecord, 'lookupCount'), }); let ChainRuleSet = new r.Array(new r.Pointer(r.uint16, ChainRule), r.uint16); export let ChainingContext = new r.VersionedStruct(r.uint16, { - 1: { // Simple context glyph substitution - coverage: new r.Pointer(r.uint16, Coverage), - chainCount: r.uint16, - chainRuleSets: new r.Array(new r.Pointer(r.uint16, ChainRuleSet), 'chainCount') + 1: { + // Simple context glyph substitution + coverage: new r.Pointer(r.uint16, Coverage), + chainCount: r.uint16, + chainRuleSets: new r.Array( + new r.Pointer(r.uint16, ChainRuleSet), + 'chainCount', + ), }, - 2: { // Class-based chaining context - coverage: new r.Pointer(r.uint16, Coverage), - backtrackClassDef: new r.Pointer(r.uint16, ClassDef), - inputClassDef: new r.Pointer(r.uint16, ClassDef), - lookaheadClassDef: new r.Pointer(r.uint16, ClassDef), - chainCount: r.uint16, - chainClassSet: new r.Array(new r.Pointer(r.uint16, ChainRuleSet), 'chainCount') + 2: { + // Class-based chaining context + coverage: new r.Pointer(r.uint16, Coverage), + backtrackClassDef: new r.Pointer(r.uint16, ClassDef), + inputClassDef: new r.Pointer(r.uint16, ClassDef), + lookaheadClassDef: new r.Pointer(r.uint16, ClassDef), + chainCount: r.uint16, + chainClassSet: new r.Array( + new r.Pointer(r.uint16, ChainRuleSet), + 'chainCount', + ), }, - 3: { // Coverage-based chaining context - backtrackGlyphCount: r.uint16, - backtrackCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'backtrackGlyphCount'), - inputGlyphCount: r.uint16, - inputCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'inputGlyphCount'), - lookaheadGlyphCount: r.uint16, - lookaheadCoverage: new r.Array(new r.Pointer(r.uint16, Coverage), 'lookaheadGlyphCount'), - lookupCount: r.uint16, - lookupRecords: new r.Array(LookupRecord, 'lookupCount') - } + 3: { + // Coverage-based chaining context + backtrackGlyphCount: r.uint16, + backtrackCoverage: new r.Array( + new r.Pointer(r.uint16, Coverage), + 'backtrackGlyphCount', + ), + inputGlyphCount: r.uint16, + inputCoverage: new r.Array( + new r.Pointer(r.uint16, Coverage), + 'inputGlyphCount', + ), + lookaheadGlyphCount: r.uint16, + lookaheadCoverage: new r.Array( + new r.Pointer(r.uint16, Coverage), + 'lookaheadGlyphCount', + ), + lookupCount: r.uint16, + lookupRecords: new r.Array(LookupRecord, 'lookupCount'), + }, }); diff --git a/src/tables/post.js b/src/tables/post.js index 04fdeabe..dc1f6551 100644 --- a/src/tables/post.js +++ b/src/tables/post.js @@ -2,15 +2,16 @@ import * as r from 'restructure'; // PostScript information export default new r.VersionedStruct(r.fixed32, { - header: { // these fields exist at the top of all versions - italicAngle: r.fixed32, // Italic angle in counter-clockwise degrees from the vertical. - underlinePosition: r.int16, // Suggested distance of the top of the underline from the baseline - underlineThickness: r.int16, // Suggested values for the underline thickness - isFixedPitch: r.uint32, // Whether the font is monospaced - minMemType42: r.uint32, // Minimum memory usage when a TrueType font is downloaded as a Type 42 font - maxMemType42: r.uint32, // Maximum memory usage when a TrueType font is downloaded as a Type 42 font - minMemType1: r.uint32, // Minimum memory usage when a TrueType font is downloaded as a Type 1 font - maxMemType1: r.uint32 // Maximum memory usage when a TrueType font is downloaded as a Type 1 font + header: { + // these fields exist at the top of all versions + italicAngle: r.fixed32, // Italic angle in counter-clockwise degrees from the vertical. + underlinePosition: r.int16, // Suggested distance of the top of the underline from the baseline + underlineThickness: r.int16, // Suggested values for the underline thickness + isFixedPitch: r.uint32, // Whether the font is monospaced + minMemType42: r.uint32, // Minimum memory usage when a TrueType font is downloaded as a Type 42 font + maxMemType42: r.uint32, // Maximum memory usage when a TrueType font is downloaded as a Type 42 font + minMemType1: r.uint32, // Minimum memory usage when a TrueType font is downloaded as a Type 1 font + maxMemType1: r.uint32, // Maximum memory usage when a TrueType font is downloaded as a Type 1 font }, 1: {}, // version 1 has no additional fields @@ -18,17 +19,17 @@ export default new r.VersionedStruct(r.fixed32, { 2: { numberOfGlyphs: r.uint16, glyphNameIndex: new r.Array(r.uint16, 'numberOfGlyphs'), - names: new r.Array(new r.String(r.uint8)) + names: new r.Array(new r.String(r.uint8)), }, 2.5: { numberOfGlyphs: r.uint16, - offsets: new r.Array(r.uint8, 'numberOfGlyphs') + offsets: new r.Array(r.uint8, 'numberOfGlyphs'), }, 3: {}, // version 3 has no additional fields 4: { - map: new r.Array(r.uint32, t => t.parent.maxp.numGlyphs) - } + map: new r.Array(r.uint32, (t) => t.parent.maxp.numGlyphs), + }, }); diff --git a/src/tables/prep.js b/src/tables/prep.js index 4b784a5a..8b17f1bb 100644 --- a/src/tables/prep.js +++ b/src/tables/prep.js @@ -2,5 +2,5 @@ import * as r from 'restructure'; // Set of instructions executed whenever the point size or font transformation change export default new r.Struct({ - controlValueProgram: new r.Array(r.uint8) + controlValueProgram: new r.Array(r.uint8), }); diff --git a/src/tables/sbix.js b/src/tables/sbix.js index 140824c6..9352adba 100644 --- a/src/tables/sbix.js +++ b/src/tables/sbix.js @@ -3,7 +3,10 @@ import * as r from 'restructure'; let ImageTable = new r.Struct({ ppem: r.uint16, resolution: r.uint16, - imageOffsets: new r.Array(new r.Pointer(r.uint32, 'void'), t => t.parent.parent.maxp.numGlyphs + 1) + imageOffsets: new r.Array( + new r.Pointer(r.uint32, 'void'), + (t) => t.parent.parent.maxp.numGlyphs + 1, + ), }); // This is the Apple sbix table, used by the "Apple Color Emoji" font. @@ -13,5 +16,5 @@ export default new r.Struct({ version: r.uint16, flags: new r.Bitfield(r.uint16, ['renderOutlines']), numImgTables: r.uint32, - imageTables: new r.Array(new r.Pointer(r.uint32, ImageTable), 'numImgTables') + imageTables: new r.Array(new r.Pointer(r.uint32, ImageTable), 'numImgTables'), }); diff --git a/src/tables/variations.js b/src/tables/variations.js index 0aae61c3..f5a9be68 100644 --- a/src/tables/variations.js +++ b/src/tables/variations.js @@ -1,4 +1,4 @@ -import {Feature} from './opentype'; +import { Feature } from './opentype'; import * as r from 'restructure'; /******************* @@ -9,19 +9,25 @@ let F2DOT14 = new r.Fixed(16, 'BE', 14); let RegionAxisCoordinates = new r.Struct({ startCoord: F2DOT14, peakCoord: F2DOT14, - endCoord: F2DOT14 + endCoord: F2DOT14, }); let VariationRegionList = new r.Struct({ axisCount: r.uint16, regionCount: r.uint16, - variationRegions: new r.Array(new r.Array(RegionAxisCoordinates, 'axisCount'), 'regionCount') + variationRegions: new r.Array( + new r.Array(RegionAxisCoordinates, 'axisCount'), + 'regionCount', + ), }); let DeltaSet = new r.Struct({ - shortDeltas: new r.Array(r.int16, t => t.parent.shortDeltaCount), - regionDeltas: new r.Array(r.int8, t => t.parent.regionIndexCount - t.parent.shortDeltaCount), - deltas: t => t.shortDeltas.concat(t.regionDeltas) + shortDeltas: new r.Array(r.int16, (t) => t.parent.shortDeltaCount), + regionDeltas: new r.Array( + r.int8, + (t) => t.parent.regionIndexCount - t.parent.shortDeltaCount, + ), + deltas: (t) => t.shortDeltas.concat(t.regionDeltas), }); let ItemVariationData = new r.Struct({ @@ -29,14 +35,17 @@ let ItemVariationData = new r.Struct({ shortDeltaCount: r.uint16, regionIndexCount: r.uint16, regionIndexes: new r.Array(r.uint16, 'regionIndexCount'), - deltaSets: new r.Array(DeltaSet, 'itemCount') + deltaSets: new r.Array(DeltaSet, 'itemCount'), }); export let ItemVariationStore = new r.Struct({ format: r.uint16, variationRegionList: new r.Pointer(r.uint32, VariationRegionList), variationDataCount: r.uint16, - itemVariationData: new r.Array(new r.Pointer(r.uint32, ItemVariationData), 'variationDataCount') + itemVariationData: new r.Array( + new r.Pointer(r.uint32, ItemVariationData), + 'variationDataCount', + ), }); /********************** @@ -48,34 +57,45 @@ let ConditionTable = new r.VersionedStruct(r.uint16, { axisIndex: r.uint16, axisIndex: r.uint16, filterRangeMinValue: F2DOT14, - filterRangeMaxValue: F2DOT14 - } + filterRangeMaxValue: F2DOT14, + }, }); let ConditionSet = new r.Struct({ conditionCount: r.uint16, - conditionTable: new r.Array(new r.Pointer(r.uint32, ConditionTable), 'conditionCount') + conditionTable: new r.Array( + new r.Pointer(r.uint32, ConditionTable), + 'conditionCount', + ), }); let FeatureTableSubstitutionRecord = new r.Struct({ featureIndex: r.uint16, - alternateFeatureTable: new r.Pointer(r.uint32, Feature, {type: 'parent'}) + alternateFeatureTable: new r.Pointer(r.uint32, Feature, { type: 'parent' }), }); let FeatureTableSubstitution = new r.Struct({ version: r.fixed32, substitutionCount: r.uint16, - substitutions: new r.Array(FeatureTableSubstitutionRecord, 'substitutionCount') + substitutions: new r.Array( + FeatureTableSubstitutionRecord, + 'substitutionCount', + ), }); let FeatureVariationRecord = new r.Struct({ - conditionSet: new r.Pointer(r.uint32, ConditionSet, {type: 'parent'}), - featureTableSubstitution: new r.Pointer(r.uint32, FeatureTableSubstitution, {type: 'parent'}) + conditionSet: new r.Pointer(r.uint32, ConditionSet, { type: 'parent' }), + featureTableSubstitution: new r.Pointer(r.uint32, FeatureTableSubstitution, { + type: 'parent', + }), }); export let FeatureVariations = new r.Struct({ majorVersion: r.uint16, minorVersion: r.uint16, featureVariationRecordCount: r.uint32, - featureVariationRecords: new r.Array(FeatureVariationRecord, 'featureVariationRecordCount') + featureVariationRecords: new r.Array( + FeatureVariationRecord, + 'featureVariationRecordCount', + ), }); diff --git a/src/tables/vhea.js b/src/tables/vhea.js index 004cdf93..b54bc367 100644 --- a/src/tables/vhea.js +++ b/src/tables/vhea.js @@ -2,18 +2,18 @@ import * as r from 'restructure'; // Vertical Header Table export default new r.Struct({ - version: r.uint16, // Version number of the Vertical Header Table - ascent: r.int16, // The vertical typographic ascender for this font - descent: r.int16, // The vertical typographic descender for this font - lineGap: r.int16, // The vertical typographic line gap for this font - advanceHeightMax: r.int16, // The maximum advance height measurement found in the font - minTopSideBearing: r.int16, // The minimum top side bearing measurement found in the font - minBottomSideBearing: r.int16, // The minimum bottom side bearing measurement found in the font - yMaxExtent: r.int16, - caretSlopeRise: r.int16, // Caret slope (rise/run) - caretSlopeRun: r.int16, - caretOffset: r.int16, // Set value equal to 0 for nonslanted fonts - reserved: new r.Reserved(r.int16, 4), - metricDataFormat: r.int16, // Set to 0 - numberOfMetrics: r.uint16 // Number of advance heights in the Vertical Metrics table + version: r.uint16, // Version number of the Vertical Header Table + ascent: r.int16, // The vertical typographic ascender for this font + descent: r.int16, // The vertical typographic descender for this font + lineGap: r.int16, // The vertical typographic line gap for this font + advanceHeightMax: r.int16, // The maximum advance height measurement found in the font + minTopSideBearing: r.int16, // The minimum top side bearing measurement found in the font + minBottomSideBearing: r.int16, // The minimum bottom side bearing measurement found in the font + yMaxExtent: r.int16, + caretSlopeRise: r.int16, // Caret slope (rise/run) + caretSlopeRun: r.int16, + caretOffset: r.int16, // Set value equal to 0 for nonslanted fonts + reserved: new r.Reserved(r.int16, 4), + metricDataFormat: r.int16, // Set to 0 + numberOfMetrics: r.uint16, // Number of advance heights in the Vertical Metrics table }); diff --git a/src/tables/vmtx.js b/src/tables/vmtx.js index 579da6b7..6bd7b311 100644 --- a/src/tables/vmtx.js +++ b/src/tables/vmtx.js @@ -1,12 +1,15 @@ import * as r from 'restructure'; let VmtxEntry = new r.Struct({ - advance: r.uint16, // The advance height of the glyph - bearing: r.int16 // The top sidebearing of the glyph + advance: r.uint16, // The advance height of the glyph + bearing: r.int16, // The top sidebearing of the glyph }); // Vertical Metrics Table export default new r.Struct({ - metrics: new r.LazyArray(VmtxEntry, t => t.parent.vhea.numberOfMetrics), - bearings: new r.LazyArray(r.int16, t => t.parent.maxp.numGlyphs - t.parent.vhea.numberOfMetrics) + metrics: new r.LazyArray(VmtxEntry, (t) => t.parent.vhea.numberOfMetrics), + bearings: new r.LazyArray( + r.int16, + (t) => t.parent.maxp.numGlyphs - t.parent.vhea.numberOfMetrics, + ), }); diff --git a/src/utils.js b/src/utils.js index 72db5760..22b85f1c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -28,7 +28,8 @@ export function range(index, end) { export const asciiDecoder = new TextDecoder('ascii'); // Based on https://github.com/niklasvh/base64-arraybuffer. MIT license. -const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +const CHARS = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; const LOOKUP = new Uint8Array(256); for (let i = 0; i < CHARS.length; i++) { LOOKUP[CHARS.charCodeAt(i)] = i; diff --git a/test/cache.js b/test/cache.js index 2440e8f2..b2a9ee67 100644 --- a/test/cache.js +++ b/test/cache.js @@ -2,7 +2,11 @@ import assert from 'assert'; import { cache } from '../src/cache.js'; class CachedFixture { - constructor(compute = function(key) { return { owner: this, key }; }) { + constructor( + compute = function (key) { + return { owner: this, key }; + }, + ) { this.compute = compute; this.calls = 0; } @@ -26,7 +30,7 @@ class CachedFixture { cache(CachedFixture, { property: 'once', once: 'once', - keyed: 'key' + keyed: 'key', }); describe('lazy caching without decorators', function () { @@ -74,7 +78,7 @@ describe('lazy caching without decorators', function () { it('should distinguish argument values and use object identity for keys', function () { let fixture = new CachedFixture(); let keys = [0, '0', false, null, undefined, NaN, {}, {}, Symbol('key')]; - let results = keys.map(key => fixture.keyed(key)); + let results = keys.map((key) => fixture.keyed(key)); assert.equal(new Set(results).size, keys.length); for (let i = 0; i < keys.length; i++) { @@ -99,14 +103,15 @@ describe('lazy caching without decorators', function () { it('should retry computations that throw without caching the exception', function () { for (let member of ['property', 'once', 'keyed']) { - let fixture = new CachedFixture(function() { + let fixture = new CachedFixture(function () { if (this.calls === 1) { throw new Error('retry'); } return {}; }); - let read = () => member === 'property' ? fixture.property : fixture[member](0); + let read = () => + member === 'property' ? fixture.property : fixture[member](0); assert.throws(read, /retry/); let result = read(); assert.strictEqual(read(), result); @@ -121,7 +126,10 @@ describe('lazy caching without decorators', function () { fixture.keyed(0); for (let member of ['property', 'once', 'keyed']) { - let prototype = Object.getOwnPropertyDescriptor(CachedFixture.prototype, member); + let prototype = Object.getOwnPropertyDescriptor( + CachedFixture.prototype, + member, + ); assert.equal(prototype.configurable, true); assert.equal(prototype.enumerable, false); @@ -134,8 +142,12 @@ describe('lazy caching without decorators', function () { it('should reject unsupported members and cache modes', function () { class Fixture { - get property() { return 1; } - method() { return 1; } + get property() { + return 1; + } + method() { + return 1; + } } assert.throws(() => cache(Fixture, { method: 'unknown' }), TypeError); diff --git a/test/data/README.md b/test/data/README.md index 9048e823..d1091304 100644 --- a/test/data/README.md +++ b/test/data/README.md @@ -1,3 +1,3 @@ The fonts in this directory are free and open source fonts used for testing purposes. -The goal is to test as much of fontkit's functionality as possible. The licenses for these +The goal is to test as much of fontkit's functionality as possible. The licenses for these fonts are included in the subfolders for each family, along with the font files themselves. diff --git a/test/directory.js b/test/directory.js index 34709dcf..ab29c889 100644 --- a/test/directory.js +++ b/test/directory.js @@ -2,7 +2,9 @@ import * as fontkit from 'fontkit'; import assert from 'assert'; describe('metadata', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); it('decodes SFNT directory values correctly', function () { let dir = font.directory; @@ -16,5 +18,4 @@ describe('metadata', function () { let dir = font.directory; assert.equal(Object.keys(dir.tables).length, dir.numTables); }); - }); diff --git a/test/glyph_mapping.js b/test/glyph_mapping.js index 6e3282dd..7762d4a1 100644 --- a/test/glyph_mapping.js +++ b/test/glyph_mapping.js @@ -3,7 +3,9 @@ import assert from 'assert'; describe('character to glyph mapping', function () { describe('basic cmap handling', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); it('should get characterSet', function () { assert(Array.isArray(font.characterSet)); @@ -11,16 +13,23 @@ describe('character to glyph mapping', function () { }); it('should cache character sets separately for each cmap processor', function () { - let other = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let other = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); let processor = font._cmapProcessor; let characterSet = processor.getCharacterSet(); assert.strictEqual(processor.getCharacterSet(), characterSet); assert.deepEqual(other._cmapProcessor.getCharacterSet(), characterSet); - assert.notStrictEqual(other._cmapProcessor.getCharacterSet(), characterSet); + assert.notStrictEqual( + other._cmapProcessor.getCharacterSet(), + characterSet, + ); }); it('should cache code points separately for each glyph and cmap processor', function () { - let other = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let other = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); let processor = font._cmapProcessor; let codePoints = processor.codePointsForGlyph(68); assert.deepEqual(codePoints, [97]); @@ -28,7 +37,10 @@ describe('character to glyph mapping', function () { assert.deepEqual(processor.codePointsForGlyph(69), [98]); assert.notStrictEqual(processor.codePointsForGlyph(69), codePoints); assert.deepEqual(other._cmapProcessor.codePointsForGlyph(68), codePoints); - assert.notStrictEqual(other._cmapProcessor.codePointsForGlyph(68), codePoints); + assert.notStrictEqual( + other._cmapProcessor.codePointsForGlyph(68), + codePoints, + ); let missing = processor.codePointsForGlyph(0xffff); assert.deepEqual(missing, []); @@ -38,9 +50,15 @@ describe('character to glyph mapping', function () { it('should leave code points mapped to .notdef out of characterSet', function () { // U+FFFF is only the closing segment of the format 4 subtable (#158) assert(!font.characterSet.includes(0xffff)); - assert(font.characterSet.every(codePoint => font.hasGlyphForCodePoint(codePoint))); + assert( + font.characterSet.every((codePoint) => + font.hasGlyphForCodePoint(codePoint), + ), + ); - let cmap14 = fontkit.openSync(new URL('data/fonttest/TestCMAP14.otf', import.meta.url)); + let cmap14 = fontkit.openSync( + new URL('data/fonttest/TestCMAP14.otf', import.meta.url), + ); assert.deepEqual(cmap14.characterSet, [0x20, 0x2269, 0x82a6]); }); @@ -59,128 +77,263 @@ describe('character to glyph mapping', function () { let glyphs = font.glyphsForString('hello', []); assert(Array.isArray(glyphs)); assert.equal(glyphs.length, 5); - assert.deepEqual(glyphs.map(g => g.id), [75, 72, 79, 79, 82]); - return assert.deepEqual(glyphs.map(g => g.codePoints), [[104], [101], [108], [108], [111]]); + assert.deepEqual( + glyphs.map((g) => g.id), + [75, 72, 79, 79, 82], + ); + return assert.deepEqual( + glyphs.map((g) => g.codePoints), + [[104], [101], [108], [108], [111]], + ); }); it('should support unicode variation selectors', function () { - let font = fontkit.openSync(new URL('data/fonttest/TestCMAP14.otf', import.meta.url)); - let glyphs = font.glyphsForString('\u{82a6}\u{82a6}\u{E0100}\u{82a6}\u{E0101}'); - assert.deepEqual(glyphs.map(g => g.id), [1, 1, 2]); + let font = fontkit.openSync( + new URL('data/fonttest/TestCMAP14.otf', import.meta.url), + ); + let glyphs = font.glyphsForString( + '\u{82a6}\u{82a6}\u{E0100}\u{82a6}\u{E0101}', + ); + assert.deepEqual( + glyphs.map((g) => g.id), + [1, 1, 2], + ); }); it('should support cmap format 10', function () { - let font = fontkit.openSync(new URL('data/aots/cmap10_font1.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/aots/cmap10_font1.otf', import.meta.url), + ); assert.deepEqual(font.characterSet, [0x109423, 0x109424, 0x109425]); let glyphs = font.glyphsForString('\u{109423}\u{109424}\u{109425}'); - assert.deepEqual(glyphs.map(g => g.id), [26, 27, 32]); + assert.deepEqual( + glyphs.map((g) => g.id), + [26, 27, 32], + ); assert.deepEqual(font.stringsForGlyph(27), ['\u{109424}']); }); it('should support legacy encodings when no unicode cmap is found', function () { - let font = fontkit.openSync(new URL('data/fonttest/TestCMAPMacTurkish.ttf', import.meta.url)); - let glyphs = font.glyphsForString("“ABÇĞIİÖŞÜ”"); - assert.deepEqual(glyphs.map(g => g.id), [200, 34, 35, 126, 176, 42, 178, 140, 181, 145, 201]); + let font = fontkit.openSync( + new URL('data/fonttest/TestCMAPMacTurkish.ttf', import.meta.url), + ); + let glyphs = font.glyphsForString('“ABÇĞIİÖŞÜ”'); + assert.deepEqual( + glyphs.map((g) => g.id), + [200, 34, 35, 126, 176, 42, 178, 140, 181, 145, 201], + ); }); it('should not map code points missing from a legacy encoding to other glyphs', function () { - let font = fontkit.openSync(new URL('data/fonttest/TestCMAPMacTurkish.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/fonttest/TestCMAPMacTurkish.ttf', import.meta.url), + ); let glyphs = font.glyphsForString(' \u00a0\u00b9\u0080'); - assert.deepEqual(glyphs.map(g => g.id), [1, 96, 0, 0]); + assert.deepEqual( + glyphs.map((g) => g.id), + [1, 96, 0, 0], + ); }); }); describe('opentype features', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url), + ); it('should list available features', () => assert.deepEqual(font.availableFeatures, [ - 'aalt', 'c2sc', 'case', 'ccmp', 'dnom', 'frac', 'liga', 'numr', - 'onum', 'ordn', 'pnum', 'salt', 'sinf', 'smcp', 'ss01', 'ss02', - 'ss03', 'ss04', 'ss05', 'subs', 'sups', 'zero', 'kern', 'mark', - 'mkmk', 'size' - ]) - ); + 'aalt', + 'c2sc', + 'case', + 'ccmp', + 'dnom', + 'frac', + 'liga', + 'numr', + 'onum', + 'ordn', + 'pnum', + 'salt', + 'sinf', + 'smcp', + 'ss01', + 'ss02', + 'ss03', + 'ss04', + 'ss05', + 'subs', + 'sups', + 'zero', + 'kern', + 'mark', + 'mkmk', + 'size', + ])); it('should apply opentype GSUB features', function () { let { glyphs } = font.layout('ffi', ['dlig']); assert.equal(glyphs.length, 2); - assert.deepEqual(glyphs.map(g => g.id), [514, 36]); - return assert.deepEqual(glyphs.map(g => g.codePoints), [[102, 102], [105]]); + assert.deepEqual( + glyphs.map((g) => g.id), + [514, 36], + ); + return assert.deepEqual( + glyphs.map((g) => g.codePoints), + [[102, 102], [105]], + ); }); it('should enable fractions when using fraction slash', function () { let { glyphs } = font.layout('123 1⁄16 123'); - return assert.deepEqual(glyphs.map(g => g.id), [1088, 1089, 1090, 1, 1617, 1724, 1603, 1608, 1, 1088, 1089, 1090]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [1088, 1089, 1090, 1, 1617, 1724, 1603, 1608, 1, 1088, 1089, 1090], + ); }); it('should not break if can’t enable fractions when using fraction slash', function () { let { glyphs } = font.layout('a⁄b ⁄ 1⁄ ⁄2'); - return assert.deepEqual(glyphs.map(g => g.id), [28, 1724, 29, 1, 1724, 1, 1617, 1724, 1, 1724, 1604]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [28, 1724, 29, 1, 1724, 1, 1617, 1724, 1, 1724, 1604], + ); }); }); describe('AAT features', function () { - let font = fontkit.openSync(new URL('data/Play/Play-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/Play/Play-Regular.ttf', import.meta.url), + ); - it('should list available features', () => assert.deepEqual(font.availableFeatures, ['tnum', 'sups', 'subs', 'numr', 'onum', 'lnum', 'liga', 'kern'])); + it('should list available features', () => + assert.deepEqual(font.availableFeatures, [ + 'tnum', + 'sups', + 'subs', + 'numr', + 'onum', + 'lnum', + 'liga', + 'kern', + ])); it('should apply default AAT morx features', function () { let { glyphs } = font.layout('ffi 1⁄2'); assert.equal(glyphs.length, 5); - assert.deepEqual(glyphs.map(g => g.id), [767, 3, 20, 645, 21]); - return assert.deepEqual(glyphs.map(g => g.codePoints), [[102, 102, 105], [32], [49], [8260], [50]]); + assert.deepEqual( + glyphs.map((g) => g.id), + [767, 3, 20, 645, 21], + ); + return assert.deepEqual( + glyphs.map((g) => g.codePoints), + [[102, 102, 105], [32], [49], [8260], [50]], + ); }); it('should allow for disabling of default AAT morx features', function () { - let { glyphs } = font.layout('ffi 1⁄2', { 'liga': false }); + let { glyphs } = font.layout('ffi 1⁄2', { liga: false }); assert.equal(glyphs.length, 7); - assert.deepEqual(glyphs.map(g => g.id), [73, 73, 76, 3, 20, 645, 21]); - return assert.deepEqual(glyphs.map(g => g.codePoints), [[102], [102], [105], [32], [49], [8260], [50]]); + assert.deepEqual( + glyphs.map((g) => g.id), + [73, 73, 76, 3, 20, 645, 21], + ); + return assert.deepEqual( + glyphs.map((g) => g.codePoints), + [[102], [102], [105], [32], [49], [8260], [50]], + ); }); it('should apply user specified features', function () { let { glyphs } = font.layout('ffi 1⁄2', ['numr']); assert.equal(glyphs.length, 3); - assert.deepEqual(glyphs.map(g => g.id), [767, 3, 126]); - return assert.deepEqual(glyphs.map(g => g.codePoints), [[102, 102, 105], [32], [49, 8260, 50]]); + assert.deepEqual( + glyphs.map((g) => g.id), + [767, 3, 126], + ); + return assert.deepEqual( + glyphs.map((g) => g.codePoints), + [[102, 102, 105], [32], [49, 8260, 50]], + ); }); it('should handle rtl direction', function () { - let { glyphs } = font.layout('ffi', [], null, null, "rtl"); + let { glyphs } = font.layout('ffi', [], null, null, 'rtl'); assert.equal(glyphs.length, 3); - assert.deepEqual(glyphs.map(g => g.id), [76, 73, 73]); - return assert.deepEqual(glyphs.map(g => g.codePoints), [[105], [102], [102]]); + assert.deepEqual( + glyphs.map((g) => g.id), + [76, 73, 73], + ); + return assert.deepEqual( + glyphs.map((g) => g.codePoints), + [[105], [102], [102]], + ); }); it('should apply indic reordering features', function () { - let f = fontkit.openSync(new URL('data/Khmer/Khmer.ttf', import.meta.url)); + let f = fontkit.openSync( + new URL('data/Khmer/Khmer.ttf', import.meta.url), + ); let { glyphs } = f.layout('ខ្ញុំអាចញ៉ាំកញ្ចក់បាន ដោយគ្មានបញ្ហា'); - assert.deepEqual(glyphs.map(g => g.id), [ - 45, 153, 177, 112, 248, 188, 49, 296, 44, 187, 149, 44, 117, 236, 188, 63, 3, 107, - 226, 188, 69, 218, 169, 188, 63, 64, 255, 175, 188 - ]); - - return assert.deepEqual(glyphs.map(g => g.codePoints), [ - [6017], [6098, 6025], [6075], [6086], [6050], [6070], [6021], - [6025, 6089, 6070, 6086], [6016], [6025], [6098, 6021], [6016], - [6091], [6036], [6070], [6035], [32], [6084], [6026], [6070], - [6041], [6018], [6098, 6040], [6070], [6035], [6036], [6025], - [6098, 6048], [6070] - ]); + assert.deepEqual( + glyphs.map((g) => g.id), + [ + 45, 153, 177, 112, 248, 188, 49, 296, 44, 187, 149, 44, 117, 236, 188, + 63, 3, 107, 226, 188, 69, 218, 169, 188, 63, 64, 255, 175, 188, + ], + ); + + return assert.deepEqual( + glyphs.map((g) => g.codePoints), + [ + [6017], + [6098, 6025], + [6075], + [6086], + [6050], + [6070], + [6021], + [6025, 6089, 6070, 6086], + [6016], + [6025], + [6098, 6021], + [6016], + [6091], + [6036], + [6070], + [6035], + [32], + [6084], + [6026], + [6070], + [6041], + [6018], + [6098, 6040], + [6070], + [6035], + [6036], + [6025], + [6098, 6048], + [6070], + ], + ); }); }); describe('glyph id to strings', function () { it('should return strings from cmap that map to a given glyph', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); let strings = font.stringsForGlyph(68); assert.deepEqual(strings, ['a']); }); it('should return strings from AAT morx table that map to the given glyph', function () { - let font = fontkit.openSync(new URL('data/Play/Play-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/Play/Play-Regular.ttf', import.meta.url), + ); let strings = font.stringsForGlyph(767); assert.deepEqual(strings, ['ffi']); }); diff --git a/test/glyph_positioning.js b/test/glyph_positioning.js index 83742b94..905eb188 100644 --- a/test/glyph_positioning.js +++ b/test/glyph_positioning.js @@ -3,31 +3,47 @@ import assert from 'assert'; describe('glyph positioning', function () { describe('basic positioning', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url), + ); - it('should get a glyph width', () => assert.equal(font.getGlyph(5).advanceWidth, 615)); + it('should get a glyph width', () => + assert.equal(font.getGlyph(5).advanceWidth, 615)); }); describe('opentype positioning', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url), + ); it('should apply opentype GPOS features', function () { let { positions } = font.layout('Twitter'); - return assert.deepEqual(positions.map(p => p.xAdvance), [502, 718, 246, 318, 324, 496, 347]); + return assert.deepEqual( + positions.map((p) => p.xAdvance), + [502, 718, 246, 318, 324, 496, 347], + ); }); it('should ignore duplicate features', function () { let { positions } = font.layout('Twitter', ['kern', 'kern']); - return assert.deepEqual(positions.map(p => p.xAdvance), [502, 718, 246, 318, 324, 496, 347]); + return assert.deepEqual( + positions.map((p) => p.xAdvance), + [502, 718, 246, 318, 324, 496, 347], + ); }); }); describe('AAT features', function () { - let font = fontkit.openSync(new URL('data/Play/Play-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/Play/Play-Regular.ttf', import.meta.url), + ); it('should apply kerning by default', function () { let { positions } = font.layout('Twitter'); - return assert.deepEqual(positions.map(p => p.xAdvance), [535, 792, 246, 372, 402, 535, 351]); + return assert.deepEqual( + positions.map((p) => p.xAdvance), + [535, 792, 246, 372, 402, 535, 351], + ); }); }); }); diff --git a/test/glyphs.js b/test/glyphs.js index db097f64..af39e512 100644 --- a/test/glyphs.js +++ b/test/glyphs.js @@ -3,8 +3,12 @@ import assert from 'assert'; describe('glyphs', function () { describe('truetype glyphs', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); - let mada = fontkit.openSync(new URL('data/Mada/Mada-VF.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); + let mada = fontkit.openSync( + new URL('data/Mada/Mada-VF.ttf', import.meta.url), + ); it('should get a TTFGlyph', function () { let glyph = font.getGlyph(39); // D @@ -13,7 +17,10 @@ describe('glyphs', function () { it('should get a path for the glyph as SVG', function () { let glyph = font.getGlyph(39); - return assert.equal(glyph.path.toSVG(), 'M1368 745Q1368 383 1171.5 191.5Q975 0 606 0L201 0L201 1462L649 1462Q990 1462 1179 1273Q1368 1084 1368 745ZM1188 739Q1188 1025 1044.5 1170Q901 1315 618 1315L371 1315L371 147L578 147Q882 147 1035 296.5Q1188 446 1188 739Z'); + return assert.equal( + glyph.path.toSVG(), + 'M1368 745Q1368 383 1171.5 191.5Q975 0 606 0L201 0L201 1462L649 1462Q990 1462 1179 1273Q1368 1084 1368 745ZM1188 739Q1188 1025 1044.5 1170Q901 1315 618 1315L371 1315L371 147L578 147Q882 147 1035 296.5Q1188 446 1188 739Z', + ); }); it('should get a path for the glyph as function', function () { @@ -22,43 +29,63 @@ describe('glyphs', function () { let ctx = { moveTo: (...args) => results.push('moveTo(' + args.join(', ') + ');'), lineTo: (...args) => results.push('lineTo(' + args.join(', ') + ');'), - quadraticCurveTo: (...args) => results.push('quadraticCurveTo(' + args.join(', ') + ');'), - bezierCurveTo: (...args) => results.push('bezierCurveTo(' + args.join(', ') + ');'), - closePath: (...args) => results.push('closePath(' + args.join(', ') + ');') + quadraticCurveTo: (...args) => + results.push('quadraticCurveTo(' + args.join(', ') + ');'), + bezierCurveTo: (...args) => + results.push('bezierCurveTo(' + args.join(', ') + ');'), + closePath: (...args) => + results.push('closePath(' + args.join(', ') + ');'), }; let fn = glyph.path.toFunction(); fn(ctx); - return assert.equal(results.join('\n'), 'moveTo(1368, 745);\nquadraticCurveTo(1368, 383, 1171.5, 191.5);\nquadraticCurveTo(975, 0, 606, 0);\nlineTo(201, 0);\nlineTo(201, 1462);\nlineTo(649, 1462);\nquadraticCurveTo(990, 1462, 1179, 1273);\nquadraticCurveTo(1368, 1084, 1368, 745);\nclosePath();\nmoveTo(1188, 739);\nquadraticCurveTo(1188, 1025, 1044.5, 1170);\nquadraticCurveTo(901, 1315, 618, 1315);\nlineTo(371, 1315);\nlineTo(371, 147);\nlineTo(578, 147);\nquadraticCurveTo(882, 147, 1035, 296.5);\nquadraticCurveTo(1188, 446, 1188, 739);\nclosePath();'); + return assert.equal( + results.join('\n'), + 'moveTo(1368, 745);\nquadraticCurveTo(1368, 383, 1171.5, 191.5);\nquadraticCurveTo(975, 0, 606, 0);\nlineTo(201, 0);\nlineTo(201, 1462);\nlineTo(649, 1462);\nquadraticCurveTo(990, 1462, 1179, 1273);\nquadraticCurveTo(1368, 1084, 1368, 745);\nclosePath();\nmoveTo(1188, 739);\nquadraticCurveTo(1188, 1025, 1044.5, 1170);\nquadraticCurveTo(901, 1315, 618, 1315);\nlineTo(371, 1315);\nlineTo(371, 147);\nlineTo(578, 147);\nquadraticCurveTo(882, 147, 1035, 296.5);\nquadraticCurveTo(1188, 446, 1188, 739);\nclosePath();', + ); }); it('should get a composite glyph', function () { let glyph = font.getGlyph(171); // é - return assert.equal(glyph.path.toSVG(), 'M639 -20Q396 -20 255.5 128Q115 276 115 539Q115 804 245.5 960Q376 1116 596 1116Q802 1116 922 980.5Q1042 845 1042 623L1042 518L287 518Q292 325 384.5 225Q477 125 645 125Q822 125 995 199L995 51Q907 13 828.5 -3.5Q750 -20 639 -20ZM594 977Q462 977 383.5 891Q305 805 291 653L864 653Q864 810 794 893.5Q724 977 594 977ZM471 1266Q519 1328 574.5 1416Q630 1504 662 1569L864 1569L864 1548Q820 1483 733 1388Q646 1293 582 1241L471 1241Z'); + return assert.equal( + glyph.path.toSVG(), + 'M639 -20Q396 -20 255.5 128Q115 276 115 539Q115 804 245.5 960Q376 1116 596 1116Q802 1116 922 980.5Q1042 845 1042 623L1042 518L287 518Q292 325 384.5 225Q477 125 645 125Q822 125 995 199L995 51Q907 13 828.5 -3.5Q750 -20 639 -20ZM594 977Q462 977 383.5 891Q305 805 291 653L864 653Q864 810 794 893.5Q724 977 594 977ZM471 1266Q519 1328 574.5 1416Q630 1504 662 1569L864 1569L864 1548Q820 1483 733 1388Q646 1293 582 1241L471 1241Z', + ); }); it('should apply the correct off-diagonal coefficients to a composite glyph', function () { // The test font has a rectangular component with different scale01 and scale10 // values, so swapping them changes the rendered outline. - let compositeFont = fontkit.openSync(new URL('data/composite-transform.ttf', import.meta.url)); + let compositeFont = fontkit.openSync( + new URL('data/composite-transform.ttf', import.meta.url), + ); let glyph = compositeFont.glyphForCodePoint(43); // + assert.equal(glyph.path.toSVG(), 'M30 20L130 -30L140 10L40 60Z'); }); it('should resolve composite glyphs recursively', function () { let r = mada.layout('ي'); - assert.equal(r.glyphs[0].path.toSVG(), 'M-140 0Q-140 -22 -125 -37Q-110 -52 -88 -52Q-66 -52 -51 -37Q-36 -22 -36 0Q-36 22 -51 37Q-66 52 -88 52Q-110 52 -125 37Q-140 22 -140 0ZM36 0Q36 -22 51 -37Q66 -52 88 -52Q110 -52 125 -37Q140 -22 140 0Q140 22 125 37Q110 52 88 52Q66 52 51 37Q36 22 36 0Z'); + assert.equal( + r.glyphs[0].path.toSVG(), + 'M-140 0Q-140 -22 -125 -37Q-110 -52 -88 -52Q-66 -52 -51 -37Q-36 -22 -36 0Q-36 22 -51 37Q-66 52 -88 52Q-110 52 -125 37Q-140 22 -140 0ZM36 0Q36 -22 51 -37Q66 -52 88 -52Q110 -52 125 -37Q140 -22 140 0Q140 22 125 37Q110 52 88 52Q66 52 51 37Q36 22 36 0Z', + ); }); it('should transform points of a composite glyph', function () { let r = mada.layout('فا'); - assert.equal(r.glyphs[0].path.toSVG(), 'M155 624L155 84Q150 90 145.5 94.5Q141 99 136 105L292 105L292 0L156 0Q128 0 103.5 13.5Q79 27 64.5 50.5Q50 74 50 104L50 624ZM282 105L312 105L312 0L282 0Z'); + assert.equal( + r.glyphs[0].path.toSVG(), + 'M155 624L155 84Q150 90 145.5 94.5Q141 99 136 105L292 105L292 0L156 0Q128 0 103.5 13.5Q79 27 64.5 50.5Q50 74 50 104L50 624ZM282 105L312 105L312 0L282 0Z', + ); }); it('should be able to get a scaled path at a given font size', function () { let glyph = font.getGlyph(39); - assert.equal(glyph.getScaledPath(1000).toSVG(), 'M667.97 363.77Q667.97 187.01 572.02 93.51Q476.07 0 295.9 0L98.14 0L98.14 713.87L316.89 713.87Q483.4 713.87 575.68 621.58Q667.97 529.3 667.97 363.77ZM580.08 360.84Q580.08 500.49 510.01 571.29Q439.94 642.09 301.76 642.09L181.15 642.09L181.15 71.78L282.23 71.78Q430.66 71.78 505.37 144.78Q580.08 217.77 580.08 360.84Z'); + assert.equal( + glyph.getScaledPath(1000).toSVG(), + 'M667.97 363.77Q667.97 187.01 572.02 93.51Q476.07 0 295.9 0L98.14 0L98.14 713.87L316.89 713.87Q483.4 713.87 575.68 621.58Q667.97 529.3 667.97 363.77ZM580.08 360.84Q580.08 500.49 510.01 571.29Q439.94 642.09 301.76 642.09L181.15 642.09L181.15 71.78L282.23 71.78Q430.66 71.78 505.37 144.78Q580.08 217.77 580.08 360.84Z', + ); }); it('should get the glyph cbox', function () { @@ -97,7 +124,9 @@ describe('glyphs', function () { }); describe('CFF glyphs', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url), + ); it('should get a CFFGlyph', function () { let glyph = font.getGlyph(5); // D @@ -106,7 +135,10 @@ describe('glyphs', function () { it('should get a path for the glyph as SVG', function () { let glyph = font.getGlyph(5); - return assert.equal(glyph.path.toSVG(), 'M90 0L258 0C456 0 564 122 564 331C564 539 456 656 254 656L90 656ZM173 68L173 588L248 588C401 588 478 496 478 331C478 165 401 68 248 68Z'); + return assert.equal( + glyph.path.toSVG(), + 'M90 0L258 0C456 0 564 122 564 331C564 539 456 656 254 656L90 656ZM173 68L173 588L248 588C401 588 478 496 478 331C478 165 401 68 248 68Z', + ); }); it('should get a path for the glyph as function', function () { @@ -115,15 +147,21 @@ describe('glyphs', function () { let ctx = { moveTo: (...args) => results.push('moveTo(' + args.join(', ') + ');'), lineTo: (...args) => results.push('lineTo(' + args.join(', ') + ');'), - quadraticCurveTo: (...args) => results.push('quadraticCurveTo(' + args.join(', ') + ');'), - bezierCurveTo: (...args) => results.push('bezierCurveTo(' + args.join(', ') + ');'), - closePath: (...args) => results.push('closePath(' + args.join(', ') + ');') + quadraticCurveTo: (...args) => + results.push('quadraticCurveTo(' + args.join(', ') + ');'), + bezierCurveTo: (...args) => + results.push('bezierCurveTo(' + args.join(', ') + ');'), + closePath: (...args) => + results.push('closePath(' + args.join(', ') + ');'), }; let fn = glyph.path.toFunction(); fn(ctx); - return assert.equal(results.join('\n'), 'moveTo(90, 0);\nlineTo(258, 0);\nbezierCurveTo(456, 0, 564, 122, 564, 331);\nbezierCurveTo(564, 539, 456, 656, 254, 656);\nlineTo(90, 656);\nclosePath();\nmoveTo(173, 68);\nlineTo(173, 588);\nlineTo(248, 588);\nbezierCurveTo(401, 588, 478, 496, 478, 331);\nbezierCurveTo(478, 165, 401, 68, 248, 68);\nclosePath();'); + return assert.equal( + results.join('\n'), + 'moveTo(90, 0);\nlineTo(258, 0);\nbezierCurveTo(456, 0, 564, 122, 564, 331);\nbezierCurveTo(564, 539, 456, 656, 254, 656);\nlineTo(90, 656);\nclosePath();\nmoveTo(173, 68);\nlineTo(173, 588);\nlineTo(248, 588);\nbezierCurveTo(401, 588, 478, 496, 478, 331);\nbezierCurveTo(478, 165, 401, 68, 248, 68);\nclosePath();', + ); }); it('should get the glyph cbox', function () { @@ -149,7 +187,9 @@ describe('glyphs', function () { }); describe('CFF glyphs (CID font)', function () { - let font = fontkit.openSync(new URL('data/NotoSansCJK/NotoSansCJKkr-Regular.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/NotoSansCJK/NotoSansCJKkr-Regular.otf', import.meta.url), + ); it('should get a CFFGlyph', function () { let glyph = font.getGlyph(27); // : @@ -158,7 +198,10 @@ describe('glyphs', function () { it('should get a path for the glyph', function () { let glyph = font.getGlyph(27); - return assert.equal(glyph.path.toSVG(), 'M139 390C175 390 205 419 205 459C205 501 175 530 139 530C103 530 73 501 73 459C73 419 103 390 139 390ZM139 -13C175 -13 205 15 205 56C205 97 175 127 139 127C103 127 73 97 73 56C73 15 103 -13 139 -13Z'); + return assert.equal( + glyph.path.toSVG(), + 'M139 390C175 390 205 419 205 459C205 501 175 530 139 530C103 530 73 501 73 459C73 419 103 390 139 390ZM139 -13C175 -13 205 15 205 56C205 97 175 127 139 127C103 127 73 97 73 56C73 15 103 -13 139 -13Z', + ); }); it('should get the glyph cbox', function () { @@ -198,7 +241,9 @@ describe('glyphs', function () { }); describe('SBIX glyphs', function () { - let font = fontkit.openSync(new URL('data/ss-emoji/ss-emoji-apple.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/ss-emoji/ss-emoji-apple.ttf', import.meta.url), + ); it('should get an SBIXGlyph', function () { let glyph = font.glyphsForString('😜')[0]; @@ -217,7 +262,7 @@ describe('glyphs', function () { originX: 0, originY: 0, type: 'png ', - data: image.data + data: image.data, }); }); @@ -228,7 +273,9 @@ describe('glyphs', function () { }); describe('COLR glyphs', function () { - let font = fontkit.openSync(new URL('data/ss-emoji/ss-emoji-microsoft.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/ss-emoji/ss-emoji-microsoft.ttf', import.meta.url), + ); it('should get an SBIXGlyph', function () { let glyph = font.glyphsForString('😜')[0]; @@ -238,9 +285,18 @@ describe('glyphs', function () { it('should get layers', function () { let glyph = font.glyphsForString('😜')[0]; return assert.deepEqual(glyph.layers, [ - { glyph: font.getGlyph(247), color: { red: 252, green: 194, blue: 0, alpha: 255 } }, - { glyph: font.getGlyph(248), color: { red: 159, green: 79, blue: 0, alpha: 255 } }, - { glyph: font.getGlyph(249), color: { red: 229, green: 65, blue: 65, alpha: 255 } } + { + glyph: font.getGlyph(247), + color: { red: 252, green: 194, blue: 0, alpha: 255 }, + }, + { + glyph: font.getGlyph(248), + color: { red: 159, green: 79, blue: 0, alpha: 255 }, + }, + { + glyph: font.getGlyph(249), + color: { red: 229, green: 65, blue: 65, alpha: 255 }, + }, ]); }); @@ -264,7 +320,12 @@ describe('glyphs', function () { }); describe('WOFF ttf glyphs', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.ttf.woff', import.meta.url)); + let font = fontkit.openSync( + new URL( + 'data/SourceSansPro/SourceSansPro-Regular.ttf.woff', + import.meta.url, + ), + ); let glyph = font.glyphsForString('D')[0]; it('should get the glyph name', function () { @@ -276,12 +337,20 @@ describe('glyphs', function () { }); it('should get a quadratic path for the glyph', function () { - return assert.equal(glyph.path.toSVG(), 'M90 0L90 656L254 656Q406 656 485 571.5Q564 487 564 331Q564 174 485.5 87Q407 0 258 0ZM173 68L248 68Q363 68 420.5 137.5Q478 207 478 331Q478 455 420.5 521.5Q363 588 248 588L173 588Z'); + return assert.equal( + glyph.path.toSVG(), + 'M90 0L90 656L254 656Q406 656 485 571.5Q564 487 564 331Q564 174 485.5 87Q407 0 258 0ZM173 68L248 68Q363 68 420.5 137.5Q478 207 478 331Q478 455 420.5 521.5Q363 588 248 588L173 588Z', + ); }); }); describe('WOFF otf glyphs', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf.woff', import.meta.url)); + let font = fontkit.openSync( + new URL( + 'data/SourceSansPro/SourceSansPro-Regular.otf.woff', + import.meta.url, + ), + ); let glyph = font.glyphsForString('D')[0]; it('should get the glyph name', function () { @@ -293,12 +362,20 @@ describe('glyphs', function () { }); it('should get a cubic path for the glyph', function () { - return assert.equal(glyph.path.toSVG(), 'M90 0L258 0C456 0 564 122 564 331C564 539 456 656 254 656L90 656ZM173 68L173 588L248 588C401 588 478 496 478 331C478 165 401 68 248 68Z'); + return assert.equal( + glyph.path.toSVG(), + 'M90 0L258 0C456 0 564 122 564 331C564 539 456 656 254 656L90 656ZM173 68L173 588L248 588C401 588 478 496 478 331C478 165 401 68 248 68Z', + ); }); }); describe('WOFF2 ttf glyph', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.ttf.woff2', import.meta.url)); + let font = fontkit.openSync( + new URL( + 'data/SourceSansPro/SourceSansPro-Regular.ttf.woff2', + import.meta.url, + ), + ); let glyph = font.glyphsForString('D')[0]; @@ -312,11 +389,17 @@ describe('glyphs', function () { it('should get a path for the glyph', function () { let tglyph = font.glyphsForString('T')[0]; - return assert.equal(tglyph.path.toSVG(), 'M226 0L226 586L28 586L28 656L508 656L508 586L310 586L310 0Z'); + return assert.equal( + tglyph.path.toSVG(), + 'M226 0L226 586L28 586L28 656L508 656L508 586L310 586L310 0Z', + ); }); it('should get a correct quadratic path for all contours', function () { - return assert.equal(glyph.path.toSVG(), 'M90 0L90 656L254 656Q406 656 485 571.5Q564 487 564 331Q564 174 485.5 87Q407 0 258 0ZM173 68L248 68Q363 68 420.5 137.5Q478 207 478 331Q478 455 420.5 521.5Q363 588 248 588L173 588Z'); + return assert.equal( + glyph.path.toSVG(), + 'M90 0L90 656L254 656Q406 656 485 571.5Q564 487 564 331Q564 174 485.5 87Q407 0 258 0ZM173 68L248 68Q363 68 420.5 137.5Q478 207 478 331Q478 455 420.5 521.5Q363 588 248 588L173 588Z', + ); }); it('should get the ttf glyph cbox', function () { @@ -335,7 +418,12 @@ describe('glyphs', function () { }); describe('WOFF2 otf glyph', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf.woff2', import.meta.url)); + let font = fontkit.openSync( + new URL( + 'data/SourceSansPro/SourceSansPro-Regular.otf.woff2', + import.meta.url, + ), + ); let glyph = font.glyphsForString('D')[0]; @@ -349,11 +437,17 @@ describe('glyphs', function () { it('should get a path for the glyph', function () { let tglyph = font.glyphsForString('T')[0]; - return assert.equal(tglyph.path.toSVG(), 'M226 0L310 0L310 586L508 586L508 656L28 656L28 586L226 586Z'); + return assert.equal( + tglyph.path.toSVG(), + 'M226 0L310 0L310 586L508 586L508 656L28 656L28 586L226 586Z', + ); }); it('should get a correct cubic path for all contours', function () { - return assert.equal(glyph.path.toSVG(), 'M90 0L258 0C456 0 564 122 564 331C564 539 456 656 254 656L90 656ZM173 68L173 588L248 588C401 588 478 496 478 331C478 165 401 68 248 68Z'); + return assert.equal( + glyph.path.toSVG(), + 'M90 0L258 0C456 0 564 122 564 331C564 539 456 656 254 656L90 656ZM173 68L173 588L248 588C401 588 478 496 478 331C478 165 401 68 248 68Z', + ); }); it('should get the otf glyph cbox', function () { diff --git a/test/i18n.js b/test/i18n.js index 81e1d1a3..10e80f03 100644 --- a/test/i18n.js +++ b/test/i18n.js @@ -5,7 +5,9 @@ describe('i18n', function () { describe('fontkit.setDefaultLanguage', function () { let font; before('load Amiri font', function () { - font = fontkit.openSync(new URL('data/amiri/amiri-regular.ttf', import.meta.url)); + font = fontkit.openSync( + new URL('data/amiri/amiri-regular.ttf', import.meta.url), + ); }); after('reset default language', function () { @@ -17,7 +19,10 @@ describe('i18n', function () { assert.equal(font.postscriptName, 'Amiri-Regular'); assert.equal(font.familyName, 'Amiri'); assert.equal(font.subfamilyName, 'Regular'); - assert.equal(font.copyright, 'Copyright (c) 2010-2017, Khaled Hosny .\nPortions copyright (c) 2010, Sebastian Kosch .'); + assert.equal( + font.copyright, + 'Copyright (c) 2010-2017, Khaled Hosny .\nPortions copyright (c) 2010, Sebastian Kosch .', + ); assert.equal(font.version, 'Version 000.110 '); }); @@ -31,20 +36,25 @@ describe('i18n', function () { assert.equal(font.postscriptName, 'Amiri-Regular'); assert.equal(font.familyName, 'Amiri'); assert.equal(font.subfamilyName, 'عادي'); - assert.equal(font.copyright, 'حقوق النشر 2010-2017، خالد حسني .'); + assert.equal( + font.copyright, + 'حقوق النشر 2010-2017، خالد حسني .', + ); assert.equal(font.version, 'إصدارة 000٫110'); }); it('can reset default language back to "en"', function () { fontkit.setDefaultLanguage(); - assert.equal(fontkit.defaultLanguage, "en"); + assert.equal(fontkit.defaultLanguage, 'en'); }); }); describe('font.setDefaultLanguage', function () { let font; before('load Amiri font', function () { - font = fontkit.openSync(new URL('data/amiri/amiri-regular.ttf', import.meta.url)); + font = fontkit.openSync( + new URL('data/amiri/amiri-regular.ttf', import.meta.url), + ); }); it('font has "en" metadata properties', function () { @@ -52,7 +62,10 @@ describe('i18n', function () { assert.equal(font.postscriptName, 'Amiri-Regular'); assert.equal(font.familyName, 'Amiri'); assert.equal(font.subfamilyName, 'Regular'); - assert.equal(font.copyright, 'Copyright (c) 2010-2017, Khaled Hosny .\nPortions copyright (c) 2010, Sebastian Kosch .'); + assert.equal( + font.copyright, + 'Copyright (c) 2010-2017, Khaled Hosny .\nPortions copyright (c) 2010, Sebastian Kosch .', + ); assert.equal(font.version, 'Version 000.110 '); }); @@ -66,11 +79,14 @@ describe('i18n', function () { assert.equal(font.postscriptName, 'Amiri-Regular'); assert.equal(font.familyName, 'Amiri'); assert.equal(font.subfamilyName, 'عادي'); - assert.equal(font.copyright, 'حقوق النشر 2010-2017، خالد حسني .'); + assert.equal( + font.copyright, + 'حقوق النشر 2010-2017، خالد حسني .', + ); assert.equal(font.version, 'إصدارة 000٫110'); }); - it('the font\'s language should not change when the global changes', function () { + it("the font's language should not change when the global changes", function () { fontkit.setDefaultLanguage('en'); assert.equal(font.defaultLanguage, 'ar'); @@ -87,14 +103,16 @@ describe('i18n', function () { describe('backup languages', function () { let font; before('load Amiri font', function () { - font = fontkit.openSync(new URL('data/amiri/amiri-regular.ttf', import.meta.url)); + font = fontkit.openSync( + new URL('data/amiri/amiri-regular.ttf', import.meta.url), + ); }); after('reset default language', function () { fontkit.setDefaultLanguage(); }); - it('if the font\'s default language isn\'t found, use the global language', function () { + it("if the font's default language isn't found, use the global language", function () { font.setDefaultLanguage('piglatin'); fontkit.setDefaultLanguage('ar'); diff --git a/test/index.js b/test/index.js index baf40fa9..4751db20 100644 --- a/test/index.js +++ b/test/index.js @@ -3,74 +3,118 @@ import assert from 'assert'; describe('fontkit', function () { it('should open a font asynchronously', async () => { - let font = await fontkit.open(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let font = await fontkit.open( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); assert.equal(font.type, 'TTF'); }); it('should open a font synchronously', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); return assert.equal(font.type, 'TTF'); }); it('should open fonts of different formats', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); assert.equal(font.type, 'TTF'); - font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url)); + font = fontkit.openSync( + new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url), + ); assert.equal(font.type, 'TTF'); - font = fontkit.openSync(new URL('data/NotoSans/NotoSans.ttc', import.meta.url)); + font = fontkit.openSync( + new URL('data/NotoSans/NotoSans.ttc', import.meta.url), + ); assert.equal(font.type, 'TTC'); - font = fontkit.openSync(new URL('data/NotoSans/NotoSans.ttc', import.meta.url), 'NotoSans'); + font = fontkit.openSync( + new URL('data/NotoSans/NotoSans.ttc', import.meta.url), + 'NotoSans', + ); assert.equal(font.type, 'TTF'); - font = fontkit.openSync(new URL('data/NotoSans/NotoSans.dfont', import.meta.url)); + font = fontkit.openSync( + new URL('data/NotoSans/NotoSans.dfont', import.meta.url), + ); assert.equal(font.type, 'DFont'); - font = fontkit.openSync(new URL('data/NotoSans/NotoSans.dfont', import.meta.url), 'NotoSans'); + font = fontkit.openSync( + new URL('data/NotoSans/NotoSans.dfont', import.meta.url), + 'NotoSans', + ); assert.equal(font.type, 'TTF'); - font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.woff', import.meta.url)); + font = fontkit.openSync( + new URL('data/SourceSansPro/SourceSansPro-Regular.woff', import.meta.url), + ); assert.equal(font.type, 'WOFF'); - font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.woff2', import.meta.url)); + font = fontkit.openSync( + new URL( + 'data/SourceSansPro/SourceSansPro-Regular.woff2', + import.meta.url, + ), + ); assert.equal(font.type, 'WOFF2'); }); it('should open fonts lacking PostScript name', function () { - let font = fontkit.openSync(new URL('data/Mada/Mada-Regular.subset1.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/Mada/Mada-Regular.subset1.ttf', import.meta.url), + ); assert.equal(font.postscriptName, null); }); it('should error when opening an invalid font asynchronously', async function () { assert.rejects( fontkit.open(new URL(import.meta.url)), - 'Unknown font format' + 'Unknown font format', ); }); it('should error when opening an invalid font synchronously', function () { - assert.throws(() => fontkit.openSync(new URL(import.meta.url)), /Unknown font format/); + assert.throws( + () => fontkit.openSync(new URL(import.meta.url)), + /Unknown font format/, + ); }); it('should get collection objects for ttc fonts', function () { - let collection = fontkit.openSync(new URL('data/NotoSans/NotoSans.ttc', import.meta.url)); + let collection = fontkit.openSync( + new URL('data/NotoSans/NotoSans.ttc', import.meta.url), + ); assert.equal(collection.type, 'TTC'); - let names = collection.fonts.map(f => f.postscriptName); - assert.deepEqual(names, ['NotoSans-Bold', 'NotoSans', 'NotoSans-Italic', 'NotoSans-BoldItalic']); + let names = collection.fonts.map((f) => f.postscriptName); + assert.deepEqual(names, [ + 'NotoSans-Bold', + 'NotoSans', + 'NotoSans-Italic', + 'NotoSans-BoldItalic', + ]); let font = collection.getFont('NotoSans-Italic'); return assert.equal(font.postscriptName, 'NotoSans-Italic'); }); it('should get collection objects for dfonts', function () { - let collection = fontkit.openSync(new URL('data/NotoSans/NotoSans.dfont', import.meta.url)); + let collection = fontkit.openSync( + new URL('data/NotoSans/NotoSans.dfont', import.meta.url), + ); assert.equal(collection.type, 'DFont'); - let names = collection.fonts.map(f => f.postscriptName); - assert.deepEqual(names, ['NotoSans', 'NotoSans-Bold', 'NotoSans-Italic', 'NotoSans-BoldItalic']); + let names = collection.fonts.map((f) => f.postscriptName); + assert.deepEqual(names, [ + 'NotoSans', + 'NotoSans-Bold', + 'NotoSans-Italic', + 'NotoSans-BoldItalic', + ]); let font = collection.getFont('NotoSans-Italic'); return assert.equal(font.postscriptName, 'NotoSans-Italic'); diff --git a/test/issues.js b/test/issues.js index 8e2518de..28016568 100644 --- a/test/issues.js +++ b/test/issues.js @@ -2,62 +2,86 @@ import * as fontkit from 'fontkit'; import assert from 'assert'; describe('issues', function () { - describe('#282 - ReferenceError: Cannot access \'c3x\' before initialization', function () { - it('should not throw a ReferenceError', function () { - let font = fontkit.openSync(new URL('data/PlayfairDisplay/PlayfairDisplay-Regular.otf', import.meta.url)); + describe("#282 - ReferenceError: Cannot access 'c3x' before initialization", function () { + it('should not throw a ReferenceError', function () { + let font = fontkit.openSync( + new URL( + 'data/PlayfairDisplay/PlayfairDisplay-Regular.otf', + import.meta.url, + ), + ); - let glyph = font.getGlyph(5); + let glyph = font.getGlyph(5); - glyph.path; - }); + glyph.path; }); + }); - describe('#154 - Glyph cache issue', function () { - it('should retain code points after a composite glyph caches a component', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); - let composite = font.layout('ç').glyphs[0]; + describe('#154 - Glyph cache issue', function () { + it('should retain code points after a composite glyph caches a component', function () { + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); + let composite = font.layout('ç').glyphs[0]; - composite.path.commands; + composite.path.commands; - let glyph = font.layout('c').glyphs[0]; - assert.deepEqual(glyph.codePoints, [99]); - }); + let glyph = font.layout('c').glyphs[0]; + assert.deepEqual(glyph.codePoints, [99]); + }); - it('should retain code points for composed glyphs', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + it('should retain code points for composed glyphs', function () { + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); - for (let [character, codePoint] of [['ã', 227], ['á', 225]]) { - let glyph = font.layout(character).glyphs[0]; - glyph.path.commands; - assert.deepEqual(glyph.codePoints, [codePoint]); - } - }); + for (let [character, codePoint] of [ + ['ã', 227], + ['á', 225], + ]) { + let glyph = font.layout(character).glyphs[0]; + glyph.path.commands; + assert.deepEqual(glyph.codePoints, [codePoint]); + } }); + }); - describe('#342 - Glyph cache issue with glyphs shared by several code points', function () { - let openFont = () => fontkit.openSync(new URL('data/NotoSans/NotoKufiArabic-Regular.ttf', import.meta.url)); + describe('#342 - Glyph cache issue with glyphs shared by several code points', function () { + let openFont = () => + fontkit.openSync( + new URL('data/NotoSans/NotoKufiArabic-Regular.ttf', import.meta.url), + ); - it('should keep the code points of each lookup when a glyph is shared', function () { - let font = openFont(); - assert.equal(font.glyphForCodePoint(0x20).id, font.glyphForCodePoint(0xa0).id); + it('should keep the code points of each lookup when a glyph is shared', function () { + let font = openFont(); + assert.equal( + font.glyphForCodePoint(0x20).id, + font.glyphForCodePoint(0xa0).id, + ); - assert.deepEqual(font.layout(' ').glyphs[0].codePoints, [0x20]); - assert.deepEqual(font.layout('\u00a0').glyphs[0].codePoints, [0xa0]); - assert.deepEqual(font.layout(' ').glyphs[0].codePoints, [0x20]); - }); + assert.deepEqual(font.layout(' ').glyphs[0].codePoints, [0x20]); + assert.deepEqual(font.layout('\u00a0').glyphs[0].codePoints, [0xa0]); + assert.deepEqual(font.layout(' ').glyphs[0].codePoints, [0x20]); + }); - it('should shape text after laying out a presentation form that shares its glyph', function () { - let word = '\u0628\u0622\u0628'; - let reference = openFont(); - assert.equal(reference.glyphForCodePoint(0x622).id, reference.glyphForCodePoint(0xfe81).id); - let expected = reference.layout(word).glyphs.map(glyph => glyph.id); + it('should shape text after laying out a presentation form that shares its glyph', function () { + let word = '\u0628\u0622\u0628'; + let reference = openFont(); + assert.equal( + reference.glyphForCodePoint(0x622).id, + reference.glyphForCodePoint(0xfe81).id, + ); + let expected = reference.layout(word).glyphs.map((glyph) => glyph.id); - let font = openFont(); - font.layout('\ufe81'); + let font = openFont(); + font.layout('\ufe81'); - let glyphs = font.layout(word).glyphs; - assert.deepEqual(glyphs.map(glyph => glyph.id), expected); - assert.deepEqual(glyphs[1].codePoints, [0x622]); - }); + let glyphs = font.layout(word).glyphs; + assert.deepEqual( + glyphs.map((glyph) => glyph.id), + expected, + ); + assert.deepEqual(glyphs[1].codePoints, [0x622]); }); + }); }); diff --git a/test/metadata.js b/test/metadata.js index 56597bf0..41fc9fc3 100644 --- a/test/metadata.js +++ b/test/metadata.js @@ -2,14 +2,20 @@ import * as fontkit from 'fontkit'; import assert from 'assert'; describe('metadata', function () { - let font = fontkit.openSync(new URL('data/NotoSans/NotoSans.ttc', import.meta.url), 'NotoSans'); + let font = fontkit.openSync( + new URL('data/NotoSans/NotoSans.ttc', import.meta.url), + 'NotoSans', + ); it('has metadata properties', function () { assert.equal(font.fullName, 'Noto Sans'); assert.equal(font.postscriptName, 'NotoSans'); assert.equal(font.familyName, 'Noto Sans'); assert.equal(font.subfamilyName, 'Regular'); - assert.equal(font.copyright, 'Copyright 2012 Google Inc. All Rights Reserved.'); + assert.equal( + font.copyright, + 'Copyright 2012 Google Inc. All Rights Reserved.', + ); return assert.equal(font.version, 'Version 1.05 uh'); }); diff --git a/test/opentype.js b/test/opentype.js index 8e39cdd2..057758fc 100644 --- a/test/opentype.js +++ b/test/opentype.js @@ -2,7 +2,9 @@ import * as fontkit from 'fontkit'; import assert from 'assert'; describe('opentype', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url), + ); it('featureParams nameID of stylistic set should be 257', function () { assert.equal(font.GSUB.featureList[150].feature.featureParams.nameID, 257); @@ -15,5 +17,4 @@ describe('opentype', function () { it('featureParams should be null of aalt opentype feature', function () { assert.equal(font.GSUB.featureList[1].feature.featureParams, null); }); - }); diff --git a/test/shaping.js b/test/shaping.js index dc005ea0..da63f80d 100644 --- a/test/shaping.js +++ b/test/shaping.js @@ -5,7 +5,11 @@ describe('shaping', function () { let fontCache = {}; let test = (description, font, text, output) => { it(description, function () { - let f = fontCache[font] || (fontCache[font] = fontkit.openSync(new URL('data/' + font, import.meta.url))); + let f = + fontCache[font] || + (fontCache[font] = fontkit.openSync( + new URL('data/' + font, import.meta.url), + )); let { glyphs, positions } = f.layout(text); // Generate a compact string representation of the results @@ -16,7 +20,7 @@ describe('shaping', function () { let pos = positions[i]; let x = `${glyph.id}`; if (pos.xOffset || pos.yOffset) { - x += `@${pos.xOffset},${pos.yOffset}` + x += `@${pos.xOffset},${pos.yOffset}`; } x += `+${pos.xAdvance}`; @@ -24,562 +28,2672 @@ describe('shaping', function () { } return assert.equal(res.join('|'), output); - }) + }); }; describe('general shaping tests', function () { - let font = fontkit.openSync(new URL('data/amiri/amiri-regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/amiri/amiri-regular.ttf', import.meta.url), + ); it('should use correct script and language when features are not specified', function () { let { glyphs } = font.layout('۴', 'arab', 'URD'); - return assert.deepEqual(glyphs.map(g => g.id), [1940]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [1940], + ); }); it('should use specified left-to-right direction', function () { let { glyphs } = font.layout('١٢٣', 'arab', 'ARA ', 'ltr'); - return assert.deepEqual(glyphs.map(g => g.id), [446, 447, 448]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [446, 447, 448], + ); }); }); describe('arabic shaper', function () { - test('should shape Arabic text', 'NotoSans/NotoKufiArabic-Regular.ttf', 'سُلَّاِّمتی', - '223+1974|143+801|39+1176|270@180,80+0|268@1060,50+0|51+1452|101@900,-600+0|15+1798'); + test( + 'should shape Arabic text', + 'NotoSans/NotoKufiArabic-Regular.ttf', + 'سُلَّاِّمتی', + '223+1974|143+801|39+1176|270@180,80+0|268@1060,50+0|51+1452|101@900,-600+0|15+1798', + ); - test('should handle cursive attachment positioning', 'NotoSans/NotoNastaliqUrduDraft.ttf', 'ححححححب', - '18@652,-180+0|226+1350|574@0,279+90|825@0,707+176|825@0,1058+176|825@0,1409+176|825@0,1760+176|509@0,2111+636'); + test( + 'should handle cursive attachment positioning', + 'NotoSans/NotoNastaliqUrduDraft.ttf', + 'ححححححب', + '18@652,-180+0|226+1350|574@0,279+90|825@0,707+176|825@0,1058+176|825@0,1409+176|825@0,1760+176|509@0,2111+636', + ); - test('should shape Mongolian text', 'NotoSans/NotoSansMongolian-Regular.ttf', 'ᠬᠦᠮᠦᠨ ᠪᠦᠷ ᠲᠥᠷᠥᠵᠦ ᠮᠡᠨᠳᠡᠯᠡᠬᠦ ᠡᠷᠬᠡ', + test( + 'should shape Mongolian text', + 'NotoSans/NotoSansMongolian-Regular.ttf', + 'ᠬᠦᠮᠦᠨ ᠪᠦᠷ ᠲᠥᠷᠥᠵᠦ ᠮᠡᠨᠳᠡᠯᠡᠬᠦ ᠡᠷᠬᠡ', '488+2417|193+582|945+1174|56+874|3+532|358+2507|32+1032|3+532|35+1372|942+1778|31+1145|943+1174|101+1085|' + - '342+1298|3+532|206+1008|64+582|946+582|957+1255|64+582|75+582|64+582|493+1438|3+532|62+1008|31+1145|396+1993'); + '342+1298|3+532|206+1008|64+582|946+582|957+1255|64+582|75+582|64+582|493+1438|3+532|62+1008|31+1145|396+1993', + ); - test('should shape Syriac text', 'NotoSans/NotoSansSyriacEstrangela-Regular.ttf', 'ܚܐܪܐ ܘܒܪܒܪ ܓܘ ܐܝܩܪܐ ܘܙܕܩܐ.', + test( + 'should shape Syriac text', + 'NotoSans/NotoSansSyriacEstrangela-Regular.ttf', + 'ܚܐܪܐ ܘܒܪܒܪ ܓܘ ܐܝܩܪܐ ܘܙܕܩܐ.', '218+545|11+1781|94+1362|26@35,0+1139|34+564|32+1250|3+532|9+1904|96+1088|93+1383|51+569|8+1904|' + - '3+532|33+1225|21+1470|3+532|96+1088|17+1496|96+1088|17+1496|32+1250|3+532|9+1904|95+1104|12+1781|39+1052'); + '3+532|33+1225|21+1470|3+532|96+1088|17+1496|96+1088|17+1496|32+1250|3+532|9+1904|95+1104|12+1781|39+1052', + ); - test('should shape N\'Ko text', 'NotoSans/NotoSansNKo-Regular.ttf', 'ߞߊ߬ ߞߐߕߐ߮ ߞߎߘߊ ߘߏ߫ ߘߊߦߟߍ߬ ߸ ߏ߬', + test( + "should shape N'Ko text", + 'NotoSans/NotoSansNKo-Regular.ttf', + 'ߞߊ߬ ߞߐߕߐ߮ ߞߎߘߊ ߘߏ߫ ߘߊߦߟߍ߬ ߸ ߏ߬', '52@10,-300+0|23+1128|3+532|64+985|3+532|52@150,-300+0|84+1268|139+1184|160+1067|76+543|119+1622|3+532|51@10,-300+0|90+1128' + - '|119+1622|3+532|75+543|118+1622|88+1212|137+1114|3+532|54@170,0+0|93+1321|109+1155|94+1321|137+1114|3+532|52@-210,0+0|75+543|137+1114'); + '|119+1622|3+532|75+543|118+1622|88+1212|137+1114|3+532|54@170,0+0|93+1321|109+1155|94+1321|137+1114|3+532|52@-210,0+0|75+543|137+1114', + ); - test('should shape Phags Pa text', 'NotoSans/NotoSansPhagsPa-Regular.ttf', 'ꡀꡁꡂꡃ ꡄꡅꡆꡇ ꡈꡉꡊꡋ ꡌꡍꡎꡏ', + test( + 'should shape Phags Pa text', + 'NotoSans/NotoSansPhagsPa-Regular.ttf', + 'ꡀꡁꡂꡃ ꡄꡅꡆꡇ ꡈꡉꡊꡋ ꡌꡍꡎꡏ', '100+1491|212+1462|217+1462|87+1386|3+532|161+1677|168+1427|148+1532|329+1122|3+532|112+1614' + - '|153+1491|158+1073|107+1231|3+532|171+1686|178+1542|313+1542|115+1231'); + '|153+1491|158+1073|107+1231|3+532|171+1686|178+1542|313+1542|115+1231', + ); - test('should attach marks to the first base of a multiple substitution', 'amiri/amiri-regular.ttf', 'الله', '1824+721|461@-267,-162+0|430@-277,-440+0|6714+0|1823+473|1822+319|388+446'); + test( + 'should attach marks to the first base of a multiple substitution', + 'amiri/amiri-regular.ttf', + 'الله', + '1824+721|461@-267,-162+0|430@-277,-440+0|6714+0|1823+473|1822+319|388+446', + ); - test('should adjust attached marks if base is adjusted', 'amiri/amiri-regular.ttf', 'لَكنت', '2054+1810|2133+500|2300+1206|427@-96,0+0|5988+380|2322+360'); + test( + 'should adjust attached marks if base is adjusted', + 'amiri/amiri-regular.ttf', + 'لَكنت', + '2054+1810|2133+500|2300+1206|427@-96,0+0|5988+380|2322+360', + ); }); describe('hangul shaper', function () { - let font = fontkit.openSync(new URL('data/NotoSansCJK/NotoSansCJKkr-Regular.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/NotoSansCJK/NotoSansCJKkr-Regular.otf', import.meta.url), + ); it('should use composed versions if supported by the font', function () { - let { glyphs } = font.layout('\uD734\uAC00\u0020\uAC00\u002D\u002D\u0020\u0028\uC624\u002D\u002D\u0029'); - return assert.deepEqual(glyphs.map(g => g.id), [58626, 47566, 62995, 47566, 14, 14, 1, 9, 54258, 14, 14, 10]); + let { glyphs } = font.layout( + '\uD734\uAC00\u0020\uAC00\u002D\u002D\u0020\u0028\uC624\u002D\u002D\u0029', + ); + return assert.deepEqual( + glyphs.map((g) => g.id), + [58626, 47566, 62995, 47566, 14, 14, 1, 9, 54258, 14, 14, 10], + ); }); it('should compose decomposed syllables if supported', function () { - let { glyphs } = font.layout('\u1112\u1172\u1100\u1161\u0020\u1100\u1161\u002D\u002D\u0020\u0028\u110B\u1169\u002D\u002D\u0029'); - return assert.deepEqual(glyphs.map(g => g.id), [58626, 47566, 62995, 47566, 14, 14, 1, 9, 54258, 14, 14, 10]); + let { glyphs } = font.layout( + '\u1112\u1172\u1100\u1161\u0020\u1100\u1161\u002D\u002D\u0020\u0028\u110B\u1169\u002D\u002D\u0029', + ); + return assert.deepEqual( + glyphs.map((g) => g.id), + [58626, 47566, 62995, 47566, 14, 14, 1, 9, 54258, 14, 14, 10], + ); }); it('should use OT features for non-combining ', function () { let { glyphs } = font.layout('\ua960\ud7b0\ud7cb'); - return assert.deepEqual(glyphs.map(g => g.id), [64003, 64479, 64822]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [64003, 64479, 64822], + ); }); it('should decompose to if is not supported', function () { // combine at first, but the T is non-combining, so this // tests that the gets decomposed again in this case. let { glyphs } = font.layout('\u1100\u1161\ud7cb'); - return assert.deepEqual(glyphs.map(g => g.id), [63657, 64408, 64685]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [63657, 64408, 64685], + ); }); it('should reorder tone marks to the beginning of syllables', function () { let { glyphs } = font.layout('\ua960\ud7b0\u302f'); - return assert.deepEqual(glyphs.map(g => g.id), [1436, 64378, 64574]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [1436, 64378, 64574], + ); }); it('should reorder tone marks to the beginning of syllables', function () { let { glyphs } = font.layout('\ua960\ud7b0\ud7cb\u302f'); - return assert.deepEqual(glyphs.map(g => g.id), [1436, 64003, 64479, 64822]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [1436, 64003, 64479, 64822], + ); }); it('should reorder tone marks to the beginning of syllables', function () { let { glyphs } = font.layout('\uac00\u302f'); - return assert.deepEqual(glyphs.map(g => g.id), [1436, 47566]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [1436, 47566], + ); }); it('should reorder tone marks to the beginning of syllables', function () { let { glyphs } = font.layout('\uac01\u302f'); - return assert.deepEqual(glyphs.map(g => g.id), [1436, 47567]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [1436, 47567], + ); }); it('should insert a dotted circle for invalid tone marks', function () { let { glyphs } = font.layout('\u1100\u302f\u1161'); - return assert.deepEqual(glyphs.map(g => g.id), [365, 1436, 1256, 462]); + return assert.deepEqual( + glyphs.map((g) => g.id), + [365, 1436, 1256, 462], + ); }); }); describe('indic shaper', function () { describe('shapes Kannada text', function () { // Tests from https://github.com/unicode-org/text-rendering-tests - test('SHKNDA-1/1', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಲ್ಲಿ', '250+1550|126+0'); - test('SHKNDA-1/2', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಟ್ಸ್', '194+2092|130+96'); - test('SHKNDA-1/3', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಳಿ', '257+1441'); - test('SHKNDA-1/4', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಡಿ', '235+1565'); - test('SHKNDA-1/5', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಮೆ', '295+2196'); - test('SHKNDA-1/6', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ರಿ', '249+1289'); - test('SHKNDA-1/7', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಖ್ಯೆ', '272+1733|124+164'); - test('SHKNDA-1/8', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಫ್ರಿ', '244+1505|125+170'); - test('SHKNDA-1/9', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ನೆ', '290+1422'); - test('SHKNDA-1/10', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಗಿ', '225+1271'); - test('SHKNDA-1/11', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಷ್ಟಿ', '253+1528|109+141'); - test('SHKNDA-1/12', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಯಿಂ', '248+2564|73+1205'); - test('SHKNDA-1/13', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಚೀ', '228+1569|35+845'); - test('SHKNDA-1/14', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ನಿ', '242+1389'); - test('SHKNDA-1/15', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಗ್ಲಿ', '225+1271|126+0'); - test('SHKNDA-1/16', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಷಿ', '253+1528'); - test('SHKNDA-1/17', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಗೆ', '273+1276'); - test('SHKNDA-1/18', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ದ್ವಿ', '240+1516|127+57'); - test('SHKNDA-1/19', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ತೀ', '238+1255|35+845'); - test('SHKNDA-1/20', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಮಿ', '247+2186'); - test('SHKNDA-1/21', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಲಿ', '250+1550'); - test('SHKNDA-1/22', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಗಿ', '225+1271'); - test('SHKNDA-1/23', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ನ್', '203+1911'); - test('SHKNDA-1/24', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಬಿ', '245+1579'); - test('SHKNDA-1/25', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಲಿ', '250+1550'); - test('SHKNDA-1/26', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ನ್ನಿಂ', '242+1389|118+158|73+1205'); - test('SHKNDA-1/27', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಲ್ಲಿ', '250+1550|126+0'); - test('SHKNDA-1/28', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಧಿ', '241+1516'); - test('SHKNDA-1/29', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಪೌ', '168+1514|34+773'); - test('SHKNDA-1/30', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ವಿಂ', '251+1533|73+1205'); - test('SHKNDA-1/31', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಡಿ', '235+1565'); - test('SHKNDA-1/32', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಟಿ', '233+1621'); - test('SHKNDA-1/33', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ನಿ', '242+1389'); - test('SHKNDA-1/34', 'NotoSans/NotoSerifKannada-Regular.ttf', 'ಧಿ', '241+1516'); - - test('SHKNDA-2/1', 'NotoSans/NotoSansKannada-Regular.ttf', 'ನ್ನಾ', '150+1456|57+919|116+215'); - test('SHKNDA-2/2', 'NotoSans/NotoSansKannada-Regular.ttf', 'ನ್ನಾ', '150+1456|57+919|116+215'); - test('SHKNDA-2/3', 'NotoSans/NotoSansKannada-Regular.ttf', 'ತ್ತಾ', '146+1275|57+919|112+133'); - test('SHKNDA-2/4', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಟ್ಟಾ', '141+1669|57+919|107+277'); - test('SHKNDA-2/5', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಡೋಂಗಿ', '249+1573|61+1526|71+843|4+1127|207+1327'); - test('SHKNDA-2/6', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಜಿ಼ೕಬೆನ್', '211+1590|55@-254,0+0|71+843|259+1651|186+2096'); - test('SHKNDA-2/7', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಜಾ಼ಕಿರ್', '139+1590|57+919|55@-1173,0+0|205+1176|193+1974'); - test('SHKNDA-2/8', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಇನ್ಫ್ಲೆಕ್ಷನಲ್', '8+1457|256+1456|118+346|335+791|282+1176|39+1456|195+2234'); - test('SHKNDA-2/9', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಇನ್ಫ್ಲೆಕ್ಷನ್', '8+1457|256+1456|118+346|335+791|282+1176|186+2096'); - test('SHKNDA-2/10', 'NotoSans/NotoSansKannada-Regular.ttf', 'ದಟ್ಸ್', '37+1566|177+2150|130+245'); - test('SHKNDA-2/11', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಎಕ್ಸ್', '14+1612|167+1656|130+245'); - test('SHKNDA-2/12', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಮಾರ್ಚ್', '155+2367|57+919|172+2281|94+1161'); - test('SHKNDA-2/13', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಟೆಕ್ಸ್ಟ್', '247+1669|167+1656|130+346|317+970'); - test('SHKNDA-2/14', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಬುಕ್ಸ್', '42+1641|60+745|167+1656|130+245'); - test('SHKNDA-2/15', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಸಾಫ್ಟ್', '163+1452|57+919|188+2101|107+277'); - test('SHKNDA-2/16', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಜಸ್ಟ್', '27+1590|200+1932|107+277'); - - test('SHKNDA-3/1', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಕೋಂ', '239+1176|61+1526|71+843|4+1127'); - test('SHKNDA-3/2', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಖೋಂ', '240+1772|61+1526|71+843|4+1127'); - test('SHKNDA-3/3', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಗೋಂ', '241+1327|61+1526|71+843|4+1127'); - test('SHKNDA-3/4', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಘೋಂ', '242+2041|279+1526|71+843|4+1127'); - test('SHKNDA-3/5', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಙೋಂ', '24+1510|67+2009|71+843|4+1127'); - test('SHKNDA-3/6', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಚೋಂ', '243+1628|61+1526|71+843|4+1127'); - test('SHKNDA-3/7', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಛೋಂ', '244+1727|61+1526|71+843|4+1127'); - test('SHKNDA-3/8', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಜೋಂ', '245+1590|61+1526|71+843|4+1127'); - test('SHKNDA-3/9', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಝೋಂ', '246+2824|61+1526|71+843|4+1127'); - test('SHKNDA-3/10', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಞೋಂ', '29+1982|67+2009|71+843|4+1127'); - test('SHKNDA-3/11', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಟೋಂ', '247+1669|61+1526|71+843|4+1127'); - test('SHKNDA-3/12', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಠೋಂ', '248+1334|61+1526|71+843|4+1127'); - test('SHKNDA-3/13', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಡೋಂ', '249+1573|61+1526|71+843|4+1127'); - test('SHKNDA-3/14', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಢೋಂ', '250+1573|61+1526|71+843|4+1127'); - test('SHKNDA-3/15', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಣೋಂ', '251+1775|61+1526|71+843|4+1127'); - test('SHKNDA-3/16', 'NotoSans/NotoSansKannada-Regular.ttf', 'ತೋಂ', '252+1275|61+1526|71+843|4+1127'); - test('SHKNDA-3/17', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಥೋಂ', '253+1566|61+1526|71+843|4+1127'); - test('SHKNDA-3/18', 'NotoSans/NotoSansKannada-Regular.ttf', 'ದೋಂ', '254+1566|61+1526|71+843|4+1127'); - test('SHKNDA-3/19', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಧೋಂ ', '255+1566|61+1526|71+843|4+1127|3+590'); - test('SHKNDA-3/20', 'NotoSans/NotoSansKannada-Regular.ttf', 'ನೋಂ', '256+1456|61+1526|71+843|4+1127'); - test('SHKNDA-3/21', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಪೋಂ', '257+1621|275+1316|71+843|4+1127'); - test('SHKNDA-3/22', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಫೋಂ', '258+1621|277+1316|71+843|4+1127'); - test('SHKNDA-3/23', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಬೋಂ', '259+1651|61+1526|71+843|4+1127'); - test('SHKNDA-3/24', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಭೋಂ', '260+1651|61+1526|71+843|4+1127'); - test('SHKNDA-3/25', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಮೋಂ', '280+3152|71+843|4+1127'); - test('SHKNDA-3/26', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಯೋಂ', '281+3506|71+843|4+1127'); - test('SHKNDA-3/27', 'NotoSans/NotoSansKannada-Regular.ttf', 'ರೋಂ', '263+1334|61+1526|71+843|4+1127'); - test('SHKNDA-3/28', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಱೋಂ', '47+1701|67+2009|71+843|4+1127'); - test('SHKNDA-3/29', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಲೋಂ', '264+1574|61+1526|71+843|4+1127'); - test('SHKNDA-3/30', 'NotoSans/NotoSansKannada-Regular.ttf', 'ವೋಂ', '266+1626|275+1316|71+843|4+1127'); - test('SHKNDA-3/31', 'NotoSans/NotoSansKannada-Regular.ttf', 'ಆ್ಯಕ್ಷಿಸ್‌', '7+1717|122+532|285+1176|200+2092|3+0'); + test( + 'SHKNDA-1/1', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಲ್ಲಿ', + '250+1550|126+0', + ); + test( + 'SHKNDA-1/2', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಟ್ಸ್', + '194+2092|130+96', + ); + test( + 'SHKNDA-1/3', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಳಿ', + '257+1441', + ); + test( + 'SHKNDA-1/4', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಡಿ', + '235+1565', + ); + test( + 'SHKNDA-1/5', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಮೆ', + '295+2196', + ); + test( + 'SHKNDA-1/6', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ರಿ', + '249+1289', + ); + test( + 'SHKNDA-1/7', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಖ್ಯೆ', + '272+1733|124+164', + ); + test( + 'SHKNDA-1/8', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಫ್ರಿ', + '244+1505|125+170', + ); + test( + 'SHKNDA-1/9', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ನೆ', + '290+1422', + ); + test( + 'SHKNDA-1/10', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಗಿ', + '225+1271', + ); + test( + 'SHKNDA-1/11', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಷ್ಟಿ', + '253+1528|109+141', + ); + test( + 'SHKNDA-1/12', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಯಿಂ', + '248+2564|73+1205', + ); + test( + 'SHKNDA-1/13', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಚೀ', + '228+1569|35+845', + ); + test( + 'SHKNDA-1/14', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ನಿ', + '242+1389', + ); + test( + 'SHKNDA-1/15', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಗ್ಲಿ', + '225+1271|126+0', + ); + test( + 'SHKNDA-1/16', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಷಿ', + '253+1528', + ); + test( + 'SHKNDA-1/17', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಗೆ', + '273+1276', + ); + test( + 'SHKNDA-1/18', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ದ್ವಿ', + '240+1516|127+57', + ); + test( + 'SHKNDA-1/19', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ತೀ', + '238+1255|35+845', + ); + test( + 'SHKNDA-1/20', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಮಿ', + '247+2186', + ); + test( + 'SHKNDA-1/21', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಲಿ', + '250+1550', + ); + test( + 'SHKNDA-1/22', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಗಿ', + '225+1271', + ); + test( + 'SHKNDA-1/23', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ನ್', + '203+1911', + ); + test( + 'SHKNDA-1/24', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಬಿ', + '245+1579', + ); + test( + 'SHKNDA-1/25', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಲಿ', + '250+1550', + ); + test( + 'SHKNDA-1/26', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ನ್ನಿಂ', + '242+1389|118+158|73+1205', + ); + test( + 'SHKNDA-1/27', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಲ್ಲಿ', + '250+1550|126+0', + ); + test( + 'SHKNDA-1/28', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಧಿ', + '241+1516', + ); + test( + 'SHKNDA-1/29', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಪೌ', + '168+1514|34+773', + ); + test( + 'SHKNDA-1/30', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ವಿಂ', + '251+1533|73+1205', + ); + test( + 'SHKNDA-1/31', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಡಿ', + '235+1565', + ); + test( + 'SHKNDA-1/32', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಟಿ', + '233+1621', + ); + test( + 'SHKNDA-1/33', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ನಿ', + '242+1389', + ); + test( + 'SHKNDA-1/34', + 'NotoSans/NotoSerifKannada-Regular.ttf', + 'ಧಿ', + '241+1516', + ); + + test( + 'SHKNDA-2/1', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ನ್ನಾ', + '150+1456|57+919|116+215', + ); + test( + 'SHKNDA-2/2', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ನ್ನಾ', + '150+1456|57+919|116+215', + ); + test( + 'SHKNDA-2/3', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ತ್ತಾ', + '146+1275|57+919|112+133', + ); + test( + 'SHKNDA-2/4', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಟ್ಟಾ', + '141+1669|57+919|107+277', + ); + test( + 'SHKNDA-2/5', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಡೋಂಗಿ', + '249+1573|61+1526|71+843|4+1127|207+1327', + ); + test( + 'SHKNDA-2/6', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಜಿ಼ೕಬೆನ್', + '211+1590|55@-254,0+0|71+843|259+1651|186+2096', + ); + test( + 'SHKNDA-2/7', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಜಾ಼ಕಿರ್', + '139+1590|57+919|55@-1173,0+0|205+1176|193+1974', + ); + test( + 'SHKNDA-2/8', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಇನ್ಫ್ಲೆಕ್ಷನಲ್', + '8+1457|256+1456|118+346|335+791|282+1176|39+1456|195+2234', + ); + test( + 'SHKNDA-2/9', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಇನ್ಫ್ಲೆಕ್ಷನ್', + '8+1457|256+1456|118+346|335+791|282+1176|186+2096', + ); + test( + 'SHKNDA-2/10', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ದಟ್ಸ್', + '37+1566|177+2150|130+245', + ); + test( + 'SHKNDA-2/11', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಎಕ್ಸ್', + '14+1612|167+1656|130+245', + ); + test( + 'SHKNDA-2/12', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಮಾರ್ಚ್', + '155+2367|57+919|172+2281|94+1161', + ); + test( + 'SHKNDA-2/13', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಟೆಕ್ಸ್ಟ್', + '247+1669|167+1656|130+346|317+970', + ); + test( + 'SHKNDA-2/14', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಬುಕ್ಸ್', + '42+1641|60+745|167+1656|130+245', + ); + test( + 'SHKNDA-2/15', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಸಾಫ್ಟ್', + '163+1452|57+919|188+2101|107+277', + ); + test( + 'SHKNDA-2/16', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಜಸ್ಟ್', + '27+1590|200+1932|107+277', + ); + + test( + 'SHKNDA-3/1', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಕೋಂ', + '239+1176|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/2', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಖೋಂ', + '240+1772|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/3', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಗೋಂ', + '241+1327|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/4', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಘೋಂ', + '242+2041|279+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/5', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಙೋಂ', + '24+1510|67+2009|71+843|4+1127', + ); + test( + 'SHKNDA-3/6', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಚೋಂ', + '243+1628|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/7', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಛೋಂ', + '244+1727|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/8', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಜೋಂ', + '245+1590|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/9', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಝೋಂ', + '246+2824|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/10', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಞೋಂ', + '29+1982|67+2009|71+843|4+1127', + ); + test( + 'SHKNDA-3/11', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಟೋಂ', + '247+1669|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/12', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಠೋಂ', + '248+1334|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/13', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಡೋಂ', + '249+1573|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/14', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಢೋಂ', + '250+1573|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/15', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಣೋಂ', + '251+1775|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/16', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ತೋಂ', + '252+1275|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/17', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಥೋಂ', + '253+1566|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/18', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ದೋಂ', + '254+1566|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/19', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಧೋಂ ', + '255+1566|61+1526|71+843|4+1127|3+590', + ); + test( + 'SHKNDA-3/20', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ನೋಂ', + '256+1456|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/21', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಪೋಂ', + '257+1621|275+1316|71+843|4+1127', + ); + test( + 'SHKNDA-3/22', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಫೋಂ', + '258+1621|277+1316|71+843|4+1127', + ); + test( + 'SHKNDA-3/23', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಬೋಂ', + '259+1651|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/24', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಭೋಂ', + '260+1651|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/25', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಮೋಂ', + '280+3152|71+843|4+1127', + ); + test( + 'SHKNDA-3/26', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಯೋಂ', + '281+3506|71+843|4+1127', + ); + test( + 'SHKNDA-3/27', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ರೋಂ', + '263+1334|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/28', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಱೋಂ', + '47+1701|67+2009|71+843|4+1127', + ); + test( + 'SHKNDA-3/29', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಲೋಂ', + '264+1574|61+1526|71+843|4+1127', + ); + test( + 'SHKNDA-3/30', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ವೋಂ', + '266+1626|275+1316|71+843|4+1127', + ); + test( + 'SHKNDA-3/31', + 'NotoSans/NotoSansKannada-Regular.ttf', + 'ಆ್ಯಕ್ಷಿಸ್‌', + '7+1717|122+532|285+1176|200+2092|3+0', + ); }); describe('shapes Telugu text', function () { - test('HB-TELU-1', 'NotoSans/NotoSansTelugu-Regular.ttf', 'కై', '326+1065'); - test('HB-TELU-2', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్', '102+1065'); - test('HB-TELU-3', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్కై', '326+1065|511+1079'); - test('HB-TELU-4', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్ర', '21+1065|549+0'); - test('HB-TELU-5', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్రి', '174+1065|549+0'); - test('HB-TELU-6', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్రై', '326+1065|496+860'); - test('HB-TELU-7', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్ర్', '102+1065|549+0'); - test('HB-TELU-8', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్ర్క', '21+1065|549+0|511+1079'); - test('HB-TELU-9', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్ష', '101+1065'); - test('HB-TELU-10', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్ష్', '137+1065'); - test('HB-TELU-11', 'NotoSans/NotoSansTelugu-Regular.ttf', 'క్ష్ణ', '21+1065|605+0'); - test('HB-TELU-12', 'NotoSans/NotoSansTelugu-Regular.ttf', 'ఽం', '56+1208|5+1038'); + test( + 'HB-TELU-1', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'కై', + '326+1065', + ); + test( + 'HB-TELU-2', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్', + '102+1065', + ); + test( + 'HB-TELU-3', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్కై', + '326+1065|511+1079', + ); + test( + 'HB-TELU-4', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్ర', + '21+1065|549+0', + ); + test( + 'HB-TELU-5', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్రి', + '174+1065|549+0', + ); + test( + 'HB-TELU-6', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్రై', + '326+1065|496+860', + ); + test( + 'HB-TELU-7', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్ర్', + '102+1065|549+0', + ); + test( + 'HB-TELU-8', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్ర్క', + '21+1065|549+0|511+1079', + ); + test( + 'HB-TELU-9', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్ష', + '101+1065', + ); + test( + 'HB-TELU-10', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్ష్', + '137+1065', + ); + test( + 'HB-TELU-11', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'క్ష్ణ', + '21+1065|605+0', + ); + test( + 'HB-TELU-12', + 'NotoSans/NotoSansTelugu-Regular.ttf', + 'ఽం', + '56+1208|5+1038', + ); }); describe('shapes Tamil text', function () { - test('HB-TAML-1', 'NotoSans/NotoSansTamil-Regular.ttf', 'தமிழ்நாடு', '25+1689|29+1762|42+537|94+1762|26+1616|41+1311|112+2078'); - test('HB-TAML-2', 'NotoSans/NotoSansTamil-Regular.ttf', 'ஓர்', '16+2018|90+1311'); - test('HB-TAML-3', 'NotoSans/NotoSansTamil-Regular.ttf', 'இந்திய', '8+2306|85+1616|25+1689|149+537|30+1972'); - test('HB-TAML-4', 'NotoSans/NotoSansTamil-Regular.ttf', 'மாநிலமாகும்.', '29+1762|41+1311|26+1616|149+537|33+2075|29+1762|41+1311|101+2175|88+1762|164+549'); - test('HB-TAML-5', 'NotoSans/NotoSansTamil-Regular.ttf', 'தமிழ்நாடு,', '25+1689|29+1762|42+537|94+1762|26+1616|41+1311|112+2078|162+512'); - test('HB-TAML-6', 'NotoSans/NotoSansTamil-Regular.ttf', 'தமிழகம்', '25+1689|29+1762|42+537|35+1762|18+1689|88+1762'); - test('HB-TAML-7', 'NotoSans/NotoSansTamil-Regular.ttf', 'என்றும்', '12+1640|86+2528|132+2329|88+1762'); - test('HB-TAML-8', 'NotoSans/NotoSansTamil-Regular.ttf', 'பரவலாக', '28+1593|31+1311|36+2139|33+2075|41+1311|18+1689'); - test('HB-TAML-9', 'NotoSans/NotoSansTamil-Regular.ttf', 'அழைக்கப்படுகிறது.', '6+2295|48+2384|35+1762|77+1689|18+1689|87+1593|28+1593|112+2078|18+1689|149+537|32+1792|116+2234|164+549'); - test('HB-TAML-10', 'NotoSans/NotoSansTamil-Regular.ttf', 'ஆங்கிலத்தில்', '7+2690|78+2139|18+1689|149+537|33+2075|84+1689|25+1689|149+537|92+2075'); - test('HB-TAML-11', 'NotoSans/NotoSansTamil-Regular.ttf', 'மெட்ராஸ்', '46+1846|29+1762|82+1419|31+1311|41+1311|98+2631'); - test('HB-TAML-12', 'NotoSans/NotoSansTamil-Regular.ttf', 'ஸ்டேட்', '98+2631|47+1491|23+1419|82+1419'); - test('HB-TAML-13', 'NotoSans/NotoSansTamil-Regular.ttf', 'என்றும்', '12+1640|86+2528|132+2329|88+1762'); - test('HB-TAML-14', 'NotoSans/NotoSansTamil-Regular.ttf', 'தமிழில்', '25+1689|29+1762|42+537|35+1762|42+537|92+2075'); - test('HB-TAML-15', 'NotoSans/NotoSansTamil-Regular.ttf', 'சென்னை', '46+1846|20+1481|86+2528|48+2384|27+2528'); - test('HB-TAML-16', 'NotoSans/NotoSansTamil-Regular.ttf', 'ராஜ்ஜியம்', '31+1311|41+1311|80+2094|21+2094|42+537|30+1972|88+1762'); - test('HB-TAML-17', 'NotoSans/NotoSansTamil-Regular.ttf', 'என்றும்', '12+1640|86+2528|132+2329|88+1762'); - test('HB-TAML-18', 'NotoSans/NotoSansTamil-Regular.ttf', 'அழைக்கப்பெற்றது.', '6+2295|48+2384|35+1762|77+1689|18+1689|87+1593|46+1846|28+1593|91+1788|32+1792|116+2234|164+549'); - test('HB-TAML-19', 'NotoSans/NotoSansTamil-Regular.ttf', 'இதனை', '8+2306|25+1689|48+2384|27+2528'); - test('HB-TAML-20', 'NotoSans/NotoSansTamil-Regular.ttf', 'தமிழ்நாடு', '25+1689|29+1762|42+537|94+1762|26+1616|41+1311|112+2078'); - test('HB-TAML-21', 'NotoSans/NotoSansTamil-Regular.ttf', 'என்று', '12+1640|86+2528|132+2329'); - test('HB-TAML-22', 'NotoSans/NotoSansTamil-Regular.ttf', 'மாற்றக்கோரி', '29+1762|41+1311|91+1788|32+1792|77+1689|47+1491|18+1689|41+1311|31+1311|42+537'); - test('HB-TAML-23', 'NotoSans/NotoSansTamil-Regular.ttf', 'போராட்டங்கள்', '47+1491|28+1593|41+1311|31+1311|41+1311|82+1419|23+1419|78+2139|18+1689|93+2192'); - test('HB-TAML-24', 'NotoSans/NotoSansTamil-Regular.ttf', 'நடைபெற்றன.', '26+1616|48+2384|23+1419|46+1846|28+1593|91+1788|32+1792|27+2528|164+549'); - test('HB-TAML-25', 'NotoSans/NotoSansTamil-Regular.ttf', 'சங்கரலிங்கனார்', '20+1481|78+2139|18+1689|31+1311|134+2603|78+2139|18+1689|27+2528|41+1311|90+1311'); - test('HB-TAML-26', 'NotoSans/NotoSansTamil-Regular.ttf', 'என்பவர்', '12+1640|86+2528|28+1593|36+2139|90+1311'); - test('HB-TAML-27', 'NotoSans/NotoSansTamil-Regular.ttf', 'நாட்கள்', '26+1616|41+1311|82+1419|18+1689|93+2192'); - test('HB-TAML-28', 'NotoSans/NotoSansTamil-Regular.ttf', 'உண்ணாவிரதம்', '10+2185|83+3377|24+3377|41+1311|36+2139|148+537|31+1311|25+1689|88+1762'); - test('HB-TAML-29', 'NotoSans/NotoSansTamil-Regular.ttf', 'இருந்து', '8+2306|130+2153|85+1616|116+2234'); - test('HB-TAML-30', 'NotoSans/NotoSansTamil-Regular.ttf', 'உயிர்துறந்தார்.', '10+2185|30+1972|148+537|90+1311|116+2234|32+1792|85+1616|25+1689|41+1311|90+1311|164+549'); - test('HB-TAML-31', 'NotoSans/NotoSansTamil-Regular.ttf', 'பின்னர்', '28+1593|148+537|86+2528|27+2528|90+1311'); - test('HB-TAML-32', 'NotoSans/NotoSansTamil-Regular.ttf', 'மதராசு', '29+1762|25+1689|31+1311|41+1311|106+1776'); - test('HB-TAML-33', 'NotoSans/NotoSansTamil-Regular.ttf', 'ஸ்டேட்', '98+2631|47+1491|23+1419|82+1419'); - test('HB-TAML-34', 'NotoSans/NotoSansTamil-Regular.ttf', 'என்று', '12+1640|86+2528|132+2329'); - test('HB-TAML-35', 'NotoSans/NotoSansTamil-Regular.ttf', 'இருந்த', '8+2306|130+2153|85+1616|25+1689'); - test('HB-TAML-36', 'NotoSans/NotoSansTamil-Regular.ttf', 'பெயர்', '46+1846|28+1593|30+1972|90+1311'); - test('HB-TAML-37', 'NotoSans/NotoSansTamil-Regular.ttf', 'ஆம்', '7+2690|88+1762'); - test('HB-TAML-38', 'NotoSans/NotoSansTamil-Regular.ttf', 'ஆண்டு', '7+2690|83+3377|112+2078'); - test('HB-TAML-39', 'NotoSans/NotoSansTamil-Regular.ttf', 'தமிழ்நாடு', '25+1689|29+1762|42+537|94+1762|26+1616|41+1311|112+2078'); - test('HB-TAML-40', 'NotoSans/NotoSansTamil-Regular.ttf', 'என்று', '12+1640|86+2528|132+2329'); - test('HB-TAML-41', 'NotoSans/NotoSansTamil-Regular.ttf', 'மாற்றப்பட்டது.', '29+1762|41+1311|91+1788|32+1792|87+1593|28+1593|82+1419|23+1419|116+2234|164+549'); - test('HB-TAML-42', 'NotoSans/NotoSansTamil-Regular.ttf', 'ஸ்ரீ', '147+3100'); - test('HB-TAML-43', 'NotoSans/NotoSansTamil-Regular.ttf', 'க்ஷ', '76+3795'); + test( + 'HB-TAML-1', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'தமிழ்நாடு', + '25+1689|29+1762|42+537|94+1762|26+1616|41+1311|112+2078', + ); + test( + 'HB-TAML-2', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'ஓர்', + '16+2018|90+1311', + ); + test( + 'HB-TAML-3', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'இந்திய', + '8+2306|85+1616|25+1689|149+537|30+1972', + ); + test( + 'HB-TAML-4', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'மாநிலமாகும்.', + '29+1762|41+1311|26+1616|149+537|33+2075|29+1762|41+1311|101+2175|88+1762|164+549', + ); + test( + 'HB-TAML-5', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'தமிழ்நாடு,', + '25+1689|29+1762|42+537|94+1762|26+1616|41+1311|112+2078|162+512', + ); + test( + 'HB-TAML-6', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'தமிழகம்', + '25+1689|29+1762|42+537|35+1762|18+1689|88+1762', + ); + test( + 'HB-TAML-7', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'என்றும்', + '12+1640|86+2528|132+2329|88+1762', + ); + test( + 'HB-TAML-8', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'பரவலாக', + '28+1593|31+1311|36+2139|33+2075|41+1311|18+1689', + ); + test( + 'HB-TAML-9', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'அழைக்கப்படுகிறது.', + '6+2295|48+2384|35+1762|77+1689|18+1689|87+1593|28+1593|112+2078|18+1689|149+537|32+1792|116+2234|164+549', + ); + test( + 'HB-TAML-10', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'ஆங்கிலத்தில்', + '7+2690|78+2139|18+1689|149+537|33+2075|84+1689|25+1689|149+537|92+2075', + ); + test( + 'HB-TAML-11', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'மெட்ராஸ்', + '46+1846|29+1762|82+1419|31+1311|41+1311|98+2631', + ); + test( + 'HB-TAML-12', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'ஸ்டேட்', + '98+2631|47+1491|23+1419|82+1419', + ); + test( + 'HB-TAML-13', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'என்றும்', + '12+1640|86+2528|132+2329|88+1762', + ); + test( + 'HB-TAML-14', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'தமிழில்', + '25+1689|29+1762|42+537|35+1762|42+537|92+2075', + ); + test( + 'HB-TAML-15', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'சென்னை', + '46+1846|20+1481|86+2528|48+2384|27+2528', + ); + test( + 'HB-TAML-16', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'ராஜ்ஜியம்', + '31+1311|41+1311|80+2094|21+2094|42+537|30+1972|88+1762', + ); + test( + 'HB-TAML-17', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'என்றும்', + '12+1640|86+2528|132+2329|88+1762', + ); + test( + 'HB-TAML-18', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'அழைக்கப்பெற்றது.', + '6+2295|48+2384|35+1762|77+1689|18+1689|87+1593|46+1846|28+1593|91+1788|32+1792|116+2234|164+549', + ); + test( + 'HB-TAML-19', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'இதனை', + '8+2306|25+1689|48+2384|27+2528', + ); + test( + 'HB-TAML-20', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'தமிழ்நாடு', + '25+1689|29+1762|42+537|94+1762|26+1616|41+1311|112+2078', + ); + test( + 'HB-TAML-21', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'என்று', + '12+1640|86+2528|132+2329', + ); + test( + 'HB-TAML-22', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'மாற்றக்கோரி', + '29+1762|41+1311|91+1788|32+1792|77+1689|47+1491|18+1689|41+1311|31+1311|42+537', + ); + test( + 'HB-TAML-23', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'போராட்டங்கள்', + '47+1491|28+1593|41+1311|31+1311|41+1311|82+1419|23+1419|78+2139|18+1689|93+2192', + ); + test( + 'HB-TAML-24', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'நடைபெற்றன.', + '26+1616|48+2384|23+1419|46+1846|28+1593|91+1788|32+1792|27+2528|164+549', + ); + test( + 'HB-TAML-25', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'சங்கரலிங்கனார்', + '20+1481|78+2139|18+1689|31+1311|134+2603|78+2139|18+1689|27+2528|41+1311|90+1311', + ); + test( + 'HB-TAML-26', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'என்பவர்', + '12+1640|86+2528|28+1593|36+2139|90+1311', + ); + test( + 'HB-TAML-27', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'நாட்கள்', + '26+1616|41+1311|82+1419|18+1689|93+2192', + ); + test( + 'HB-TAML-28', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'உண்ணாவிரதம்', + '10+2185|83+3377|24+3377|41+1311|36+2139|148+537|31+1311|25+1689|88+1762', + ); + test( + 'HB-TAML-29', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'இருந்து', + '8+2306|130+2153|85+1616|116+2234', + ); + test( + 'HB-TAML-30', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'உயிர்துறந்தார்.', + '10+2185|30+1972|148+537|90+1311|116+2234|32+1792|85+1616|25+1689|41+1311|90+1311|164+549', + ); + test( + 'HB-TAML-31', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'பின்னர்', + '28+1593|148+537|86+2528|27+2528|90+1311', + ); + test( + 'HB-TAML-32', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'மதராசு', + '29+1762|25+1689|31+1311|41+1311|106+1776', + ); + test( + 'HB-TAML-33', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'ஸ்டேட்', + '98+2631|47+1491|23+1419|82+1419', + ); + test( + 'HB-TAML-34', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'என்று', + '12+1640|86+2528|132+2329', + ); + test( + 'HB-TAML-35', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'இருந்த', + '8+2306|130+2153|85+1616|25+1689', + ); + test( + 'HB-TAML-36', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'பெயர்', + '46+1846|28+1593|30+1972|90+1311', + ); + test( + 'HB-TAML-37', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'ஆம்', + '7+2690|88+1762', + ); + test( + 'HB-TAML-38', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'ஆண்டு', + '7+2690|83+3377|112+2078', + ); + test( + 'HB-TAML-39', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'தமிழ்நாடு', + '25+1689|29+1762|42+537|94+1762|26+1616|41+1311|112+2078', + ); + test( + 'HB-TAML-40', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'என்று', + '12+1640|86+2528|132+2329', + ); + test( + 'HB-TAML-41', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'மாற்றப்பட்டது.', + '29+1762|41+1311|91+1788|32+1792|87+1593|28+1593|82+1419|23+1419|116+2234|164+549', + ); + test( + 'HB-TAML-42', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'ஸ்ரீ', + '147+3100', + ); + test( + 'HB-TAML-43', + 'NotoSans/NotoSansTamil-Regular.ttf', + 'க்ஷ', + '76+3795', + ); }); describe('shapes Devanagari text', function () { describe('joiners', function () { - test('HB-DEVA-joiners-1', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्ह', '61+1088|181+0'); - test('HB-DEVA-joiners-2', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्‌ह', '52+838|81@-48,0+0|3+0|61+1088'); - test('HB-DEVA-joiners-3', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्‍ह', '209+818|61+1088'); - test('HB-DEVA-joiners-4', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'ऱ्ह', '209+818|61+1088'); - test('HB-DEVA-joiners-5', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'ऱ्‌ह', '53+838|81@-48,0+0|3+0|61+1088'); - test('HB-DEVA-joiners-6', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'ऱ्‍ह', '209+818|3+0|61+1088'); - test('HB-DEVA-joiners-7', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्क', '183+1104|25+1561'); - test('HB-DEVA-joiners-8', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‍', '183+1204|3+0'); - test('HB-DEVA-joiners-9', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‌क', '25+1561|81@-454,0+0|3+0|25+1561'); - test('HB-DEVA-joiners-10', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‍क', '183+1104|3+0|25+1561'); - test('HB-DEVA-joiners-11', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्कि', '558+530|183+1104|25+1561'); - test('HB-DEVA-joiners-12', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‌कि', '25+1561|81@-454,0+0|3+0|561+530|25+1561'); - test('HB-DEVA-joiners-13', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‍कि', '558+530|183+1104|3+0|25+1561'); - test('HB-DEVA-joiners-14', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्ष', '179+1458'); - test('HB-DEVA-joiners-15', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‌ष', '25+1561|81@-454,0+0|3+0|59+1184'); - test('HB-DEVA-joiners-16', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‍ष', '183+1204|3+0|59+1184'); - test('HB-DEVA-joiners-17', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'द्सि', '42+1064|81@96,0+0|563+530|60+1375'); - test('HB-DEVA-joiners-18', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'द्‌सि', '42+1064|81@96,0+0|3+0|563+530|60+1375'); - test('HB-DEVA-joiners-19', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'द्‍सि', '558+530|200+1064|60+1375'); + test( + 'HB-DEVA-joiners-1', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्ह', + '61+1088|181+0', + ); + test( + 'HB-DEVA-joiners-2', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्‌ह', + '52+838|81@-48,0+0|3+0|61+1088', + ); + test( + 'HB-DEVA-joiners-3', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्‍ह', + '209+818|61+1088', + ); + test( + 'HB-DEVA-joiners-4', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'ऱ्ह', + '209+818|61+1088', + ); + test( + 'HB-DEVA-joiners-5', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'ऱ्‌ह', + '53+838|81@-48,0+0|3+0|61+1088', + ); + test( + 'HB-DEVA-joiners-6', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'ऱ्‍ह', + '209+818|3+0|61+1088', + ); + test( + 'HB-DEVA-joiners-7', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्क', + '183+1104|25+1561', + ); + test( + 'HB-DEVA-joiners-8', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‍', + '183+1204|3+0', + ); + test( + 'HB-DEVA-joiners-9', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‌क', + '25+1561|81@-454,0+0|3+0|25+1561', + ); + test( + 'HB-DEVA-joiners-10', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‍क', + '183+1104|3+0|25+1561', + ); + test( + 'HB-DEVA-joiners-11', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्कि', + '558+530|183+1104|25+1561', + ); + test( + 'HB-DEVA-joiners-12', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‌कि', + '25+1561|81@-454,0+0|3+0|561+530|25+1561', + ); + test( + 'HB-DEVA-joiners-13', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‍कि', + '558+530|183+1104|3+0|25+1561', + ); + test( + 'HB-DEVA-joiners-14', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्ष', + '179+1458', + ); + test( + 'HB-DEVA-joiners-15', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‌ष', + '25+1561|81@-454,0+0|3+0|59+1184', + ); + test( + 'HB-DEVA-joiners-16', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‍ष', + '183+1204|3+0|59+1184', + ); + test( + 'HB-DEVA-joiners-17', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'द्सि', + '42+1064|81@96,0+0|563+530|60+1375', + ); + test( + 'HB-DEVA-joiners-18', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'द्‌सि', + '42+1064|81@96,0+0|3+0|563+530|60+1375', + ); + test( + 'HB-DEVA-joiners-19', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'द्‍सि', + '558+530|200+1064|60+1375', + ); }); describe('misc', function () { - test('HB-DEVA-misc-1', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क', '25+1561'); - test('HB-DEVA-misc-2', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क़', '92+1561'); - test('HB-DEVA-misc-3', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'कि', '561+530|25+1561'); - test('HB-DEVA-misc-4', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्', '25+1561|81@-454,0+0'); - test('HB-DEVA-misc-5', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्क', '183+1104|25+1561'); - test('HB-DEVA-misc-6', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्र', '254+1561'); - test('HB-DEVA-misc-7', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्र्क', '327+1204|25+1561'); - test('HB-DEVA-misc-8', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्र्‍', '327+1204|3+0'); - test('HB-DEVA-misc-9', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्ष', '179+1458'); - test('HB-DEVA-misc-10', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्ष्', '179+1458|81+0'); - test('HB-DEVA-misc-11', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‌ष', '25+1561|81@-454,0+0|3+0|59+1184'); - test('HB-DEVA-misc-12', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‍', '183+1204|3+0'); - test('HB-DEVA-misc-13', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‍ष', '183+1204|3+0|59+1184'); - test('HB-DEVA-misc-14', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'छ्र्क', '334+1435|25+1561'); - test('HB-DEVA-misc-15', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'ज्ञ्', '180+1313|81+0'); - test('HB-DEVA-misc-16', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'ट्रु', '35+1032|657@-10,0+0'); - test('HB-DEVA-misc-17', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्क', '25+1561|181@-454,0+0'); - test('HB-DEVA-misc-18', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्कि', '585+530|25+1561|606+0'); - test('HB-DEVA-misc-19', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्क्रि', '585+530|254+1561|606+0'); - test('HB-DEVA-misc-20', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्‍', '209+818'); - test('HB-DEVA-misc-21', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'ि', '67+530|135+1044'); - test('HB-DEVA-misc-22', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'फ़्र', '314+1579'); - test('HB-DEVA-misc-23', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'फ्र', '275+1579'); - test('HB-DEVA-misc-24', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'द्दि', '560+530|511+1105'); - test('HB-DEVA-misc-25', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्ष', '179+1458'); - test('HB-DEVA-misc-26', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‌ष', '25+1561|81@-454,0+0|3+0|59+1184'); - test('HB-DEVA-misc-27', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क्‍ष', '183+1204|3+0|59+1184'); - test('HB-DEVA-misc-28', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्अ्', '9+1565|81+0|181+0'); - test('HB-DEVA-misc-29', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्अ्‌', '9+1565|81+0|3+0|181+0'); - test('HB-DEVA-misc-30', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्अ्‍', '52+838|81@-48,0+0|9+1565|81+0|3+0'); - test('HB-DEVA-misc-31', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्आ्र्', '10+2095|81+0|181+0|52+838|81@-48,0+0'); - test('HB-DEVA-misc-32', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'क‌ि', '561+530|25+1561|3+0'); - test('HB-DEVA-misc-33', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'ऽं', '65+957|6+0'); - test('HB-DEVA-misc-34', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'रुँः', '413+1152|5@-314,0+0|7+558'); - test('HB-DEVA-misc-35', 'NotoSans/NotoSansDevanagari-Regular.ttf', '1ि', '558+530|748+1128'); - test('HB-DEVA-misc-36', 'NotoSans/NotoSansDevanagari-Regular.ttf', '१॑', '107+1128|85@-298,0+0'); + test( + 'HB-DEVA-misc-1', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क', + '25+1561', + ); + test( + 'HB-DEVA-misc-2', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क़', + '92+1561', + ); + test( + 'HB-DEVA-misc-3', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'कि', + '561+530|25+1561', + ); + test( + 'HB-DEVA-misc-4', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्', + '25+1561|81@-454,0+0', + ); + test( + 'HB-DEVA-misc-5', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्क', + '183+1104|25+1561', + ); + test( + 'HB-DEVA-misc-6', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्र', + '254+1561', + ); + test( + 'HB-DEVA-misc-7', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्र्क', + '327+1204|25+1561', + ); + test( + 'HB-DEVA-misc-8', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्र्‍', + '327+1204|3+0', + ); + test( + 'HB-DEVA-misc-9', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्ष', + '179+1458', + ); + test( + 'HB-DEVA-misc-10', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्ष्', + '179+1458|81+0', + ); + test( + 'HB-DEVA-misc-11', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‌ष', + '25+1561|81@-454,0+0|3+0|59+1184', + ); + test( + 'HB-DEVA-misc-12', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‍', + '183+1204|3+0', + ); + test( + 'HB-DEVA-misc-13', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‍ष', + '183+1204|3+0|59+1184', + ); + test( + 'HB-DEVA-misc-14', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'छ्र्क', + '334+1435|25+1561', + ); + test( + 'HB-DEVA-misc-15', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'ज्ञ्', + '180+1313|81+0', + ); + test( + 'HB-DEVA-misc-16', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'ट्रु', + '35+1032|657@-10,0+0', + ); + test( + 'HB-DEVA-misc-17', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्क', + '25+1561|181@-454,0+0', + ); + test( + 'HB-DEVA-misc-18', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्कि', + '585+530|25+1561|606+0', + ); + test( + 'HB-DEVA-misc-19', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्क्रि', + '585+530|254+1561|606+0', + ); + test( + 'HB-DEVA-misc-20', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्‍', + '209+818', + ); + test( + 'HB-DEVA-misc-21', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'ि', + '67+530|135+1044', + ); + test( + 'HB-DEVA-misc-22', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'फ़्र', + '314+1579', + ); + test( + 'HB-DEVA-misc-23', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'फ्र', + '275+1579', + ); + test( + 'HB-DEVA-misc-24', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'द्दि', + '560+530|511+1105', + ); + test( + 'HB-DEVA-misc-25', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्ष', + '179+1458', + ); + test( + 'HB-DEVA-misc-26', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‌ष', + '25+1561|81@-454,0+0|3+0|59+1184', + ); + test( + 'HB-DEVA-misc-27', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क्‍ष', + '183+1204|3+0|59+1184', + ); + test( + 'HB-DEVA-misc-28', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्अ्', + '9+1565|81+0|181+0', + ); + test( + 'HB-DEVA-misc-29', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्अ्‌', + '9+1565|81+0|3+0|181+0', + ); + test( + 'HB-DEVA-misc-30', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्अ्‍', + '52+838|81@-48,0+0|9+1565|81+0|3+0', + ); + test( + 'HB-DEVA-misc-31', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्आ्र्', + '10+2095|81+0|181+0|52+838|81@-48,0+0', + ); + test( + 'HB-DEVA-misc-32', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'क‌ि', + '561+530|25+1561|3+0', + ); + test( + 'HB-DEVA-misc-33', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'ऽं', + '65+957|6+0', + ); + test( + 'HB-DEVA-misc-34', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'रुँः', + '413+1152|5@-314,0+0|7+558', + ); + test( + 'HB-DEVA-misc-35', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + '1ि', + '558+530|748+1128', + ); + test( + 'HB-DEVA-misc-36', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + '१॑', + '107+1128|85@-298,0+0', + ); }); describe('dotted circle', function () { - test('HB-DEVA-dottedcircle-1', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्◌', '135+1044|181+0'); - test('HB-DEVA-dottedcircle-2', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्◌्च', '135+1044|81+0|181+0|30+1299'); - test('HB-DEVA-dottedcircle-3', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्◌्च्छे', '135+1044|81+0|181+0|188+810|31+1435|75@-156,0+0'); - test('HB-DEVA-dottedcircle-4', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्◌ि', '67+530|135+1044|181+0'); - test('HB-DEVA-dottedcircle-5', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्◌्', '135+1044|81+0|181+0'); - test('HB-DEVA-dottedcircle-6', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र्◌़', '135+1044|64+0|181+0'); - test('HB-DEVA-dottedcircle-7', 'NotoSans/NotoSansDevanagari-Regular.ttf', '◌्च्छे', '135+1044|81+0|188+810|31+1435|75@-156,0+0'); - test('HB-DEVA-dottedcircle-8', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'र् ', '52+838|81@-48,0+0|3+532'); + test( + 'HB-DEVA-dottedcircle-1', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्◌', + '135+1044|181+0', + ); + test( + 'HB-DEVA-dottedcircle-2', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्◌्च', + '135+1044|81+0|181+0|30+1299', + ); + test( + 'HB-DEVA-dottedcircle-3', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्◌्च्छे', + '135+1044|81+0|181+0|188+810|31+1435|75@-156,0+0', + ); + test( + 'HB-DEVA-dottedcircle-4', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्◌ि', + '67+530|135+1044|181+0', + ); + test( + 'HB-DEVA-dottedcircle-5', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्◌्', + '135+1044|81+0|181+0', + ); + test( + 'HB-DEVA-dottedcircle-6', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र्◌़', + '135+1044|64+0|181+0', + ); + test( + 'HB-DEVA-dottedcircle-7', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + '◌्च्छे', + '135+1044|81+0|188+810|31+1435|75@-156,0+0', + ); + test( + 'HB-DEVA-dottedcircle-8', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'र् ', + '52+838|81@-48,0+0|3+532', + ); }); describe('eyelash', function () { - test('HB-DEVA-eyelash-1', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'त्र्क', '347+782|25+1561'); - test('HB-DEVA-eyelash-2', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'त्र्‍क', '347+782|3+0|25+1561'); - test('HB-DEVA-eyelash-3', 'NotoSans/NotoSansDevanagari-Regular.ttf', 'त्र्‌क', '269+1130|81+0|3+0|25+1561'); + test( + 'HB-DEVA-eyelash-1', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'त्र्क', + '347+782|25+1561', + ); + test( + 'HB-DEVA-eyelash-2', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'त्र्‍क', + '347+782|3+0|25+1561', + ); + test( + 'HB-DEVA-eyelash-3', + 'NotoSans/NotoSansDevanagari-Regular.ttf', + 'त्र्‌क', + '269+1130|81+0|3+0|25+1561', + ); }); }); describe('shapes Bengali text', function () { - test('HB-BENG-1', 'NotoSans/NotoSansBengali-Regular.ttf', 'অ্য', '7+1828|198+523'); + test( + 'HB-BENG-1', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'অ্য', + '7+1828|198+523', + ); test('HB-BENG-2', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক', '19+1653'); - test('HB-BENG-3', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক়', '96+1653'); - test('HB-BENG-4', 'NotoSans/NotoSansBengali-Regular.ttf', 'কি', '54+545|19+1653'); - test('HB-BENG-5', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক্', '19+1653|64@-453,0+0'); - test('HB-BENG-6', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক্ক', '280+1575'); - test('HB-BENG-7', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক্র', '199+1905'); - test('HB-BENG-8', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক্র্ক', '199+1905|64@-436,0+0|19+1653'); - test('HB-BENG-9', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক্‌ক', '19+1653|64@-453,0+0|3+0|19+1653'); - test('HB-BENG-10', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক্‍ক', '130+1397|3+0|19+1653'); - test('HB-BENG-11', 'NotoSans/NotoSansBengali-Regular.ttf', 'দ্য', '36+1235|198+523'); - test('HB-BENG-12', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্ক', '149+756|19+1653'); - test('HB-BENG-13', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্ধ', '360+1586'); - test('HB-BENG-14', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্ব', '260+1253'); - test('HB-BENG-15', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্য', '38+1236|198+523'); - test('HB-BENG-16', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্র', '219+1357'); - test('HB-BENG-17', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‌ক', '38+1236|64+0|3+0|19+1653'); - test('HB-BENG-18', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‌ধ', '38+1236|64+0|3+0|37+1221'); - test('HB-BENG-19', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‌ব', '38+1236|64+0|3+0|41+1221'); - test('HB-BENG-20', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‌র', '38+1236|64+0|3+0|45+1221'); - test('HB-BENG-21', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‍ক', '149+756|3+0|19+1653'); - test('HB-BENG-22', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‍ধ', '149+756|3+0|37+1221'); - test('HB-BENG-23', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‍ব', '149+756|3+0|41+1221'); - test('HB-BENG-24', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‍র', '149+756|3+0|45+1221'); - test('HB-BENG-25', 'NotoSans/NotoSansBengali-Regular.ttf', 'য্', '44+1282|64+0'); - test('HB-BENG-26', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্ক', '19+1653|127@-453,0+0'); - test('HB-BENG-27', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্কি', '54+545|19+1653|127@-453,0+0'); - test('HB-BENG-28', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্কৌ', '446+708|19+1653|127@-453,0+0|66+545'); - test('HB-BENG-29', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্ন্‍', '45+1221|64+0|38+1236|64+0|3+0'); - test('HB-BENG-30', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্ব্ব', '263+2001|127+0'); - test('HB-BENG-31', 'NotoSans/NotoSansBengali-Regular.ttf', 'শ্য', '47+1386|198+523'); - test('HB-BENG-32', 'NotoSans/NotoSansBengali-Regular.ttf', 'ষ্য', '48+1296|198+523'); - test('HB-BENG-33', 'NotoSans/NotoSansBengali-Regular.ttf', 'স্য', '49+1397|198+523'); - test('HB-BENG-34', 'NotoSans/NotoSansBengali-Regular.ttf', 'ি', '54+545|575+1044'); - test('HB-BENG-35', 'NotoSans/NotoSansBengali-Regular.ttf', 'কো', '446+708|19+1653|53+545'); - test('HB-BENG-36', 'NotoSans/NotoSansBengali-Regular.ttf', 'কৌ', '446+708|19+1653|66+545'); - test('HB-BENG-37', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক্র্ক', '199+1905|64@-436,0+0|19+1653'); - test('HB-BENG-38', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‌ক', '38+1236|64+0|3+0|19+1653'); - test('HB-BENG-39', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‌ব', '38+1236|64+0|3+0|41+1221'); - test('HB-BENG-40', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‍ক', '149+756|3+0|19+1653'); - test('HB-BENG-41', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‍ব', '149+756|3+0|41+1221'); - test('HB-BENG-42', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্‍র', '149+756|3+0|45+1221'); - test('HB-BENG-43', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্কাং', '19+1653|127@-453,0+0|53+545|5+938'); - test('HB-BENG-44', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্কাঃ', '19+1653|127@-453,0+0|53+545|6+938'); - test('HB-BENG-45', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্কৌ', '446+708|19+1653|127@-453,0+0|66+545'); - test('HB-BENG-46', 'NotoSans/NotoSansBengali-Regular.ttf', 'র্ভ', '42+1476|127@-339,0+0'); - test('HB-BENG-47', 'NotoSans/NotoSansBengali-Regular.ttf', 'ৰ্ভ', '42+1476|127@-339,0+0'); - test('HB-BENG-48', 'NotoSans/NotoSansBengali-Regular.ttf', 'ৱ্ভ', '85+1221|64+0|42+1476'); - test('HB-BENG-49', 'NotoSans/NotoSansBengali-Regular.ttf', 'অৗ', '7+1828|66+545'); - test('HB-BENG-50', 'NotoSans/NotoSansBengali-Regular.ttf', 'ন্ত্র', '365+1403'); - test('HB-BENG-51', 'NotoSans/NotoSansBengali-Regular.ttf', 'ত্যু', '34+1447|518@-222,0+0|198+523'); - test('HB-BENG-52', 'NotoSans/NotoSansBengali-Regular.ttf', 'চ্য্র', '135+1014|225+1408'); - test('HB-BENG-53', 'NotoSans/NotoSansBengali-Regular.ttf', 'ক্‍ষ', '130+1397|3+0|48+1296'); + test( + 'HB-BENG-3', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক়', + '96+1653', + ); + test( + 'HB-BENG-4', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'কি', + '54+545|19+1653', + ); + test( + 'HB-BENG-5', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক্', + '19+1653|64@-453,0+0', + ); + test( + 'HB-BENG-6', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক্ক', + '280+1575', + ); + test( + 'HB-BENG-7', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক্র', + '199+1905', + ); + test( + 'HB-BENG-8', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক্র্ক', + '199+1905|64@-436,0+0|19+1653', + ); + test( + 'HB-BENG-9', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক্‌ক', + '19+1653|64@-453,0+0|3+0|19+1653', + ); + test( + 'HB-BENG-10', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক্‍ক', + '130+1397|3+0|19+1653', + ); + test( + 'HB-BENG-11', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'দ্য', + '36+1235|198+523', + ); + test( + 'HB-BENG-12', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্ক', + '149+756|19+1653', + ); + test( + 'HB-BENG-13', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্ধ', + '360+1586', + ); + test( + 'HB-BENG-14', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্ব', + '260+1253', + ); + test( + 'HB-BENG-15', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্য', + '38+1236|198+523', + ); + test( + 'HB-BENG-16', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্র', + '219+1357', + ); + test( + 'HB-BENG-17', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‌ক', + '38+1236|64+0|3+0|19+1653', + ); + test( + 'HB-BENG-18', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‌ধ', + '38+1236|64+0|3+0|37+1221', + ); + test( + 'HB-BENG-19', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‌ব', + '38+1236|64+0|3+0|41+1221', + ); + test( + 'HB-BENG-20', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‌র', + '38+1236|64+0|3+0|45+1221', + ); + test( + 'HB-BENG-21', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‍ক', + '149+756|3+0|19+1653', + ); + test( + 'HB-BENG-22', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‍ধ', + '149+756|3+0|37+1221', + ); + test( + 'HB-BENG-23', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‍ব', + '149+756|3+0|41+1221', + ); + test( + 'HB-BENG-24', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‍র', + '149+756|3+0|45+1221', + ); + test( + 'HB-BENG-25', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'য্', + '44+1282|64+0', + ); + test( + 'HB-BENG-26', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্ক', + '19+1653|127@-453,0+0', + ); + test( + 'HB-BENG-27', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্কি', + '54+545|19+1653|127@-453,0+0', + ); + test( + 'HB-BENG-28', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্কৌ', + '446+708|19+1653|127@-453,0+0|66+545', + ); + test( + 'HB-BENG-29', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্ন্‍', + '45+1221|64+0|38+1236|64+0|3+0', + ); + test( + 'HB-BENG-30', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্ব্ব', + '263+2001|127+0', + ); + test( + 'HB-BENG-31', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'শ্য', + '47+1386|198+523', + ); + test( + 'HB-BENG-32', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ষ্য', + '48+1296|198+523', + ); + test( + 'HB-BENG-33', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'স্য', + '49+1397|198+523', + ); + test( + 'HB-BENG-34', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ি', + '54+545|575+1044', + ); + test( + 'HB-BENG-35', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'কো', + '446+708|19+1653|53+545', + ); + test( + 'HB-BENG-36', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'কৌ', + '446+708|19+1653|66+545', + ); + test( + 'HB-BENG-37', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক্র্ক', + '199+1905|64@-436,0+0|19+1653', + ); + test( + 'HB-BENG-38', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‌ক', + '38+1236|64+0|3+0|19+1653', + ); + test( + 'HB-BENG-39', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‌ব', + '38+1236|64+0|3+0|41+1221', + ); + test( + 'HB-BENG-40', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‍ক', + '149+756|3+0|19+1653', + ); + test( + 'HB-BENG-41', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‍ব', + '149+756|3+0|41+1221', + ); + test( + 'HB-BENG-42', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্‍র', + '149+756|3+0|45+1221', + ); + test( + 'HB-BENG-43', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্কাং', + '19+1653|127@-453,0+0|53+545|5+938', + ); + test( + 'HB-BENG-44', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্কাঃ', + '19+1653|127@-453,0+0|53+545|6+938', + ); + test( + 'HB-BENG-45', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্কৌ', + '446+708|19+1653|127@-453,0+0|66+545', + ); + test( + 'HB-BENG-46', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'র্ভ', + '42+1476|127@-339,0+0', + ); + test( + 'HB-BENG-47', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ৰ্ভ', + '42+1476|127@-339,0+0', + ); + test( + 'HB-BENG-48', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ৱ্ভ', + '85+1221|64+0|42+1476', + ); + test( + 'HB-BENG-49', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'অৗ', + '7+1828|66+545', + ); + test( + 'HB-BENG-50', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ন্ত্র', + '365+1403', + ); + test( + 'HB-BENG-51', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ত্যু', + '34+1447|518@-222,0+0|198+523', + ); + test( + 'HB-BENG-52', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'চ্য্র', + '135+1014|225+1408', + ); + test( + 'HB-BENG-53', + 'NotoSans/NotoSansBengali-Regular.ttf', + 'ক্‍ষ', + '130+1397|3+0|48+1296', + ); }); describe('shapes Gurmukhi text', function () { - test('HB-GURU-1', 'NotoSans/NotoSansGurmukhi-Regular.ttf', 'ਕ੍ਹ', '17+1273|111@75,0+0'); - test('HB-GURU-2', 'NotoSans/NotoSansGurmukhi-Regular.ttf', 'ਤ੍ਯੋ', '32+1110|175+1363|58+0'); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGurmukhi-Regular.ttf', + 'ਕ੍ਹ', + '17+1273|111@75,0+0', + ); + test( + 'HB-GURU-2', + 'NotoSans/NotoSansGurmukhi-Regular.ttf', + 'ਤ੍ਯੋ', + '32+1110|175+1363|58+0', + ); }); describe('shapes Gujarati text', function () { - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ગ્ષ', '132+839|52+1183'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ગ્સ', '132+839|53+1457'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ગ્હ', '132+839|54+1296'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ક', '133+899|21+1047'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ખ', '133+899|22+1528'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ગ', '133+899|23+1339'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ઘ', '133+729|24+1271'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ઙ', '133+899|25+1004'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ચ', '133+899|26+1353'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્છ', '133+899|27+1512'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્જ', '133+899|28+1786'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ઝ', '133+899|29+1430'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ઞ', '133+899|30+1417'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ટ', '133+899|31+923'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ઠ', '133+899|32+1059'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ડ', '133+899|33+986'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ઢ', '133+899|34+1056'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ણ', '133+899|35+1683'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્ત', '133+899|36+1173'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્થ', '133+899|37+1280'); - test('HB-GURU-1', 'NotoSans/NotoSansGujarati-Regular.ttf', 'ઘ્દ', '133+899|38+956'); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ગ્ષ', + '132+839|52+1183', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ગ્સ', + '132+839|53+1457', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ગ્હ', + '132+839|54+1296', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ક', + '133+899|21+1047', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ખ', + '133+899|22+1528', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ગ', + '133+899|23+1339', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ઘ', + '133+729|24+1271', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ઙ', + '133+899|25+1004', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ચ', + '133+899|26+1353', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્છ', + '133+899|27+1512', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્જ', + '133+899|28+1786', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ઝ', + '133+899|29+1430', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ઞ', + '133+899|30+1417', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ટ', + '133+899|31+923', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ઠ', + '133+899|32+1059', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ડ', + '133+899|33+986', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ઢ', + '133+899|34+1056', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ણ', + '133+899|35+1683', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્ત', + '133+899|36+1173', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્થ', + '133+899|37+1280', + ); + test( + 'HB-GURU-1', + 'NotoSans/NotoSansGujarati-Regular.ttf', + 'ઘ્દ', + '133+899|38+956', + ); }); describe('shapes Malayalam text', function () { - test('HB-MLYM-1', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'അൎത്ഥം', '6+3058|180+3448|73@-2606,0+0|4+927'); - test('HB-MLYM-2', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'അഥൎവ്വം', '6+3058|36+1835|208+1963|73@-1864,0+0|4+927'); - test('HB-MLYM-3', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ക്‍', '101+2470'); - test('HB-MLYM-4', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കായ്‌കറി', '20+2125|59+1033|46+2120|72+0|3+0|20+2125|48+1381|60+467'); - test('HB-MLYM-5', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കാര്‍ക്കോടകന്‍', '20+2125|59+1033|98+1507|67+1219|147+3085|59+1033|30+1152|20+2125|97+2173'); - test('HB-MLYM-6', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കുറ്റ്യാടി', '20+2125|62+679|203+1271|229+697|59+1033|30+1152|60+467'); - test('HB-MLYM-7', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കെ', '66+1465|20+2125'); - test('HB-MLYM-8', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കേ', '67+1219|20+2125'); - test('HB-MLYM-9', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കൈ', '68+2935|20+2125'); - test('HB-MLYM-10', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കൊ', '66+1465|20+2125|59+1033'); - test('HB-MLYM-11', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കോ', '67+1219|20+2125|59+1033'); - test('HB-MLYM-12', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കൌ', '66+1465|20+2125|74+1555'); - test('HB-MLYM-13', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ക്കെ', '66+1465|147+3085'); - test('HB-MLYM-14', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ക്കൊ', '66+1465|147+3085|59+1033'); - test('HB-MLYM-15', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ക്ത്ര', '146+409|148+3707'); - test('HB-MLYM-16', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ക്യ', '20+2125|144+497'); - test('HB-MLYM-17', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ക്വ', '20+2125|145+467'); - test('HB-MLYM-18', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ഖ്യ', '21+2047|144+497'); - test('HB-MLYM-19', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ഖ്ര', '146+469|21+2047'); - test('HB-MLYM-20', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ഗ്ദ്ധ്രോ', '22+1837|72+0|67+1219|146+444|183+2428|59+1033'); - test('HB-MLYM-21', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ട്ട', '167+1152'); - test('HB-MLYM-22', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ട്ടു്', '167+1206|225+719|72+0'); - test('HB-MLYM-23', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ണ്‍', '96+3110'); - test('HB-MLYM-24', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ണ്ട', '174+2995'); - test('HB-MLYM-25', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ത്ത', '179+3603'); - test('HB-MLYM-26', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ത്തെ', '66+1465|179+3603'); - test('HB-MLYM-27', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ത്തൊ', '66+1465|179+3603|59+1033'); - test('HB-MLYM-28', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ദ്ദ', '182+1310'); - test('HB-MLYM-29', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ന്‍', '97+2173'); - test('HB-MLYM-30', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ന്ത', '189+2734'); - test('HB-MLYM-31', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ന്ത്യ', '189+2734|144+497'); - test('HB-MLYM-32', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ന്ത്ര്യ', '146+499|189+2734|144+497'); - test('HB-MLYM-33', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'പ്ര', '146+420|41+1835'); - test('HB-MLYM-34', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'പ്ലോ', '67+1219|192+1835|59+1033'); - test('HB-MLYM-35', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'മുഖ്യമന്ത്രി', '45+1485|62+679|21+2047|144+497|45+1485|146+499|189+2734|60+467'); - test('HB-MLYM-36', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'മ്പ', '199+2447'); - test('HB-MLYM-37', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'യാത്രാകൂലി', '46+2120|59+1033|146+475|35+2077|59+1033|20+2125|63+679|49+1759|60+467'); - test('HB-MLYM-38', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'യും', '46+2050|62+659|4+927'); - test('HB-MLYM-39', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'യ്ക്കു', '46+2120|72+0|147+3010|62+679'); - test('HB-MLYM-40', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'യ്യ', '202+2120'); - test('HB-MLYM-41', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ര്', '47+1507|72+0'); - test('HB-MLYM-42', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ര്‍', '98+1507'); - test('HB-MLYM-43', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ര്ക', '47+1507|72+0|20+2125'); - test('HB-MLYM-44', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ര്യ', '47+1507|144+497'); - test('HB-MLYM-45', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ര്‍വ്വ', '98+1507|208+1963'); - test('HB-MLYM-46', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ല്‍', '99+2454'); - test('HB-MLYM-47', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ല്യ', '49+1759|144+497'); - test('HB-MLYM-48', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ല്ല', '205+1759'); - test('HB-MLYM-49', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ല്ലാം', '205+1759|59+1033|4+927'); - test('HB-MLYM-50', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'വ്വ', '208+1963'); - test('HB-MLYM-51', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ഷ്ട്രീ', '54+2354|72+0|146+519|30+1152|61+467'); - test('HB-MLYM-52', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'സോഫ്റ്റ്‌വെയര്‍', '67+1219|55+2505|59+1033|42+2312|72+0|203+1381|72+0|3+0|66+1465|52+1963|46+2120|98+1507'); - test('HB-MLYM-53', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'സ്പ്രി', '55+2505|72+0|146+420|41+1835|60+467'); - test('HB-MLYM-54', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'സ്പ്രേ', '55+2505|72+0|67+1219|146+420|41+1835'); - test('HB-MLYM-55', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'സ്പ്ലേ', '55+2505|72+0|67+1219|192+1835'); - test('HB-MLYM-56', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'സ്വാതന്ത്ര്യം', '55+2505|145+467|59+1033|35+2077|146+499|189+2734|144+497|4+927'); - test('HB-MLYM-57', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ഹാര്‍ഡ്‌വെയര്‍', '56+2437|59+1033|98+1507|32+2505|72+0|3+0|66+1465|52+1963|46+2120|98+1507'); - test('HB-MLYM-58', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ള്‍', '100+2139'); - test('HB-MLYM-59', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ള്യം', '50+1466|229+697|4+927'); - test('HB-MLYM-60', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ള്ള', '206+2906'); - test('HB-MLYM-61', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ല്‍പ്പേ', '99+2454|67+1219|191+1836'); - test('HB-MLYM-62', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'ശിം‌', '53+2130|60+467|3+0|4+927'); - test('HB-MLYM-63', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'കോം‌', '67+1219|20+2125|59+1033|3+0|4+927'); - test('HB-MLYM-64', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'യ‍്യ', '46+2120|3+0|144+497'); - test('HB-MLYM-65', 'NotoSans/NotoSansMalayalam-Regular.ttf', 'സ്റ്റ്', '214+2505|72+0'); + test( + 'HB-MLYM-1', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'അൎത്ഥം', + '6+3058|180+3448|73@-2606,0+0|4+927', + ); + test( + 'HB-MLYM-2', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'അഥൎവ്വം', + '6+3058|36+1835|208+1963|73@-1864,0+0|4+927', + ); + test( + 'HB-MLYM-3', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ക്‍', + '101+2470', + ); + test( + 'HB-MLYM-4', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കായ്‌കറി', + '20+2125|59+1033|46+2120|72+0|3+0|20+2125|48+1381|60+467', + ); + test( + 'HB-MLYM-5', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കാര്‍ക്കോടകന്‍', + '20+2125|59+1033|98+1507|67+1219|147+3085|59+1033|30+1152|20+2125|97+2173', + ); + test( + 'HB-MLYM-6', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കുറ്റ്യാടി', + '20+2125|62+679|203+1271|229+697|59+1033|30+1152|60+467', + ); + test( + 'HB-MLYM-7', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കെ', + '66+1465|20+2125', + ); + test( + 'HB-MLYM-8', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കേ', + '67+1219|20+2125', + ); + test( + 'HB-MLYM-9', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കൈ', + '68+2935|20+2125', + ); + test( + 'HB-MLYM-10', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കൊ', + '66+1465|20+2125|59+1033', + ); + test( + 'HB-MLYM-11', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കോ', + '67+1219|20+2125|59+1033', + ); + test( + 'HB-MLYM-12', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കൌ', + '66+1465|20+2125|74+1555', + ); + test( + 'HB-MLYM-13', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ക്കെ', + '66+1465|147+3085', + ); + test( + 'HB-MLYM-14', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ക്കൊ', + '66+1465|147+3085|59+1033', + ); + test( + 'HB-MLYM-15', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ക്ത്ര', + '146+409|148+3707', + ); + test( + 'HB-MLYM-16', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ക്യ', + '20+2125|144+497', + ); + test( + 'HB-MLYM-17', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ക്വ', + '20+2125|145+467', + ); + test( + 'HB-MLYM-18', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ഖ്യ', + '21+2047|144+497', + ); + test( + 'HB-MLYM-19', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ഖ്ര', + '146+469|21+2047', + ); + test( + 'HB-MLYM-20', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ഗ്ദ്ധ്രോ', + '22+1837|72+0|67+1219|146+444|183+2428|59+1033', + ); + test( + 'HB-MLYM-21', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ട്ട', + '167+1152', + ); + test( + 'HB-MLYM-22', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ട്ടു്', + '167+1206|225+719|72+0', + ); + test( + 'HB-MLYM-23', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ണ്‍', + '96+3110', + ); + test( + 'HB-MLYM-24', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ണ്ട', + '174+2995', + ); + test( + 'HB-MLYM-25', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ത്ത', + '179+3603', + ); + test( + 'HB-MLYM-26', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ത്തെ', + '66+1465|179+3603', + ); + test( + 'HB-MLYM-27', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ത്തൊ', + '66+1465|179+3603|59+1033', + ); + test( + 'HB-MLYM-28', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ദ്ദ', + '182+1310', + ); + test( + 'HB-MLYM-29', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ന്‍', + '97+2173', + ); + test( + 'HB-MLYM-30', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ന്ത', + '189+2734', + ); + test( + 'HB-MLYM-31', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ന്ത്യ', + '189+2734|144+497', + ); + test( + 'HB-MLYM-32', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ന്ത്ര്യ', + '146+499|189+2734|144+497', + ); + test( + 'HB-MLYM-33', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'പ്ര', + '146+420|41+1835', + ); + test( + 'HB-MLYM-34', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'പ്ലോ', + '67+1219|192+1835|59+1033', + ); + test( + 'HB-MLYM-35', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'മുഖ്യമന്ത്രി', + '45+1485|62+679|21+2047|144+497|45+1485|146+499|189+2734|60+467', + ); + test( + 'HB-MLYM-36', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'മ്പ', + '199+2447', + ); + test( + 'HB-MLYM-37', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'യാത്രാകൂലി', + '46+2120|59+1033|146+475|35+2077|59+1033|20+2125|63+679|49+1759|60+467', + ); + test( + 'HB-MLYM-38', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'യും', + '46+2050|62+659|4+927', + ); + test( + 'HB-MLYM-39', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'യ്ക്കു', + '46+2120|72+0|147+3010|62+679', + ); + test( + 'HB-MLYM-40', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'യ്യ', + '202+2120', + ); + test( + 'HB-MLYM-41', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ര്', + '47+1507|72+0', + ); + test( + 'HB-MLYM-42', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ര്‍', + '98+1507', + ); + test( + 'HB-MLYM-43', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ര്ക', + '47+1507|72+0|20+2125', + ); + test( + 'HB-MLYM-44', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ര്യ', + '47+1507|144+497', + ); + test( + 'HB-MLYM-45', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ര്‍വ്വ', + '98+1507|208+1963', + ); + test( + 'HB-MLYM-46', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ല്‍', + '99+2454', + ); + test( + 'HB-MLYM-47', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ല്യ', + '49+1759|144+497', + ); + test( + 'HB-MLYM-48', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ല്ല', + '205+1759', + ); + test( + 'HB-MLYM-49', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ല്ലാം', + '205+1759|59+1033|4+927', + ); + test( + 'HB-MLYM-50', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'വ്വ', + '208+1963', + ); + test( + 'HB-MLYM-51', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ഷ്ട്രീ', + '54+2354|72+0|146+519|30+1152|61+467', + ); + test( + 'HB-MLYM-52', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'സോഫ്റ്റ്‌വെയര്‍', + '67+1219|55+2505|59+1033|42+2312|72+0|203+1381|72+0|3+0|66+1465|52+1963|46+2120|98+1507', + ); + test( + 'HB-MLYM-53', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'സ്പ്രി', + '55+2505|72+0|146+420|41+1835|60+467', + ); + test( + 'HB-MLYM-54', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'സ്പ്രേ', + '55+2505|72+0|67+1219|146+420|41+1835', + ); + test( + 'HB-MLYM-55', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'സ്പ്ലേ', + '55+2505|72+0|67+1219|192+1835', + ); + test( + 'HB-MLYM-56', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'സ്വാതന്ത്ര്യം', + '55+2505|145+467|59+1033|35+2077|146+499|189+2734|144+497|4+927', + ); + test( + 'HB-MLYM-57', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ഹാര്‍ഡ്‌വെയര്‍', + '56+2437|59+1033|98+1507|32+2505|72+0|3+0|66+1465|52+1963|46+2120|98+1507', + ); + test( + 'HB-MLYM-58', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ള്‍', + '100+2139', + ); + test( + 'HB-MLYM-59', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ള്യം', + '50+1466|229+697|4+927', + ); + test( + 'HB-MLYM-60', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ള്ള', + '206+2906', + ); + test( + 'HB-MLYM-61', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ല്‍പ്പേ', + '99+2454|67+1219|191+1836', + ); + test( + 'HB-MLYM-62', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'ശിം‌', + '53+2130|60+467|3+0|4+927', + ); + test( + 'HB-MLYM-63', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'കോം‌', + '67+1219|20+2125|59+1033|3+0|4+927', + ); + test( + 'HB-MLYM-64', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'യ‍്യ', + '46+2120|3+0|144+497', + ); + test( + 'HB-MLYM-65', + 'NotoSans/NotoSansMalayalam-Regular.ttf', + 'സ്റ്റ്', + '214+2505|72+0', + ); }); describe('shapes Oriya text', function () { - test('HB-ORYA-1', 'NotoSans/NotoSansOriya-Regular.ttf', 'କ୍ତ୍ର', '165+1354|527@-225,0+0'); - test('HB-ORYA-2', 'NotoSans/NotoSansOriya-Regular.ttf', 'ତ୍ତ୍ବ', '195+1397|150@-333,0+0'); - test('HB-ORYA-3', 'NotoSans/NotoSansOriya-Regular.ttf', 'ନ୍ତ୍ବ', '206+1298|525@-280,0+0'); - test('HB-ORYA-4', 'NotoSans/NotoSansOriya-Regular.ttf', 'ନ୍ତ୍ର', '38+1298|161@-280,0+0'); - test('HB-ORYA-5', 'NotoSans/NotoSansOriya-Regular.ttf', 'ନ୍ତ୍ର୍ଯ', '38+1298|161@-280,0+0|162+768'); - test('HB-ORYA-6', 'NotoSans/NotoSansOriya-Regular.ttf', 'ସ୍ତ୍ର', '51+1317|161+0'); - test('HB-ORYA-7', 'NotoSans/NotoSansOriya-Regular.ttf', 'ମୁଁ', '43+1327|4+0|58+0'); - test('HB-ORYA-8', 'NotoSans/NotoSansOriya-Regular.ttf', 'ମୁଂ', '43+1327|58+0|5+618'); + test( + 'HB-ORYA-1', + 'NotoSans/NotoSansOriya-Regular.ttf', + 'କ୍ତ୍ର', + '165+1354|527@-225,0+0', + ); + test( + 'HB-ORYA-2', + 'NotoSans/NotoSansOriya-Regular.ttf', + 'ତ୍ତ୍ବ', + '195+1397|150@-333,0+0', + ); + test( + 'HB-ORYA-3', + 'NotoSans/NotoSansOriya-Regular.ttf', + 'ନ୍ତ୍ବ', + '206+1298|525@-280,0+0', + ); + test( + 'HB-ORYA-4', + 'NotoSans/NotoSansOriya-Regular.ttf', + 'ନ୍ତ୍ର', + '38+1298|161@-280,0+0', + ); + test( + 'HB-ORYA-5', + 'NotoSans/NotoSansOriya-Regular.ttf', + 'ନ୍ତ୍ର୍ଯ', + '38+1298|161@-280,0+0|162+768', + ); + test( + 'HB-ORYA-6', + 'NotoSans/NotoSansOriya-Regular.ttf', + 'ସ୍ତ୍ର', + '51+1317|161+0', + ); + test( + 'HB-ORYA-7', + 'NotoSans/NotoSansOriya-Regular.ttf', + 'ମୁଁ', + '43+1327|4+0|58+0', + ); + test( + 'HB-ORYA-8', + 'NotoSans/NotoSansOriya-Regular.ttf', + 'ମୁଂ', + '43+1327|58+0|5+618', + ); }); describe('shapes Khmer text', function () { - test('HB-KHMR-1', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ខ្មែ', '108+588|45+1300|169+0'); - test('HB-KHMR-2', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ជា', '51+1300|96+588'); - test('HB-KHMR-3', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ថ្ងៃ', '109+588|60+1300|148+0'); - test('HB-KHMR-4', 'NotoSans/NotoSansKhmer-Regular.ttf', 'មា', '68+1300|96+588'); - test('HB-KHMR-5', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ម្ពុ', '68+1300|167+0|177+0'); + test( + 'HB-KHMR-1', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ខ្មែ', + '108+588|45+1300|169+0', + ); + test( + 'HB-KHMR-2', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ជា', + '51+1300|96+588', + ); + test( + 'HB-KHMR-3', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ថ្ងៃ', + '109+588|60+1300|148+0', + ); + test( + 'HB-KHMR-4', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'មា', + '68+1300|96+588', + ); + test( + 'HB-KHMR-5', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ម្ពុ', + '68+1300|167+0|177+0', + ); test('HB-KHMR-6', 'NotoSans/NotoSansKhmer-Regular.ttf', 'រ', '70+588'); - test('HB-KHMR-7', 'NotoSans/NotoSansKhmer-Regular.ttf', 'រី', '70+588|194+0'); - test('HB-KHMR-8', 'NotoSans/NotoSansKhmer-Regular.ttf', 'រ៍', '70+588|199+0'); - test('HB-KHMR-9', 'NotoSans/NotoSansKhmer-Regular.ttf', 'សៅ', '107+588|75+1900|111+588'); - test('HB-KHMR-10', 'NotoSans/NotoSansKhmer-Regular.ttf', 'រ្ឥ', '70+588|124+0|81+1300'); - test('HB-KHMR-11', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ងឹ្ឈ', '48+1300|99+0|152+588'); - test('HB-KHMR-12', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ង្ឈឹ', '48+1300|152+588|99+0'); - test('HB-KHMR-13', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ង្គ្រ', '189+588|48+1300|146+0'); - test('HB-KHMR-14', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ង្រ្គ', '189+588|48+1300|146+0'); - test('HB-KHMR-15', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ម៉្លេះ', '107+588|68+1300|115+0|172+0|113+850'); - test('HB-KHMR-16', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ម‌៉្លេះ', '107+588|68+1300|3+0|115+0|172+0|113+850'); - test('HB-KHMR-17', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ប៊័', '64+1300|116+0|122+0'); - test('HB-KHMR-18', 'NotoSans/NotoSansKhmer-Regular.ttf', 'នែ៎', '108+588|63+1300|120+0'); - test('HB-KHMR-19', 'NotoSans/NotoSansKhmer-Regular.ttf', 'កេ្រ', '107+588|171+588|44+1300'); - test('HB-KHMR-20', 'NotoSans/NotoSansKhmer-Regular.ttf', 'កៀ្រ', '171+588|107+588|44+1300|106+588'); - test('HB-KHMR-21', 'NotoSans/NotoSansKhmer-Regular.ttf', 'កោ្រ', '171+588|107+588|44+1300|110+588'); - test('HB-KHMR-22', 'NotoSans/NotoSansKhmer-Regular.ttf', 'កៅ្រ', '171+588|107+588|44+1300|111+588'); - test('HB-KHMR-23', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ព៑ា', '66+1300|123+0|96+588'); - - test('decomposes split matras', 'NotoSans/NotoSansKhmer-Regular.ttf', 'ដើម្បីឲ្យបានកាន់តែប្រសើរឡើងសម្រាប់ការធ្វើដំណើររបស់ភ្ញៀវទេសចរណ៍', '107+588|54+1300|104+0|68+1300|165+588|98+0|94+1300|170+588|188+1300|96+588|63+1300|44+1300|96+588|63+1300|117+0|108+588|59+1300|171+588|64+1300|107+588|75+1900|104+0|70+588|107+588|77+1900|104+0|48+1300|75+1900|171+588|68+1300|96+588|64+1300|117+0|44+1300|96+588|70+588|107+588|62+1300|173+0|104+0|54+1300|112+0|107+588|58+2538|104+0|70+588|70+588|64+1300|75+1900|117+0|107+588|67+1300|153+0|192+588|72+588|107+588|61+1300|75+1900|49+1300|70+588|58+2538|119+0'); + test( + 'HB-KHMR-7', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'រី', + '70+588|194+0', + ); + test( + 'HB-KHMR-8', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'រ៍', + '70+588|199+0', + ); + test( + 'HB-KHMR-9', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'សៅ', + '107+588|75+1900|111+588', + ); + test( + 'HB-KHMR-10', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'រ្ឥ', + '70+588|124+0|81+1300', + ); + test( + 'HB-KHMR-11', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ងឹ្ឈ', + '48+1300|99+0|152+588', + ); + test( + 'HB-KHMR-12', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ង្ឈឹ', + '48+1300|152+588|99+0', + ); + test( + 'HB-KHMR-13', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ង្គ្រ', + '189+588|48+1300|146+0', + ); + test( + 'HB-KHMR-14', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ង្រ្គ', + '189+588|48+1300|146+0', + ); + test( + 'HB-KHMR-15', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ម៉្លេះ', + '107+588|68+1300|115+0|172+0|113+850', + ); + test( + 'HB-KHMR-16', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ម‌៉្លេះ', + '107+588|68+1300|3+0|115+0|172+0|113+850', + ); + test( + 'HB-KHMR-17', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ប៊័', + '64+1300|116+0|122+0', + ); + test( + 'HB-KHMR-18', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'នែ៎', + '108+588|63+1300|120+0', + ); + test( + 'HB-KHMR-19', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'កេ្រ', + '107+588|171+588|44+1300', + ); + test( + 'HB-KHMR-20', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'កៀ្រ', + '171+588|107+588|44+1300|106+588', + ); + test( + 'HB-KHMR-21', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'កោ្រ', + '171+588|107+588|44+1300|110+588', + ); + test( + 'HB-KHMR-22', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'កៅ្រ', + '171+588|107+588|44+1300|111+588', + ); + test( + 'HB-KHMR-23', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ព៑ា', + '66+1300|123+0|96+588', + ); + + test( + 'decomposes split matras', + 'NotoSans/NotoSansKhmer-Regular.ttf', + 'ដើម្បីឲ្យបានកាន់តែប្រសើរឡើងសម្រាប់ការធ្វើដំណើររបស់ភ្ញៀវទេសចរណ៍', + '107+588|54+1300|104+0|68+1300|165+588|98+0|94+1300|170+588|188+1300|96+588|63+1300|44+1300|96+588|63+1300|117+0|108+588|59+1300|171+588|64+1300|107+588|75+1900|104+0|70+588|107+588|77+1900|104+0|48+1300|75+1900|171+588|68+1300|96+588|64+1300|117+0|44+1300|96+588|70+588|107+588|62+1300|173+0|104+0|54+1300|112+0|107+588|58+2538|104+0|70+588|70+588|64+1300|75+1900|117+0|107+588|67+1300|153+0|192+588|72+588|107+588|61+1300|75+1900|49+1300|70+588|58+2538|119+0', + ); }); }); describe('universal shaping engine', function () { describe('shapes balinese text', function () { // Tests from https://github.com/unicode-org/text-rendering-tests - test('SHBALI-1/1', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᬸᬀ", '23+2275|60@5,0+0|4@-95,0+0'); - test('SHBALI-1/2', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬕ᭄ᬖᬂ", '25+2237|132+0|6@-307,0+0'); - test('SHBALI-1/3', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬘᬻ", '28+1627|62@3,0+0|57+916'); - test('SHBALI-1/4', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬙᭀ", '66+990|29+2155|57+916'); - test('SHBALI-1/5', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬚᬿ", '67+990|30+1800'); - test('SHBALI-1/6', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬔᬶ", '24+2316|58@-620,0+0'); - test('SHBALI-1/7', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬓᬁ", '23+2275|129+0|5@-95,0+0'); - test('SHBALI-1/8', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬛᬁ", '23+2275|137+0|5@550,370+0'); - test('SHBALI-1/9', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬦᬃ", '23+2275|148+0|7@-245,0+0'); - test('SHBALI-1/10', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬓᬸ", '23+2275|129+0|60@0,-1000+0'); - test('SHBALI-1/11', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬓᬼ", '23+2275|129+0|70@35,0+0|170@5,0+0'); - test('SHBALI-1/12', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬓᬽ", '23+2275|129+0|70@35,0+0|170@5,0+0|57+916'); - test('SHBALI-1/13', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᬾ", '66+990|23+2275'); - test('SHBALI-1/14', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᬶᬾ", '23+2275|58@-95,0+0|66+990|128+1127'); - test('SHBALI-1/15', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᬸᬾ", '23+2275|60@5,0+0|66+990|128+1127'); - test('SHBALI-1/16', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬕᬾ", '66+990|23+2275|131+0'); - test('SHBALI-1/17', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᭀ", '66+990|23+2275|57+916'); - test('SHBALI-1/18', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᬾ", '66+990|23+2275'); - test('SHBALI-1/19', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᬾᬶ", '66+990|23+2275|58@-95,0+0'); - test('SHBALI-1/20', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᬾᬸ", '66+990|23+2275|60@5,0+0'); - test('SHBALI-1/21', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬕᬾ", '66+990|23+2275|131+0'); - test('SHBALI-1/22', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓᭀ", '66+990|23+2275|57+916'); - - test('SHBALI-2/1', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬧᬾ", '66+990|23+2275|149+1315'); - test('SHBALI-2/2', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬨᬿ", '67+990|23+2275|150+1228'); - test('SHBALI-2/3', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬱᬾ", '66+990|23+2275|159+1315'); - test('SHBALI-2/4', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬲᬾ", '66+990|23+2275|60@5,0+0|149+1315'); - test('SHBALI-2/5', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᭊᬾ", '66+990|23+2275|60@5,0+0|165+1315'); - test('SHBALI-2/6', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬛ᭄ᬓ", '181+2473|129@-293,-400+0'); - test('SHBALI-2/7', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬛ᭄ᬓᬾ", '66+990|181+2473|129@-293,-400+0'); - test('SHBALI-2/8', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬛ᭄ᬓᬸᬀ", '181+2473|129@-293,-400+0|60@-293,-1400+0|4@-722,0+0'); - test('SHBALI-2/9', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬓᬸ", '23+2275|129+0|60@0,-1000+0'); - test('SHBALI-2/10', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬛᬹ", '23+2275|137+0|61@308,-1000+0'); - test('SHBALI-2/11', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᬱᬺ", '23+2275|159+1315|62+0'); - test('SHBALI-2/12', 'NotoSans/NotoSansBalinese-Regular.ttf', "ᬓ᭄ᭅᬸ", '23+2275|162+0|60@0,-1000+0'); + test( + 'SHBALI-1/1', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᬸᬀ', + '23+2275|60@5,0+0|4@-95,0+0', + ); + test( + 'SHBALI-1/2', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬕ᭄ᬖᬂ', + '25+2237|132+0|6@-307,0+0', + ); + test( + 'SHBALI-1/3', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬘᬻ', + '28+1627|62@3,0+0|57+916', + ); + test( + 'SHBALI-1/4', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬙᭀ', + '66+990|29+2155|57+916', + ); + test( + 'SHBALI-1/5', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬚᬿ', + '67+990|30+1800', + ); + test( + 'SHBALI-1/6', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬔᬶ', + '24+2316|58@-620,0+0', + ); + test( + 'SHBALI-1/7', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬓᬁ', + '23+2275|129+0|5@-95,0+0', + ); + test( + 'SHBALI-1/8', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬛᬁ', + '23+2275|137+0|5@550,370+0', + ); + test( + 'SHBALI-1/9', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬦᬃ', + '23+2275|148+0|7@-245,0+0', + ); + test( + 'SHBALI-1/10', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬓᬸ', + '23+2275|129+0|60@0,-1000+0', + ); + test( + 'SHBALI-1/11', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬓᬼ', + '23+2275|129+0|70@35,0+0|170@5,0+0', + ); + test( + 'SHBALI-1/12', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬓᬽ', + '23+2275|129+0|70@35,0+0|170@5,0+0|57+916', + ); + test( + 'SHBALI-1/13', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᬾ', + '66+990|23+2275', + ); + test( + 'SHBALI-1/14', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᬶᬾ', + '23+2275|58@-95,0+0|66+990|128+1127', + ); + test( + 'SHBALI-1/15', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᬸᬾ', + '23+2275|60@5,0+0|66+990|128+1127', + ); + test( + 'SHBALI-1/16', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬕᬾ', + '66+990|23+2275|131+0', + ); + test( + 'SHBALI-1/17', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᭀ', + '66+990|23+2275|57+916', + ); + test( + 'SHBALI-1/18', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᬾ', + '66+990|23+2275', + ); + test( + 'SHBALI-1/19', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᬾᬶ', + '66+990|23+2275|58@-95,0+0', + ); + test( + 'SHBALI-1/20', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᬾᬸ', + '66+990|23+2275|60@5,0+0', + ); + test( + 'SHBALI-1/21', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬕᬾ', + '66+990|23+2275|131+0', + ); + test( + 'SHBALI-1/22', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓᭀ', + '66+990|23+2275|57+916', + ); + + test( + 'SHBALI-2/1', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬧᬾ', + '66+990|23+2275|149+1315', + ); + test( + 'SHBALI-2/2', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬨᬿ', + '67+990|23+2275|150+1228', + ); + test( + 'SHBALI-2/3', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬱᬾ', + '66+990|23+2275|159+1315', + ); + test( + 'SHBALI-2/4', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬲᬾ', + '66+990|23+2275|60@5,0+0|149+1315', + ); + test( + 'SHBALI-2/5', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᭊᬾ', + '66+990|23+2275|60@5,0+0|165+1315', + ); + test( + 'SHBALI-2/6', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬛ᭄ᬓ', + '181+2473|129@-293,-400+0', + ); + test( + 'SHBALI-2/7', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬛ᭄ᬓᬾ', + '66+990|181+2473|129@-293,-400+0', + ); + test( + 'SHBALI-2/8', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬛ᭄ᬓᬸᬀ', + '181+2473|129@-293,-400+0|60@-293,-1400+0|4@-722,0+0', + ); + test( + 'SHBALI-2/9', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬓᬸ', + '23+2275|129+0|60@0,-1000+0', + ); + test( + 'SHBALI-2/10', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬛᬹ', + '23+2275|137+0|61@308,-1000+0', + ); + test( + 'SHBALI-2/11', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᬱᬺ', + '23+2275|159+1315|62+0', + ); + test( + 'SHBALI-2/12', + 'NotoSans/NotoSansBalinese-Regular.ttf', + 'ᬓ᭄ᭅᬸ', + '23+2275|162+0|60@0,-1000+0', + ); }); }); }); diff --git a/test/subset.js b/test/subset.js index bb01e062..0e45910a 100644 --- a/test/subset.js +++ b/test/subset.js @@ -6,7 +6,9 @@ import fs from 'fs'; describe('font subsetting', function () { describe('truetype subsetting', function () { - let font = fontkit.openSync(new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/OpenSans/OpenSans-Regular.ttf', import.meta.url), + ); it('should produce a subset', function () { let subset = font.createSubset(); @@ -17,7 +19,10 @@ describe('font subsetting', function () { let buf = subset.encode(); let f = fontkit.create(buf); assert.equal(f.numGlyphs, 5); - assert.equal(f.getGlyph(1).path.toSVG(), font.glyphsForString('h')[0].path.toSVG()); + assert.equal( + f.getGlyph(1).path.toSVG(), + font.glyphsForString('h')[0].path.toSVG(), + ); }); it('should re-encode variation glyphs', function () { @@ -31,7 +36,10 @@ describe('font subsetting', function () { let buf = subset.encode(); let f = fontkit.create(buf); - assert.equal(f.getGlyph(1).path.toSVG(), font.glyphsForString('e')[0].path.toSVG()); + assert.equal( + f.getGlyph(1).path.toSVG(), + font.glyphsForString('e')[0].path.toSVG(), + ); }); it('should handle composite glyphs', function () { @@ -41,11 +49,16 @@ describe('font subsetting', function () { let buf = subset.encode(); let f = fontkit.create(buf); assert.equal(f.numGlyphs, 4); - assert.equal(f.getGlyph(1).path.toSVG(), font.glyphsForString('é')[0].path.toSVG()); + assert.equal( + f.getGlyph(1).path.toSVG(), + font.glyphsForString('é')[0].path.toSVG(), + ); }); it('should handle fonts with long index to location format (indexToLocFormat = 1)', function () { - let font = fontkit.openSync(new URL('data/FiraSans/FiraSans-Regular.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/FiraSans/FiraSans-Regular.ttf', import.meta.url), + ); let subset = font.createSubset(); for (let glyph of font.glyphsForString('abcd')) { subset.includeGlyph(glyph); @@ -54,14 +67,22 @@ describe('font subsetting', function () { let buf = subset.encode(); let f = fontkit.create(buf); assert.equal(f.numGlyphs, 5); - assert.equal(f.getGlyph(1).path.toSVG(), font.glyphsForString('a')[0].path.toSVG()); + assert.equal( + f.getGlyph(1).path.toSVG(), + font.glyphsForString('a')[0].path.toSVG(), + ); // must test also second glyph which has an odd loca index - assert.equal(f.getGlyph(2).path.toSVG(), font.glyphsForString('b')[0].path.toSVG()); + assert.equal( + f.getGlyph(2).path.toSVG(), + font.glyphsForString('b')[0].path.toSVG(), + ); }); }); describe('CFF subsetting', function () { - let font = fontkit.openSync(new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/SourceSansPro/SourceSansPro-Regular.otf', import.meta.url), + ); it('should produce a subset', function () { let subset = font.createSubset(); @@ -77,11 +98,16 @@ describe('font subsetting', function () { let CFFGlyph = iterable[0].constructor; let cff = new CFFFont(stream); let glyph = new CFFGlyph(1, [], { stream, 'CFF ': cff }); - assert.equal(glyph.path.toSVG(), font.glyphsForString('h')[0].path.toSVG()); + assert.equal( + glyph.path.toSVG(), + font.glyphsForString('h')[0].path.toSVG(), + ); }); it('should handle CID fonts', function () { - let f = fontkit.openSync(new URL('data/NotoSansCJK/NotoSansCJKkr-Regular.otf', import.meta.url)); + let f = fontkit.openSync( + new URL('data/NotoSansCJK/NotoSansCJKkr-Regular.otf', import.meta.url), + ); let subset = f.createSubset(); let iterable = f.glyphsForString('갈휸'); for (let i = 0; i < iterable.length; i++) { @@ -101,7 +127,9 @@ describe('font subsetting', function () { }); it('should produce a subset with asian punctuation corretly', function () { - const koreanFont = fontkit.openSync(new URL('data/NotoSansCJK/NotoSansCJKkr-Regular.otf', import.meta.url)); + const koreanFont = fontkit.openSync( + new URL('data/NotoSansCJK/NotoSansCJKkr-Regular.otf', import.meta.url), + ); const subset = koreanFont.createSubset(); const iterable = koreanFont.glyphsForString('a。d'); for (let i = 0; i < iterable.length; i++) { @@ -115,11 +143,20 @@ describe('font subsetting', function () { let CFFGlyph = iterable[0].constructor; const cff = new CFFFont(stream); let glyph = new CFFGlyph(1, [], { stream, 'CFF ': cff }); - assert.equal(glyph.path.toSVG(), koreanFont.glyphsForString('a')[0].path.toSVG()); + assert.equal( + glyph.path.toSVG(), + koreanFont.glyphsForString('a')[0].path.toSVG(), + ); glyph = new CFFGlyph(2, [], { stream, 'CFF ': cff }); - assert.equal(glyph.path.toSVG(), koreanFont.glyphsForString('。')[0].path.toSVG()); + assert.equal( + glyph.path.toSVG(), + koreanFont.glyphsForString('。')[0].path.toSVG(), + ); glyph = new CFFGlyph(3, [], { stream, 'CFF ': cff }); - assert.equal(glyph.path.toSVG(), koreanFont.glyphsForString('d')[0].path.toSVG()); + assert.equal( + glyph.path.toSVG(), + koreanFont.glyphsForString('d')[0].path.toSVG(), + ); }); }); }); diff --git a/test/variations.js b/test/variations.js index 7181ae4a..cbfcf309 100644 --- a/test/variations.js +++ b/test/variations.js @@ -28,9 +28,16 @@ describe('variations', function () { it('should get named variation instances', function () { let named = font.namedVariations; assert.deepEqual(Object.keys(named), [ - 'Black', 'Extended', 'Condensed', 'Light', 'Regular', - 'Black Extended', 'Light Extended', 'Black Condensed', - 'Light Condensed', 'Bold' + 'Black', + 'Extended', + 'Condensed', + 'Light', + 'Regular', + 'Black Extended', + 'Light Extended', + 'Black Condensed', + 'Light Condensed', + 'Bold', ]); assert.equal(Math.round(named.Bold.wght * 100) / 100, 1.95); @@ -42,7 +49,10 @@ describe('variations', function () { assert.equal(variation.constructor.name, 'TTFFont'); let glyph = variation.getGlyph(68); // D - return assert.equal(glyph.path.toSVG(), 'M1438 662Q1438 486 1351.5 353Q1265 220 1127 139Q1007 68 857 31Q707 -6 508 -6Q415 -6 303.5 -3.5Q192 -1 179 -1Q179 9 181 211Q183 413 183 683Q183 795 182 963Q181 1131 179 1339Q195 1339 312 1340Q429 1341 476 1341Q695 1341 859.5 1304Q1024 1267 1150 1187Q1296 1094 1367 963Q1438 832 1438 662ZM1098 673Q1098 773 1053.5 856Q1009 939 915 996Q831 1047 731.5 1066.5Q632 1086 543 1086Q533 1086 521.5 1086Q510 1086 507 1086Q506 984 506 892Q506 800 506 741Q506 689 506 572.5Q506 456 507 254Q516 254 523 254Q530 254 540 254Q630 254 730.5 276.5Q831 299 896 337Q997 395 1047.5 479Q1098 563 1098 673Z'); + return assert.equal( + glyph.path.toSVG(), + 'M1438 662Q1438 486 1351.5 353Q1265 220 1127 139Q1007 68 857 31Q707 -6 508 -6Q415 -6 303.5 -3.5Q192 -1 179 -1Q179 9 181 211Q183 413 183 683Q183 795 182 963Q181 1131 179 1339Q195 1339 312 1340Q429 1341 476 1341Q695 1341 859.5 1304Q1024 1267 1150 1187Q1296 1094 1367 963Q1438 832 1438 662ZM1098 673Q1098 773 1053.5 856Q1009 939 915 996Q831 1047 731.5 1066.5Q632 1086 543 1086Q533 1086 521.5 1086Q510 1086 507 1086Q506 984 506 892Q506 800 506 741Q506 689 506 572.5Q506 456 507 254Q516 254 523 254Q530 254 540 254Q630 254 730.5 276.5Q831 299 896 337Q997 395 1047.5 479Q1098 563 1098 673Z', + ); }); it('should get a variation by settings', function () { @@ -50,14 +60,20 @@ describe('variations', function () { assert.equal(variation.constructor.name, 'TTFFont'); let glyph = variation.getGlyph(68); // D - return assert.equal(glyph.path.toSVG(), 'M1259 662Q1259 496 1181.5 361.5Q1104 227 967 138Q848 64 716 29.5Q584 -5 408 -5Q365 -5 305.5 -4Q246 -3 220 -2Q220 42 221 207.5Q222 373 222 668Q222 853 221 1043.5Q220 1234 220 1339Q243 1340 288 1340Q333 1340 372 1340Q567 1340 721.5 1301.5Q876 1263 988 1188Q1125 1098 1192 964.5Q1259 831 1259 662ZM1175 662Q1175 813 1115 933.5Q1055 1054 922 1139Q813 1208 678 1240.5Q543 1273 371 1273Q355 1273 333.5 1273Q312 1273 303 1273Q303 1189 302 1047.5Q301 906 301 760Q301 510 301.5 351Q302 192 303 62Q320 62 337.5 62Q355 62 371 62Q532 62 665.5 89.5Q799 117 901 180Q1038 266 1106.5 388.5Q1175 511 1175 662Z'); + return assert.equal( + glyph.path.toSVG(), + 'M1259 662Q1259 496 1181.5 361.5Q1104 227 967 138Q848 64 716 29.5Q584 -5 408 -5Q365 -5 305.5 -4Q246 -3 220 -2Q220 42 221 207.5Q222 373 222 668Q222 853 221 1043.5Q220 1234 220 1339Q243 1340 288 1340Q333 1340 372 1340Q567 1340 721.5 1301.5Q876 1263 988 1188Q1125 1098 1192 964.5Q1259 831 1259 662ZM1175 662Q1175 813 1115 933.5Q1055 1054 922 1139Q813 1208 678 1240.5Q543 1273 371 1273Q355 1273 333.5 1273Q312 1273 303 1273Q303 1189 302 1047.5Q301 906 301 760Q301 510 301.5 351Q302 192 303 62Q320 62 337.5 62Q355 62 371 62Q532 62 665.5 89.5Q799 117 901 180Q1038 266 1106.5 388.5Q1175 511 1175 662Z', + ); }); it('interpolates points without delta values', function () { let variation = font.getVariation('Bold'); let glyph = variation.glyphForCodePoint('Q'.charCodeAt()); - return assert.equal(glyph.path.toSVG(), 'M799 -39Q662 -39 538 4Q414 47 320 131Q213 227 152 365Q91 503 91 670Q91 825 141.5 952.5Q192 1080 295 1182Q389 1276 517 1326Q645 1376 795 1376Q942 1376 1067.5 1329.5Q1193 1283 1288 1193Q1395 1092 1448.5 957.5Q1502 823 1502 669Q1502 514 1434.5 366Q1367 218 1240 114Q1141 32 1030 -3.5Q919 -39 799 -39ZM1162 654Q1162 755 1128.5 856.5Q1095 958 1024 1024Q980 1066 923 1090Q866 1114 796 1114Q727 1114 669 1089.5Q611 1065 562 1017Q500 955 465.5 859Q431 763 431 665Q431 556 465.5 463Q500 370 566 307Q610 265 669 240Q728 215 797 215Q847 215 908 232.5Q969 250 1023 299Q1088 360 1125 457Q1162 554 1162 654ZM789 452L955 596Q1004.9 537.73 1170.53 350.36Q1336.15 163 1540 -53L1358 -210Q1146.97 32.91 994.12 211.7Q841.27 390.49 789 452Z'); + return assert.equal( + glyph.path.toSVG(), + 'M799 -39Q662 -39 538 4Q414 47 320 131Q213 227 152 365Q91 503 91 670Q91 825 141.5 952.5Q192 1080 295 1182Q389 1276 517 1326Q645 1376 795 1376Q942 1376 1067.5 1329.5Q1193 1283 1288 1193Q1395 1092 1448.5 957.5Q1502 823 1502 669Q1502 514 1434.5 366Q1367 218 1240 114Q1141 32 1030 -3.5Q919 -39 799 -39ZM1162 654Q1162 755 1128.5 856.5Q1095 958 1024 1024Q980 1066 923 1090Q866 1114 796 1114Q727 1114 669 1089.5Q611 1065 562 1017Q500 955 465.5 859Q431 763 431 665Q431 556 465.5 463Q500 370 566 307Q610 265 669 240Q728 215 797 215Q847 215 908 232.5Q969 250 1023 299Q1088 360 1125 457Q1162 554 1162 654ZM789 452L955 596Q1004.9 537.73 1170.53 350.36Q1336.15 163 1540 -53L1358 -210Q1146.97 32.91 994.12 211.7Q841.27 390.49 789 452Z', + ); }); it('recomputes cbox and advance width', function () { @@ -71,85 +87,114 @@ describe('variations', function () { describe('truetype variations', function () { it('should support sharing all points', function () { - let font = fontkit.openSync(new URL('data/fonttest/TestGVAROne.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/fonttest/TestGVAROne.ttf', import.meta.url), + ); assert.equal( - font.getVariation({ wght: 300 }).glyphsForString("彌")[0].path.toSVG(), - 'M371 -102L371 539L914 539L914 -27Q914 -102 840 -102Q796 -102 755 -98L742 -59Q790 -66 836 -66Q871 -66 871 -31L871 504L414 504L414 -102ZM203 -94Q138 -94 86 -90L74 -52Q137 -59 188 -59Q211 -59 222 -46.5Q233 -34 235.5 12Q238 58 240 134.5Q242 211 242 262L74 262L94 527L242 527L242 719L63 719L63 754L285 754L285 492L133 492L117 297L285 297Q285 241 284 185Q284 104 281 46Q278 -20 269 -49Q260 -78 241.5 -86Q223 -94 203 -94ZM461 12L434 43Q473 73 503 115Q478 150 441 188L469 211Q501 179 525 147Q538 172 559 230L594 211Q571 152 551 117Q577 84 602 43L566 20Q544 64 528 86Q500 44 461 12ZM465 258L438 285Q474 316 501 351Q474 388 445 418L473 441Q500 414 523 381Q546 413 563 453L598 434Q571 382 549 352Q576 320 598 285L563 262Q546 294 525 322Q491 280 465 258ZM707 12L680 43Q717 68 753 115Q731 147 691 188L719 211Q739 190 754 172Q769 154 774 147Q793 185 809 230L844 211Q822 155 801 117Q828 82 852 43L820 20Q798 58 778 87Q747 43 707 12ZM621 -94L621 730L664 730L664 -94ZM348 570L324 605Q425 629 527 688L555 656Q491 621 438.5 601Q386 581 348 570ZM715 258L688 285Q727 318 753 351Q733 378 695 418L723 441Q754 410 775 381Q794 407 813 453L848 434Q826 387 801 352Q823 321 848 281L813 262Q791 301 775 323Q749 288 715 258ZM348 719L348 754L941 754L941 719ZM936 570Q870 602 817 621.5Q764 641 727 652L749 688Q852 655 957 605Z' + font.getVariation({ wght: 300 }).glyphsForString('彌')[0].path.toSVG(), + 'M371 -102L371 539L914 539L914 -27Q914 -102 840 -102Q796 -102 755 -98L742 -59Q790 -66 836 -66Q871 -66 871 -31L871 504L414 504L414 -102ZM203 -94Q138 -94 86 -90L74 -52Q137 -59 188 -59Q211 -59 222 -46.5Q233 -34 235.5 12Q238 58 240 134.5Q242 211 242 262L74 262L94 527L242 527L242 719L63 719L63 754L285 754L285 492L133 492L117 297L285 297Q285 241 284 185Q284 104 281 46Q278 -20 269 -49Q260 -78 241.5 -86Q223 -94 203 -94ZM461 12L434 43Q473 73 503 115Q478 150 441 188L469 211Q501 179 525 147Q538 172 559 230L594 211Q571 152 551 117Q577 84 602 43L566 20Q544 64 528 86Q500 44 461 12ZM465 258L438 285Q474 316 501 351Q474 388 445 418L473 441Q500 414 523 381Q546 413 563 453L598 434Q571 382 549 352Q576 320 598 285L563 262Q546 294 525 322Q491 280 465 258ZM707 12L680 43Q717 68 753 115Q731 147 691 188L719 211Q739 190 754 172Q769 154 774 147Q793 185 809 230L844 211Q822 155 801 117Q828 82 852 43L820 20Q798 58 778 87Q747 43 707 12ZM621 -94L621 730L664 730L664 -94ZM348 570L324 605Q425 629 527 688L555 656Q491 621 438.5 601Q386 581 348 570ZM715 258L688 285Q727 318 753 351Q733 378 695 418L723 441Q754 410 775 381Q794 407 813 453L848 434Q826 387 801 352Q823 321 848 281L813 262Q791 301 775 323Q749 288 715 258ZM348 719L348 754L941 754L941 719ZM936 570Q870 602 817 621.5Q764 641 727 652L749 688Q852 655 957 605Z', ); }); it('should support sharing enumerated points', function () { - let font = fontkit.openSync(new URL('data/fonttest/TestGVARTwo.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/fonttest/TestGVARTwo.ttf', import.meta.url), + ); assert.equal( - font.getVariation({ wght: 300 }).glyphsForString("彌")[0].path.toSVG(), - 'M371 -102L371 539L914 539L914 -27Q914 -102 840 -102Q796 -102 755 -98L742 -59Q790 -66 836 -66Q871 -66 871 -31L871 504L414 504L414 -102ZM203 -94Q138 -94 86 -90L74 -52Q137 -59 188 -59Q211 -59 222 -46.5Q233 -34 235.5 12Q238 58 240 134.5Q242 211 242 262L74 262L94 527L242 527L242 719L63 719L63 754L285 754L285 492L133 492L117 297L285 297Q285 241 284 185Q284 104 281 46Q278 -20 269 -49Q260 -78 241.5 -86Q223 -94 203 -94ZM461 12L434 43Q473 73 503 115Q478 150 441 188L469 211Q501 179 525 147Q538 172 559 230L594 211Q571 152 551 117Q577 84 602 43L566 20Q544 64 528 86Q500 44 461 12ZM465 258L438 285Q474 316 501 351Q474 388 445 418L473 441Q500 414 523 381Q546 413 563 453L598 434Q571 382 549 352Q576 320 598 285L563 262Q546 294 525 322Q491 280 465 258ZM707 12L680 43Q717 68 753 115Q731 147 691 188L719 211Q739 190 754 172Q769 154 774 147Q793 185 809 230L844 211Q822 155 801 117Q828 82 852 43L820 20Q798 58 778 87Q747 43 707 12ZM621 -94L621 730L664 730L664 -94ZM348 570L324 605Q425 629 527 688L555 656Q491 621 438.5 601Q386 581 348 570ZM715 258L688 285Q727 318 753 351Q733 378 695 418L723 441Q754 410 775 381Q794 407 813 453L848 434Q826 387 801 352Q823 321 848 281L813 262Q791 301 775 323Q749 288 715 258ZM348 719L348 754L941 754L941 719ZM936 570Q870 602 817 621.5Q764 641 727 652L749 688Q852 655 957 605Z' + font.getVariation({ wght: 300 }).glyphsForString('彌')[0].path.toSVG(), + 'M371 -102L371 539L914 539L914 -27Q914 -102 840 -102Q796 -102 755 -98L742 -59Q790 -66 836 -66Q871 -66 871 -31L871 504L414 504L414 -102ZM203 -94Q138 -94 86 -90L74 -52Q137 -59 188 -59Q211 -59 222 -46.5Q233 -34 235.5 12Q238 58 240 134.5Q242 211 242 262L74 262L94 527L242 527L242 719L63 719L63 754L285 754L285 492L133 492L117 297L285 297Q285 241 284 185Q284 104 281 46Q278 -20 269 -49Q260 -78 241.5 -86Q223 -94 203 -94ZM461 12L434 43Q473 73 503 115Q478 150 441 188L469 211Q501 179 525 147Q538 172 559 230L594 211Q571 152 551 117Q577 84 602 43L566 20Q544 64 528 86Q500 44 461 12ZM465 258L438 285Q474 316 501 351Q474 388 445 418L473 441Q500 414 523 381Q546 413 563 453L598 434Q571 382 549 352Q576 320 598 285L563 262Q546 294 525 322Q491 280 465 258ZM707 12L680 43Q717 68 753 115Q731 147 691 188L719 211Q739 190 754 172Q769 154 774 147Q793 185 809 230L844 211Q822 155 801 117Q828 82 852 43L820 20Q798 58 778 87Q747 43 707 12ZM621 -94L621 730L664 730L664 -94ZM348 570L324 605Q425 629 527 688L555 656Q491 621 438.5 601Q386 581 348 570ZM715 258L688 285Q727 318 753 351Q733 378 695 418L723 441Q754 410 775 381Q794 407 813 453L848 434Q826 387 801 352Q823 321 848 281L813 262Q791 301 775 323Q749 288 715 258ZM348 719L348 754L941 754L941 719ZM936 570Q870 602 817 621.5Q764 641 727 652L749 688Q852 655 957 605Z', ); }); it('should support sharing no points', function () { - let font = fontkit.openSync(new URL('data/fonttest/TestGVARThree.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/fonttest/TestGVARThree.ttf', import.meta.url), + ); assert.equal( - font.getVariation({ wght: 300 }).glyphsForString("彌")[0].path.toSVG(), - 'M371 -102L371 539L914 539L914 -27Q914 -102 840 -102Q796 -102 755 -98L742 -59Q790 -66 836 -66Q871 -66 871 -31L871 504L414 504L414 -102ZM203 -94Q138 -94 86 -90L74 -52Q137 -59 188 -59Q211 -59 222 -46.5Q233 -34 235.5 12Q238 58 240 134.5Q242 211 242 262L74 262L94 527L242 527L242 719L63 719L63 754L285 754L285 492L133 492L117 297L285 297Q285 241 284 185Q284 104 281 46Q278 -20 269 -49Q260 -78 241.5 -86Q223 -94 203 -94ZM461 12L434 43Q473 73 503 115Q478 150 441 188L469 211Q501 179 525 147Q538 172 559 230L594 211Q571 152 551 117Q577 84 602 43L566 20Q544 64 528 86Q500 44 461 12ZM465 258L438 285Q474 316 501 351Q474 388 445 418L473 441Q500 414 523 381Q546 413 563 453L598 434Q571 382 549 352Q576 320 598 285L563 262Q546 294 525 322Q491 280 465 258ZM707 12L680 43Q717 68 753 115Q731 147 691 188L719 211Q739 190 754 172Q769 154 774 147Q793 185 809 230L844 211Q822 155 801 117Q828 82 852 43L820 20Q798 58 778 87Q747 43 707 12ZM621 -94L621 730L664 730L664 -94ZM348 570L324 605Q425 629 527 688L555 656Q491 621 438.5 601Q386 581 348 570ZM715 258L688 285Q727 318 753 351Q733 378 695 418L723 441Q754 410 775 381Q794 407 813 453L848 434Q826 387 801 352Q823 321 848 281L813 262Q791 301 775 323Q749 288 715 258ZM348 719L348 754L941 754L941 719ZM936 570Q870 602 817 621.5Q764 641 727 652L749 688Q852 655 957 605Z' + font.getVariation({ wght: 300 }).glyphsForString('彌')[0].path.toSVG(), + 'M371 -102L371 539L914 539L914 -27Q914 -102 840 -102Q796 -102 755 -98L742 -59Q790 -66 836 -66Q871 -66 871 -31L871 504L414 504L414 -102ZM203 -94Q138 -94 86 -90L74 -52Q137 -59 188 -59Q211 -59 222 -46.5Q233 -34 235.5 12Q238 58 240 134.5Q242 211 242 262L74 262L94 527L242 527L242 719L63 719L63 754L285 754L285 492L133 492L117 297L285 297Q285 241 284 185Q284 104 281 46Q278 -20 269 -49Q260 -78 241.5 -86Q223 -94 203 -94ZM461 12L434 43Q473 73 503 115Q478 150 441 188L469 211Q501 179 525 147Q538 172 559 230L594 211Q571 152 551 117Q577 84 602 43L566 20Q544 64 528 86Q500 44 461 12ZM465 258L438 285Q474 316 501 351Q474 388 445 418L473 441Q500 414 523 381Q546 413 563 453L598 434Q571 382 549 352Q576 320 598 285L563 262Q546 294 525 322Q491 280 465 258ZM707 12L680 43Q717 68 753 115Q731 147 691 188L719 211Q739 190 754 172Q769 154 774 147Q793 185 809 230L844 211Q822 155 801 117Q828 82 852 43L820 20Q798 58 778 87Q747 43 707 12ZM621 -94L621 730L664 730L664 -94ZM348 570L324 605Q425 629 527 688L555 656Q491 621 438.5 601Q386 581 348 570ZM715 258L688 285Q727 318 753 351Q733 378 695 418L723 441Q754 410 775 381Q794 407 813 453L848 434Q826 387 801 352Q823 321 848 281L813 262Q791 301 775 323Q749 288 715 258ZM348 719L348 754L941 754L941 719ZM936 570Q870 602 817 621.5Q764 641 727 652L749 688Q852 655 957 605Z', ); }); it('should use the HVAR table when available for variation metrics', function () { - let font = fontkit.openSync(new URL('data/fonttest/TestGVARFour.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/fonttest/TestGVARFour.ttf', import.meta.url), + ); assert.equal( - Math.round(font.getVariation({ wght: 150 }).glyphsForString('O')[0].advanceWidth), - 706 + Math.round( + font.getVariation({ wght: 150 }).glyphsForString('O')[0].advanceWidth, + ), + 706, ); }); it('should fall back to the last entry in an HVAR table', function () { - let font = fontkit.openSync(new URL('data/fonttest/TestHVARTwo.ttf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/fonttest/TestHVARTwo.ttf', import.meta.url), + ); assert.equal( - Math.round(font.getVariation({ wght: 400 }).glyphsForString('A')[0].advanceWidth), - 584 + Math.round( + font.getVariation({ wght: 400 }).glyphsForString('A')[0].advanceWidth, + ), + 584, ); }); it('should support adjusting GPOS mark anchor points for variations', function () { - let font = fontkit.openSync(new URL('data/Mada/Mada-VF.ttf', import.meta.url), { wght: 900 }); + let font = fontkit.openSync( + new URL('data/Mada/Mada-VF.ttf', import.meta.url), + { wght: 900 }, + ); let run = font.layout('ف'); assert.equal(Math.floor(run.positions[0].xOffset), 639); assert.equal(Math.floor(run.positions[0].yOffset), 542); }); it('should not change variation metrics of glyphs used by several composites', function () { - let font = fontkit.openSync(new URL('data/Mada/Mada-VF.ttf', import.meta.url)).getVariation({ wght: 100 }); + let font = fontkit + .openSync(new URL('data/Mada/Mada-VF.ttf', import.meta.url)) + .getVariation({ wght: 100 }); let run = font.layout('\u00ec\u00ed\u00ee\u00ef\u0131'); - assert.deepEqual(run.positions.map(p => p.xAdvance), [229, 229, 229, 229, 229]); - assert.deepEqual(font.layout('\u00e9\u00e8e').positions.map(p => p.xAdvance), [483, 483, 483]); + assert.deepEqual( + run.positions.map((p) => p.xAdvance), + [229, 229, 229, 229, 229], + ); + assert.deepEqual( + font.layout('\u00e9\u00e8e').positions.map((p) => p.xAdvance), + [483, 483, 483], + ); }); }); describe('CFF2 variations', function () { - let font = fontkit.openSync(new URL('data/fonttest/AdobeVFPrototype-Subset.otf', import.meta.url)); + let font = fontkit.openSync( + new URL('data/fonttest/AdobeVFPrototype-Subset.otf', import.meta.url), + ); it('applies variations to CFF2 glyphs', function () { assert.equal( font.getVariation({ wght: 100 }).glyphsForString('$')[0].path.toSVG(), - 'M245.82 14.61C187.88 14.61 147.25 26.89 101.25 68.2L141.87 23.46L116.86 116.93C110.69 142.99 95.97 149.44 81.44 149.44C65.26 149.44 55.63 141.35 52.46 125.72C71.02 40.17 137.46 -13 244.46 -13C347.69 -13 435.51 46.25 435.51 156.16C435.51 229.42 405.44 295.15 271.16 349.44L247 358.79C159.98 393.45 118.52 438.64 118.52 505.55C118.52 592.21 177.71 637.22 261.9 637.22C310.84 637.22 346.11 625.66 389.56 584.63L347.76 628.64L372.77 535.16C380.4 510.11 394.48 502.66 408.47 502.66C423.83 502.66 434.27 510.48 437.17 526.38C418.07 613.84 347.53 665.1 258.91 665.1C160.66 665.1 78.39 606.22 78.39 499.85C78.39 414.41 128.01 361.14 223.54 320.5L260.54 304.59C366.66 258.56 395.38 216.91 395.38 152.46C395.38 65.35 333.64 14.61 245.82 14.61ZM267.35 330.74L267.35 758.74L240.46 758.74L240.46 330.74L267.35 330.74ZM240.18 -115L267.08 -115L267.08 330.74L240.18 330.74L240.18 -115Z' + 'M245.82 14.61C187.88 14.61 147.25 26.89 101.25 68.2L141.87 23.46L116.86 116.93C110.69 142.99 95.97 149.44 81.44 149.44C65.26 149.44 55.63 141.35 52.46 125.72C71.02 40.17 137.46 -13 244.46 -13C347.69 -13 435.51 46.25 435.51 156.16C435.51 229.42 405.44 295.15 271.16 349.44L247 358.79C159.98 393.45 118.52 438.64 118.52 505.55C118.52 592.21 177.71 637.22 261.9 637.22C310.84 637.22 346.11 625.66 389.56 584.63L347.76 628.64L372.77 535.16C380.4 510.11 394.48 502.66 408.47 502.66C423.83 502.66 434.27 510.48 437.17 526.38C418.07 613.84 347.53 665.1 258.91 665.1C160.66 665.1 78.39 606.22 78.39 499.85C78.39 414.41 128.01 361.14 223.54 320.5L260.54 304.59C366.66 258.56 395.38 216.91 395.38 152.46C395.38 65.35 333.64 14.61 245.82 14.61ZM267.35 330.74L267.35 758.74L240.46 758.74L240.46 330.74L267.35 330.74ZM240.18 -115L267.08 -115L267.08 330.74L240.18 330.74L240.18 -115Z', ); assert.equal( font.getVariation({ wght: 500 }).glyphsForString('$')[0].path.toSVG(), - 'M250.51 35.84C206.08 35.84 164.63 42.09 118 61.34L176.22 21.37L161.1 99.25C150.56 152.04 128.56 166.51 100.6 166.51C77.76 166.51 61.04 154.88 51 131.12C54.16 43.49 133.08 -13.63 246.76 -13.63C388.4 -13.63 473.95 64.04 473.95 171.25C473.95 258.48 429.82 321.18 294.19 370.06L257.44 383.06C188.12 406.48 150.2 437.92 150.2 498.58C150.2 571.08 204.28 605.57 275.56 605.57C308.07 605.57 342.19 600.78 386.28 582.32L327.39 620.61L342.92 546.49C354.72 489.69 382.22 475.69 407.77 475.69C428.24 475.69 447.74 486.73 455.12 511.91C450.37 597.49 369.53 655.82 264.36 655.82C140.37 655.82 56.96 575.82 56.96 473.61C56.96 372.57 119.37 318.36 226.88 278.85L262.63 265.85C344.91 235.85 379.24 208.15 379.24 145.15C379.24 76.37 329.16 35.84 250.51 35.84ZM288.61 320.33L288.61 746.03L242.13 746.03L242.13 320.33L288.61 320.33ZM239.67 -115L286.15 -115L286.15 320.33L239.67 320.33L239.67 -115Z' + 'M250.51 35.84C206.08 35.84 164.63 42.09 118 61.34L176.22 21.37L161.1 99.25C150.56 152.04 128.56 166.51 100.6 166.51C77.76 166.51 61.04 154.88 51 131.12C54.16 43.49 133.08 -13.63 246.76 -13.63C388.4 -13.63 473.95 64.04 473.95 171.25C473.95 258.48 429.82 321.18 294.19 370.06L257.44 383.06C188.12 406.48 150.2 437.92 150.2 498.58C150.2 571.08 204.28 605.57 275.56 605.57C308.07 605.57 342.19 600.78 386.28 582.32L327.39 620.61L342.92 546.49C354.72 489.69 382.22 475.69 407.77 475.69C428.24 475.69 447.74 486.73 455.12 511.91C450.37 597.49 369.53 655.82 264.36 655.82C140.37 655.82 56.96 575.82 56.96 473.61C56.96 372.57 119.37 318.36 226.88 278.85L262.63 265.85C344.91 235.85 379.24 208.15 379.24 145.15C379.24 76.37 329.16 35.84 250.51 35.84ZM288.61 320.33L288.61 746.03L242.13 746.03L242.13 320.33L288.61 320.33ZM239.67 -115L286.15 -115L286.15 320.33L239.67 320.33L239.67 -115Z', ); }); it('substitutes GSUB features depending on variations', function () { let glyph = font.getVariation({ wght: 900 }).layout('$').glyphs[0]; assert.equal(glyph.name, 'dollar.nostroke'); - assert.equal(glyph.path.toSVG(), 'M258.1 38.37C197.22 38.37 166.53 48.42 118 71.47L192.04 19.47L182.62 103.05C176.51 155.21 154.51 174.1 114.52 174.1C89.15 174.1 64.21 160.58 51 125.42C51.63 35.9 124.22 -15.53 258.15 -15.53C416.88 -15.53 513.19 67.21 513.19 175.05C513.19 278.1 457.04 327.94 322.04 388.41L289.09 403.1C231.56 428.62 203.34 451.84 203.34 499.84C203.34 562.22 244.35 589.11 300.67 589.11C341.61 589.11 370.04 584.96 420.46 562.06L340.68 607.32L351.78 538.9C362.94 467.54 398.04 453.54 434.35 453.54C459.25 453.54 486.35 467.75 491.82 505.58C490.87 589.9 407.51 643.16 289.67 643.16C141 643.16 57.16 563.16 57.16 460.32C57.16 356.96 121.68 307.16 232.58 255.85L264.53 241.17C333.53 209.49 362.8 186.22 362.8 129.96C362.8 77 319.9 38.37 258.1 38.37ZM317.72 615.64L317.72 734.01L251.63 734.01L251.63 615.64L317.72 615.64ZM253.15 -115L319.25 -115L319.25 13.68L253.15 13.68L253.15 -115Z'); + assert.equal( + glyph.path.toSVG(), + 'M258.1 38.37C197.22 38.37 166.53 48.42 118 71.47L192.04 19.47L182.62 103.05C176.51 155.21 154.51 174.1 114.52 174.1C89.15 174.1 64.21 160.58 51 125.42C51.63 35.9 124.22 -15.53 258.15 -15.53C416.88 -15.53 513.19 67.21 513.19 175.05C513.19 278.1 457.04 327.94 322.04 388.41L289.09 403.1C231.56 428.62 203.34 451.84 203.34 499.84C203.34 562.22 244.35 589.11 300.67 589.11C341.61 589.11 370.04 584.96 420.46 562.06L340.68 607.32L351.78 538.9C362.94 467.54 398.04 453.54 434.35 453.54C459.25 453.54 486.35 467.75 491.82 505.58C490.87 589.9 407.51 643.16 289.67 643.16C141 643.16 57.16 563.16 57.16 460.32C57.16 356.96 121.68 307.16 232.58 255.85L264.53 241.17C333.53 209.49 362.8 186.22 362.8 129.96C362.8 77 319.9 38.37 258.1 38.37ZM317.72 615.64L317.72 734.01L251.63 734.01L251.63 615.64L317.72 615.64ZM253.15 -115L319.25 -115L319.25 13.68L253.15 13.68L253.15 -115Z', + ); }); }); }); - From 6c31c0192fa711948cc92811b2fb8dc8c0587f8d Mon Sep 17 00:00:00 2001 From: Luiz Americo Date: Fri, 9 Oct 2026 22:29:36 -0300 Subject: [PATCH 5/6] Add github lint / test workflow --- .github/workflows/lint-test.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/lint-test.yml diff --git a/.github/workflows/lint-test.yml b/.github/workflows/lint-test.yml new file mode 100644 index 00000000..4cec9518 --- /dev/null +++ b/.github/workflows/lint-test.yml @@ -0,0 +1,31 @@ +name: Lint and Test + +on: [pull_request] + +permissions: + contents: read + +jobs: + build: + name: Lint and Test (Node ${{ matrix.node-version }}) + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + node-version: [20.x, 22.x, 24.x] + + steps: + - uses: actions/checkout@v7 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v7 + with: + node-version: ${{ matrix.node-version }} + cache: npm + cache-dependency-path: package-lock.json + - name: Install dependencies + run: npm ci + - name: Run Prettier check + run: npm run format:check + - name: Run tests + run: npm test From f3905a485372913a63ff282df5a597e80bee821d Mon Sep 17 00:00:00 2001 From: Luiz Americo Date: Sat, 8 Aug 2026 11:22:38 -0300 Subject: [PATCH 6/6] Replace tiny-inflate by fflate --- CHANGELOG.md | 21 ++++++++++----------- package.json | 1 + src/WOFFFont.js | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 114a4303..86ab4a09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,16 +2,15 @@ ### Unreleased - - Replace cache decorators with specialized lazy caching - - Map space and missing code points correctly with a legacy Mac cmap (#394) - - Keep a glyph's variation metrics stable when several composites use it - - Return the requested code points for glyphs shared by several code points (#342) (#395) - - Map glyphs back to code points for cmap formats 6 and 10 (#392) - - Size cmap format 10 glyph indices by entryCount (#391) - - Leave code points mapped to .notdef out of characterSet (#390) - - Fix glyph code point cache after composite decomposition (#387) - - Fix off-diagonal coefficients in composite glyph transforms (#388) - +- Replace cache decorators with specialized lazy caching +- Map space and missing code points correctly with a legacy Mac cmap (#394) +- Keep a glyph's variation metrics stable when several composites use it +- Return the requested code points for glyphs shared by several code points (#342) (#395) +- Map glyphs back to code points for cmap formats 6 and 10 (#392) +- Size cmap format 10 glyph indices by entryCount (#391) +- Leave code points mapped to .notdef out of characterSet (#390) +- Fix glyph code point cache after composite decomposition (#387) +- Fix off-diagonal coefficients in composite glyph transforms (#388) +- Replace tiny-inflate by fflate ### [v2.0.4] - 08-09-2024 - diff --git a/package.json b/package.json index becb9e9a..b8b62137 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", + "fflate": "^0.8.3", "restructure": "^3.0.2", "tiny-inflate": "^1.0.3", "unicode-properties": "^2.0.1", diff --git a/src/WOFFFont.js b/src/WOFFFont.js index 23982d1b..c076bddb 100644 --- a/src/WOFFFont.js +++ b/src/WOFFFont.js @@ -1,7 +1,7 @@ import TTFFont from './TTFFont'; import WOFFDirectory from './tables/WOFFDirectory'; import tables from './tables'; -import inflate from 'tiny-inflate'; +import { inflateSync } from 'fflate'; import * as r from 'restructure'; import { asciiDecoder } from './utils'; @@ -24,7 +24,7 @@ export default class WOFFFont extends TTFFont { if (table.compLength < table.length) { this.stream.pos += 2; // skip deflate header let outBuffer = new Uint8Array(table.length); - let buf = inflate( + let buf = inflateSync( this.stream.readBuffer(table.compLength - 2), outBuffer, );