From 9f27ff9b10c802cd670af97d660387ec9a9f4333 Mon Sep 17 00:00:00 2001 From: JounQin Date: Thu, 11 Aug 2022 01:53:35 +0800 Subject: [PATCH] feat: add `swc` (`@swc-node/register`) support out of box (#106) close #102 --- .changeset/clean-walls-trade.md | 5 + README.md | 17 ++- package.json | 1 + src/index.ts | 10 ++ test/esbuild-register.worker.mjs | 6 - test/esbuild-runner-error.worker.mts | 6 - test/esbuild-runner.worker.mjs | 6 - test/ts-runner.spec.ts | 106 +++++++++----- test/tsx.worker.mts | 6 - ...gister-error.worker.mts => worker-mts.mts} | 0 yarn.lock | 134 +++++++++++++++++- 11 files changed, 233 insertions(+), 64 deletions(-) create mode 100644 .changeset/clean-walls-trade.md delete mode 100644 test/esbuild-register.worker.mjs delete mode 100644 test/esbuild-runner-error.worker.mts delete mode 100644 test/esbuild-runner.worker.mjs delete mode 100644 test/tsx.worker.mts rename test/{esbuild-register-error.worker.mts => worker-mts.mts} (100%) diff --git a/.changeset/clean-walls-trade.md b/.changeset/clean-walls-trade.md new file mode 100644 index 000000000..82fdacabf --- /dev/null +++ b/.changeset/clean-walls-trade.md @@ -0,0 +1,5 @@ +--- +"synckit": patch +--- + +feat: add `swc` (`@swc-node/register`) support out of box diff --git a/README.md b/README.md index 86b125370..b6f849936 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Perform async work synchronously in Node.js using `worker_threads` with first-cl - [`ts-node`](#ts-node) - [`esbuild-register`](#esbuild-register) - [`esbuild-runner`](#esbuild-runner) + - [`swc`](#swc) - [`tsx`](#tsx) - [Benchmark](#benchmark) - [Sponsors](#sponsors) @@ -83,7 +84,7 @@ You must make sure, the `result` is serializable by [`Structured Clone Algorithm 1. `SYNCKIT_BUFFER_SIZE`: `bufferSize` to create `SharedArrayBuffer` for `worker_threads` (default as `1024`) 2. `SYNCKIT_TIMEOUT`: `timeout` for performing the async job (no default) 3. `SYNCKIT_EXEC_ARGV`: List of node CLI options passed to the worker, split with comma `,`. (default as `[]`), see also [`node` docs](https://nodejs.org/api/worker_threads.html) -4. `SYNCKIT_TS_RUNNER`: Which TypeScript runner to be used, it could be very useful for development, could be `'ts-node' | 'esbuild-register' | 'esbuild-runner' | 'tsx'`, `'ts-node'` is used by default, make sure you have installed them already +4. `SYNCKIT_TS_RUNNER`: Which TypeScript runner to be used, it could be very useful for development, could be `'ts-node' | 'esbuild-register' | 'esbuild-runner' | 'swc' | 'tsx'`, `'ts-node'` is used by default, make sure you have installed them already ### TypeScript @@ -97,15 +98,19 @@ If you want to integrate with [tsconfig-paths](https://www.npmjs.com/package/tsc #### `esbuild-register` -Please view for its document +Please view [`esbuild-register`][] for its document #### `esbuild-runner` -Please view for its document +Please view [`esbuild-runner`][] for its document + +#### `swc` + +Please view [`@swc-node/register`][] for its document #### `tsx` -Please view for its document +Please view [`tsx`][] for its document ## Benchmark @@ -137,6 +142,10 @@ Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.m [MIT][] © [JounQin][]@[1stG.me][] +[`esbuild-register`]: https://github.com/egoist/esbuild-register +[`esbuild-runner`]: https://github.com/folke/esbuild-runner +[`@swc-node/register`]: https://github.com/swc-project/swc-node/tree/master/packages/register +[`tsx`]: https://github.com/esbuild-kit/tsx [1stg.me]: https://www.1stg.me [jounqin]: https://GitHub.com/JounQin [mit]: http://opensource.org/licenses/MIT diff --git a/package.json b/package.json index e6102aad5..88030eefc 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "@1stg/lib-config": "^9.0.2", "@changesets/changelog-github": "^0.4.6", "@changesets/cli": "^2.23.2", + "@swc-node/register": "^1.5.1", "@types/jest": "^28.1.5", "@types/node": "^18.0.4", "deasync": "^0.1.27", diff --git a/src/index.ts b/src/index.ts index db98e2a4c..c5c117b46 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,6 +32,8 @@ export const TsRunner = { EsbuildRegister: 'esbuild-register', // https://github.com/folke/esbuild-runner EsbuildRunner: 'esbuild-runner', + // https://github.com/swc-project/swc-node/tree/master/packages/register + SWC: 'swc', // https://github.com/esbuild-kit/tsx TSX: 'tsx', } as const @@ -207,6 +209,12 @@ const setupTsRunner = ( } break } + case TsRunner.SWC: { + if (!execArgv.includes('-r')) { + execArgv = ['-r', `@${TsRunner.SWC}-node/register`, ...execArgv] + } + break + } case TsRunner.TSX: { if (!execArgv.includes('--loader')) { execArgv = ['--loader', TsRunner.TSX, ...execArgv] @@ -282,6 +290,8 @@ function startWorkerThread>( TsRunner.EsbuildRegister, // https://github.com/folke/esbuild-runner/issues/67 TsRunner.EsbuildRunner, + // https://github.com/swc-project/swc-node/issues/667 + TsRunner.SWC, .../* istanbul ignore next */ (isTsxSupported ? [] : [TsRunner.TSX]), ] as TsRunner[] ).includes(tsRunner) diff --git a/test/esbuild-register.worker.mjs b/test/esbuild-register.worker.mjs deleted file mode 100644 index 115ab999e..000000000 --- a/test/esbuild-register.worker.mjs +++ /dev/null @@ -1,6 +0,0 @@ -import { runAsWorker } from 'synckit' - -runAsWorker( - (result, timeout) => - new Promise(resolve => setTimeout(() => resolve(result), timeout)), -) diff --git a/test/esbuild-runner-error.worker.mts b/test/esbuild-runner-error.worker.mts deleted file mode 100644 index eff74dc15..000000000 --- a/test/esbuild-runner-error.worker.mts +++ /dev/null @@ -1,6 +0,0 @@ -import { runAsWorker } from 'synckit' - -runAsWorker( - (result: number, timeout: number) => - new Promise(resolve => setTimeout(() => resolve(result), timeout)), -) diff --git a/test/esbuild-runner.worker.mjs b/test/esbuild-runner.worker.mjs deleted file mode 100644 index 115ab999e..000000000 --- a/test/esbuild-runner.worker.mjs +++ /dev/null @@ -1,6 +0,0 @@ -import { runAsWorker } from 'synckit' - -runAsWorker( - (result, timeout) => - new Promise(resolve => setTimeout(() => resolve(result), timeout)), -) diff --git a/test/ts-runner.spec.ts b/test/ts-runner.spec.ts index 19376cf85..3d656eea7 100644 --- a/test/ts-runner.spec.ts +++ b/test/ts-runner.spec.ts @@ -13,75 +13,111 @@ beforeEach(() => { jest.resetModules() }) -it(TsRunner.EsbuildRegister, async () => { +const workerJsPath = path.resolve(_dirname, 'worker-js') +const workerMjsPath = path.resolve(_dirname, 'worker.mjs') +const workerMtsPath = path.resolve(_dirname, 'worker-mts.mjs') + +test(TsRunner.EsbuildRegister, async () => { const { createSyncFn } = await import('synckit') - const syncFn = createSyncFn( - path.resolve(_dirname, 'esbuild-register.worker.mjs'), - { - tsRunner: TsRunner.EsbuildRegister, - }, - ) + + let syncFn = createSyncFn(workerJsPath, { + tsRunner: TsRunner.EsbuildRegister, + }) + expect(syncFn(1)).toBe(1) + expect(syncFn(2)).toBe(2) + expect(syncFn(5)).toBe(5) + + syncFn = createSyncFn(workerMjsPath, { + tsRunner: TsRunner.EsbuildRegister, + }) expect(syncFn(1)).toBe(1) expect(syncFn(2)).toBe(2) expect(syncFn(5)).toBe(5) expect(() => - createSyncFn( - path.resolve(_dirname, 'esbuild-register-error.worker.mjs'), - { - tsRunner: TsRunner.EsbuildRegister, - }, - ), + createSyncFn(workerMtsPath, { + tsRunner: TsRunner.EsbuildRegister, + }), ).toThrowError('esbuild-register is not supported for .mts files yet') }) -it(TsRunner.EsbuildRunner, async () => { +test(TsRunner.EsbuildRunner, async () => { const { createSyncFn } = await import('synckit') - const syncFn = createSyncFn( - path.resolve(_dirname, 'esbuild-runner.worker.mjs'), - { - tsRunner: TsRunner.EsbuildRunner, - }, - ) + + let syncFn = createSyncFn(workerJsPath, { + tsRunner: TsRunner.EsbuildRunner, + }) + expect(syncFn(1)).toBe(1) + expect(syncFn(2)).toBe(2) + expect(syncFn(5)).toBe(5) + + syncFn = createSyncFn(workerMjsPath, { + tsRunner: TsRunner.EsbuildRunner, + }) expect(syncFn(1)).toBe(1) expect(syncFn(2)).toBe(2) expect(syncFn(5)).toBe(5) expect(() => - createSyncFn( - path.resolve(_dirname, 'esbuild-runner-error.worker.mjs'), - { - tsRunner: TsRunner.EsbuildRunner, - }, - ), + createSyncFn(workerMtsPath, { + tsRunner: TsRunner.EsbuildRunner, + }), ).toThrowError('esbuild-runner is not supported for .mts files yet') }) -it(TsRunner.TSX, async () => { +test(TsRunner.SWC, async () => { const { createSyncFn } = await import('synckit') + let syncFn = createSyncFn(workerJsPath, { + tsRunner: TsRunner.SWC, + }) + expect(syncFn(1)).toBe(1) + expect(syncFn(2)).toBe(2) + expect(syncFn(5)).toBe(5) + + syncFn = createSyncFn(workerMjsPath, { + tsRunner: TsRunner.SWC, + }) + expect(syncFn(1)).toBe(1) + expect(syncFn(2)).toBe(2) + expect(syncFn(5)).toBe(5) + + expect(() => + createSyncFn(workerMtsPath, { + tsRunner: TsRunner.SWC, + }), + ).toThrowError('swc is not supported for .mts files yet') +}) + +test(TsRunner.TSX, async () => { + const { createSyncFn } = await import('synckit') + + let syncFn = createSyncFn(workerJsPath, { + tsRunner: TsRunner.TSX, + }) + expect(syncFn(1)).toBe(1) + expect(syncFn(2)).toBe(2) + expect(syncFn(5)).toBe(5) + if (Number.parseFloat(process.versions.node) < MTS_SUPPORTED_NODE_VERSION) { // eslint-disable-next-line jest/no-conditional-expect expect(() => - createSyncFn(path.resolve(_dirname, 'tsx.worker.mjs'), { + createSyncFn(workerMtsPath, { tsRunner: TsRunner.TSX, }), ).toThrowError('tsx is not supported for .mts files yet') return } - const syncFn = createSyncFn( - path.resolve(_dirname, 'tsx.worker.mjs'), - { - tsRunner: TsRunner.TSX, - }, - ) + syncFn = createSyncFn(workerMjsPath, { + tsRunner: TsRunner.TSX, + }) expect(syncFn(1)).toBe(1) expect(syncFn(2)).toBe(2) expect(syncFn(5)).toBe(5) }) -it('unknown ts runner', async () => { +test('unknown ts runner', async () => { const { createSyncFn } = await import('synckit') expect(() => diff --git a/test/tsx.worker.mts b/test/tsx.worker.mts deleted file mode 100644 index eff74dc15..000000000 --- a/test/tsx.worker.mts +++ /dev/null @@ -1,6 +0,0 @@ -import { runAsWorker } from 'synckit' - -runAsWorker( - (result: number, timeout: number) => - new Promise(resolve => setTimeout(() => resolve(result), timeout)), -) diff --git a/test/esbuild-register-error.worker.mts b/test/worker-mts.mts similarity index 100% rename from test/esbuild-register-error.worker.mts rename to test/worker-mts.mts diff --git a/yarn.lock b/yarn.lock index 7714aa00b..64b4fc8ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2506,6 +2506,138 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@swc-node/core@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@swc-node/core/-/core-1.9.0.tgz#f5208d575c1aed5a2cab7e4c04e46aca34d8c240" + integrity sha512-vRnvsMtL9OxybA/Wun1ZhlDvB6MNs4Zujnina0VKdGk+yI6s87KUhdTcbAY6dQMZhQTLFiC1Lnv/BuwCKcCEug== + dependencies: + "@swc/core" "^1.2.172" + +"@swc-node/register@^1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@swc-node/register/-/register-1.5.1.tgz#8927783c1a53207ded076d8700270f7941aa0305" + integrity sha512-6IL5s4QShKGs08qAeNou3rDA3gbp2WHk6fo0XnJXQn/aC9k6FnVBbj/thGOIEDtgNhC/DKpZT8tCY1LpQnOZFg== + dependencies: + "@swc-node/core" "^1.9.0" + "@swc-node/sourcemap-support" "^0.2.0" + colorette "^2.0.16" + debug "^4.3.4" + pirates "^4.0.5" + tslib "^2.4.0" + +"@swc-node/sourcemap-support@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@swc-node/sourcemap-support/-/sourcemap-support-0.2.0.tgz#e9079f739921fbe5c49d85791703fcb1540c356b" + integrity sha512-FNrxdI6XMYfoNt81L8eFKEm1d8P82I1nPwS3MrnBGzZoMWB+seQhQK+iN6M5RreJxXbfZw5lF86LRjHEQeGMqg== + dependencies: + source-map-support "^0.5.21" + +"@swc/core-android-arm-eabi@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.224.tgz#ee31c1855f2ac6583258d3b20da884868128a295" + integrity sha512-viVOYrhSqNxdDOCNu2UUfiAK0qjkmk/fB9mObdSb+48JlHv4kYBnSLjaIhj0NlXCsxgetH7QFbjrKXRJ+gpHqw== + dependencies: + "@swc/wasm" "1.2.122" + +"@swc/core-android-arm64@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-android-arm64/-/core-android-arm64-1.2.224.tgz#bbbab34ed297ee34e1f0b4780d5b04eb528581bf" + integrity sha512-HCfdnVyslhMX25BDOqE7rOcl3a6QHs34O3xLLY2J/wg2ICtbxehpbpBPrp+VBG3Ngv7VGD9OPhmFgGxElFtZLQ== + dependencies: + "@swc/wasm" "1.2.130" + +"@swc/core-darwin-arm64@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.224.tgz#71175f1574e7fb9a8a33b2795c334adc9bb1ac1d" + integrity sha512-jzv8Eop0GDe4owRDWr02n/xT7Bm6eTFWoM3nFXOM865gNYfASGGm3HHm4z20yndIxq5xuKHcOOH9QXQQhe/lQA== + +"@swc/core-darwin-x64@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.2.224.tgz#ca93a1903cc0455fe0be24ac6f87ba0b7b6c66b7" + integrity sha512-hpdJt/BJ45+hcgs461nJxgMJVNN/2uJL8TLvFxeOJiDpF4r1elRxYfDC1W8ctMWB3eB3Wepz3Ku2z8l9UgPnyQ== + +"@swc/core-freebsd-x64@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.224.tgz#24cfd1b17e0378cedb8e0ee87182e060d4efce6a" + integrity sha512-bVIXwwjYA1ZdMKTwrAosxG808nQqvHhzs/fOKUrl1VeZ9CTHA0FzpSXwaBf1shbUVKvQVPKydY0K5q9dkSUkpw== + dependencies: + "@swc/wasm" "1.2.130" + +"@swc/core-linux-arm-gnueabihf@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.224.tgz#e3941f308384793f5be582c751ac7e42badb3665" + integrity sha512-MY3UQI3IOjME5TpuIhwI0lqKHsU3x7BwlU4n/mLNe2lH3DLaP0rrGHCMI2iJqfiYKU1Rg1r01HXmysuiriF1TA== + dependencies: + "@swc/wasm" "1.2.130" + +"@swc/core-linux-arm64-gnu@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.224.tgz#9f3f9c68997d2dec198a53b1cdc70950511e207a" + integrity sha512-tEpaGq4wp79tR+4s0h8xbzcxW6tZOfb2/Jf1vrmRYfRBqryBRTdtn14Rfy4qlK3s/SC3NfI2MKxZRgcGnMCeWw== + +"@swc/core-linux-arm64-musl@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.224.tgz#5215a83fa97f5b1879f49a1da4c7a7b1c68f445d" + integrity sha512-jnrYqXc7aRzBnEqEp3nAi9tjuUhBnN0pSKiHJytlBP1QkXnH7HD44Da9udmKUFYB5hHpwaXE0NIh7jK0nSMnhw== + +"@swc/core-linux-x64-gnu@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.224.tgz#09e0fd990e3a884a6a8dab3491264e8ce9087aae" + integrity sha512-UBkeDlG+PrIXDH1sR4EIXN5qK4a677IHb6RBghbvBDJS61X9/nTDxtCF7/zCqDxJRahhUrT6lDsYpuLCws2hiw== + +"@swc/core-linux-x64-musl@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.224.tgz#f214bf93d4fd1be0d8a5185b766074b5aee88536" + integrity sha512-CQMGDzxKvkzf6TOdaWnmhb6uk1XEhM/mM3BDfX+hx9j3Hg3bFw9qmPvrkoWI2G8J50MvpoR1iPBYyG2LNeQWeg== + +"@swc/core-win32-arm64-msvc@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.224.tgz#8b771ecd0af29209f374df5b95c0bac8e5ff0a3a" + integrity sha512-03V4apubsOhLKQNmfWGlgvDCJkhlh0ZOHcGddxb7bD4PeP6U0lnABG3hlz2uicwcIGBPu/p7jtm5/hezeiXE6Q== + dependencies: + "@swc/wasm" "1.2.130" + +"@swc/core-win32-ia32-msvc@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.224.tgz#07a0dc112a4b7fdc5ab5b4bcd7aac85de3a4c2aa" + integrity sha512-gPOmIdhCwkb5BbDiPs/4t1LIElFLoQwiv45XwK5wADh1qzLD3A8EtpnpXfLsjL/fUMlLIGCgHQ6BQ0x04VrI1Q== + dependencies: + "@swc/wasm" "1.2.130" + +"@swc/core-win32-x64-msvc@1.2.224": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.224.tgz#eea8f04097dcf88f3a7c7eaa7aed049f38501f43" + integrity sha512-xALNoKi/UAQ2NflIkCBaZ4Nib75a4YwFp2pZ5Yen3vR8hxK2UJYlaNwyfsBwWfMOMsNxQ1Q1aaqoo0L+XON53Q== + +"@swc/core@^1.2.172": + version "1.2.224" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.2.224.tgz#615d9a862daab7e9e41031f4292619b43eaf64a2" + integrity sha512-K0B0QKT0eSpPlL4amWJzllYJigQdE7+ha6VQVks6g/oiko1yMYP8lGcCKOKb+KuvW1ltPzlyFqi7h7ryEVG2vQ== + optionalDependencies: + "@swc/core-android-arm-eabi" "1.2.224" + "@swc/core-android-arm64" "1.2.224" + "@swc/core-darwin-arm64" "1.2.224" + "@swc/core-darwin-x64" "1.2.224" + "@swc/core-freebsd-x64" "1.2.224" + "@swc/core-linux-arm-gnueabihf" "1.2.224" + "@swc/core-linux-arm64-gnu" "1.2.224" + "@swc/core-linux-arm64-musl" "1.2.224" + "@swc/core-linux-x64-gnu" "1.2.224" + "@swc/core-linux-x64-musl" "1.2.224" + "@swc/core-win32-arm64-msvc" "1.2.224" + "@swc/core-win32-ia32-msvc" "1.2.224" + "@swc/core-win32-x64-msvc" "1.2.224" + +"@swc/wasm@1.2.122": + version "1.2.122" + resolved "https://registry.yarnpkg.com/@swc/wasm/-/wasm-1.2.122.tgz#87a5e654b26a71b2e84b801f41e45f823b856639" + integrity sha512-sM1VCWQxmNhFtdxME+8UXNyPNhxNu7zdb6ikWpz0YKAQQFRGT5ThZgJrubEpah335SUToNg8pkdDF7ibVCjxbQ== + +"@swc/wasm@1.2.130": + version "1.2.130" + resolved "https://registry.yarnpkg.com/@swc/wasm/-/wasm-1.2.130.tgz#88ac26433335d1f957162a9a92f1450b73c176a0" + integrity sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q== + "@toml-tools/lexer@^0.3.1": version "0.3.1" resolved "https://registry.yarnpkg.com/@toml-tools/lexer/-/lexer-0.3.1.tgz#f5a4b04ee075b2862f08825972d24e73c6bea367" @@ -8532,7 +8664,7 @@ pify@^5.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== -pirates@^4.0.4: +pirates@^4.0.4, pirates@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==