From 74052724e04de1218e608af25aee6fd2d0e647f9 Mon Sep 17 00:00:00 2001 From: lynn Date: Wed, 9 Aug 2023 13:57:39 +0800 Subject: [PATCH 1/8] feat: createBlob & createFace --- .gitignore | 4 +- package.json | 34 +- pnpm-lock.yaml | 1823 ++++++++++++++++++++++++++++++++++++++++++ src/hb.ts | 119 +++ src/index.ts | 13 + src/schema/blob.ts | 6 + src/schema/export.ts | 84 ++ src/utils/index.ts | 17 + test/face.spec.ts | 54 ++ tsconfig.json | 7 +- tsup.config.ts | 11 + vitest.config.ts | 10 + 12 files changed, 2177 insertions(+), 5 deletions(-) create mode 100644 pnpm-lock.yaml create mode 100644 src/hb.ts create mode 100644 src/index.ts create mode 100644 src/schema/blob.ts create mode 100644 src/schema/export.ts create mode 100644 src/utils/index.ts create mode 100644 test/face.spec.ts create mode 100644 tsup.config.ts create mode 100644 vitest.config.ts diff --git a/.gitignore b/.gitignore index 9a95569..7f3a96c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.wasm -.DS_Store \ No newline at end of file +.DS_Store +node_modules +dist \ No newline at end of file diff --git a/package.json b/package.json index ffbd428..4e91838 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,33 @@ "name": "harfbuzzjs", "version": "0.3.3", "description": "Minimal version of HarfBuzz for JavaScript use", - "main": "index.js", + "packageManager": "pnpm@8.6.3", + "engines": { + "node": ">= 16" + }, + "main": "dist/index.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "files": [ + "dist", + "hb.wasm" + ], "scripts": { - "test": "mocha test/index.js" + "build": "tsup", + "test": "vitest" + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "default": "./dist/index.mjs", + "types": "./dist/index.d.mts" + }, + "require": { + "default": "./dist/index.js", + "types": "./dist/index.d.ts" + } + } }, "keywords": [ "harfbuzz", @@ -31,7 +55,11 @@ }, "homepage": "https://github.com/harfbuzz/harfbuzzjs#readme", "devDependencies": { + "@types/node": "^20.4.9", "chai": "^4.3.7", - "mocha": "^10.2.0" + "mocha": "^10.2.0", + "tsup": "^7.2.0", + "typescript": "^5.1.6", + "vitest": "^0.34.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..78994fc --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1823 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + '@types/node': + specifier: ^20.4.9 + version: 20.4.9 + chai: + specifier: ^4.3.7 + version: 4.3.7 + mocha: + specifier: ^10.2.0 + version: 10.2.0 + tsup: + specifier: ^7.2.0 + version: 7.2.0(typescript@5.1.6) + typescript: + specifier: ^5.1.6 + version: 5.1.6 + vitest: + specifier: ^0.34.1 + version: 0.34.1 + +packages: + + /@esbuild/android-arm64@0.17.19: + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.17.19: + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.17.19: + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.17.19: + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.17.19: + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.17.19: + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.17.19: + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.17.19: + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.17.19: + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.17.19: + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.17.19: + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.17.19: + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.17.19: + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.17.19: + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.17.19: + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.17.19: + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.17.19: + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.17.19: + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.17.19: + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.17.19: + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.17.19: + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.17.19: + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@jest/schemas@29.6.0: + resolution: {integrity: sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.19: + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true + + /@types/chai-subset@1.3.3: + resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + dependencies: + '@types/chai': 4.3.5 + dev: true + + /@types/chai@4.3.5: + resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} + dev: true + + /@types/node@20.4.9: + resolution: {integrity: sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ==} + dev: true + + /@vitest/expect@0.34.1: + resolution: {integrity: sha512-q2CD8+XIsQ+tHwypnoCk8Mnv5e6afLFvinVGCq3/BOT4kQdVQmY6rRfyKkwcg635lbliLPqbunXZr+L1ssUWiQ==} + dependencies: + '@vitest/spy': 0.34.1 + '@vitest/utils': 0.34.1 + chai: 4.3.7 + dev: true + + /@vitest/runner@0.34.1: + resolution: {integrity: sha512-YfQMpYzDsYB7yqgmlxZ06NI4LurHWfrH7Wy3Pvf/z/vwUSgq1zLAb1lWcItCzQG+NVox+VvzlKQrYEXb47645g==} + dependencies: + '@vitest/utils': 0.34.1 + p-limit: 4.0.0 + pathe: 1.1.1 + dev: true + + /@vitest/snapshot@0.34.1: + resolution: {integrity: sha512-0O9LfLU0114OqdF8lENlrLsnn024Tb1CsS9UwG0YMWY2oGTQfPtkW+B/7ieyv0X9R2Oijhi3caB1xgGgEgclSQ==} + dependencies: + magic-string: 0.30.2 + pathe: 1.1.1 + pretty-format: 29.6.2 + dev: true + + /@vitest/spy@0.34.1: + resolution: {integrity: sha512-UT4WcI3EAPUNO8n6y9QoEqynGGEPmmRxC+cLzneFFXpmacivjHZsNbiKD88KUScv5DCHVDgdBsLD7O7s1enFcQ==} + dependencies: + tinyspy: 2.1.1 + dev: true + + /@vitest/utils@0.34.1: + resolution: {integrity: sha512-/ql9dsFi4iuEbiNcjNHQWXBum7aL8pyhxvfnD9gNtbjR9fUKAjxhj4AA3yfLXg6gJpMGGecvtF8Au2G9y3q47Q==} + dependencies: + diff-sequences: 29.4.3 + loupe: 2.3.6 + pretty-format: 29.6.2 + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.9.0: + resolution: {integrity: sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + dev: true + + /bundle-require@4.0.1(esbuild@0.18.20): + resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.17' + dependencies: + esbuild: 0.18.20 + load-tsconfig: 0.2.5 + dev: true + + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /chai@4.3.7: + resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.2 + deep-eql: 4.1.3 + get-func-name: 2.0.0 + loupe: 2.3.6 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /check-error@1.0.2: + resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + dev: true + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /debug@4.3.4(supports-color@8.1.1): + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + supports-color: 8.1.1 + dev: true + + /decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + dev: true + + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + + /diff-sequences@29.4.3: + resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-func-name@2.0.0: + resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.1.6: + resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.1 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: true + + /loupe@2.3.6: + resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + dependencies: + get-func-name: 2.0.0 + dev: true + + /magic-string@0.30.2: + resolution: {integrity: sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@5.0.1: + resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /mlly@1.4.0: + resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} + dependencies: + acorn: 8.9.0 + pathe: 1.1.1 + pkg-types: 1.0.3 + ufo: 1.1.2 + dev: true + + /mocha@10.2.0: + resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} + engines: {node: '>= 14.0.0'} + hasBin: true + dependencies: + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.0.1 + ms: 2.1.3 + nanoid: 3.3.3 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.2.1 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + + /nanoid@3.3.3: + resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /pathe@1.1.1: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.4.0 + pathe: 1.1.1 + dev: true + + /postcss-load-config@4.0.1: + resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + yaml: 2.3.1 + dev: true + + /postcss@8.4.24: + resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /pretty-format@29.6.2: + resolution: {integrity: sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.0 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rollup@3.25.3: + resolution: {integrity: sha512-ZT279hx8gszBj9uy5FfhoG4bZx8c+0A1sbqtr7Q3KNWIizpTdDEPZbV2xcbvHsnFp4MavCQYZyzApJ+virB8Yw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + dependencies: + randombytes: 2.1.0 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + + /std-env@3.3.3: + resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /strip-literal@1.0.1: + resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} + dependencies: + acorn: 8.9.0 + dev: true + + /sucrase@3.34.0: + resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + commander: 4.1.1 + glob: 7.1.6 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + + /tinybench@2.5.0: + resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} + dev: true + + /tinypool@0.7.0: + resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@2.1.1: + resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} + engines: {node: '>=14.0.0'} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.3.0 + dev: true + + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: true + + /tsup@7.2.0(typescript@5.1.6): + resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==} + engines: {node: '>=16.14'} + hasBin: true + peerDependencies: + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.1.0' + peerDependenciesMeta: + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + dependencies: + bundle-require: 4.0.1(esbuild@0.18.20) + cac: 6.7.14 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@8.1.1) + esbuild: 0.18.20 + execa: 5.1.1 + globby: 11.1.0 + joycon: 3.1.1 + postcss-load-config: 4.0.1 + resolve-from: 5.0.0 + rollup: 3.25.3 + source-map: 0.8.0-beta.0 + sucrase: 3.34.0 + tree-kill: 1.2.2 + typescript: 5.1.6 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /typescript@5.1.6: + resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /ufo@1.1.2: + resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} + dev: true + + /vite-node@0.34.1(@types/node@20.4.9): + resolution: {integrity: sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4(supports-color@8.1.1) + mlly: 1.4.0 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 4.3.9(@types/node@20.4.9) + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite@4.3.9(@types/node@20.4.9): + resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.4.9 + esbuild: 0.17.19 + postcss: 8.4.24 + rollup: 3.25.3 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitest@0.34.1: + resolution: {integrity: sha512-G1PzuBEq9A75XSU88yO5G4vPT20UovbC/2osB2KEuV/FisSIIsw7m5y2xMdB7RsAGHAfg2lPmp2qKr3KWliVlQ==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.5 + '@types/chai-subset': 1.3.3 + '@types/node': 20.4.9 + '@vitest/expect': 0.34.1 + '@vitest/runner': 0.34.1 + '@vitest/snapshot': 0.34.1 + '@vitest/spy': 0.34.1 + '@vitest/utils': 0.34.1 + acorn: 8.9.0 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + debug: 4.3.4(supports-color@8.1.1) + local-pkg: 0.4.3 + magic-string: 0.30.2 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.3.3 + strip-literal: 1.0.1 + tinybench: 2.5.0 + tinypool: 0.7.0 + vite: 4.3.9(@types/node@20.4.9) + vite-node: 0.34.1(@types/node@20.4.9) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + + /whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + + /workerpool@6.2.1: + resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yaml@2.3.1: + resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} + engines: {node: '>= 14'} + dev: true + + /yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + dev: true + + /yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + dev: true + + /yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true diff --git a/src/hb.ts b/src/hb.ts new file mode 100644 index 0000000..0f6baac --- /dev/null +++ b/src/hb.ts @@ -0,0 +1,119 @@ +import type { Exports } from '~/schema/export' +import type { BlobInstace } from '~/schema/blob' +import { hb_tag, hb_untag } from '~/utils/index' + +const HB_MEMORY_MODE_WRITABLE = 2 +const HB_SET_VALUE_INVALID = -1 + +export function hb(instance: WebAssembly.Instance) { + const exports = instance.exports as unknown as Exports + const memory = exports.memory + const heapu8 = new Uint8Array(memory.buffer) + const heapu32 = new Uint32Array(memory.buffer) + const heapi32 = new Int32Array(memory.buffer) + const heapf32 = new Float32Array(memory.buffer) + + /** + * Create an object representing a Harfbuzz blob. + * @param blob A blob of binary data (usually the contents of a font file). + */ + function createBlob(blob: ArrayBuffer) { + const blobPtr = exports.malloc(blob.byteLength) + heapu8.set(new Uint8Array(blob), blobPtr) + const ptr = exports.hb_blob_create(blobPtr, blob.byteLength, HB_MEMORY_MODE_WRITABLE, blobPtr, exports.free_ptr()) + + return { + ptr, + destory() { + exports.hb_blob_destroy(ptr) + } + } + } + + function createFace(blob: BlobInstace, index: number) { + const ptr = exports.hb_face_create(blob.ptr, index) + const upem = exports.hb_face_get_upem(ptr) + + return { + ptr, + upem, + /** + * Return the binary contents of an OpenType table. + * @param table Table name + * @returns + */ + reference_table(table: string) { + const blob = exports.hb_face_reference_table(ptr, hb_tag(table)) + const length = exports.hb_blob_get_length(blob) + if (!length) return + + const blobPtr = exports.hb_blob_get_data(blob, null) + return heapu8.subarray(blobPtr) + }, + getAxisInfos() { + const axis = exports.malloc(64 * 32) + const c = exports.malloc(4) + heapu32[c / 4] = 64 + exports.hb_ot_var_get_axis_infos(ptr, 0, c, axis) + const result: { [p: string]: { min: number; default: number; max: number }} = {} + Array.from({ length: heapu32[c / 4] }).forEach((_, i) => { + result[hb_untag(heapu32[axis / 4 + i * 8 + 1])] = { + min: heapf32[axis / 4 + i * 8 + 4], + default: heapf32[axis / 4 + i * 8 + 5], + max: heapf32[axis / 4 + i * 8 + 6] + } + }) + exports.free(c) + exports.free(axis) + + return result + }, + collectUnicodes() { + const unicodeSetPtr = exports.hb_set_create() + exports.hb_face_collect_unicodes(ptr, unicodeSetPtr) + const result = resolveTypedArrayFromSet(unicodeSetPtr, 'u32') + exports.hb_set_destroy(unicodeSetPtr) + return result + }, + destory() { + exports.hb_face_destroy(ptr) + } + } + } + + function resolveTypedArrayFromSet(ptr: number, type: 'u8' | 'u32' | 'i32' | 'f32') { + const heap: Uint8Array | Uint32Array | Int32Array | Float32Array = type === 'u32' + ? heapu32 + : type === 'i32' + ? heapi32 + : type === 'f32' + ? heapf32 + : heapu8 + + const bytesPerElment = type === 'u32' + ? Uint32Array.BYTES_PER_ELEMENT + : type === 'i32' + ? Int32Array.BYTES_PER_ELEMENT + : type === 'f32' + ? Float32Array.BYTES_PER_ELEMENT + : Uint8Array.BYTES_PER_ELEMENT + + const setCount = exports.hb_set_get_population(ptr) + const arrayPtr = exports.malloc(setCount * bytesPerElment) + const arrayOffset = arrayPtr / bytesPerElment + const array = heap.subarray(arrayOffset, arrayOffset + setCount) + heap.set(array, arrayOffset) + exports.hb_set_next_many( + ptr, + HB_SET_VALUE_INVALID, + arrayPtr, + setCount + ) + return array + } + + return { + createBlob, + createFace + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..65766d0 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,13 @@ +import { resolve } from 'path' +import { readFile } from 'fs/promises' +import { hb } from './hb' + +export async function initHB() { + const data = await readFile(resolve(__dirname, '../hb.wasm')) + + const wasm = await WebAssembly.instantiate(data) + + return hb(wasm.instance) +} + +export * from './hb' \ No newline at end of file diff --git a/src/schema/blob.ts b/src/schema/blob.ts new file mode 100644 index 0000000..3575476 --- /dev/null +++ b/src/schema/blob.ts @@ -0,0 +1,6 @@ +import { Pointer } from "./export" + +export interface BlobInstace { + ptr: Pointer + destory(): void +} \ No newline at end of file diff --git a/src/schema/export.ts b/src/schema/export.ts new file mode 100644 index 0000000..9cbc94e --- /dev/null +++ b/src/schema/export.ts @@ -0,0 +1,84 @@ +export type Pointer = number +type BCP47LanguageTag = string + +export enum BufferFlag { + HB_BUFFER_FLAG_DEFAULT = 0x0, + HB_BUFFER_FLAG_BOT = 0x1, /* Beginning-of-text */ + HB_BUFFER_FLAG_EOT = 0x2, /* End-of-text */ + HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x4, + HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x8, + HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x10, + HB_BUFFER_FLAG_VERIFY = 0x20, + HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x40, + HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL = 0x80, + HB_BUFFER_FLAG_DEFINED = 0xFF +} + +export enum ClusterLevel { + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, + HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT = 0 +} + +export enum GlyphFlag { + HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x1, + HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x2, + HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL = 0x4, + HB_GLYPH_FLAG_DEFINED = 0x7 +} + +export interface Exports { + memory: WebAssembly.Memory + malloc: (length: number) => Pointer + free: (ptr: Pointer) => void + free_ptr: () => Pointer + hb_blob_create: (data: Pointer, length: number, memoryMode: number, useData: Pointer, destroyFunction: Pointer) => Pointer + hb_blob_destroy: (ptr: Pointer) => void + hb_blob_get_length: (blob: Blob) => number + hb_blob_get_data: (blob: Blob, length: number | null) => Pointer + + hb_face_create: (blobPtr: Pointer, index: number) => Pointer + hb_face_get_upem: (facePtr: Pointer) => number + hb_face_destroy: (ptr: Pointer) => void + hb_face_reference_table: (ptr: Pointer, tag: number) => Blob + hb_face_collect_unicodes: (facePtr: Pointer, setPtr: Pointer) => void + hb_font_set_variations: (font: Pointer, variations: Pointer, variations_length: number) => void + hb_ot_var_get_axis_infos: (ptr: Pointer, start_offset: number, axes_count: Pointer, axes_array: Pointer) => number + + hb_set_create: () => Pointer + hb_set_destroy: (setPtr: Pointer) => void + hb_set_get_population: (setPtr: Pointer) => number + hb_set_next_many: ( + setPtr: Pointer, + greaterThanUnicodePtr: Pointer, + outputU32ArrayPtr: Pointer, + size: number, + ) => number + + hb_font_create: (facePtr: Pointer) => Pointer + hb_font_set_scale: (fontPtr: Pointer, xScale: number, yScale: number) => void + hb_font_glyph_to_string: (facePtr: Pointer, glyph: number, s: number, size: number) => void + hb_font_destroy: (ptr: Pointer) => void + hb_buffer_create: () => Pointer + hb_buffer_add_utf8: (bufferPtr: Pointer, stringPtr: Pointer, stringLength: number, itemOffset: number, itemLength: number) => void + hb_buffer_add_utf16: (bufferPtr: Pointer, stringPtr: Pointer, stringLength: number, itemOffset: number, itemLength: number) => void + hb_buffer_guess_segment_properties: (bufferPtr: Pointer) => void + hb_buffer_set_direction: (bufferPtr: Pointer, direction: number) => void + hb_shape: (fontPtr: Pointer, bufferPtr: Pointer, features: any, numFeatures: number) => void + hb_buffer_get_length: (bufferPtr: Pointer) => number + hb_buffer_get_glyph_infos: (bufferPtr: Pointer, length: number) => any + hb_buffer_get_glyph_positions: (bufferPtr: Pointer, length: number) => any + hb_buffer_destroy: (bufferPtr: Pointer) => void + hb_buffer_set_flags: (bufferPtr: Pointer, bufferFlag: BufferFlag) => void + hb_buffer_set_language: (bufferPtr: Pointer, language: string) => void + hb_buffer_set_script: (bufferPtr: Pointer, script: string) => void + hb_buffer_set_cluster_level: (bufferPtr: Pointer, cluster_level: ClusterLevel) => void + hb_glyph_info_get_glyph_flags: (bufferPtr: Pointer) => GlyphFlag + hbjs_glyph_svg: (font: Pointer, glyphId: number, pathBuffer: number, size: number) => number + hbjs_shape_with_trace: (font: Pointer, buffer: Pointer, features: Pointer, stop_at: number, stop_phase: number, outbuf: Pointer, buf_size: number) => number + + hb_language_from_string: (ptr: Pointer, len: number) => BCP47LanguageTag + + hb_script_from_string: (ptr: Pointer, len: number) => string +} \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..c1f8efc --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,17 @@ +export function hb_tag(s: string) { + return ( + (s.charCodeAt(0) & 0xFF) << 24 | + (s.charCodeAt(1) & 0xFF) << 16 | + (s.charCodeAt(2) & 0xFF) << 8 | + (s.charCodeAt(3) & 0xFF) << 0 + ) +} + +export function hb_untag(tag: number) { + return [ + String.fromCharCode((tag >> 24) & 0xFF), + String.fromCharCode((tag >> 16) & 0xFF), + String.fromCharCode((tag >> 8) & 0xFF), + String.fromCharCode((tag >> 0) & 0xFF) + ].join('') +} \ No newline at end of file diff --git a/test/face.spec.ts b/test/face.spec.ts new file mode 100644 index 0000000..9ed4712 --- /dev/null +++ b/test/face.spec.ts @@ -0,0 +1,54 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest' +import * as path from 'path' +import * as fs from 'fs' +import { initHB, hb as hbjs } from '../src/index' + +type HB = ReturnType +type Nullable = T | undefined | null +declare global { + var blob: Nullable> + var face: Nullable> +} +let hb: HB +beforeEach(async () => { + hb = await initHB() +}) + +afterEach(() => { + if (globalThis.blob) globalThis.blob.destory() + if (globalThis.face) globalThis.face.destory() + globalThis.blob = globalThis.face = null +}) + +describe('Face', () => { + it('collectUnicodes reflects codepoints supported by the font', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + const codepoints = [ + ...globalThis.face.collectUnicodes() + ] + expect(codepoints).to.include('a'.codePointAt(0)) + expect(codepoints).to.not.include('ا'.codePointAt(0)) + }) + + it('expose upem', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + expect(globalThis.face.upem).to.equal(1000) + }) + + it('getAxisInfos returns details of a variable font', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + expect(globalThis.face.getAxisInfos()).to.deep.equal({ + wght: { min: 100, default: 400, max: 900 }, + wdth: { min: 62.5, default: 100, max: 100 } + }) + }) + + it('getAxisInfos returns an empty object for a non-variable font', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + expect(Object.keys(globalThis.face.getAxisInfos())).to.have.length(0) + }) +}) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 4e2c2e2..69c4c8b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,9 +9,14 @@ "noImplicitAny": true, "noImplicitReturns": true, "strictNullChecks": true, + "moduleResolution": "NodeNext", "skipLibCheck": true, - "strictPropertyInitialization": true + "strictPropertyInitialization": true, + "paths": { + "~/*": ["./src/*"] + } }, + "include": ["./src/**/*.ts", "vitest.config.ts"], "exclude": [ "node_modules" ] diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 0000000..a681b9c --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'tsup' + +export default defineConfig({ + entry: ['src/index.ts'], + minify: true, + splitting: false, + sourcemap: true, + target: 'node16', + dts: true, + format: ['esm', 'cjs'] +}) \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..7cb5566 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,10 @@ +import { resolve } from 'path' +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + resolve: { + alias: [ + { find: '~', replacement: resolve(__dirname, './src') } + ] + } +}) \ No newline at end of file From c5573b3a961b6a3506a3cda5d30459059e4a1ae0 Mon Sep 17 00:00:00 2001 From: lynn Date: Wed, 9 Aug 2023 17:33:54 +0800 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- harfbuzz.ts | 289 ----------- hbjs.js | 450 ------------------ index.js | 12 - src/hb.ts | 273 ++++++++++- src/schema/buffer.ts | 21 + src/schema/face.ts | 16 + src/schema/font.ts | 12 + src/utils/index.ts | 10 + test/index.js | 185 ------- tests/buffer.spec.ts | 69 +++ {test => tests}/face.spec.ts | 0 tests/font.spec.ts | 60 +++ .../fonts/noto/NotoSans-Regular.ttf | Bin .../fonts/noto/NotoSansArabic-Variable.ttf | Bin {test => tests}/fonts/noto/OFL.txt | 0 tests/shape.spec.ts | 85 ++++ tsconfig.json | 4 +- 17 files changed, 544 insertions(+), 942 deletions(-) delete mode 100644 harfbuzz.ts delete mode 100644 hbjs.js delete mode 100644 index.js create mode 100644 src/schema/buffer.ts create mode 100644 src/schema/face.ts create mode 100644 src/schema/font.ts delete mode 100644 test/index.js create mode 100644 tests/buffer.spec.ts rename {test => tests}/face.spec.ts (100%) create mode 100644 tests/font.spec.ts rename {test => tests}/fonts/noto/NotoSans-Regular.ttf (100%) rename {test => tests}/fonts/noto/NotoSansArabic-Variable.ttf (100%) rename {test => tests}/fonts/noto/OFL.txt (100%) create mode 100644 tests/shape.spec.ts diff --git a/harfbuzz.ts b/harfbuzz.ts deleted file mode 100644 index 486f315..0000000 --- a/harfbuzz.ts +++ /dev/null @@ -1,289 +0,0 @@ -type Pointer = number; - -const HB_MEMORY_MODE_WRITABLE: number = 2; -const HB_SET_VALUE_INVALID: Pointer = -1; - -class HarfBuzzExports { - readonly heapu8: Uint8Array; - readonly heapu32: Uint32Array; - readonly heapi32: Int32Array; - readonly utf8Encoder: TextEncoder; - - //exported HarfBuzz methods - readonly malloc: (length: number) => Pointer - readonly free: (ptr: Pointer) => void - readonly free_ptr: () => Pointer - readonly hb_blob_create: (data: Pointer, length: number, memoryMode: number, useData: Pointer, destroyFunction: Pointer) => Pointer - readonly hb_blob_destroy: (ptr: Pointer) => void - readonly hb_face_create: (blobPtr: Pointer, index: number) => Pointer - readonly hb_face_get_upem: (facePtr: Pointer) => number - readonly hb_face_destroy: (ptr: Pointer) => void - readonly hb_font_create: (facePtr: Pointer) => Pointer - readonly hb_font_set_scale: (fontPtr: Pointer, xScale: number, yScale: number) => void - readonly hb_font_destroy: (ptr: Pointer) => void - readonly hb_face_collect_unicodes: (facePtr: Pointer, setPtr: Pointer) => void - readonly hb_set_create: () => Pointer - readonly hb_set_destroy: (setPtr: Pointer) => void - readonly hb_set_get_population: (setPtr: Pointer) => number - readonly hb_set_next_many: ( - setPtr: Pointer, - greaterThanUnicodePtr: Pointer, - outputU32ArrayPtr: Pointer, - size: number, - ) => number - readonly hb_buffer_create: () => Pointer - readonly hb_buffer_add_utf8: (bufferPtr: Pointer, stringPtr: Pointer, stringLength: number, itemOffset: number, itemLength: number) => void - readonly hb_buffer_guess_segment_properties: (bufferPtr: Pointer) => void - readonly hb_buffer_set_direction: (bufferPtr: Pointer, direction: number) => void - readonly hb_shape: (fontPtr: Pointer, bufferPtr: Pointer, features: any, numFeatures: number) => void - readonly hb_buffer_get_length: (bufferPtr: Pointer) => number - readonly hb_buffer_get_glyph_infos: (bufferPtr: Pointer, length: number) => any - readonly hb_buffer_get_glyph_positions: (bufferPtr: Pointer, length: number) => any - readonly hb_buffer_destroy: (bufferPtr: Pointer) => void - - constructor(exports: any) { - this.heapu8 = new Uint8Array(exports.memory.buffer); - this.heapu32 = new Uint32Array(exports.memory.buffer); - this.heapi32 = new Int32Array(exports.memory.buffer); - this.utf8Encoder = new TextEncoder(); - - this.malloc = exports.malloc; - this.free = exports.free; - this.free_ptr = exports.free_ptr; - this.hb_blob_destroy = exports.hb_blob_destroy; - this.hb_blob_create = exports.hb_blob_create; - this.hb_face_create = exports.hb_face_create; - this.hb_face_get_upem = exports.hb_face_get_upem; - this.hb_face_destroy = exports.hb_face_destroy; - this.hb_face_collect_unicodes = exports.hb_face_collect_unicodes; - this.hb_set_create = exports.hb_set_create; - this.hb_set_destroy = exports.hb_set_destroy; - this.hb_set_get_population = exports.hb_set_get_population; - this.hb_set_next_many = exports.hb_set_next_many; - this.hb_font_create = exports.hb_font_create; - this.hb_font_set_scale = exports.hb_font_set_scale; - this.hb_font_destroy = exports.hb_font_destroy; - this.hb_buffer_create = exports.hb_buffer_create; - this.hb_buffer_add_utf8 = exports.hb_buffer_add_utf8; - this.hb_buffer_guess_segment_properties = exports.hb_buffer_guess_segment_properties; - this.hb_buffer_set_direction = exports.hb_buffer_set_direction; - this.hb_shape = exports.hb_shape; - this.hb_buffer_get_length = exports.hb_buffer_get_length; - this.hb_buffer_get_glyph_infos = exports.hb_buffer_get_glyph_infos; - this.hb_buffer_get_glyph_positions = exports.hb_buffer_get_glyph_positions; - this.hb_buffer_destroy = exports.hb_buffer_destroy; - } - -} - -let hb: HarfBuzzExports; - -class CString { - readonly ptr: Pointer; - readonly length: number; - - constructor(text: string) { - var bytes = hb.utf8Encoder.encode(text); - this.ptr = hb.malloc(bytes.byteLength); - hb.heapu8.set(bytes, this.ptr); - this.length = bytes.byteLength; - } - - destroy() { - hb.free(this.ptr); - } -} - -export class HarfBuzzBlob { - readonly ptr: Pointer; - - constructor(data: Uint8Array) { - let blobPtr = hb.malloc(data.length); - hb.heapu8.set(data, blobPtr); - this.ptr = hb.hb_blob_create(blobPtr, data.byteLength, HB_MEMORY_MODE_WRITABLE, blobPtr, hb.free_ptr()); - } - - destroy() { - hb.hb_blob_destroy(this.ptr); - } -} - -function typedArrayFromSet(setPtr: Pointer, arrayType: T) { - const heap = hb[`heap${arrayType}`]; - const bytesPerElment = heap.BYTES_PER_ELEMENT; - const setCount = hb.hb_set_get_population(setPtr); - const arrayPtr = hb.malloc( - setCount * bytesPerElment, - ); - const arrayOffset = arrayPtr / bytesPerElment; - const array = heap.subarray( - arrayOffset, - arrayOffset + setCount, - ) as typeof hb[`heap${T}`]; - heap.set(array, arrayOffset); - hb.hb_set_next_many( - setPtr, - HB_SET_VALUE_INVALID, - arrayPtr, - setCount, - ); - return array; -} - -export class HarfBuzzFace { - readonly ptr: Pointer; - - constructor(blob: HarfBuzzBlob, index: number) { - this.ptr = hb.hb_face_create(blob.ptr, index); - } - - getUnitsPerEM() { - return hb.hb_face_get_upem(this.ptr); - } - - collectUnicodes() { - const unicodeSetPtr = hb.hb_set_create(); - hb.hb_face_collect_unicodes(this.ptr, unicodeSetPtr); - const result = typedArrayFromSet(unicodeSetPtr, 'u32'); - hb.hb_set_destroy(unicodeSetPtr); - return result; - } - - destroy() { - hb.hb_face_destroy(this.ptr); - } -} - -export class HarfBuzzFont { - readonly ptr: Pointer - readonly unitsPerEM: number - - constructor(face: HarfBuzzFace) { - this.ptr = hb.hb_font_create(face.ptr); - this.unitsPerEM = face.getUnitsPerEM(); - } - - setScale(xScale: number, yScale: number) { - hb.hb_font_set_scale(this.ptr, xScale, yScale); - } - - destroy() { - hb.hb_font_destroy(this.ptr); - } -} - -export type HarfBuzzDirection = "ltr" | "rtl" | "ttb" | "btt" - -class GlyphInformation { - readonly GlyphId: number - readonly Cluster: number - readonly XAdvance: number - readonly YAdvance: number - readonly XOffset: number - readonly YOffset: number - - constructor(glyphId: number, cluster: number, xAdvance: number, yAdvance: number, xOffset: number, yOffset: number) { - this.GlyphId = glyphId; - this.Cluster = cluster; - this.XAdvance = xAdvance; - this.YAdvance = yAdvance; - this.XOffset = xOffset; - this.YOffset = yOffset; - } -} - -export class HarfBuzzBuffer { - readonly ptr: Pointer - - constructor() { - this.ptr = hb.hb_buffer_create(); - } - - addText(text: string) { - let str = new CString(text); - hb.hb_buffer_add_utf8(this.ptr, str.ptr, str.length, 0, str.length); - str.destroy(); - } - - guessSegmentProperties() { - hb.hb_buffer_guess_segment_properties(this.ptr); - } - - setDirection(direction: HarfBuzzDirection) { - let d = { "ltr": 4, "rtl": 5, "ttb": 6, "btt": 7 }[direction]; - hb.hb_buffer_set_direction(this.ptr, d); - } - - json() { - var length = hb.hb_buffer_get_length(this.ptr); - var result = new Array(); - var infosPtr32 = hb.hb_buffer_get_glyph_infos(this.ptr, 0) / 4; - var positionsPtr32 = hb.hb_buffer_get_glyph_positions(this.ptr, 0) / 4; - var infos = hb.heapu32.subarray(infosPtr32, infosPtr32 + 5 * length); - var positions = hb.heapi32.subarray(positionsPtr32, positionsPtr32 + 5 * length); - for (var i = 0; i < length; ++i) { - result.push(new GlyphInformation( - infos[i * 5 + 0], - infos[i * 5 + 2], - positions[i * 5 + 0], - positions[i * 5 + 1], - positions[i * 5 + 2], - positions[i * 5 + 3])); - } - return result; - } - - destroy() { - hb.hb_buffer_destroy(this.ptr) - } -} - -export function shape(text: string, font: HarfBuzzFont, features: any): Array { - let buffer = new HarfBuzzBuffer(); - buffer.addText(text); - buffer.guessSegmentProperties(); - buffer.shape(font, features); - let result = buffer.json(); - buffer.destroy(); - return result; -} - -export function getWidth(text: string, font: HarfBuzzFont, fontSizeInPixel: number, features: any): number { - let scale = fontSizeInPixel / font.unitsPerEM; - let shapeResult = shape(text, font, features); - let totalWidth = shapeResult.map((glyphInformation) => { - return glyphInformation.XAdvance; - }).reduce((previous, current, i, arr) => { - return previous + current; - }, 0.0); - - return totalWidth * scale; -} - -export const harfbuzzFonts = new Map(); - -export function loadHarfbuzz(webAssemblyUrl: string): Promise { - return fetch(webAssemblyUrl).then(response => { - return response.arrayBuffer(); - }).then(wasm => { - return WebAssembly.instantiate(wasm); - }).then(result => { - //@ts-ignore - hb = new HarfBuzzExports(result.instance.exports); - }); -} - -export function loadAndCacheFont(fontName: string, fontUrl: string): Promise { - return fetch(fontUrl).then((response) => { - return response.arrayBuffer().then((blob) => { - let fontBlob = new Uint8Array(blob); - let harfbuzzBlob = new HarfBuzzBlob(fontBlob); - let harfbuzzFace = new HarfBuzzFace(harfbuzzBlob, 0); - let harfbuzzFont = new HarfBuzzFont(harfbuzzFace); - - harfbuzzFonts.set(fontName, harfbuzzFont); - harfbuzzFace.destroy(); - harfbuzzBlob.destroy(); - }); - }); -} \ No newline at end of file diff --git a/hbjs.js b/hbjs.js deleted file mode 100644 index 78bdbde..0000000 --- a/hbjs.js +++ /dev/null @@ -1,450 +0,0 @@ -function hbjs(instance) { - 'use strict'; - - var exports = instance.exports; - var heapu8 = new Uint8Array(exports.memory.buffer); - var heapu32 = new Uint32Array(exports.memory.buffer); - var heapi32 = new Int32Array(exports.memory.buffer); - var heapf32 = new Float32Array(exports.memory.buffer); - var utf8Decoder = new TextDecoder("utf8"); - - var HB_MEMORY_MODE_WRITABLE = 2; - var HB_SET_VALUE_INVALID = -1; - - function hb_tag(s) { - return ( - (s.charCodeAt(0) & 0xFF) << 24 | - (s.charCodeAt(1) & 0xFF) << 16 | - (s.charCodeAt(2) & 0xFF) << 8 | - (s.charCodeAt(3) & 0xFF) << 0 - ); - } - - function _hb_untag(tag) { - return [ - String.fromCharCode((tag >> 24) & 0xFF), - String.fromCharCode((tag >> 16) & 0xFF), - String.fromCharCode((tag >> 8) & 0xFF), - String.fromCharCode((tag >> 0) & 0xFF) - ].join(''); - } - - function _buffer_flag(s) { - if (s == "BOT") { return 0x1; } - if (s == "EOT") { return 0x2; } - if (s == "PRESERVE_DEFAULT_IGNORABLES") { return 0x4; } - if (s == "REMOVE_DEFAULT_IGNORABLES") { return 0x8; } - if (s == "DO_NOT_INSERT_DOTTED_CIRCLE") { return 0x10; } - if (s == "PRODUCE_UNSAFE_TO_CONCAT") { return 0x40; } - return 0x0; - } - - /** - * Create an object representing a Harfbuzz blob. - * @param {string} blob A blob of binary data (usually the contents of a font file). - **/ - function createBlob(blob) { - var blobPtr = exports.malloc(blob.byteLength); - heapu8.set(new Uint8Array(blob), blobPtr); - var ptr = exports.hb_blob_create(blobPtr, blob.byteLength, HB_MEMORY_MODE_WRITABLE, blobPtr, exports.free_ptr()); - return { - ptr: ptr, - /** - * Free the object. - */ - destroy: function () { exports.hb_blob_destroy(ptr); } - }; - } - - /** - * Return the typed array of HarfBuzz set contents. - * @template {typeof Uint8Array | typeof Uint32Array | typeof Int32Array | typeof Float32Array} T - * @param {number} setPtr Pointer of set - * @param {T} arrayClass Typed array class - * @returns {InstanceType} Typed array instance - */ - function typedArrayFromSet(setPtr, arrayClass) { - let heap = heapu8; - if (arrayClass === Uint32Array) { - heap = heapu32; - } else if (arrayClass === Int32Array) { - heap = heapi32; - } else if (arrayClass === Float32Array) { - heap = heapf32; - } - const bytesPerElment = arrayClass.BYTES_PER_ELEMENT; - const setCount = exports.hb_set_get_population(setPtr); - const arrayPtr = exports.malloc( - setCount * bytesPerElment, - ); - const arrayOffset = arrayPtr / bytesPerElment; - const array = heap.subarray( - arrayOffset, - arrayOffset + setCount, - ); - heap.set(array, arrayOffset); - exports.hb_set_next_many( - setPtr, - HB_SET_VALUE_INVALID, - arrayPtr, - setCount, - ); - return array; - } - - /** - * Create an object representing a Harfbuzz face. - * @param {object} blob An object returned from `createBlob`. - * @param {number} index The index of the font in the blob. (0 for most files, - * or a 0-indexed font number if the `blob` came form a TTC/OTC file.) - **/ - function createFace(blob, index) { - var ptr = exports.hb_face_create(blob.ptr, index); - const upem = exports.hb_face_get_upem(ptr); - return { - ptr: ptr, - upem, - /** - * Return the binary contents of an OpenType table. - * @param {string} table Table name - */ - reference_table: function(table) { - var blob = exports.hb_face_reference_table(ptr, hb_tag(table)); - var length = exports.hb_blob_get_length(blob); - if (!length) { return; } - var blobptr = exports.hb_blob_get_data(blob, null); - var table_string = heapu8.subarray(blobptr, blobptr+length); - return table_string; - }, - /** - * Return variation axis infos - */ - getAxisInfos: function() { - var axis = exports.malloc(64 * 32); - var c = exports.malloc(4); - heapu32[c / 4] = 64; - exports.hb_ot_var_get_axis_infos(ptr, 0, c, axis); - var result = {}; - Array.from({ length: heapu32[c / 4] }).forEach(function (_, i) { - result[_hb_untag(heapu32[axis / 4 + i * 8 + 1])] = { - min: heapf32[axis / 4 + i * 8 + 4], - default: heapf32[axis / 4 + i * 8 + 5], - max: heapf32[axis / 4 + i * 8 + 6] - }; - }); - exports.free(c); - exports.free(axis); - return result; - }, - /** - * Return unicodes the face supports - */ - collectUnicodes: function() { - var unicodeSetPtr = exports.hb_set_create(); - exports.hb_face_collect_unicodes(ptr, unicodeSetPtr); - var result = typedArrayFromSet(unicodeSetPtr, Uint32Array); - exports.hb_set_destroy(unicodeSetPtr); - return result; - }, - /** - * Free the object. - */ - destroy: function () { - exports.hb_face_destroy(ptr); - }, - }; - } - - var pathBufferSize = 65536; // should be enough for most glyphs - var pathBuffer = exports.malloc(pathBufferSize); // permanently allocated - - var nameBufferSize = 256; // should be enough for most glyphs - var nameBuffer = exports.malloc(nameBufferSize); // permanently allocated - - /** - * Create an object representing a Harfbuzz font. - * @param {object} blob An object returned from `createFace`. - **/ - function createFont(face) { - var ptr = exports.hb_font_create(face.ptr); - - /** - * Return a glyph as an SVG path string. - * @param {number} glyphId ID of the requested glyph in the font. - **/ - function glyphToPath(glyphId) { - var svgLength = exports.hbjs_glyph_svg(ptr, glyphId, pathBuffer, pathBufferSize); - return svgLength > 0 ? utf8Decoder.decode(heapu8.subarray(pathBuffer, pathBuffer + svgLength)) : ""; - } - - /** - * Return glyph name. - * @param {number} glyphId ID of the requested glyph in the font. - **/ - function glyphName(glyphId) { - exports.hb_font_glyph_to_string( - ptr, - glyphId, - nameBuffer, - nameBufferSize - ); - var array = heapu8.subarray(nameBuffer, nameBuffer + nameBufferSize); - return utf8Decoder.decode(array.slice(0, array.indexOf(0))); - } - - return { - ptr: ptr, - glyphName: glyphName, - glyphToPath: glyphToPath, - /** - * Return a glyph as a JSON path string - * based on format described on https://svgwg.org/specs/paths/#InterfaceSVGPathSegment - * @param {number} glyphId ID of the requested glyph in the font. - **/ - glyphToJson: function (glyphId) { - var path = glyphToPath(glyphId); - return path.replace(/([MLQCZ])/g, '|$1 ').split('|').filter(function (x) { return x.length; }).map(function (x) { - var row = x.split(/[ ,]/g); - return { type: row[0], values: row.slice(1).filter(function (x) { return x.length; }).map(function (x) { return +x; }) }; - }); - }, - /** - * Set the font's scale factor, affecting the position values returned from - * shaping. - * @param {number} xScale Units to scale in the X dimension. - * @param {number} yScale Units to scale in the Y dimension. - **/ - setScale: function (xScale, yScale) { - exports.hb_font_set_scale(ptr, xScale, yScale); - }, - /** - * Set the font's variations. - * @param {object} variations Dictionary of variations to set - **/ - setVariations: function (variations) { - var entries = Object.entries(variations); - var vars = exports.malloc(8 * entries.length); - entries.forEach(function (entry, i) { - heapu32[vars / 4 + i * 2 + 0] = hb_tag(entry[0]); - heapf32[vars / 4 + i * 2 + 1] = entry[1]; - }); - exports.hb_font_set_variations(ptr, vars, entries.length); - exports.free(vars); - }, - /** - * Free the object. - */ - destroy: function () { exports.hb_font_destroy(ptr); } - }; - } - - /** - * Use when you know the input range should be ASCII. - * Faster than encoding to UTF-8 - **/ - function createAsciiString(text) { - var ptr = exports.malloc(text.length + 1); - for (let i = 0; i < text.length; ++i) { - const char = text.charCodeAt(i); - if (char > 127) throw new Error('Expected ASCII text'); - heapu8[ptr + i] = char; - } - heapu8[ptr + text.length] = 0; - return { - ptr: ptr, - length: text.length, - free: function () { exports.free(ptr); } - }; - } - - function createJsString(text) { - const ptr = exports.malloc(text.length * 2); - const words = new Uint16Array(exports.memory.buffer, ptr, text.length); - for (let i = 0; i < words.length; ++i) words[i] = text.charCodeAt(i); - return { - ptr: ptr, - length: words.length, - free: function () { exports.free(ptr); } - }; - } - - /** - * Create an object representing a Harfbuzz buffer. - **/ - function createBuffer() { - var ptr = exports.hb_buffer_create(); - return { - ptr: ptr, - /** - * Add text to the buffer. - * @param {string} text Text to be added to the buffer. - **/ - addText: function (text) { - const str = createJsString(text); - exports.hb_buffer_add_utf16(ptr, str.ptr, str.length, 0, str.length); - str.free(); - }, - /** - * Set buffer script, language and direction. - * - * This needs to be done before shaping. - **/ - guessSegmentProperties: function () { - return exports.hb_buffer_guess_segment_properties(ptr); - }, - /** - * Set buffer direction explicitly. - * @param {string} direction: One of "ltr", "rtl", "ttb" or "btt" - */ - setDirection: function (dir) { - exports.hb_buffer_set_direction(ptr, { - ltr: 4, - rtl: 5, - ttb: 6, - btt: 7 - }[dir] || 0); - }, - /** - * Set buffer flags explicitly. - * @param {string[]} flags: A list of strings which may be either: - * "BOT" - * "EOT" - * "PRESERVE_DEFAULT_IGNORABLES" - * "REMOVE_DEFAULT_IGNORABLES" - * "DO_NOT_INSERT_DOTTED_CIRCLE" - * "PRODUCE_UNSAFE_TO_CONCAT" - */ - setFlags: function (flags) { - var flagValue = 0 - flags.forEach(function (s) { - flagValue |= _buffer_flag(s); - }) - - exports.hb_buffer_set_flags(ptr,flagValue); - }, - /** - * Set buffer language explicitly. - * @param {string} language: The buffer language - */ - setLanguage: function (language) { - var str = createAsciiString(language); - exports.hb_buffer_set_language(ptr, exports.hb_language_from_string(str.ptr,-1)); - str.free(); - }, - /** - * Set buffer script explicitly. - * @param {string} script: The buffer script - */ - setScript: function (script) { - var str = createAsciiString(script); - exports.hb_buffer_set_script(ptr, exports.hb_script_from_string(str.ptr,-1)); - str.free(); - }, - - /** - * Set the Harfbuzz clustering level. - * - * Affects the cluster values returned from shaping. - * @param {number} level: Clustering level. See the Harfbuzz manual chapter - * on Clusters. - **/ - setClusterLevel: function (level) { - exports.hb_buffer_set_cluster_level(ptr, level) - }, - /** - * Return the buffer contents as a JSON object. - * - * After shaping, this function will return an array of glyph information - * objects. Each object will have the following attributes: - * - * - g: The glyph ID - * - cl: The cluster ID - * - ax: Advance width (width to advance after this glyph is painted) - * - ay: Advance height (height to advance after this glyph is painted) - * - dx: X displacement (adjustment in X dimension when painting this glyph) - * - dy: Y displacement (adjustment in Y dimension when painting this glyph) - * - flags: Glyph flags like `HB_GLYPH_FLAG_UNSAFE_TO_BREAK` (0x1) - **/ - json: function () { - var length = exports.hb_buffer_get_length(ptr); - var result = []; - var infosPtr = exports.hb_buffer_get_glyph_infos(ptr, 0); - var infosPtr32 = infosPtr / 4; - var positionsPtr32 = exports.hb_buffer_get_glyph_positions(ptr, 0) / 4; - var infos = heapu32.subarray(infosPtr32, infosPtr32 + 5 * length); - var positions = heapi32.subarray(positionsPtr32, positionsPtr32 + 5 * length); - for (var i = 0; i < length; ++i) { - result.push({ - g: infos[i * 5 + 0], - cl: infos[i * 5 + 2], - ax: positions[i * 5 + 0], - ay: positions[i * 5 + 1], - dx: positions[i * 5 + 2], - dy: positions[i * 5 + 3], - flags: exports.hb_glyph_info_get_glyph_flags(infosPtr + i * 20) - }); - } - return result; - }, - /** - * Free the object. - */ - destroy: function () { exports.hb_buffer_destroy(ptr); } - }; - } - - /** - * Shape a buffer with a given font. - * - * This returns nothing, but modifies the buffer. - * - * @param {object} font: A font returned from `createFont` - * @param {object} buffer: A buffer returned from `createBuffer` and suitably - * prepared. - * @param {object} features: (Currently unused). - */ - function shape(font, buffer, features) { - exports.hb_shape(font.ptr, buffer.ptr, 0, 0); - } - - /** - * Shape a buffer with a given font, returning a JSON trace of the shaping process. - * - * This function supports "partial shaping", where the shaping process is - * terminated after a given lookup ID is reached. If the user requests the function - * to terminate shaping after an ID in the GSUB phase, GPOS table lookups will be - * processed as normal. - * - * @param {object} font: A font returned from `createFont` - * @param {object} buffer: A buffer returned from `createBuffer` and suitably - * prepared. - * @param {object} features: A dictionary of OpenType features to apply. - * @param {number} stop_at: A lookup ID at which to terminate shaping. - * @param {number} stop_phase: Either 0 (don't terminate shaping), 1 (`stop_at` - refers to a lookup ID in the GSUB table), 2 (`stop_at` refers to a lookup - ID in the GPOS table). - */ - - function shapeWithTrace(font, buffer, features, stop_at, stop_phase) { - var bufLen = 1024 * 1024; - var traceBuffer = exports.malloc(bufLen); - var featurestr = createAsciiString(features); - var traceLen = exports.hbjs_shape_with_trace(font.ptr, buffer.ptr, featurestr.ptr, stop_at, stop_phase, traceBuffer, bufLen); - featurestr.free(); - var trace = utf8Decoder.decode(heapu8.subarray(traceBuffer, traceBuffer + traceLen - 1)); - exports.free(traceBuffer); - return JSON.parse(trace); - } - - return { - createBlob: createBlob, - createFace: createFace, - createFont: createFont, - createBuffer: createBuffer, - shape: shape, - shapeWithTrace: shapeWithTrace - }; -}; - -// Should be replaced with something more reliable -try { module.exports = hbjs; } catch(e) {} diff --git a/index.js b/index.js deleted file mode 100644 index 3931d54..0000000 --- a/index.js +++ /dev/null @@ -1,12 +0,0 @@ -var fs = require('fs'); -var path = require('path'); -var hbjs = require('./hbjs.js') - -module.exports = new Promise(function (resolve, reject) { - fs.readFile(path.resolve(__dirname, 'hb.wasm'), function (err, data) { - if (err) { reject(err); return; } - WebAssembly.instantiate(data).then(function (result) { - resolve(hbjs(result.instance)); - }, reject); - }); -}); diff --git a/src/hb.ts b/src/hb.ts index 0f6baac..7457d91 100644 --- a/src/hb.ts +++ b/src/hb.ts @@ -1,6 +1,9 @@ -import type { Exports } from '~/schema/export' +import type { Exports, GlyphFlag } from '~/schema/export' import type { BlobInstace } from '~/schema/blob' -import { hb_tag, hb_untag } from '~/utils/index' +import type { FaceInstance } from '~/schema/face' +import type { FontInstance } from '~/schema/font' +import type { BufferInstance } from '~/schema/buffer' +import { hb_tag, hb_untag, buffer_flag } from '~/utils/index' const HB_MEMORY_MODE_WRITABLE = 2 const HB_SET_VALUE_INVALID = -1 @@ -12,6 +15,7 @@ export function hb(instance: WebAssembly.Instance) { const heapu32 = new Uint32Array(memory.buffer) const heapi32 = new Int32Array(memory.buffer) const heapf32 = new Float32Array(memory.buffer) + const utf8Decoder = new TextDecoder('utf8') /** * Create an object representing a Harfbuzz blob. @@ -30,6 +34,12 @@ export function hb(instance: WebAssembly.Instance) { } } + /** + * Create an object representing a Harfbuzz face. + * @param {BlobInstace} blob An object returned from `createBlob`. + * @param {number} index The index of the font in the blob. (0 for most files, + * or a 0-indexed font number if the `blob` came form a TTC/OTC file.) + **/ function createFace(blob: BlobInstace, index: number) { const ptr = exports.hb_face_create(blob.ptr, index) const upem = exports.hb_face_get_upem(ptr) @@ -71,7 +81,7 @@ export function hb(instance: WebAssembly.Instance) { collectUnicodes() { const unicodeSetPtr = exports.hb_set_create() exports.hb_face_collect_unicodes(ptr, unicodeSetPtr) - const result = resolveTypedArrayFromSet(unicodeSetPtr, 'u32') + const result = resolveTypedArrayFromSet(unicodeSetPtr, 'u32') as Uint32Array exports.hb_set_destroy(unicodeSetPtr) return result }, @@ -81,6 +91,207 @@ export function hb(instance: WebAssembly.Instance) { } } + var pathBufferSize = 65536; // should be enough for most glyphs + var pathBuffer = exports.malloc(pathBufferSize); // permanently allocated + + var nameBufferSize = 256; // should be enough for most glyphs + var nameBuffer = exports.malloc(nameBufferSize); // permanently allocated + + function createFont(face: FaceInstance) { + const ptr = exports.hb_font_create(face.ptr) + + /** + * Return a glyph as an SVG path string. + * @param {number} glyphId ID of the requested glyph in the font. + **/ + function glyphToPath(glyphId: number) { + const length = exports.hbjs_glyph_svg(ptr, glyphId, pathBuffer, pathBufferSize) + return length > 0 ? utf8Decoder.decode(heapu8.subarray(pathBuffer, pathBuffer + length)) : '' + } + + /** + * Return glyph name. + * @param {number} glyphId ID of the requested glyph in the font. + **/ + function glyphName(glyphId: number) { + exports.hb_font_glyph_to_string(ptr, glyphId, nameBuffer, nameBufferSize) + const array = heapu8.subarray(nameBuffer, nameBuffer + nameBufferSize) + return utf8Decoder.decode(array.slice(0, array.indexOf(0))) + } + + return { + ptr, + glyphName, + glyphToPath, + /** + * Return a glyph as a JSON path string + * based on format described on https://svgwg.org/specs/paths/#InterfaceSVGPathSegment + * @param {number} glyphId ID of the requested glyph in the font. + **/ + glyphToJson(glyphId: number) { + const path = glyphToPath(glyphId) + return path.replace(/([MLQCZ])/g, '|$1 ') + .split('|') + .filter(v => v.length) + .map(v => { + const row = v.split(/[ ,]/g) + return { + type: row[0], + values: row.slice(1).filter(v => v.length).map(Number) + } + }) + }, + /** + * Set the font's scale factor, affecting the position values returned from + * shaping. + * @param {number} xScale Units to scale in the X dimension. + * @param {number} yScale Units to scale in the Y dimension. + **/ + setScale(xScale: number, yScale: number) { + exports.hb_font_set_scale(ptr, xScale, yScale) + }, + /** + * Set the font's variations. + * @param {object} variations Dictionary of variations to set + **/ + setVariations (variations: Record) { + var entries = Object.entries(variations) + var vars = exports.malloc(8 * entries.length) + entries.forEach(function (entry, i) { + heapu32[vars / 4 + i * 2 + 0] = hb_tag(entry[0]); + heapf32[vars / 4 + i * 2 + 1] = entry[1]; + }); + exports.hb_font_set_variations(ptr, vars, entries.length) + exports.free(vars) + }, + destroy() { + exports.hb_font_destroy(ptr) + } + } + } + + function createBuffer() { + const ptr = exports.hb_buffer_create() + + return { + ptr, + /** + * Add text to the buffer. + * @param {string} text Text to be added to the buffer. + **/ + addText(text: string) { + const str = createJsString(text) + exports.hb_buffer_add_utf16(ptr, str.ptr, str.length, 0, str.length) + str.free() + }, + /** + * Set buffer script, language and direction. + * + * This needs to be done before shaping. + **/ + guessSegmentProperties() { + return exports.hb_buffer_guess_segment_properties(ptr) + }, + /** + * Set buffer direction explicitly. + * @param {string} direction: One of "ltr", "rtl", "ttb" or "btt" + */ + setDirection(dir: 'ltr' | 'rtl' | 'ttb' | 'btt') { + exports.hb_buffer_set_direction(ptr, { + ltr: 4, + rtl: 5, + ttb: 6, + btt: 7 + }[dir] || 0) + }, + /** + * Set buffer flags explicitly. + * @param {string[]} flags: A list of strings which may be either: + */ + setFlags(flags: Array<'BOT' | 'EOT' | 'PRESERVE_DEFAULT_IGNORABLES' | 'REMOVE_DEFAULT_IGNORABLES' | 'DO_NOT_INSERT_DOTTED_CIRCLE' | 'PRODUCE_UNSAFE_TO_CONCAT'>) { + const flag = flags.reduce((res, item) => res |= buffer_flag(item), 0) + + exports.hb_buffer_set_flags(ptr, flag) + }, + /** + * Set buffer language explicitly. + * @param {string} language: The buffer language + */ + setLanguage(language: string) { + const str = createAsciiString(language) + exports.hb_buffer_set_language(ptr, exports.hb_language_from_string(str.ptr, -1)) + str.free() + }, + /** + * Set buffer script explicitly. + * @param {string} script: The buffer script + */ + setScript (script: string) { + var str = createAsciiString(script) + exports.hb_buffer_set_script(ptr, exports.hb_script_from_string(str.ptr, -1)) + str.free() + }, + /** + * Set the Harfbuzz clustering level. + * + * Affects the cluster values returned from shaping. + * @param {number} level: Clustering level. See the Harfbuzz manual chapter + * on Clusters. + **/ + setClusterLevel (level: number) { + exports.hb_buffer_set_cluster_level(ptr, level) + }, + /** + * Return the buffer contents as a JSON object. + * + * After shaping, this function will return an array of glyph information + * objects. Each object will have the following attributes: + * + * - g: The glyph ID + * - cl: The cluster ID + * - ax: Advance width (width to advance after this glyph is painted) + * - ay: Advance height (height to advance after this glyph is painted) + * - dx: X displacement (adjustment in X dimension when painting this glyph) + * - dy: Y displacement (adjustment in Y dimension when painting this glyph) + * - flags: Glyph flags like `HB_GLYPH_FLAG_UNSAFE_TO_BREAK` (0x1) + **/ + json() { + const length = exports.hb_buffer_get_length(ptr) + const infosPtr = exports.hb_buffer_get_glyph_infos(ptr, 0) + const infosPtr32 = infosPtr / 4 + const positionsPtr32 = exports.hb_buffer_get_glyph_positions(ptr, 0) / 4 + const infos = heapu32.subarray(infosPtr32, infosPtr32 + 5 * length) + const positions = heapi32.subarray(positionsPtr32, positionsPtr32 + 5 * length) + const result: Array<{ + g: number + cl: number + ax: number + ay: number + dx: number + dy: number + flags: GlyphFlag + }> = [] + for (var i = 0; i < length; ++i) { + result.push({ + g: infos[i * 5 + 0], + cl: infos[i * 5 + 2], + ax: positions[i * 5 + 0], + ay: positions[i * 5 + 1], + dx: positions[i * 5 + 2], + dy: positions[i * 5 + 3], + flags: exports.hb_glyph_info_get_glyph_flags(infosPtr + i * 20) + }); + } + return result + }, + destroy() { exports.hb_buffer_destroy(ptr) } + } + } + + function shape(font: FontInstance, buffer: BufferInstance) { + exports.hb_shape(font.ptr, buffer.ptr, 0, 0) + } + function resolveTypedArrayFromSet(ptr: number, type: 'u8' | 'u32' | 'i32' | 'f32') { const heap: Uint8Array | Uint32Array | Int32Array | Float32Array = type === 'u32' ? heapu32 @@ -112,8 +323,62 @@ export function hb(instance: WebAssembly.Instance) { return array } + function createJsString(text: string) { + const ptr = exports.malloc(text.length * 2) + const words = new Uint16Array(exports.memory.buffer, ptr, text.length) + for (let i = 0; i < words.length; ++i) words[i] = text.charCodeAt(i) + return { + ptr, + length: words.length, + free() { exports.free(ptr) } + } + } + + /** + * Use when you know the input range should be ASCII. + * Faster than encoding to UTF-8 + **/ + function createAsciiString(text: string) { + const length = text.length + const ptr = exports.malloc(length + 1) + for (let i = 0; i < length; ++i) { + const char = text.charCodeAt(i) + if (char > 127) throw new Error('Expected ASCII text') + heapu8[ptr + i] = char + } + heapu8[ptr + length] = 0 + + return { + ptr, + length, + free() { exports.free(ptr) } + } + } + + function shapeWithTrace( + font: FontInstance, + buffer: BufferInstance, + features: string, + stop_at: number, + stop_phase: 0 | 1 | 2 + ) { + const length = 1024 * 1024 + const traceBuffer = exports.malloc(length) + const featureStr = createAsciiString(features) + const traceLength = exports.hbjs_shape_with_trace(font.ptr, buffer.ptr, featureStr.ptr, stop_at, stop_phase, traceBuffer, length) + featureStr.free() + const trace = utf8Decoder.decode(heapu8.subarray(traceBuffer, traceBuffer + traceLength - 1)) + exports.free(traceBuffer) + + return JSON.parse(trace) + } + return { createBlob, - createFace + createFace, + createFont, + createBuffer, + shape, + shapeWithTrace } } \ No newline at end of file diff --git a/src/schema/buffer.ts b/src/schema/buffer.ts new file mode 100644 index 0000000..342bb2c --- /dev/null +++ b/src/schema/buffer.ts @@ -0,0 +1,21 @@ +import { GlyphFlag } from "./export" + +export interface BufferInstance { + ptr: number + addText(text: string): void + guessSegmentProperties(): void + setDirection(dir: 'ltr' | 'rtl' | 'ttb' | 'btt'): void + setFlags(flags: Array<'BOT' | 'EOT' | 'PRESERVE_DEFAULT_IGNORABLES' | 'REMOVE_DEFAULT_IGNORABLES' | 'DO_NOT_INSERT_DOTTED_CIRCLE' | 'PRODUCE_UNSAFE_TO_CONCAT'>): void + setLanguage(language: string): void + setScript(script: string): void + setClusterLevel(level: number): void + json(): Array<{ + g: number + cl: number + ax: number + ay: number + dx: number + dy: number + flags: GlyphFlag + }> +} \ No newline at end of file diff --git a/src/schema/face.ts b/src/schema/face.ts new file mode 100644 index 0000000..01efcec --- /dev/null +++ b/src/schema/face.ts @@ -0,0 +1,16 @@ +import { Pointer } from "./export"; + +export interface FaceInstance { + ptr: Pointer + upem: Pointer + reference_table(table: string): Uint8Array | undefined + getAxisInfos(): { + [p: string]: { + min: number + default: number + max: number + } + } + collectUnicodes(): Uint32Array + destory(): void +} \ No newline at end of file diff --git a/src/schema/font.ts b/src/schema/font.ts new file mode 100644 index 0000000..4c07489 --- /dev/null +++ b/src/schema/font.ts @@ -0,0 +1,12 @@ +export interface FontInstance { + ptr: number + glyphToPath(id: number): string + glyphName(id: number): string + glyphToJson: Array<{ + type: string + values: number[] + }> + setScale(x: number, y: number): void + setVariations (variations: Record): void + destroy(): void +} \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts index c1f8efc..b4f8f80 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -14,4 +14,14 @@ export function hb_untag(tag: number) { String.fromCharCode((tag >> 8) & 0xFF), String.fromCharCode((tag >> 0) & 0xFF) ].join('') +} + +export function buffer_flag(s: string) { + if (s == "BOT") { return 0x1 } + if (s == "EOT") { return 0x2 } + if (s == "PRESERVE_DEFAULT_IGNORABLES") { return 0x4 } + if (s == "REMOVE_DEFAULT_IGNORABLES") { return 0x8 } + if (s == "DO_NOT_INSERT_DOTTED_CIRCLE") { return 0x10 } + if (s == "PRODUCE_UNSAFE_TO_CONCAT") { return 0x40 } + return 0x0 } \ No newline at end of file diff --git a/test/index.js b/test/index.js deleted file mode 100644 index 0976650..0000000 --- a/test/index.js +++ /dev/null @@ -1,185 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const {expect} = require('chai'); -let hb; - -before(async function () { - hb = await require('..'); -}); - -afterEach(function () { - if (this.blob) this.blob.destroy(); - if (this.face) this.face.destroy(); - if (this.font) this.font.destroy(); - if (this.buffer) this.buffer.destroy(); - this.blob = this.face = this.font = this.buffer = null; -}); - -describe('Face', function () { - it('collectUnicodes reflects codepoints supported by the font', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - const codepoints = [...this.face.collectUnicodes()]; - expect(codepoints).to.include('a'.codePointAt(0)); - expect(codepoints).not.to.include('ا'.codePointAt(0)); - }); - - it('exposes upem', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - expect(this.face.upem).to.equal(1000); - }); - - it('getAxisInfos returns details of a variable font', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf'))); - this.face = hb.createFace(this.blob); - expect(this.face.getAxisInfos()).to.deep.equal({ - wght: {min: 100, default: 400, max: 900}, - wdth: {min: 62.5, default: 100, max: 100} - }); - }); - - it('getAxisInfos returns an empty object for a non-variable font', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - expect(Object.keys(this.face.getAxisInfos())).to.have.lengthOf(0); - }); -}); - -describe('Font', function () { - it('glyphName returns names for glyph ids', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - expect(this.font.glyphName(20)).to.equal('one'); - }); - - it('setScale affects advances', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - this.buffer = hb.createBuffer(); - this.buffer.addText('a'); - this.buffer.guessSegmentProperties(); - this.font.setScale(1000 * 2, 1000 * 2); - hb.shape(this.font, this.buffer) - const glyphs = this.buffer.json(); - expect(glyphs[0].ax).to.equal(561 * 2); - }); - - it('setVariations affects advances', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - this.font.setVariations({'wght': 789}); - this.buffer = hb.createBuffer(); - this.buffer.addText('آلو'); - this.buffer.guessSegmentProperties(); - hb.shape(this.font, this.buffer) - const glyphs = this.buffer.json(); - expect(glyphs[0].ax).to.equal(526); - }); -}); - -describe('Buffer', function () { - it('setDirection controls direction of glyphs', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - this.buffer = hb.createBuffer(); - this.buffer.addText('rtl'); - this.buffer.setDirection('rtl'); - hb.shape(this.font, this.buffer) - const glyphs = this.buffer.json(); - expect(glyphs[0].g).to.equal(79); // l - expect(glyphs[1].g).to.equal(87); // t - expect(glyphs[2].g).to.equal(85); // r - }); - - it('setClusterLevel affects cluster merging', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - this.buffer = hb.createBuffer(); - this.buffer.setClusterLevel(1); - this.buffer.addText('x́'); - this.buffer.guessSegmentProperties(); - hb.shape(this.font, this.buffer) - const glyphs = this.buffer.json(); - expect(glyphs[0].cl).to.equal(0); - expect(glyphs[1].cl).to.equal(1); - }); - - it('setFlags with PRESERVE_DEFAULT_IGNORABLES affects glyph ids', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - this.buffer = hb.createBuffer(); - this.buffer.addText('\u200dhi'); - this.buffer.setFlags(['PRESERVE_DEFAULT_IGNORABLES']); - this.buffer.guessSegmentProperties(); - hb.shape(this.font, this.buffer) - const glyphs = this.buffer.json(); - expect(glyphs[0].g).not.to.equal(3 /* space */); - }); -}); - -describe('shape', function () { - it('shape Latin string', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - this.buffer = hb.createBuffer(); - this.buffer.addText('abc'); - this.buffer.guessSegmentProperties(); - hb.shape(this.font, this.buffer) - const glyphs = this.buffer.json(); - expect(glyphs[0]).to.deep.equal({cl: 0, g: 68, ax: 561, ay: 0, dx: 0, dy: 0, flags: 0} /* a */); - expect(glyphs[1]).to.deep.equal({cl: 1, g: 69, ax: 615, ay: 0, dx: 0, dy: 0, flags: 0} /* b */); - expect(glyphs[2]).to.deep.equal({cl: 2, g: 70, ax: 480, ay: 0, dx: 0, dy: 0, flags: 0} /* c */); - }); - - it('shape Arabic string', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - this.buffer = hb.createBuffer(); - this.buffer.addText('أبجد'); - this.buffer.guessSegmentProperties(); - hb.shape(this.font, this.buffer) - const glyphs = this.buffer.json(); - expect(glyphs[0]).to.deep.equal({cl: 3, g: 213, ax: 532, ay: 0, dx: 0, dy: 0, flags: 1} /* د */); - expect(glyphs[1]).to.deep.equal({cl: 2, g: 529, ax: 637, ay: 0, dx: 0, dy: 0, flags: 1} /* ج */); - expect(glyphs[2]).to.deep.equal({cl: 1, g: 101, ax: 269, ay: 0, dx: 0, dy: 0, flags: 0} /* ب */); - expect(glyphs[3]).to.deep.equal({cl: 0, g: 50, ax: 235, ay: 0, dx: 0, dy: 0, flags: 0} /* أ */); - }); - - it('shape with tracing', function () { - this.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))); - this.face = hb.createFace(this.blob); - this.font = hb.createFont(this.face); - this.buffer = hb.createBuffer(); - this.buffer.addText('abc'); - this.buffer.guessSegmentProperties(); - const result = hb.shapeWithTrace(this.font, this.buffer, 0, 0) - expect(result).to.have.lengthOf(42); - expect(result[0]).to.deep.equal({ - "m": "start table GSUB script tag 'latn'", - "glyphs": true, - "t": [ - {cl: 0, g: 68}, - {cl: 1, g: 69}, - {cl: 2, g: 70}, - ], - }); - expect(result[41]).to.deep.equal({ - "m": "end table GPOS script tag 'latn'", - "glyphs": true, - "t": [ - {cl: 0, g: 68, ax: 561, ay: 0, dx: 0, dy: 0}, - {cl: 1, g: 69, ax: 615, ay: 0, dx: 0, dy: 0}, - {cl: 2, g: 70, ax: 480, ay: 0, dx: 0, dy: 0}, - ], - }); - }); -}); diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts new file mode 100644 index 0000000..5b40efe --- /dev/null +++ b/tests/buffer.spec.ts @@ -0,0 +1,69 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest' +import * as path from 'path' +import * as fs from 'fs' +import { initHB, hb as hbjs } from '../src/index' + +type HB = ReturnType +type Nullable = T | undefined | null +declare global { + var blob: Nullable> + var face: Nullable> + var font: Nullable> + var buffer: Nullable> +} +let hb: HB +beforeEach(async () => { + hb = await initHB() +}) + +afterEach(() => { + if (globalThis.buffer) globalThis.buffer.destroy() + if (globalThis.font) globalThis.font.destroy() + if (globalThis.face) globalThis.face.destory() + if (globalThis.blob) globalThis.blob.destory() + globalThis.blob = globalThis.face = globalThis.font = globalThis.buffer = null +}) + +describe('Buffer', () => { + it('setDirection controls direction of glyphs', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + globalThis.buffer = hb.createBuffer() + globalThis.buffer.addText('rtl') + globalThis.buffer.setDirection('rtl') + hb.shape(globalThis.font, globalThis.buffer) + const glyphs = globalThis.buffer.json() + + expect(glyphs[0].g).to.equal(79) // l + expect(glyphs[1].g).to.equal(87) // t + expect(glyphs[2].g).to.equal(85) // r + }) + + it('setClusterLevel affects cluster merging', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + globalThis.buffer = hb.createBuffer() + globalThis.buffer.setClusterLevel(1) + globalThis.buffer.addText('x́') + globalThis.buffer.guessSegmentProperties() + hb.shape(globalThis.font, globalThis.buffer) + const glyphs = globalThis.buffer.json() + expect(glyphs[0].cl).to.equal(0) + expect(glyphs[1].cl).to.equal(1) + }) + + it('setFlags with PRESERVE_DEFAULT_IGNORABLES affects glyph ids', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + globalThis.buffer = hb.createBuffer() + globalThis.buffer.addText('\u200dhi') + globalThis.buffer.setFlags(['REMOVE_DEFAULT_IGNORABLES']) + globalThis.buffer.guessSegmentProperties() + hb.shape(globalThis.font, globalThis.buffer) + const glyphs = globalThis.buffer.json() + expect(glyphs[0].g).not.to.equal(3 /* space */) + }) +}) \ No newline at end of file diff --git a/test/face.spec.ts b/tests/face.spec.ts similarity index 100% rename from test/face.spec.ts rename to tests/face.spec.ts diff --git a/tests/font.spec.ts b/tests/font.spec.ts new file mode 100644 index 0000000..3fb51b7 --- /dev/null +++ b/tests/font.spec.ts @@ -0,0 +1,60 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest' +import * as path from 'path' +import * as fs from 'fs' +import { initHB, hb as hbjs } from '../src/index' + +type HB = ReturnType +type Nullable = T | undefined | null +declare global { + var blob: Nullable> + var face: Nullable> + var font: Nullable> + var buffer: Nullable> +} +let hb: HB +beforeEach(async () => { + hb = await initHB() +}) + +afterEach(() => { + if (globalThis.buffer) globalThis.buffer.destroy() + if (globalThis.font) globalThis.font.destroy() + if (globalThis.face) globalThis.face.destory() + if (globalThis.blob) globalThis.blob.destory() + globalThis.blob = globalThis.face = globalThis.font = globalThis.buffer = null +}) + +describe('Font', () => { + it('glyphName returns names for glyph ids', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + expect(globalThis.font.glyphName(20)).to.equal('one') + }) + + it('setScale affects advances', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + globalThis.buffer = hb.createBuffer() + globalThis.buffer.addText('a') + globalThis.buffer.guessSegmentProperties() + globalThis.font.setScale(1000 * 2, 1000 * 2) + hb.shape(globalThis.font, globalThis.buffer) + const glyphs = globalThis.buffer.json() + expect(glyphs[0].ax).to.equal(561 * 2) + }) + + it('setVariations affects advances', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + globalThis.font.setVariations({ wght: 789 }) + globalThis.buffer = hb.createBuffer() + globalThis.buffer.addText('آلو') + globalThis.buffer.guessSegmentProperties() + hb.shape(globalThis.font, globalThis.buffer) + const glyphs = globalThis.buffer.json() + expect(glyphs[0].ax).to.equal(526) + }) +}) \ No newline at end of file diff --git a/test/fonts/noto/NotoSans-Regular.ttf b/tests/fonts/noto/NotoSans-Regular.ttf similarity index 100% rename from test/fonts/noto/NotoSans-Regular.ttf rename to tests/fonts/noto/NotoSans-Regular.ttf diff --git a/test/fonts/noto/NotoSansArabic-Variable.ttf b/tests/fonts/noto/NotoSansArabic-Variable.ttf similarity index 100% rename from test/fonts/noto/NotoSansArabic-Variable.ttf rename to tests/fonts/noto/NotoSansArabic-Variable.ttf diff --git a/test/fonts/noto/OFL.txt b/tests/fonts/noto/OFL.txt similarity index 100% rename from test/fonts/noto/OFL.txt rename to tests/fonts/noto/OFL.txt diff --git a/tests/shape.spec.ts b/tests/shape.spec.ts new file mode 100644 index 0000000..175d4d0 --- /dev/null +++ b/tests/shape.spec.ts @@ -0,0 +1,85 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest' +import * as path from 'path' +import * as fs from 'fs' +import { initHB, hb as hbjs } from '../src/index' + +type HB = ReturnType +type Nullable = T | undefined | null +declare global { + var blob: Nullable> + var face: Nullable> + var font: Nullable> + var buffer: Nullable> +} +let hb: HB +beforeEach(async () => { + hb = await initHB() +}) + +afterEach(() => { + if (globalThis.buffer) globalThis.buffer.destroy() + if (globalThis.font) globalThis.font.destroy() + if (globalThis.face) globalThis.face.destory() + if (globalThis.blob) globalThis.blob.destory() + globalThis.blob = globalThis.face = globalThis.font = globalThis.buffer = null +}) + +describe('shape', () => { + it('shape Latin string', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + globalThis.buffer = hb.createBuffer() + globalThis.buffer.addText('abc') + globalThis.buffer.guessSegmentProperties() + hb.shape(globalThis.font, globalThis.buffer) + const glyphs = globalThis.buffer.json() + expect(glyphs[0]).to.deep.equal({cl: 0, g: 68, ax: 561, ay: 0, dx: 0, dy: 0, flags: 0} /* a */); + expect(glyphs[1]).to.deep.equal({cl: 1, g: 69, ax: 615, ay: 0, dx: 0, dy: 0, flags: 0} /* b */); + expect(glyphs[2]).to.deep.equal({cl: 2, g: 70, ax: 480, ay: 0, dx: 0, dy: 0, flags: 0} /* c */); + }) + + it('shape Arabic string', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + globalThis.buffer = hb.createBuffer() + globalThis.buffer.addText('أبجد') + globalThis.buffer.guessSegmentProperties() + hb.shape(globalThis.font, globalThis.buffer) + const glyphs = globalThis.buffer.json() + expect(glyphs[0]).to.deep.equal({cl: 3, g: 213, ax: 532, ay: 0, dx: 0, dy: 0, flags: 1} /* د */) + expect(glyphs[1]).to.deep.equal({cl: 2, g: 529, ax: 637, ay: 0, dx: 0, dy: 0, flags: 1} /* ج */) + expect(glyphs[2]).to.deep.equal({cl: 1, g: 101, ax: 269, ay: 0, dx: 0, dy: 0, flags: 0} /* ب */) + expect(glyphs[3]).to.deep.equal({cl: 0, g: 50, ax: 235, ay: 0, dx: 0, dy: 0, flags: 0} /* أ */) + }) + + it('shape with tracing', () => { + globalThis.blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf'))) + globalThis.face = hb.createFace(globalThis.blob, 0) + globalThis.font = hb.createFont(globalThis.face) + globalThis.buffer = hb.createBuffer() + globalThis.buffer.addText('abc') + globalThis.buffer.guessSegmentProperties() + const result = hb.shapeWithTrace(globalThis.font, globalThis.buffer, '', 0, 0) + expect(result).to.have.lengthOf(42) + expect(result[0]).to.deep.equal({ + "m": "start table GSUB script tag 'latn'", + "glyphs": true, + "t": [ + {cl: 0, g: 68}, + {cl: 1, g: 69}, + {cl: 2, g: 70}, + ], + }) + expect(result[41]).to.deep.equal({ + "m": "end table GPOS script tag 'latn'", + "glyphs": true, + "t": [ + {cl: 0, g: 68, ax: 561, ay: 0, dx: 0, dy: 0}, + {cl: 1, g: 69, ax: 615, ay: 0, dx: 0, dy: 0}, + {cl: 2, g: 70, ax: 480, ay: 0, dx: 0, dy: 0}, + ], + }) + }) +}) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 69c4c8b..ee22c6c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,8 @@ { "compileOnSave": true, "compilerOptions": { - "module": "es6", - "target": "es6", + "module": "ES6", + "target": "ES6", "sourceMap": true, "alwaysStrict": true, "noImplicitThis": true, From 7930ecadb72e4735372b1a7cea3628a7c46ff88f Mon Sep 17 00:00:00 2001 From: lynn Date: Wed, 9 Aug 2023 17:45:21 +0800 Subject: [PATCH 3/8] fix: add eslint --- .eslintignore | 5 + .eslintrc.js | 155 ++++ package.json | 26 +- pnpm-lock.yaml | 1734 +++++++++++++++++++++++++++++++++++++++++- src/schema/blob.ts | 2 +- src/schema/buffer.ts | 2 +- src/schema/export.ts | 3 +- src/schema/face.ts | 2 +- 8 files changed, 1895 insertions(+), 34 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..3150993 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +.eslintrc.js +examples +node_modules +harfbuzz +*.wasm \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..3e67c5a --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,155 @@ +const { defineConfig } = require('eslint-define-config') + +module.exports = defineConfig({ + env: { + es6: true, + browser: true, + node: true, + }, + plugins: ['@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:import/recommended', + 'plugin:eslint-comments/recommended', + 'plugin:@typescript-eslint/recommended' + ], + settings: { + 'import/resolver': { + node: { extensions: ['.js', '.mjs', '.ts', '.d.ts'] }, + }, + }, + overrides: [ + { + files: ['*.ts'], + rules: { + 'no-undef': 'off', + }, + }, + { + files: ['**/__tests__/**'], + rules: { + 'no-console': 'off' + }, + }, + { + files: ['*.d.ts'], + rules: { + 'import/no-duplicates': 'off', + }, + }, + { + files: ['*.js'], + rules: { + '@typescript-eslint/no-var-requires': 'off', + }, + } + ], + rules: { + // js/ts + 'no-console': ['warn', { allow: ['error'] }], + 'no-debugger': 'warn', + 'no-constant-condition': ['error', { checkLoops: false }], + 'no-restricted-syntax': ['error', 'LabeledStatement', 'WithStatement'], + 'no-return-await': 'error', + 'no-var': 'error', + 'no-empty': ['error', { allowEmptyCatch: true }], + 'prefer-const': [ + 'warn', + { destructuring: 'all', ignoreReadBeforeAssign: true }, + ], + 'prefer-arrow-callback': [ + 'error', + { allowNamedFunctions: false, allowUnboundThis: true }, + ], + 'object-shorthand': [ + 'error', + 'always', + { ignoreConstructors: false, avoidQuotes: true }, + ], + 'prefer-rest-params': 'error', + 'prefer-spread': 'error', + 'prefer-template': 'error', + + 'no-redeclare': 'off', + '@typescript-eslint/no-redeclare': 'error', + + // best-practice + 'array-callback-return': 'error', + 'block-scoped-var': 'error', + 'no-alert': 'warn', + 'no-case-declarations': 'error', + 'no-multi-str': 'error', + 'no-with': 'error', + 'no-void': 'error', + + 'sort-imports': [ + 'warn', + { + ignoreCase: false, + ignoreDeclarationSort: true, + ignoreMemberSort: false, + memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], + allowSeparatedGroups: false, + }, + ], + + // stylistic-issues + 'prefer-exponentiation-operator': 'error', + + // ts + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'off', + '@typescript-eslint/consistent-type-imports': [ + 'error', + { disallowTypeAnnotations: false }, + ], + + // import + 'import/first': 'error', + 'import/no-duplicates': 'error', + 'import/order': [ + 'error', + { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + + pathGroups: [ + { + pattern: 'vue', + group: 'external', + position: 'before', + }, + { + pattern: '@vue/**', + group: 'external', + position: 'before', + }, + { + pattern: '@element-plus/**', + group: 'internal', + }, + ], + pathGroupsExcludedImportTypes: ['type'], + }, + ], + 'import/no-unresolved': 'off', + 'import/namespace': 'off', + 'import/default': 'off', + 'import/no-named-as-default': 'off', + 'import/no-named-as-default-member': 'off', + 'import/named': 'off', + + // eslint-plugin-eslint-comments + 'eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }], + }, +}) \ No newline at end of file diff --git a/package.json b/package.json index 4e91838..008b1f8 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,19 @@ "hb.wasm" ], "scripts": { - "build": "tsup", - "test": "vitest" + "prepare": "simple-git-hooks", + "build": "rimraf dist && tsup", + "test": "vitest", + "lint": "eslint ./src/**/*.ts", + "lint:fix": "eslint ./src/**/*.ts --fix" + }, + "simple-git-hooks": { + "pre-commit": "pnpm exec lint-staged" + }, + "lint-staged": { + "packages/**/*.ts": [ + "pnpm lint" + ] }, "exports": { "./package.json": "./package.json", @@ -56,8 +67,19 @@ "homepage": "https://github.com/harfbuzz/harfbuzzjs#readme", "devDependencies": { "@types/node": "^20.4.9", + "@typescript-eslint/eslint-plugin": "^6.3.0", "chai": "^4.3.7", + "eslint": "^8.46.0", + "eslint-config-standard": "^17.1.0", + "eslint-define-config": "^1.22.0", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-import": "^2.28.0", + "eslint-plugin-n": "^16.0.1", + "eslint-plugin-promise": "^6.1.1", + "lint-staged": "^13.2.3", "mocha": "^10.2.0", + "rimraf": "^5.0.1", + "simple-git-hooks": "^2.9.0", "tsup": "^7.2.0", "typescript": "^5.1.6", "vitest": "^0.34.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78994fc..5789c98 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,45 @@ devDependencies: '@types/node': specifier: ^20.4.9 version: 20.4.9 + '@typescript-eslint/eslint-plugin': + specifier: ^6.3.0 + version: 6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0)(typescript@5.1.6) chai: specifier: ^4.3.7 version: 4.3.7 + eslint: + specifier: ^8.46.0 + version: 8.46.0 + eslint-config-standard: + specifier: ^17.1.0 + version: 17.1.0(eslint-plugin-import@2.28.0)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.46.0) + eslint-define-config: + specifier: ^1.22.0 + version: 1.22.0 + eslint-plugin-eslint-comments: + specifier: ^3.2.0 + version: 3.2.0(eslint@8.46.0) + eslint-plugin-import: + specifier: ^2.28.0 + version: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0) + eslint-plugin-n: + specifier: ^16.0.1 + version: 16.0.1(eslint@8.46.0) + eslint-plugin-promise: + specifier: ^6.1.1 + version: 6.1.1(eslint@8.46.0) + lint-staged: + specifier: ^13.2.3 + version: 13.2.3 mocha: specifier: ^10.2.0 version: 10.2.0 + rimraf: + specifier: ^5.0.1 + version: 5.0.1 + simple-git-hooks: + specifier: ^2.9.0 + version: 2.9.0 tsup: specifier: ^7.2.0 version: 7.2.0(typescript@5.1.6) @@ -26,6 +59,11 @@ devDependencies: packages: + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + /@esbuild/android-arm64@0.17.19: resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} @@ -422,6 +460,75 @@ packages: dev: true optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.46.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.46.0 + eslint-visitor-keys: 3.4.2 + dev: true + + /@eslint-community/regexpp@4.6.2: + resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.1: + resolution: {integrity: sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@8.1.1) + espree: 9.6.1 + globals: 13.20.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.46.0: + resolution: {integrity: sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.10: + resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + /@jest/schemas@29.6.0: resolution: {integrity: sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -480,6 +587,13 @@ packages: fastq: 1.15.0 dev: true + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -494,10 +608,154 @@ packages: resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} dev: true + /@types/json-schema@7.0.12: + resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + /@types/node@20.4.9: resolution: {integrity: sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ==} dev: true + /@types/semver@7.5.0: + resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + dev: true + + /@typescript-eslint/eslint-plugin@6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0)(typescript@5.1.6): + resolution: {integrity: sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.6.2 + '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + '@typescript-eslint/scope-manager': 6.3.0 + '@typescript-eslint/type-utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + '@typescript-eslint/utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + '@typescript-eslint/visitor-keys': 6.3.0 + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.46.0 + graphemer: 1.4.0 + ignore: 5.2.4 + natural-compare: 1.4.0 + natural-compare-lite: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.1(typescript@5.1.6) + typescript: 5.1.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@6.3.0(eslint@8.46.0)(typescript@5.1.6): + resolution: {integrity: sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.3.0 + '@typescript-eslint/types': 6.3.0 + '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) + '@typescript-eslint/visitor-keys': 6.3.0 + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.46.0 + typescript: 5.1.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@6.3.0: + resolution: {integrity: sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.3.0 + '@typescript-eslint/visitor-keys': 6.3.0 + dev: true + + /@typescript-eslint/type-utils@6.3.0(eslint@8.46.0)(typescript@5.1.6): + resolution: {integrity: sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) + '@typescript-eslint/utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.46.0 + ts-api-utils: 1.0.1(typescript@5.1.6) + typescript: 5.1.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@6.3.0: + resolution: {integrity: sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@6.3.0(typescript@5.1.6): + resolution: {integrity: sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.3.0 + '@typescript-eslint/visitor-keys': 6.3.0 + debug: 4.3.4(supports-color@8.1.1) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.1(typescript@5.1.6) + typescript: 5.1.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@6.3.0(eslint@8.46.0)(typescript@5.1.6): + resolution: {integrity: sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) + '@types/json-schema': 7.0.12 + '@types/semver': 7.5.0 + '@typescript-eslint/scope-manager': 6.3.0 + '@typescript-eslint/types': 6.3.0 + '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) + eslint: 8.46.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@6.3.0: + resolution: {integrity: sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.3.0 + eslint-visitor-keys: 3.4.2 + dev: true + /@vitest/expect@0.34.1: resolution: {integrity: sha512-q2CD8+XIsQ+tHwypnoCk8Mnv5e6afLFvinVGCq3/BOT4kQdVQmY6rRfyKkwcg635lbliLPqbunXZr+L1ssUWiQ==} dependencies: @@ -536,6 +794,14 @@ packages: pretty-format: 29.6.2 dev: true + /acorn-jsx@5.3.2(acorn@8.9.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.9.0 + dev: true + /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} @@ -547,16 +813,45 @@ packages: hasBin: true dev: true + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + /ansi-colors@4.1.1: resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} engines: {node: '>=6'} dev: true + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: true + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -569,6 +864,11 @@ packages: engines: {node: '>=10'} dev: true + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} dev: true @@ -585,15 +885,86 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.2 + is-array-buffer: 3.0.2 + dev: true + + /array-includes@3.1.6: + resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + get-intrinsic: 1.2.1 + is-string: 1.0.7 + dev: true + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true + /array.prototype.findlastindex@1.2.2: + resolution: {integrity: sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + es-shim-unscopables: 1.0.0 + get-intrinsic: 1.2.1 + dev: true + + /array.prototype.flat@1.3.1: + resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.flatmap@1.3.1: + resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + es-shim-unscopables: 1.0.0 + dev: true + + /arraybuffer.prototype.slice@1.0.1: + resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.2 + define-properties: 1.2.0 + get-intrinsic: 1.2.1 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + dev: true + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true + /astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -627,6 +998,12 @@ packages: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: true + /builtins@5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.5.4 + dev: true + /bundle-require@4.0.1(esbuild@0.18.20): resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -642,6 +1019,18 @@ packages: engines: {node: '>=8'} dev: true + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} @@ -668,6 +1057,11 @@ packages: supports-color: 7.2.0 dev: true + /chalk@5.2.0: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + /check-error@1.0.2: resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} dev: true @@ -687,6 +1081,34 @@ packages: fsevents: 2.3.2 dev: true + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + dev: true + + /cli-truncate@3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + slice-ansi: 5.0.0 + string-width: 5.1.2 + dev: true + /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: @@ -706,6 +1128,15 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + dev: true + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -724,6 +1155,17 @@ packages: which: 2.0.2 dev: true + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -749,6 +1191,18 @@ packages: type-detect: 4.0.8 dev: true + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-properties@1.2.0: + resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + /diff-sequences@29.4.3: resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -766,10 +1220,101 @@ packages: path-type: 4.0.0 dev: true + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /es-abstract@1.22.1: + resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.1 + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.2.1 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.12.3 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.0 + safe-array-concat: 1.0.0 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.7 + string.prototype.trimend: 1.0.6 + string.prototype.trimstart: 1.0.6 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.11 + dev: true + + /es-set-tostringtag@2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + has-tostringtag: 1.0.0 + dev: true + + /es-shim-unscopables@1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + /esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} @@ -835,48 +1380,322 @@ packages: engines: {node: '>=6'} dev: true + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: true - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + /eslint-config-standard@17.1.0(eslint-plugin-import@2.28.0)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.46.0): + resolution: {integrity: sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + eslint: ^8.0.1 + eslint-plugin-import: ^2.25.2 + eslint-plugin-n: '^15.0.0 || ^16.0.0 ' + eslint-plugin-promise: ^6.0.0 dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 + eslint: 8.46.0 + eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0) + eslint-plugin-n: 16.0.1(eslint@8.46.0) + eslint-plugin-promise: 6.1.1(eslint@8.46.0) dev: true - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} - engines: {node: '>=8.6.0'} + /eslint-define-config@1.22.0: + resolution: {integrity: sha512-pckNJppFwC4AX+AGK63aa4sX5BluPwWwHES3fq/ER0jDR2U2czwlngg38B4EQ2ibvofufc+R5QfmdPKI6+74vQ==} + engines: {node: ^16.13.0 || >=18.0.0, npm: '>=7.0.0', pnpm: '>= 8.6.0'} + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 + debug: 3.2.7 + is-core-module: 2.13.0 + resolve: 1.22.4 + transitivePeerDependencies: + - supports-color dev: true - /fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint@8.46.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true dependencies: - reusify: 1.0.4 + '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + debug: 3.2.7 + eslint: 8.46.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color dev: true - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} + /eslint-plugin-es-x@7.2.0(eslint@8.46.0): + resolution: {integrity: sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' dependencies: - to-regex-range: 5.0.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) + '@eslint-community/regexpp': 4.6.2 + eslint: 8.46.0 + dev: true + + /eslint-plugin-eslint-comments@3.2.0(eslint@8.46.0): + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + escape-string-regexp: 1.0.5 + eslint: 8.46.0 + ignore: 5.2.4 + dev: true + + /eslint-plugin-import@2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0): + resolution: {integrity: sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + array-includes: 3.1.6 + array.prototype.findlastindex: 1.2.2 + array.prototype.flat: 1.3.1 + array.prototype.flatmap: 1.3.1 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.46.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint@8.46.0) + has: 1.0.3 + is-core-module: 2.13.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.6 + object.groupby: 1.0.0 + object.values: 1.1.6 + resolve: 1.22.4 + semver: 6.3.1 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-n@16.0.1(eslint@8.46.0): + resolution: {integrity: sha512-CDmHegJN0OF3L5cz5tATH84RPQm9kG+Yx39wIqIwPR2C0uhBGMWfbbOtetR83PQjjidA5aXMu+LEFw1jaSwvTA==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) + builtins: 5.0.1 + eslint: 8.46.0 + eslint-plugin-es-x: 7.2.0(eslint@8.46.0) + ignore: 5.2.4 + is-core-module: 2.13.0 + minimatch: 3.1.2 + resolve: 1.22.4 + semver: 7.5.4 + dev: true + + /eslint-plugin-promise@6.1.1(eslint@8.46.0): + resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.46.0 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.2: + resolution: {integrity: sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.46.0: + resolution: {integrity: sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) + '@eslint-community/regexpp': 4.6.2 + '@eslint/eslintrc': 2.1.1 + '@eslint/js': 8.46.0 + '@humanwhocodes/config-array': 0.11.10 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4(supports-color@8.1.1) + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.2 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.20.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.9.0 + acorn-jsx: 5.3.2(acorn@8.9.0) + eslint-visitor-keys: 3.4.2 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 dev: true /find-up@5.0.0: @@ -887,11 +1706,37 @@ packages: path-exists: 4.0.0 dev: true + /flat-cache@3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.7 + rimraf: 3.0.2 + dev: true + /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true dev: true + /flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: true + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -904,6 +1749,24 @@ packages: dev: true optional: true + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name@1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -913,11 +1776,28 @@ packages: resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} dev: true + /get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + dev: true + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} dev: true + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + dev: true + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -925,6 +1805,25 @@ packages: is-glob: 4.0.3 dev: true + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@10.3.3: + resolution: {integrity: sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.2.2 + minimatch: 9.0.3 + minipass: 7.0.2 + path-scurry: 1.10.1 + dev: true + /glob@7.1.6: resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} dependencies: @@ -947,6 +1846,20 @@ packages: path-is-absolute: 1.0.1 dev: true + /globals@13.20.0: + resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.0 + dev: true + /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -959,11 +1872,55 @@ packages: slash: 3.0.0 dev: true + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} dev: true + /has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true @@ -974,11 +1931,34 @@ packages: engines: {node: '>=10.17.0'} dev: true + /human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + dev: true + /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} dev: true + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -990,6 +1970,29 @@ packages: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true + /internal-slot@1.0.5: + resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -997,6 +2000,32 @@ packages: binary-extensions: 2.2.0 dev: true + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.0: + resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1007,6 +2036,11 @@ packages: engines: {node: '>=8'} dev: true + /is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -1014,30 +2048,106 @@ packages: is-extglob: 2.1.1 dev: true + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: true + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + /is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} dev: true + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} dev: true + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.11 + dev: true + /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} dev: true + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true + /jackspeak@2.2.2: + resolution: {integrity: sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + /joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -1050,10 +2160,33 @@ packages: argparse: 2.0.1 dev: true + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: true + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -1063,6 +2196,48 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true + /lint-staged@13.2.3: + resolution: {integrity: sha512-zVVEXLuQIhr1Y7R7YAWx4TZLdvuzk7DnmrsTNL0fax6Z3jrpFcas+vKbzxhhvp6TA55m1SQuWkpzI1qbfDZbAg==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + dependencies: + chalk: 5.2.0 + cli-truncate: 3.1.0 + commander: 10.0.1 + debug: 4.3.4(supports-color@8.1.1) + execa: 7.2.0 + lilconfig: 2.1.0 + listr2: 5.0.8 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-inspect: 1.12.3 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.3.1 + transitivePeerDependencies: + - enquirer + - supports-color + dev: true + + /listr2@5.0.8: + resolution: {integrity: sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==} + engines: {node: ^14.13.1 || >=16.0.0} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.20 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.3.0 + rxjs: 7.8.1 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + /load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1080,6 +2255,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + /lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} dev: true @@ -1092,12 +2271,34 @@ packages: is-unicode-supported: 0.1.0 dev: true + /log-update@4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + dev: true + /loupe@2.3.6: resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} dependencies: get-func-name: 2.0.0 dev: true + /lru-cache@10.0.0: + resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==} + engines: {node: 14 || >=16.14} + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + /magic-string@0.30.2: resolution: {integrity: sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==} engines: {node: '>=12'} @@ -1127,6 +2328,11 @@ packages: engines: {node: '>=6'} dev: true + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -1140,6 +2346,22 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass@7.0.2: + resolution: {integrity: sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + /mlly@1.4.0: resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} dependencies: @@ -1205,6 +2427,14 @@ packages: hasBin: true dev: true + /natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -1217,11 +2447,64 @@ packages: path-key: 3.1.1 dev: true + /npm-run-path@5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} dev: true + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.fromentries@2.0.6: + resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + + /object.groupby@1.0.0: + resolution: {integrity: sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + get-intrinsic: 1.2.1 + dev: true + + /object.values@1.1.6: + resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -1235,6 +2518,25 @@ packages: mimic-fn: 2.1.0 dev: true + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -1256,6 +2558,20 @@ packages: p-limit: 3.1.0 dev: true + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1271,6 +2587,23 @@ packages: engines: {node: '>=8'} dev: true + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.0.0 + minipass: 7.0.2 + dev: true + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -1293,6 +2626,12 @@ packages: engines: {node: '>=8.6'} dev: true + /pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -1331,6 +2670,11 @@ packages: source-map-js: 1.0.2 dev: true + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + /pretty-format@29.6.2: resolution: {integrity: sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1366,21 +2710,71 @@ packages: picomatch: 2.3.1 dev: true + /regexp.prototype.flags@1.5.0: + resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + functions-have-names: 1.2.3 + dev: true + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} dev: true + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} dev: true + /resolve@1.22.4: + resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} + hasBin: true + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true + /rfdc@1.3.0: + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.0 + dev: true + + /rimraf@5.0.1: + resolution: {integrity: sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==} + engines: {node: '>=14'} + hasBin: true + dependencies: + glob: 10.3.3 + dev: true + /rollup@3.25.3: resolution: {integrity: sha512-ZT279hx8gszBj9uy5FfhoG4bZx8c+0A1sbqtr7Q3KNWIizpTdDEPZbV2xcbvHsnFp4MavCQYZyzApJ+virB8Yw==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} @@ -1395,10 +2789,47 @@ packages: queue-microtask: 1.2.3 dev: true + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.6.1 + dev: true + + /safe-array-concat@1.0.0: + resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-regex: 1.1.4 + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: @@ -1417,6 +2848,14 @@ packages: engines: {node: '>=8'} dev: true + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + dev: true + /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} dev: true @@ -1425,11 +2864,48 @@ packages: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /simple-git-hooks@2.9.0: + resolution: {integrity: sha512-waSQ5paUQtyGC0ZxlHmcMmD9I1rRXauikBwX31bX58l5vTOhCEcBC5Bi+ZDkPXTjDnZAF8TbCqKBY+9+sVPScw==} + hasBin: true + requiresBuild: true + dev: true + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} dev: true + /slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -1450,6 +2926,11 @@ packages: resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} dev: true + /string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + dev: true + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -1459,6 +2940,40 @@ packages: strip-ansi: 6.0.1 dev: true + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + + /string.prototype.trim@1.2.7: + resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + + /string.prototype.trimend@1.0.6: + resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + + /string.prototype.trimstart@1.0.6: + resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -1466,11 +2981,28 @@ packages: ansi-regex: 5.0.1 dev: true + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} dev: true + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -1510,6 +3042,15 @@ packages: has-flag: 4.0.0 dev: true + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + /thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -1523,6 +3064,10 @@ packages: any-promise: 1.3.0 dev: true + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + /tinybench@2.5.0: resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} dev: true @@ -1555,10 +3100,32 @@ packages: hasBin: true dev: true + /ts-api-utils@1.0.1(typescript@5.1.6): + resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.1.6 + dev: true + /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true + /tsconfig-paths@3.14.2: + resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@2.6.1: + resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} + dev: true + /tsup@7.2.0(typescript@5.1.6): resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==} engines: {node: '>=16.14'} @@ -1595,11 +3162,66 @@ packages: - ts-node dev: true + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} dev: true + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.12 + dev: true + /typescript@5.1.6: resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} engines: {node: '>=14.17'} @@ -1610,6 +3232,21 @@ packages: resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} dev: true + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + /vite-node@0.34.1(@types/node@20.4.9): resolution: {integrity: sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==} engines: {node: '>=v14.18.0'} @@ -1740,6 +3377,27 @@ packages: webidl-conversions: 4.0.2 dev: true + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-typed-array@1.1.11: + resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1761,6 +3419,15 @@ packages: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: true + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -1770,6 +3437,15 @@ packages: strip-ansi: 6.0.1 dev: true + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true @@ -1779,6 +3455,10 @@ packages: engines: {node: '>=10'} dev: true + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + /yaml@2.3.1: resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} engines: {node: '>= 14'} diff --git a/src/schema/blob.ts b/src/schema/blob.ts index 3575476..7a25321 100644 --- a/src/schema/blob.ts +++ b/src/schema/blob.ts @@ -1,4 +1,4 @@ -import { Pointer } from "./export" +import type { Pointer } from "./export" export interface BlobInstace { ptr: Pointer diff --git a/src/schema/buffer.ts b/src/schema/buffer.ts index 342bb2c..c4d4d81 100644 --- a/src/schema/buffer.ts +++ b/src/schema/buffer.ts @@ -1,4 +1,4 @@ -import { GlyphFlag } from "./export" +import type { GlyphFlag } from "./export" export interface BufferInstance { ptr: number diff --git a/src/schema/export.ts b/src/schema/export.ts index 9cbc94e..2a212fd 100644 --- a/src/schema/export.ts +++ b/src/schema/export.ts @@ -17,8 +17,7 @@ export enum BufferFlag { export enum ClusterLevel { HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, - HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, - HB_BUFFER_CLUSTER_LEVEL_DEFAULT = 0 + HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2 } export enum GlyphFlag { diff --git a/src/schema/face.ts b/src/schema/face.ts index 01efcec..e4d3ae8 100644 --- a/src/schema/face.ts +++ b/src/schema/face.ts @@ -1,4 +1,4 @@ -import { Pointer } from "./export"; +import type { Pointer } from "./export"; export interface FaceInstance { ptr: Pointer From 1e92a54373cf09ace892b83dbd82a14abae7af45 Mon Sep 17 00:00:00 2001 From: lynn Date: Wed, 9 Aug 2023 18:20:17 +0800 Subject: [PATCH 4/8] fix: schema --- src/schema/font.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schema/font.ts b/src/schema/font.ts index 4c07489..deb9713 100644 --- a/src/schema/font.ts +++ b/src/schema/font.ts @@ -2,7 +2,7 @@ export interface FontInstance { ptr: number glyphToPath(id: number): string glyphName(id: number): string - glyphToJson: Array<{ + glyphToJson(id: number): Array<{ type: string values: number[] }> From 97601c4e53c7e38c7b2b12487991850ff227ab5b Mon Sep 17 00:00:00 2001 From: lynn Date: Wed, 9 Aug 2023 18:46:14 +0800 Subject: [PATCH 5/8] refine --- playground/.gitignore | 24 +++++ playground/index.html | 13 +++ playground/package.json | 17 ++++ playground/public/vite.svg | 1 + playground/src/assets/NotoSans-Regular.ttf | Bin 0 -> 556216 bytes playground/src/counter.ts | 9 ++ playground/src/main.ts | 59 +++++++++++++ playground/src/style.css | 97 +++++++++++++++++++++ playground/src/typescript.svg | 1 + playground/src/vite-env.d.ts | 1 + playground/tsconfig.json | 23 +++++ 11 files changed, 245 insertions(+) create mode 100644 playground/.gitignore create mode 100644 playground/index.html create mode 100644 playground/package.json create mode 100644 playground/public/vite.svg create mode 100644 playground/src/assets/NotoSans-Regular.ttf create mode 100644 playground/src/counter.ts create mode 100644 playground/src/main.ts create mode 100644 playground/src/style.css create mode 100644 playground/src/typescript.svg create mode 100644 playground/src/vite-env.d.ts create mode 100644 playground/tsconfig.json diff --git a/playground/.gitignore b/playground/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/playground/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/playground/index.html b/playground/index.html new file mode 100644 index 0000000..44a9335 --- /dev/null +++ b/playground/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + TS + + +
+ + + diff --git a/playground/package.json b/playground/package.json new file mode 100644 index 0000000..46c446a --- /dev/null +++ b/playground/package.json @@ -0,0 +1,17 @@ +{ + "name": "playground", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "harfbuzzjs": "workspace:*" + }, + "devDependencies": { + "vite": "^4.4.5" + } +} diff --git a/playground/public/vite.svg b/playground/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/playground/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/src/assets/NotoSans-Regular.ttf b/playground/src/assets/NotoSans-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..973bc2ed3a92372004f5bc0c3fe85092c75624e0 GIT binary patch literal 556216 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%0D^4;qm))4yI9G6aVhf!OeW^Oi~ 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�O( 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