@things-factory/auth-base 8.0.0-alpha.18 → 8.0.0-alpha.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './auth'
2
2
  export * from './profiled'
3
3
  export * from './directive/privileged'
4
+ export * from './verify-webauthn'
@@ -0,0 +1,86 @@
1
+ /*
2
+ // Usage example
3
+ async function performSensitiveAction() {
4
+ try {
5
+ const result = await verifyBiometric()
6
+ if (result.verified) {
7
+ console.log('Verification successful. Proceeding with sensitive action.')
8
+ // Perform the sensitive action here
9
+ } else if (result.needsRegistration) {
10
+ console.log('Biometric registration needed:', result.message)
11
+ // Redirect user to biometric registration page or show registration prompt
12
+ } else {
13
+ console.log('Verification failed:', result.message)
14
+ // Handle the failure (e.g., show an error message to the user)
15
+ }
16
+ } catch (error) {
17
+ console.error('Error during biometric verification:', error)
18
+ // Handle any unexpected errors
19
+ }
20
+ }
21
+ */
22
+
23
+ import { startAuthentication } from '@simplewebauthn/browser'
24
+
25
+ interface BiometricVerificationResult {
26
+ verified: boolean
27
+ message: string
28
+ needsRegistration?: boolean
29
+ }
30
+
31
+ /**
32
+ * Performs biometric verification for the current user.
33
+ * @param challengeUrl The URL to fetch the authentication challenge.
34
+ * @param verifyUrl The URL to send the authentication assertion for verification.
35
+ * @returns A promise that resolves to a BiometricVerificationResult.
36
+ */
37
+ export async function verifyBiometric(
38
+ challengeUrl: string = '/auth/verify-webauthn/challenge',
39
+ verifyUrl: string = '/auth/verify-webauthn'
40
+ ): Promise<BiometricVerificationResult> {
41
+ try {
42
+ // 1. Get the challenge from the server
43
+ const challengeResponse = await fetch(challengeUrl)
44
+ if (!challengeResponse.ok) {
45
+ const errorData = await challengeResponse.json()
46
+ if (challengeResponse.status === 400 && errorData.error === 'No biometric credentials registered for this user') {
47
+ return {
48
+ verified: false,
49
+ message: 'Biometric authentication is not set up for this account. Please register first.',
50
+ needsRegistration: true
51
+ }
52
+ }
53
+ throw new Error(`Failed to get challenge: ${errorData.error || challengeResponse.statusText}`)
54
+ }
55
+ const options = await challengeResponse.json()
56
+
57
+ // 2. Start the authentication process
58
+ const assertion = await startAuthentication(options)
59
+
60
+ // 3. Send the assertion to the server for verification
61
+ const verificationResponse = await fetch(verifyUrl, {
62
+ method: 'POST',
63
+ headers: {
64
+ 'Content-Type': 'application/json'
65
+ },
66
+ body: JSON.stringify(assertion)
67
+ })
68
+
69
+ if (!verificationResponse.ok) {
70
+ throw new Error(`Verification failed: ${verificationResponse.statusText}`)
71
+ }
72
+
73
+ const verificationResult = await verificationResponse.json()
74
+
75
+ return {
76
+ verified: verificationResult.verified,
77
+ message: verificationResult.message || 'Biometric verification successful!'
78
+ }
79
+ } catch (error: any) {
80
+ console.error('Biometric verification error:', error)
81
+ return {
82
+ verified: false,
83
+ message: `Error: ${error.message}`
84
+ }
85
+ }
86
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './auth';
2
2
  export * from './profiled';
3
3
  export * from './directive/privileged';
4
+ export * from './verify-webauthn';
@@ -1,4 +1,5 @@
1
1
  export * from './auth';
2
2
  export * from './profiled';
3
3
  export * from './directive/privileged';
4
+ export * from './verify-webauthn';
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA","sourcesContent":["export * from './auth'\nexport * from './profiled'\nexport * from './directive/privileged'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA","sourcesContent":["export * from './auth'\nexport * from './profiled'\nexport * from './directive/privileged'\nexport * from './verify-webauthn'\n"]}
@@ -1 +1 @@
1
- {"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/tslib/tslib.d.ts","../client/auth.ts","../../../node_modules/@operato/shell/dist/src/types/domain.d.ts","../../../node_modules/@operato/shell/dist/src/types/user.d.ts","../../../node_modules/@operato/shell/dist/src/types/role.d.ts","../../../node_modules/@operato/shell/dist/src/types/privilege.d.ts","../../../node_modules/@operato/shell/dist/src/types/types.d.ts","../../../node_modules/@operato/shell/dist/src/types/index.d.ts","../../../node_modules/redux/dist/redux.d.ts","../../../node_modules/pwa-helpers/lazy-reducer-enhancer.d.ts","../../../node_modules/@operato/shell/node_modules/redux/index.d.ts","../../../node_modules/@operato/shell/dist/src/store.d.ts","../../../node_modules/@operato/shell/dist/src/actions/app.d.ts","../../../node_modules/@operato/shell/dist/src/actions/route.d.ts","../../../node_modules/@operato/shell/dist/src/actions/busy.d.ts","../../../node_modules/@operato/shell/dist/src/actions/const.d.ts","../../../node_modules/@operato/shell/dist/src/actions/index.d.ts","../../../node_modules/@lit/reactive-element/css-tag.d.ts","../../../node_modules/@lit/reactive-element/reactive-controller.d.ts","../../../node_modules/@lit/reactive-element/reactive-element.d.ts","../../../node_modules/lit-html/directive.d.ts","../../../node_modules/@types/trusted-types/lib/index.d.ts","../../../node_modules/lit-html/lit-html.d.ts","../../../node_modules/lit-element/lit-element.d.ts","../../../node_modules/lit-html/is-server.d.ts","../../../node_modules/lit/index.d.ts","../../../node_modules/@operato/shell/dist/src/app/pages/page-view.d.ts","../../../node_modules/@operato/shell/dist/src/object-store.d.ts","../../../node_modules/@operato/shell/dist/src/custom-alert.d.ts","../../../node_modules/@operato/shell/dist/src/index.d.ts","../../../node_modules/immer/dist/immer.d.ts","../../../node_modules/@reduxjs/toolkit/node_modules/reselect/dist/reselect.d.ts","../../../node_modules/@reduxjs/toolkit/node_modules/redux-thunk/dist/redux-thunk.d.ts","../../../node_modules/@reduxjs/toolkit/dist/uncheckedindexed.ts","../../../node_modules/@reduxjs/toolkit/dist/index.d.ts","../../../node_modules/redux-thunk/es/types.d.ts","../../../node_modules/redux-thunk/es/index.d.ts","../client/actions/auth.ts","../client/reducers/auth.ts","../../../node_modules/lit-html/async-directive.d.ts","../../../node_modules/lit/async-directive.d.ts","../client/profiled.ts","../client/directive/privileged.ts","../client/bootstrap.ts","../client/index.ts","../../../node_modules/@types/node/ts5.6/globals.typedarray.d.ts","../../../node_modules/@types/node/ts5.6/buffer.buffer.d.ts","../../../node_modules/@types/node/assert.d.ts","../../../node_modules/@types/node/assert/strict.d.ts","../../../node_modules/buffer/index.d.ts","../../../node_modules/undici-types/header.d.ts","../../../node_modules/undici-types/readable.d.ts","../../../node_modules/undici-types/file.d.ts","../../../node_modules/undici-types/fetch.d.ts","../../../node_modules/undici-types/formdata.d.ts","../../../node_modules/undici-types/connector.d.ts","../../../node_modules/undici-types/client.d.ts","../../../node_modules/undici-types/errors.d.ts","../../../node_modules/undici-types/dispatcher.d.ts","../../../node_modules/undici-types/global-dispatcher.d.ts","../../../node_modules/undici-types/global-origin.d.ts","../../../node_modules/undici-types/pool-stats.d.ts","../../../node_modules/undici-types/pool.d.ts","../../../node_modules/undici-types/handlers.d.ts","../../../node_modules/undici-types/balanced-pool.d.ts","../../../node_modules/undici-types/agent.d.ts","../../../node_modules/undici-types/mock-interceptor.d.ts","../../../node_modules/undici-types/mock-agent.d.ts","../../../node_modules/undici-types/mock-client.d.ts","../../../node_modules/undici-types/mock-pool.d.ts","../../../node_modules/undici-types/mock-errors.d.ts","../../../node_modules/undici-types/proxy-agent.d.ts","../../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../../node_modules/undici-types/retry-handler.d.ts","../../../node_modules/undici-types/retry-agent.d.ts","../../../node_modules/undici-types/api.d.ts","../../../node_modules/undici-types/interceptors.d.ts","../../../node_modules/undici-types/util.d.ts","../../../node_modules/undici-types/cookies.d.ts","../../../node_modules/undici-types/patch.d.ts","../../../node_modules/undici-types/websocket.d.ts","../../../node_modules/undici-types/eventsource.d.ts","../../../node_modules/undici-types/filereader.d.ts","../../../node_modules/undici-types/diagnostics-channel.d.ts","../../../node_modules/undici-types/content-type.d.ts","../../../node_modules/undici-types/cache.d.ts","../../../node_modules/undici-types/index.d.ts","../../../node_modules/@types/node/globals.d.ts","../../../node_modules/@types/node/async_hooks.d.ts","../../../node_modules/@types/node/buffer.d.ts","../../../node_modules/@types/node/child_process.d.ts","../../../node_modules/@types/node/cluster.d.ts","../../../node_modules/@types/node/console.d.ts","../../../node_modules/@types/node/constants.d.ts","../../../node_modules/@types/node/crypto.d.ts","../../../node_modules/@types/node/dgram.d.ts","../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/@types/node/dns.d.ts","../../../node_modules/@types/node/dns/promises.d.ts","../../../node_modules/@types/node/domain.d.ts","../../../node_modules/@types/node/dom-events.d.ts","../../../node_modules/@types/node/events.d.ts","../../../node_modules/@types/node/fs.d.ts","../../../node_modules/@types/node/fs/promises.d.ts","../../../node_modules/@types/node/http.d.ts","../../../node_modules/@types/node/http2.d.ts","../../../node_modules/@types/node/https.d.ts","../../../node_modules/@types/node/inspector.d.ts","../../../node_modules/@types/node/module.d.ts","../../../node_modules/@types/node/net.d.ts","../../../node_modules/@types/node/os.d.ts","../../../node_modules/@types/node/path.d.ts","../../../node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/@types/node/process.d.ts","../../../node_modules/@types/node/punycode.d.ts","../../../node_modules/@types/node/querystring.d.ts","../../../node_modules/@types/node/readline.d.ts","../../../node_modules/@types/node/readline/promises.d.ts","../../../node_modules/@types/node/repl.d.ts","../../../node_modules/@types/node/sea.d.ts","../../../node_modules/@types/node/sqlite.d.ts","../../../node_modules/@types/node/stream.d.ts","../../../node_modules/@types/node/stream/promises.d.ts","../../../node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/@types/node/stream/web.d.ts","../../../node_modules/@types/node/string_decoder.d.ts","../../../node_modules/@types/node/test.d.ts","../../../node_modules/@types/node/timers.d.ts","../../../node_modules/@types/node/timers/promises.d.ts","../../../node_modules/@types/node/tls.d.ts","../../../node_modules/@types/node/trace_events.d.ts","../../../node_modules/@types/node/tty.d.ts","../../../node_modules/@types/node/url.d.ts","../../../node_modules/@types/node/util.d.ts","../../../node_modules/@types/node/v8.d.ts","../../../node_modules/@types/node/vm.d.ts","../../../node_modules/@types/node/wasi.d.ts","../../../node_modules/@types/node/worker_threads.d.ts","../../../node_modules/@types/node/zlib.d.ts","../../../node_modules/@types/node/globals.global.d.ts","../../../node_modules/@types/node/ts5.6/index.d.ts","../../../node_modules/@jest/expect-utils/build/index.d.ts","../../../node_modules/chalk/index.d.ts","../../../node_modules/@sinclair/typebox/typebox.d.ts","../../../node_modules/@jest/schemas/build/index.d.ts","../../../node_modules/pretty-format/build/index.d.ts","../../../node_modules/jest-diff/build/index.d.ts","../../../node_modules/jest-matcher-utils/build/index.d.ts","../../../node_modules/expect/build/index.d.ts","../../../node_modules/@types/jest/index.d.ts"],"fileIdsList":[[94,137],[94,137,191],[65,66,94,137],[60,61,62,63,94,137],[73,94,137],[55,59,64,74,75,76,94,137],[57,58,94,137],[50,51,52,53,54,94,137],[51,52,94,137],[50,51,53,94,137],[56,78,79,80,81,94,137],[48,94,137],[56,94,137],[94,137,193,196],[94,95,137],[94,136,137],[94,137,142,172],[94,137,138,143,149,150,157,169,180],[94,137,138,139,149,157],[94,137,140,181],[94,137,141,142,150,158],[94,137,142,169,177],[94,137,143,145,149,157],[94,136,137,144],[94,137,145,146],[94,137,149],[94,137,147,149],[94,136,137,149],[94,137,149,150,151,169,180],[94,137,149,150,151,164,169,172],[94,134,137,185],[94,134,137,145,149,152,157,169,180],[94,137,149,150,152,153,157,169,177,180],[94,137,152,154,169,177,180],[94,137,149,155],[94,137,156,180,185],[94,137,145,149,157,169],[94,137,158],[94,137,159],[94,136,137,160],[94,95,96,136,137,138,139,140,141,142,143,144,145,146,147,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186],[94,137,162],[94,137,163],[94,137,149,164,165],[94,137,164,166,181,183],[94,137,149,169,170,171,172],[94,137,169,171],[94,137,169,170],[94,137,172],[94,137,173],[94,95,137,169],[94,137,149,175,176],[94,137,175,176],[94,137,142,157,169,177],[94,137,178],[137],[93,94,95,96,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187],[94,137,157,179],[94,137,152,163,180],[94,137,142,181],[94,137,169,182],[94,137,156,183],[94,137,184],[94,137,142,149,151,160,169,180,183,185],[94,137,169,186],[94,137,189,195],[94,137,193],[94,137,190,194],[67,70,94,137],[68,70,94,137],[70,94,137],[68,69,94,137],[87,94,137],[67,70,71,72,94,137],[94,137,192],[56,83,94,137],[94,106,110,137,180],[94,106,137,169,180],[94,101,137],[94,103,106,137,177,180],[94,137,157,177],[94,137,188],[94,101,137,188],[94,103,106,137,157,180],[94,98,99,102,105,137,149,169,180],[94,106,113,137],[94,98,104,137],[94,106,127,128,137],[94,102,106,137,172,180,188],[94,127,137,188],[94,100,101,137,188],[94,106,137],[94,100,101,102,103,104,105,106,107,108,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,128,129,130,131,132,133,137],[94,106,121,137],[94,106,113,114,137],[94,104,106,114,115,137],[94,105,137],[94,98,101,106,137],[94,106,110,114,115,137],[94,110,137],[94,104,106,109,137,180],[94,98,103,106,113,137],[94,137,169],[94,101,106,127,137,185,188],[48,82,84,94,137],[48,49,77,85,86,90,94,137],[48,73,88,89,94,137],[48,49,89,90,94,137],[48,49,94,137],[48,85,94,137]],"fileInfos":[{"version":"44e584d4f6444f58791784f1d530875970993129442a847597db702a073ca68c","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"9a68c0c07ae2fa71b44384a839b7b8d81662a236d4b9ac30916718f7510b1b2d","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"9e8ca8ed051c2697578c023d9c29d6df689a083561feba5c14aedee895853999","affectsGlobalScope":true,"impliedFormat":1},{"version":"69e65d976bf166ce4a9e6f6c18f94d2424bf116e90837ace179610dbccad9b42","affectsGlobalScope":true,"impliedFormat":1},{"version":"6920e1448680767498a0b77c6a00a8e77d14d62c3da8967b171f1ddffa3c18e4","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"45d8ccb3dfd57355eb29749919142d4321a0aa4df6acdfc54e30433d7176600a","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"93495ff27b8746f55d19fcbcdbaccc99fd95f19d057aed1bd2c0cafe1335fbf0","affectsGlobalScope":true,"impliedFormat":1},{"version":"6fc23bb8c3965964be8c597310a2878b53a0306edb71d4b5a4dfe760186bcc01","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea011c76963fb15ef1cdd7ce6a6808b46322c527de2077b6cfdf23ae6f5f9ec7","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"4738f2420687fd85629c9efb470793bb753709c2379e5f85bc1815d875ceadcd","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"9fc46429fbe091ac5ad2608c657201eb68b6f1b8341bd6d670047d32ed0a88fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"1a94697425a99354df73d9c8291e2ecd4dddd370aed4023c2d6dee6cccb32666","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"bf14a426dbbf1022d11bd08d6b8e709a2e9d246f0c6c1032f3b2edb9a902adbe","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3f9fc0ec0b96a9e642f11eda09c0be83a61c7b336977f8b9fdb1e9788e925fe","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"479553e3779be7d4f68e9f40cdb82d038e5ef7592010100410723ceced22a0f7","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"33358442698bb565130f52ba79bfd3d4d484ac85fe33f3cb1759c54d18201393","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"4a882ffbb4ed09d9b7734f784aebb1dfe488d63725c40759165c5d9c657ca029","impliedFormat":1},{"version":"b43c3d6f808876e21ed81a3bb8e348be01110ca6c464a080256b2b0ee17aa7ba","signature":"ead7c69443921d68ef00bb0c31d11c3eddefd5cbfca08f7a6979b5bb46a2a2c6"},{"version":"4d4cf93a6b4c81851ad759e4569b6feb7a701e80b13a6f9d8d9c6012bbb86bd6","impliedFormat":1},{"version":"2e6035af8f3e43bf95e4983329c8277d66f9b271106af27b99a85d1c1b9daf4a","impliedFormat":1},{"version":"774308610e8d4a9954cd93840f99decbf340accfe3ad7365547950ede8162c92","impliedFormat":1},{"version":"36c15dd26c66c97b9df26ce34baacdb13fc760c5b9a2d789dcc317d27b189257","impliedFormat":1},{"version":"3d7c0b593a29d717b2b2ba3f03f819c3c48bf9e250d79c4a31860af80f177e8c","impliedFormat":1},{"version":"f228d440342f5d0933f5db093aafab2f07de24a427b4488ccfae27b7457d7666","impliedFormat":1},{"version":"f734b58ea162765ff4d4a36f671ee06da898921e985a2064510f4925ec1ed062","affectsGlobalScope":true,"impliedFormat":1},{"version":"701978f3975f96e76e3ffc2e1762e3a97e3d323812049fb6fdfd559579b89708","impliedFormat":1},{"version":"fd624f7d7b264922476685870f08c5e1c6d6a0f05dee2429a9747b41f6b699d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ab17f80ced148d509345cee706b2b85941515dd76e32cf47118bcdf6a4bd56a","affectsGlobalScope":true,"impliedFormat":1},{"version":"641089f0b8094ef74b9d4b3364d5dec1592d5e3b8a51c1ba491bc8872049e79a","impliedFormat":1},{"version":"950fc6ac97ce76785f03282f907aac4b2cbd8ac74b17c963f1389847962cbc20","impliedFormat":1},{"version":"b42033bf1067564808e4d360d79281667c2b3b0792c2d615ab641eb85974d4ba","impliedFormat":1},{"version":"7af29b0589483f7bb8a99405ddb849f34bc053146184561ed4179e02f5fe4d0f","impliedFormat":1},{"version":"78faa3783191b2d5d5f7a9e835ee3f6a1456dc391d6eb5b40d3a27dfd9decd6e","impliedFormat":1},{"version":"e056bb30bf82271634daeee81f772f4a7960085f01f6d4d09c8da1ebe5f6a623","impliedFormat":99},{"version":"5e30131b6a5587fe666926ad1d9807e733c0a597ed12d682669fcaa331aea576","impliedFormat":99},{"version":"86492a546c3308feaf1dde967afd325c321483b5e96f5fa9e9b6e691dc23fa9e","affectsGlobalScope":true,"impliedFormat":99},{"version":"00cb63103f9670f8094c238a4a7e252c8b4c06ba371fea5c44add7e41b7247e4","impliedFormat":99},{"version":"15fe687c59d62741b4494d5e623d497d55eb38966ecf5bea7f36e48fc3fbe15e","impliedFormat":1},{"version":"43f58358870effc43ba93c92c040dee2285cbd8685ddfa77658e498780727c4e","impliedFormat":99},{"version":"9a318e3a8900672b85cd3c8c3a5acf51b88049557a3ae897ccdcf2b85a8f61f9","impliedFormat":99},{"version":"1bcd560deed90a43c51b08aa18f7f55229f2e30974ab5ed1b7bb5721be379013","impliedFormat":99},{"version":"dc08fe04e50bc24d1baded4f33e942222bbdd5d77d6341a93cfe6e4e4586a3be","impliedFormat":99},{"version":"9c7568f9c75cf6a7d35dc9f18c5971cd5b21344c686c7cce56b3558d3305d40f","impliedFormat":1},{"version":"fc48282c397084016a939e1b3f91dcaf4199b6cba339d91d8b2dc2acade79762","impliedFormat":1},{"version":"3e62a55b950132d6eeacc607b7a1bff990d5484347b2be5a1f54db51af30ff25","impliedFormat":1},{"version":"a6203646763fb7340123eace99b924c9586ea3cf56f65fe8c56308e6ecb2b805","impliedFormat":1},{"version":"07cbc706c24fa086bcc20daee910b9afa5dc5294e14771355861686c9d5235fd","impliedFormat":1},{"version":"37f96daaddc2dd96712b2e86f3901f477ac01a5c2539b1bc07fd609d62039ee1","impliedFormat":1},{"version":"9c5c84c449a3d74e417343410ba9f1bd8bfeb32abd16945a1b3d0592ded31bc8","impliedFormat":1},{"version":"c0bd5112f5e51ab7dfa8660cdd22af3b4385a682f33eefde2a1be35b60d57eb1","impliedFormat":1},{"version":"38ae8ed1881fd8c27f6614d7b300c33dbbbd8981ef6c72fa073882cfa3a785c0","impliedFormat":1},{"version":"d50a158fc581be7b1c51253ad33cb29c0a8ce3c42ca38775ffadf104c36376d0","impliedFormat":1},{"version":"1f2cdbf59d0b7933678a64ac26ae2818c48ff9ebf93249dde775dc3e173e16bf","impliedFormat":1},{"version":"2ba328775832040cb87cb16f6fc454ae00f9620f8dd97dd283ae3bfd9f744637","signature":"a3c81c9082ad3d86a42d51980ce4e29c85e9b91ae9beefb76d1dcf62f8355fa8"},{"version":"d3a72e3acec55990c739ec2c7ec487ace738418d0650356c2db86b67a3d1b818","signature":"6a716b8d3a52002354a3e530ee6c90d52209af1f53eaefb9c4527228bf0a6f67"},{"version":"c42f9b18f5f559b133cf9b409f678afb30df9c6498865aae9a1abad0f1e727a8","impliedFormat":99},{"version":"eabff483c855b848eefb979dbfb64c8858444c56a2f3ea0e59de026ef03fd089","impliedFormat":99},{"version":"2ef2abb081acc60d2fe8083d8aa8925a9fabf6eee88a331c0234dd8fad71bcfc","signature":"d75a3e4665db49528093a3d868b69a53ac6bfc368b232d4db3130fd0a5e543c2"},{"version":"a9b96633c658f87988e20b077d45dc11e39a9237e829bcbbf400e5686c249b7b","signature":"9848af2eb0cfdf37577332c9c5035c616918c3139fa09d5c1f504b878f2281a3"},{"version":"85d18863957bd329e9e801ea8467123d8e0d12dedced776718fd648ea7c0b28f","signature":"d09851f8824ccbae129caa791d49356c8b7406f05687cb38a7c7eb3ed21d197b"},{"version":"6bfaa102744d3d84c104cbda522e2d54b8bde1813f8dbeda0808eb3757e521d3","signature":"9a70edd7f635c389010a87dea788970736712497a34392e5f28e716bab2fd892"},{"version":"613b21ccdf3be6329d56e6caa13b258c842edf8377be7bc9f014ed14cdcfc308","affectsGlobalScope":true,"impliedFormat":1},{"version":"2d1319e6b5d0efd8c5eae07eb864a00102151e8b9afddd2d45db52e9aae002c4","affectsGlobalScope":true,"impliedFormat":1},{"version":"f6114eb1e8f70ec08816bdaa6ec740a0a7a01f25743e36f655f00157be394374","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"4967529644e391115ca5592184d4b63980569adf60ee685f968fd59ab1557188","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"24bd580b5743dc56402c440dc7f9a4f5d592ad7a419f25414d37a7bfe11e342b","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"6bdc71028db658243775263e93a7db2fd2abfce3ca569c3cca5aee6ed5eb186d","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"4d2b0eb911816f66abe4970898f97a2cfc902bcd743cbfa5017fad79f7ef90d8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"e53a3c2a9f624d90f24bf4588aacd223e7bec1b9d0d479b68d2f4a9e6011147f","impliedFormat":1},{"version":"24b8685c62562f5d98615c5a0c1d05f297cf5065f15246edfe99e81ec4c0e011","impliedFormat":1},{"version":"93507c745e8f29090efb99399c3f77bec07db17acd75634249dc92f961573387","impliedFormat":1},{"version":"339dc5265ee5ed92e536a93a04c4ebbc2128f45eeec6ed29f379e0085283542c","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"bb2cd9339d0201e7e78ccb6ff2f71aac103934bf35eaaa37e139ac2b68af0db8","affectsGlobalScope":true,"impliedFormat":1},{"version":"76103716ba397bbb61f9fa9c9090dca59f39f9047cb1352b2179c5d8e7f4e8d0","impliedFormat":1},{"version":"53eac70430b30089a3a1959d8306b0f9cfaf0de75224b68ef25243e0b5ad1ca3","affectsGlobalScope":true,"impliedFormat":1},{"version":"4314c7a11517e221f7296b46547dbc4df047115b182f544d072bdccffa57fc72","impliedFormat":1},{"version":"115971d64632ea4742b5b115fb64ed04bcaae2c3c342f13d9ba7e3f9ee39c4e7","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"a40826e8476694e90da94aa008283a7de50d1dafd37beada623863f1901cb7fb","impliedFormat":1},{"version":"46e07db372dd75edc1a26e68f16d1b7ffb34b7ab3db5cdb3e391a3604ad7bb7c","affectsGlobalScope":true,"impliedFormat":1},{"version":"24642567d3729bcc545bacb65ee7c0db423400c7f1ef757cab25d05650064f98","impliedFormat":1},{"version":"e6f5a38687bebe43a4cef426b69d34373ef68be9a6b1538ec0a371e69f309354","impliedFormat":1},{"version":"a6bf63d17324010ca1fbf0389cab83f93389bb0b9a01dc8a346d092f65b3605f","impliedFormat":1},{"version":"e009777bef4b023a999b2e5b9a136ff2cde37dc3f77c744a02840f05b18be8ff","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"ee1ee365d88c4c6c0c0a5a5701d66ebc27ccd0bcfcfaa482c6e2e7fe7b98edf7","affectsGlobalScope":true,"impliedFormat":1},{"version":"f501a53b94ba382d9ba396a5c486969a3abc68309828fa67f916035f5d37fe2b","affectsGlobalScope":true,"impliedFormat":1},{"version":"c956ba45704d4a97f7a96923a307a6203bc0e7c4c532930d4c8ca261eaaff32a","impliedFormat":1},{"version":"ab0e88d33ccf15d8b3c891038b5a16094b0dd7e860ab0e2ba08da4384afce02b","impliedFormat":1},{"version":"954580f86c8e2a4abd5dcd1bcdf1a4c7e012495f1c39e058dc738bc93024642a","impliedFormat":1},{"version":"fa56be9b96f747e93b895d8dc2aa4fb9f0816743e6e2abb9d60705e88d4743a2","impliedFormat":1},{"version":"8257c55ff6bff6169142a35fce6811b511d857b4ae4f522cdb6ce20fd2116b2c","impliedFormat":1},{"version":"6d386bc0d7f3afa1d401afc3e00ed6b09205a354a9795196caed937494a713e6","impliedFormat":1},{"version":"3a9e5dddbd6ca9507d0c06a557535ba2224a94a2b0f3e146e8215f93b7e5b3a8","affectsGlobalScope":true,"impliedFormat":1},{"version":"d8b56de03a9f79f3fc1ac3a01a0d63bb48cc15f95a6b95549b4fb420e6030973","impliedFormat":1},{"version":"b1b6ee0d012aeebe11d776a155d8979730440082797695fc8e2a5c326285678f","impliedFormat":1},{"version":"45875bcae57270aeb3ebc73a5e3fb4c7b9d91d6b045f107c1d8513c28ece71c0","impliedFormat":1},{"version":"3c36ab47df4668254ccc170fc42e7d5116fd86a7e408d8dc220e559837cd2bbb","affectsGlobalScope":true,"impliedFormat":1},{"version":"6f6abdaf8764ef01a552a958f45e795b5e79153b87ddad3af5264b86d2681b72","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"c6b4e0a02545304935ecbf7de7a8e056a31bb50939b5b321c9d50a405b5a0bba","impliedFormat":1},{"version":"c86b9afa9b39b12db8e877d23b48888d80f26e1fe72a95f58552746a6e1fa4fe","impliedFormat":1},{"version":"e432b0e3761ca9ba734bdd41e19a75fec1454ca8e9769bfdf8b31011854cf06a","impliedFormat":1},{"version":"e1120271ebbc9952fdc7b2dd3e145560e52e06956345e6fdf91d70ca4886464f","impliedFormat":1},{"version":"15c5e91b5f08be34a78e3d976179bf5b7a9cc28dc0ef1ffebffeb3c7812a2dca","impliedFormat":1},{"version":"a8f06c2382a30b7cb89ad2dfc48fc3b2b490f3dafcd839dadc008e4e5d57031d","impliedFormat":1},{"version":"07b9d3b7204d931acc29269c98ac3aac87ebcba6e05141552d42a4c17f895aa4","impliedFormat":1},{"version":"269929a24b2816343a178008ac9ae9248304d92a8ba8e233055e0ed6dbe6ef71","impliedFormat":1},{"version":"93452d394fdd1dc551ec62f5042366f011a00d342d36d50793b3529bfc9bd633","impliedFormat":1},{"version":"1425f76ac97ce8617d1e2fa79e9a14e0fd1cfdaa155e13d4e92403a468177bc2","affectsGlobalScope":true,"impliedFormat":1},{"version":"2754d8221d77c7b382096651925eb476f1066b3348da4b73fe71ced7801edada","impliedFormat":1},{"version":"cca97c55398b8699fa3a96ef261b01d200ed2a44d2983586ab1a81d7d7b23cd9","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef91efa0baea5d0e0f0f27b574a8bc100ce62a6d7e70220a0d58af6acab5e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"f59493f68eade5200559e5016b5855f7d12e6381eb6cab9ad8a379af367b3b2d","impliedFormat":1},{"version":"125e3472965f529de239d2bc85b54579fed8e0b060d1d04de6576fb910a6ec7f","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"18f5c7c4ad71748cffdd42e829398acdfd2d150a887e5f07aae4f2acab68e71b","affectsGlobalScope":true,"impliedFormat":1},{"version":"72ed3074450a4a315063278f046637afdeea90aa72b2292a7976958ceafc344a","affectsGlobalScope":true,"impliedFormat":1},{"version":"a5c09990a37469b0311a92ce8feeb8682e83918723aedbd445bd7a0f510eaaa3","impliedFormat":1},{"version":"6b29aea17044029b257e5bd4e3e4f765cd72b8d3c11c753f363ab92cc3f9f947","impliedFormat":1},{"version":"ac5ed35e649cdd8143131964336ab9076937fa91802ec760b3ea63b59175c10a","impliedFormat":1},{"version":"d008cf1330c86b37a8128265c80795397c287cecff273bc3ce3a4883405f5112","affectsGlobalScope":true,"impliedFormat":1},{"version":"78dc0513cc4f1642906b74dda42146bcbd9df7401717d6e89ea6d72d12ecb539","impliedFormat":1},{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true,"impliedFormat":1},{"version":"f2b6058d3dd78c1b4dafc97083c5d44bdfbf4155194044bd17b8fcca554e766a","impliedFormat":1},{"version":"cdcc132f207d097d7d3aa75615ab9a2e71d6a478162dde8b67f88ea19f3e54de","impliedFormat":1},{"version":"0d14fa22c41fdc7277e6f71473b20ebc07f40f00e38875142335d5b63cdfc9d2","impliedFormat":1},{"version":"c085e9aa62d1ae1375794c1fb927a445fa105fed891a7e24edbb1c3300f7384a","impliedFormat":1},{"version":"f315e1e65a1f80992f0509e84e4ae2df15ecd9ef73df975f7c98813b71e4c8da","impliedFormat":1},{"version":"5b9586e9b0b6322e5bfbd2c29bd3b8e21ab9d871f82346cb71020e3d84bae73e","impliedFormat":1},{"version":"3e70a7e67c2cb16f8cd49097360c0309fe9d1e3210ff9222e9dac1f8df9d4fb6","impliedFormat":1},{"version":"ab68d2a3e3e8767c3fba8f80de099a1cfc18c0de79e42cb02ae66e22dfe14a66","impliedFormat":1},{"version":"d96cc6598148bf1a98fb2e8dcf01c63a4b3558bdaec6ef35e087fd0562eb40ec","impliedFormat":1},{"version":"e9b76bb505b61fdb2b4347398776a0c3d081877cee7669f7ca09846aeb325c63","affectsGlobalScope":true,"impliedFormat":1}],"root":[49,85,86,[89,92]],"options":{"allowJs":true,"allowSyntheticDefaultImports":true,"declaration":true,"emitDecoratorMetadata":true,"esModuleInterop":true,"experimentalDecorators":true,"importHelpers":true,"inlineSources":true,"module":99,"noEmitOnError":true,"noImplicitAny":false,"outDir":"./","skipLibCheck":true,"sourceMap":true,"strict":true,"target":4,"useDefineForClassFields":false},"referencedMap":[[189,1],[192,2],[65,1],[66,1],[67,3],[60,1],[62,1],[63,1],[64,4],[61,1],[74,5],[76,1],[77,6],[75,1],[59,7],[50,1],[55,8],[53,9],[52,10],[54,1],[51,1],[58,1],[82,11],[81,12],[80,13],[79,1],[191,1],[197,14],[95,15],[96,15],[136,16],[137,17],[138,18],[139,19],[140,20],[141,21],[142,22],[143,23],[144,24],[145,25],[146,25],[148,26],[147,27],[149,28],[150,29],[151,30],[135,31],[187,1],[152,32],[153,33],[154,34],[155,35],[156,36],[157,37],[158,38],[159,39],[160,40],[161,41],[162,42],[163,43],[164,44],[165,44],[166,45],[167,1],[168,1],[169,46],[171,47],[170,48],[172,49],[173,50],[174,51],[175,52],[176,53],[177,54],[178,55],[94,56],[93,1],[188,57],[179,58],[180,59],[181,60],[182,61],[183,62],[184,63],[185,64],[186,65],[69,1],[97,1],[190,1],[196,66],[78,1],[194,67],[195,68],[71,69],[87,70],[68,71],[72,1],[70,72],[88,73],[73,74],[193,75],[57,13],[84,76],[83,13],[56,1],[48,1],[46,1],[47,1],[8,1],[9,1],[11,1],[10,1],[2,1],[12,1],[13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[19,1],[3,1],[20,1],[4,1],[21,1],[25,1],[22,1],[23,1],[24,1],[26,1],[27,1],[28,1],[5,1],[29,1],[30,1],[31,1],[32,1],[6,1],[36,1],[33,1],[34,1],[35,1],[37,1],[7,1],[38,1],[43,1],[44,1],[39,1],[40,1],[41,1],[42,1],[1,1],[45,1],[113,77],[123,78],[112,77],[133,79],[104,80],[103,81],[132,82],[126,83],[131,84],[106,85],[120,86],[105,87],[129,88],[101,89],[100,82],[130,90],[102,91],[107,92],[108,1],[111,92],[98,1],[134,93],[124,94],[115,95],[116,96],[118,97],[114,98],[117,99],[127,82],[109,100],[110,101],[119,102],[99,103],[122,94],[121,92],[125,1],[128,104],[85,105],[49,12],[91,106],[90,107],[92,108],[89,109],[86,110]],"version":"5.6.2"}
1
+ {"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/tslib/tslib.d.ts","../client/auth.ts","../../../node_modules/@operato/shell/dist/src/types/domain.d.ts","../../../node_modules/@operato/shell/dist/src/types/user.d.ts","../../../node_modules/@operato/shell/dist/src/types/role.d.ts","../../../node_modules/@operato/shell/dist/src/types/privilege.d.ts","../../../node_modules/@operato/shell/dist/src/types/types.d.ts","../../../node_modules/@operato/shell/dist/src/types/index.d.ts","../../../node_modules/redux/dist/redux.d.ts","../../../node_modules/pwa-helpers/lazy-reducer-enhancer.d.ts","../../../node_modules/@operato/shell/node_modules/redux/index.d.ts","../../../node_modules/@operato/shell/dist/src/store.d.ts","../../../node_modules/@operato/shell/dist/src/actions/app.d.ts","../../../node_modules/@operato/shell/dist/src/actions/route.d.ts","../../../node_modules/@operato/shell/dist/src/actions/busy.d.ts","../../../node_modules/@operato/shell/dist/src/actions/const.d.ts","../../../node_modules/@operato/shell/dist/src/actions/index.d.ts","../../../node_modules/@lit/reactive-element/css-tag.d.ts","../../../node_modules/@lit/reactive-element/reactive-controller.d.ts","../../../node_modules/@lit/reactive-element/reactive-element.d.ts","../../../node_modules/lit-html/directive.d.ts","../../../node_modules/@types/trusted-types/lib/index.d.ts","../../../node_modules/lit-html/lit-html.d.ts","../../../node_modules/lit-element/lit-element.d.ts","../../../node_modules/lit-html/is-server.d.ts","../../../node_modules/lit/index.d.ts","../../../node_modules/@operato/shell/dist/src/app/pages/page-view.d.ts","../../../node_modules/@operato/shell/dist/src/object-store.d.ts","../../../node_modules/@operato/shell/dist/src/custom-alert.d.ts","../../../node_modules/@operato/shell/dist/src/index.d.ts","../../../node_modules/immer/dist/immer.d.ts","../../../node_modules/@reduxjs/toolkit/node_modules/reselect/dist/reselect.d.ts","../../../node_modules/@reduxjs/toolkit/node_modules/redux-thunk/dist/redux-thunk.d.ts","../../../node_modules/@reduxjs/toolkit/dist/uncheckedindexed.ts","../../../node_modules/@reduxjs/toolkit/dist/index.d.ts","../../../node_modules/redux-thunk/es/types.d.ts","../../../node_modules/redux-thunk/es/index.d.ts","../client/actions/auth.ts","../client/reducers/auth.ts","../../../node_modules/lit-html/async-directive.d.ts","../../../node_modules/lit/async-directive.d.ts","../client/profiled.ts","../client/directive/privileged.ts","../client/bootstrap.ts","../../../node_modules/@simplewebauthn/types/types/dom.d.ts","../../../node_modules/@simplewebauthn/types/types/index.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/methods/startregistration.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/methods/startauthentication.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/helpers/browsersupportswebauthn.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/helpers/platformauthenticatorisavailable.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/helpers/browsersupportswebauthnautofill.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/helpers/base64urlstringtobuffer.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/helpers/buffertobase64urlstring.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/helpers/webauthnabortservice.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/helpers/webauthnerror.d.ts","../../../node_modules/@simplewebauthn/browser/dist/types/index.d.ts","../client/verify-webauthn.ts","../client/index.ts","../../../node_modules/@types/node/ts5.6/globals.typedarray.d.ts","../../../node_modules/@types/node/ts5.6/buffer.buffer.d.ts","../../../node_modules/@types/node/assert.d.ts","../../../node_modules/@types/node/assert/strict.d.ts","../../../node_modules/buffer/index.d.ts","../../../node_modules/undici-types/header.d.ts","../../../node_modules/undici-types/readable.d.ts","../../../node_modules/undici-types/file.d.ts","../../../node_modules/undici-types/fetch.d.ts","../../../node_modules/undici-types/formdata.d.ts","../../../node_modules/undici-types/connector.d.ts","../../../node_modules/undici-types/client.d.ts","../../../node_modules/undici-types/errors.d.ts","../../../node_modules/undici-types/dispatcher.d.ts","../../../node_modules/undici-types/global-dispatcher.d.ts","../../../node_modules/undici-types/global-origin.d.ts","../../../node_modules/undici-types/pool-stats.d.ts","../../../node_modules/undici-types/pool.d.ts","../../../node_modules/undici-types/handlers.d.ts","../../../node_modules/undici-types/balanced-pool.d.ts","../../../node_modules/undici-types/agent.d.ts","../../../node_modules/undici-types/mock-interceptor.d.ts","../../../node_modules/undici-types/mock-agent.d.ts","../../../node_modules/undici-types/mock-client.d.ts","../../../node_modules/undici-types/mock-pool.d.ts","../../../node_modules/undici-types/mock-errors.d.ts","../../../node_modules/undici-types/proxy-agent.d.ts","../../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../../node_modules/undici-types/retry-handler.d.ts","../../../node_modules/undici-types/retry-agent.d.ts","../../../node_modules/undici-types/api.d.ts","../../../node_modules/undici-types/interceptors.d.ts","../../../node_modules/undici-types/util.d.ts","../../../node_modules/undici-types/cookies.d.ts","../../../node_modules/undici-types/patch.d.ts","../../../node_modules/undici-types/websocket.d.ts","../../../node_modules/undici-types/eventsource.d.ts","../../../node_modules/undici-types/filereader.d.ts","../../../node_modules/undici-types/diagnostics-channel.d.ts","../../../node_modules/undici-types/content-type.d.ts","../../../node_modules/undici-types/cache.d.ts","../../../node_modules/undici-types/index.d.ts","../../../node_modules/@types/node/globals.d.ts","../../../node_modules/@types/node/async_hooks.d.ts","../../../node_modules/@types/node/buffer.d.ts","../../../node_modules/@types/node/child_process.d.ts","../../../node_modules/@types/node/cluster.d.ts","../../../node_modules/@types/node/console.d.ts","../../../node_modules/@types/node/constants.d.ts","../../../node_modules/@types/node/crypto.d.ts","../../../node_modules/@types/node/dgram.d.ts","../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/@types/node/dns.d.ts","../../../node_modules/@types/node/dns/promises.d.ts","../../../node_modules/@types/node/domain.d.ts","../../../node_modules/@types/node/dom-events.d.ts","../../../node_modules/@types/node/events.d.ts","../../../node_modules/@types/node/fs.d.ts","../../../node_modules/@types/node/fs/promises.d.ts","../../../node_modules/@types/node/http.d.ts","../../../node_modules/@types/node/http2.d.ts","../../../node_modules/@types/node/https.d.ts","../../../node_modules/@types/node/inspector.d.ts","../../../node_modules/@types/node/module.d.ts","../../../node_modules/@types/node/net.d.ts","../../../node_modules/@types/node/os.d.ts","../../../node_modules/@types/node/path.d.ts","../../../node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/@types/node/process.d.ts","../../../node_modules/@types/node/punycode.d.ts","../../../node_modules/@types/node/querystring.d.ts","../../../node_modules/@types/node/readline.d.ts","../../../node_modules/@types/node/readline/promises.d.ts","../../../node_modules/@types/node/repl.d.ts","../../../node_modules/@types/node/sea.d.ts","../../../node_modules/@types/node/sqlite.d.ts","../../../node_modules/@types/node/stream.d.ts","../../../node_modules/@types/node/stream/promises.d.ts","../../../node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/@types/node/stream/web.d.ts","../../../node_modules/@types/node/string_decoder.d.ts","../../../node_modules/@types/node/test.d.ts","../../../node_modules/@types/node/timers.d.ts","../../../node_modules/@types/node/timers/promises.d.ts","../../../node_modules/@types/node/tls.d.ts","../../../node_modules/@types/node/trace_events.d.ts","../../../node_modules/@types/node/tty.d.ts","../../../node_modules/@types/node/url.d.ts","../../../node_modules/@types/node/util.d.ts","../../../node_modules/@types/node/v8.d.ts","../../../node_modules/@types/node/vm.d.ts","../../../node_modules/@types/node/wasi.d.ts","../../../node_modules/@types/node/worker_threads.d.ts","../../../node_modules/@types/node/zlib.d.ts","../../../node_modules/@types/node/globals.global.d.ts","../../../node_modules/@types/node/ts5.6/index.d.ts","../../../node_modules/@jest/expect-utils/build/index.d.ts","../../../node_modules/chalk/index.d.ts","../../../node_modules/@sinclair/typebox/typebox.d.ts","../../../node_modules/@jest/schemas/build/index.d.ts","../../../node_modules/pretty-format/build/index.d.ts","../../../node_modules/jest-diff/build/index.d.ts","../../../node_modules/jest-matcher-utils/build/index.d.ts","../../../node_modules/expect/build/index.d.ts","../../../node_modules/@types/jest/index.d.ts"],"fileIdsList":[[107,150],[107,150,204],[65,66,107,150],[60,61,62,63,107,150],[73,107,150],[55,59,64,74,75,76,107,150],[57,58,107,150],[50,51,52,53,54,107,150],[51,52,107,150],[50,51,53,107,150],[56,78,79,80,81,107,150],[48,107,150],[56,107,150],[94,95,96,97,98,99,100,101,102,107,150],[93,107,150],[92,107,150],[107,150,206,209],[107,108,150],[107,149,150],[107,150,155,185],[107,150,151,156,162,163,170,182,193],[107,150,151,152,162,170],[107,150,153,194],[107,150,154,155,163,171],[107,150,155,182,190],[107,150,156,158,162,170],[107,149,150,157],[107,150,158,159],[107,150,162],[107,150,160,162],[107,149,150,162],[107,150,162,163,164,182,193],[107,150,162,163,164,177,182,185],[107,147,150,198],[107,147,150,158,162,165,170,182,193],[107,150,162,163,165,166,170,182,190,193],[107,150,165,167,182,190,193],[107,150,162,168],[107,150,169,193,198],[107,150,158,162,170,182],[107,150,171],[107,150,172],[107,149,150,173],[107,108,109,149,150,151,152,153,154,155,156,157,158,159,160,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199],[107,150,175],[107,150,176],[107,150,162,177,178],[107,150,177,179,194,196],[107,150,162,182,183,184,185],[107,150,182,184],[107,150,182,183],[107,150,185],[107,150,186],[107,108,150,182],[107,150,162,188,189],[107,150,188,189],[107,150,155,170,182,190],[107,150,191],[150],[106,107,108,109,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200],[107,150,170,192],[107,150,165,176,193],[107,150,155,194],[107,150,182,195],[107,150,169,196],[107,150,197],[107,150,155,162,164,173,182,193,196,198],[107,150,182,199],[107,150,202,208],[107,150,206],[107,150,203,207],[67,70,107,150],[68,70,107,150],[70,107,150],[68,69,107,150],[87,107,150],[67,70,71,72,107,150],[107,150,205],[56,83,107,150],[107,119,123,150,193],[107,119,150,182,193],[107,114,150],[107,116,119,150,190,193],[107,150,170,190],[107,150,201],[107,114,150,201],[107,116,119,150,170,193],[107,111,112,115,118,150,162,182,193],[107,119,126,150],[107,111,117,150],[107,119,140,141,150],[107,115,119,150,185,193,201],[107,140,150,201],[107,113,114,150,201],[107,119,150],[107,113,114,115,116,117,118,119,120,121,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,141,142,143,144,145,146,150],[107,119,134,150],[107,119,126,127,150],[107,117,119,127,128,150],[107,118,150],[107,111,114,119,150],[107,119,123,127,128,150],[107,123,150],[107,117,119,122,150,193],[107,111,116,119,126,150],[107,150,182],[107,114,119,140,150,198,201],[48,82,84,107,150],[48,49,77,85,86,90,107,150],[48,73,88,89,107,150],[48,49,89,90,104,107,150],[48,49,107,150],[48,85,107,150],[48,103,107,150]],"fileInfos":[{"version":"44e584d4f6444f58791784f1d530875970993129442a847597db702a073ca68c","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"9a68c0c07ae2fa71b44384a839b7b8d81662a236d4b9ac30916718f7510b1b2d","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"9e8ca8ed051c2697578c023d9c29d6df689a083561feba5c14aedee895853999","affectsGlobalScope":true,"impliedFormat":1},{"version":"69e65d976bf166ce4a9e6f6c18f94d2424bf116e90837ace179610dbccad9b42","affectsGlobalScope":true,"impliedFormat":1},{"version":"6920e1448680767498a0b77c6a00a8e77d14d62c3da8967b171f1ddffa3c18e4","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"45d8ccb3dfd57355eb29749919142d4321a0aa4df6acdfc54e30433d7176600a","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"93495ff27b8746f55d19fcbcdbaccc99fd95f19d057aed1bd2c0cafe1335fbf0","affectsGlobalScope":true,"impliedFormat":1},{"version":"6fc23bb8c3965964be8c597310a2878b53a0306edb71d4b5a4dfe760186bcc01","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea011c76963fb15ef1cdd7ce6a6808b46322c527de2077b6cfdf23ae6f5f9ec7","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"4738f2420687fd85629c9efb470793bb753709c2379e5f85bc1815d875ceadcd","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"9fc46429fbe091ac5ad2608c657201eb68b6f1b8341bd6d670047d32ed0a88fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"1a94697425a99354df73d9c8291e2ecd4dddd370aed4023c2d6dee6cccb32666","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"bf14a426dbbf1022d11bd08d6b8e709a2e9d246f0c6c1032f3b2edb9a902adbe","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3f9fc0ec0b96a9e642f11eda09c0be83a61c7b336977f8b9fdb1e9788e925fe","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"479553e3779be7d4f68e9f40cdb82d038e5ef7592010100410723ceced22a0f7","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"33358442698bb565130f52ba79bfd3d4d484ac85fe33f3cb1759c54d18201393","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"4a882ffbb4ed09d9b7734f784aebb1dfe488d63725c40759165c5d9c657ca029","impliedFormat":1},{"version":"b43c3d6f808876e21ed81a3bb8e348be01110ca6c464a080256b2b0ee17aa7ba","signature":"ead7c69443921d68ef00bb0c31d11c3eddefd5cbfca08f7a6979b5bb46a2a2c6"},{"version":"4d4cf93a6b4c81851ad759e4569b6feb7a701e80b13a6f9d8d9c6012bbb86bd6","impliedFormat":1},{"version":"2e6035af8f3e43bf95e4983329c8277d66f9b271106af27b99a85d1c1b9daf4a","impliedFormat":1},{"version":"774308610e8d4a9954cd93840f99decbf340accfe3ad7365547950ede8162c92","impliedFormat":1},{"version":"36c15dd26c66c97b9df26ce34baacdb13fc760c5b9a2d789dcc317d27b189257","impliedFormat":1},{"version":"3d7c0b593a29d717b2b2ba3f03f819c3c48bf9e250d79c4a31860af80f177e8c","impliedFormat":1},{"version":"f228d440342f5d0933f5db093aafab2f07de24a427b4488ccfae27b7457d7666","impliedFormat":1},{"version":"f734b58ea162765ff4d4a36f671ee06da898921e985a2064510f4925ec1ed062","affectsGlobalScope":true,"impliedFormat":1},{"version":"701978f3975f96e76e3ffc2e1762e3a97e3d323812049fb6fdfd559579b89708","impliedFormat":1},{"version":"fd624f7d7b264922476685870f08c5e1c6d6a0f05dee2429a9747b41f6b699d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ab17f80ced148d509345cee706b2b85941515dd76e32cf47118bcdf6a4bd56a","affectsGlobalScope":true,"impliedFormat":1},{"version":"641089f0b8094ef74b9d4b3364d5dec1592d5e3b8a51c1ba491bc8872049e79a","impliedFormat":1},{"version":"950fc6ac97ce76785f03282f907aac4b2cbd8ac74b17c963f1389847962cbc20","impliedFormat":1},{"version":"b42033bf1067564808e4d360d79281667c2b3b0792c2d615ab641eb85974d4ba","impliedFormat":1},{"version":"7af29b0589483f7bb8a99405ddb849f34bc053146184561ed4179e02f5fe4d0f","impliedFormat":1},{"version":"78faa3783191b2d5d5f7a9e835ee3f6a1456dc391d6eb5b40d3a27dfd9decd6e","impliedFormat":1},{"version":"e056bb30bf82271634daeee81f772f4a7960085f01f6d4d09c8da1ebe5f6a623","impliedFormat":99},{"version":"5e30131b6a5587fe666926ad1d9807e733c0a597ed12d682669fcaa331aea576","impliedFormat":99},{"version":"86492a546c3308feaf1dde967afd325c321483b5e96f5fa9e9b6e691dc23fa9e","affectsGlobalScope":true,"impliedFormat":99},{"version":"00cb63103f9670f8094c238a4a7e252c8b4c06ba371fea5c44add7e41b7247e4","impliedFormat":99},{"version":"15fe687c59d62741b4494d5e623d497d55eb38966ecf5bea7f36e48fc3fbe15e","impliedFormat":1},{"version":"43f58358870effc43ba93c92c040dee2285cbd8685ddfa77658e498780727c4e","impliedFormat":99},{"version":"9a318e3a8900672b85cd3c8c3a5acf51b88049557a3ae897ccdcf2b85a8f61f9","impliedFormat":99},{"version":"1bcd560deed90a43c51b08aa18f7f55229f2e30974ab5ed1b7bb5721be379013","impliedFormat":99},{"version":"dc08fe04e50bc24d1baded4f33e942222bbdd5d77d6341a93cfe6e4e4586a3be","impliedFormat":99},{"version":"9c7568f9c75cf6a7d35dc9f18c5971cd5b21344c686c7cce56b3558d3305d40f","impliedFormat":1},{"version":"fc48282c397084016a939e1b3f91dcaf4199b6cba339d91d8b2dc2acade79762","impliedFormat":1},{"version":"3e62a55b950132d6eeacc607b7a1bff990d5484347b2be5a1f54db51af30ff25","impliedFormat":1},{"version":"a6203646763fb7340123eace99b924c9586ea3cf56f65fe8c56308e6ecb2b805","impliedFormat":1},{"version":"07cbc706c24fa086bcc20daee910b9afa5dc5294e14771355861686c9d5235fd","impliedFormat":1},{"version":"37f96daaddc2dd96712b2e86f3901f477ac01a5c2539b1bc07fd609d62039ee1","impliedFormat":1},{"version":"9c5c84c449a3d74e417343410ba9f1bd8bfeb32abd16945a1b3d0592ded31bc8","impliedFormat":1},{"version":"a7f09d2aaf994dbfd872eda4f2411d619217b04dbe0916202304e7a3d4b0f5f8","impliedFormat":1},{"version":"031f331d8b2e12010bca1334866b75344d7986e8a693c9f916edb0e30cf8d013","impliedFormat":1},{"version":"d50a158fc581be7b1c51253ad33cb29c0a8ce3c42ca38775ffadf104c36376d0","impliedFormat":1},{"version":"1f2cdbf59d0b7933678a64ac26ae2818c48ff9ebf93249dde775dc3e173e16bf","impliedFormat":1},{"version":"2ba328775832040cb87cb16f6fc454ae00f9620f8dd97dd283ae3bfd9f744637","signature":"a3c81c9082ad3d86a42d51980ce4e29c85e9b91ae9beefb76d1dcf62f8355fa8"},{"version":"d3a72e3acec55990c739ec2c7ec487ace738418d0650356c2db86b67a3d1b818","signature":"6a716b8d3a52002354a3e530ee6c90d52209af1f53eaefb9c4527228bf0a6f67"},{"version":"c42f9b18f5f559b133cf9b409f678afb30df9c6498865aae9a1abad0f1e727a8","impliedFormat":99},{"version":"eabff483c855b848eefb979dbfb64c8858444c56a2f3ea0e59de026ef03fd089","impliedFormat":99},{"version":"2ef2abb081acc60d2fe8083d8aa8925a9fabf6eee88a331c0234dd8fad71bcfc","signature":"d75a3e4665db49528093a3d868b69a53ac6bfc368b232d4db3130fd0a5e543c2"},{"version":"a9b96633c658f87988e20b077d45dc11e39a9237e829bcbbf400e5686c249b7b","signature":"9848af2eb0cfdf37577332c9c5035c616918c3139fa09d5c1f504b878f2281a3"},{"version":"85d18863957bd329e9e801ea8467123d8e0d12dedced776718fd648ea7c0b28f","signature":"d09851f8824ccbae129caa791d49356c8b7406f05687cb38a7c7eb3ed21d197b"},{"version":"7c7b0cb8e73236466a6b82bc4cfc5432bf020d6486fba6971b7f4e3626d8596c","impliedFormat":1},{"version":"30649028712370b111202f9dcff2258c5d18b316ac8dd482d63e9f990ea6d8a3","impliedFormat":1},{"version":"0e9743024712c79f563c2b25f89702df6c3362d40a6e98ecaf2bb7ba925f00f6","impliedFormat":99},{"version":"eaa5f2320d2f3fbb55db39ad329fc9458e41ea03436cd6e7cf6cd4ebff249ee6","impliedFormat":99},{"version":"2c0a002077618a07de8522922288d4a667e4d460420ed99dceac5730085512e9","impliedFormat":99},{"version":"c6fa5ebddfaef8807b7a7c0fe7685ab25ea18bd68c33e44c8ebaaf84044412e5","impliedFormat":99},{"version":"9b4d21e314ee98044e2a66e9ea21e4d6c99661826d7df52f28ec552e2f68c245","impliedFormat":99},{"version":"0352d5db70863892f7d417503f91af86b6eeca496268612770d2f045025d4e11","impliedFormat":99},{"version":"b8186275886abd7a3a815ec8b11e31b2151c745b67acfbb844757168bfae724c","impliedFormat":99},{"version":"d8df0567ffec6200245b5b2576211cf5377b891793b4e98b726049e930b488a4","impliedFormat":99},{"version":"487c2b19335d262629852b48051cf237f2d613e038dc4f479add7237fced54f9","impliedFormat":99},{"version":"c9f61cbd94350f5d0789052338a9dc51d0d25c83ecd7da00db2da840ddd4d63a","impliedFormat":99},{"version":"997c14dffeb1bbffe14e7f79307295aa83d7ef1ee38762c13514d53ae43d2ede","signature":"e899b1dbfb78597e87307ffaccf5617114bfc97fd39a0b773cbefebfd5c3a870"},{"version":"37cdc656fa1e607de2bdcc5b6d6481edfe2a19e896ca6ed826638a503031b817","signature":"483c80302dd9ff5161b05031ef4d06c4e50fd500f09875cf790ba8b82e33aa1d"},{"version":"613b21ccdf3be6329d56e6caa13b258c842edf8377be7bc9f014ed14cdcfc308","affectsGlobalScope":true,"impliedFormat":1},{"version":"2d1319e6b5d0efd8c5eae07eb864a00102151e8b9afddd2d45db52e9aae002c4","affectsGlobalScope":true,"impliedFormat":1},{"version":"f6114eb1e8f70ec08816bdaa6ec740a0a7a01f25743e36f655f00157be394374","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"4967529644e391115ca5592184d4b63980569adf60ee685f968fd59ab1557188","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"24bd580b5743dc56402c440dc7f9a4f5d592ad7a419f25414d37a7bfe11e342b","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"6bdc71028db658243775263e93a7db2fd2abfce3ca569c3cca5aee6ed5eb186d","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"4d2b0eb911816f66abe4970898f97a2cfc902bcd743cbfa5017fad79f7ef90d8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"e53a3c2a9f624d90f24bf4588aacd223e7bec1b9d0d479b68d2f4a9e6011147f","impliedFormat":1},{"version":"24b8685c62562f5d98615c5a0c1d05f297cf5065f15246edfe99e81ec4c0e011","impliedFormat":1},{"version":"93507c745e8f29090efb99399c3f77bec07db17acd75634249dc92f961573387","impliedFormat":1},{"version":"339dc5265ee5ed92e536a93a04c4ebbc2128f45eeec6ed29f379e0085283542c","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"bb2cd9339d0201e7e78ccb6ff2f71aac103934bf35eaaa37e139ac2b68af0db8","affectsGlobalScope":true,"impliedFormat":1},{"version":"76103716ba397bbb61f9fa9c9090dca59f39f9047cb1352b2179c5d8e7f4e8d0","impliedFormat":1},{"version":"53eac70430b30089a3a1959d8306b0f9cfaf0de75224b68ef25243e0b5ad1ca3","affectsGlobalScope":true,"impliedFormat":1},{"version":"4314c7a11517e221f7296b46547dbc4df047115b182f544d072bdccffa57fc72","impliedFormat":1},{"version":"115971d64632ea4742b5b115fb64ed04bcaae2c3c342f13d9ba7e3f9ee39c4e7","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"a40826e8476694e90da94aa008283a7de50d1dafd37beada623863f1901cb7fb","impliedFormat":1},{"version":"46e07db372dd75edc1a26e68f16d1b7ffb34b7ab3db5cdb3e391a3604ad7bb7c","affectsGlobalScope":true,"impliedFormat":1},{"version":"24642567d3729bcc545bacb65ee7c0db423400c7f1ef757cab25d05650064f98","impliedFormat":1},{"version":"e6f5a38687bebe43a4cef426b69d34373ef68be9a6b1538ec0a371e69f309354","impliedFormat":1},{"version":"a6bf63d17324010ca1fbf0389cab83f93389bb0b9a01dc8a346d092f65b3605f","impliedFormat":1},{"version":"e009777bef4b023a999b2e5b9a136ff2cde37dc3f77c744a02840f05b18be8ff","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"ee1ee365d88c4c6c0c0a5a5701d66ebc27ccd0bcfcfaa482c6e2e7fe7b98edf7","affectsGlobalScope":true,"impliedFormat":1},{"version":"42a872b757f365f61369e869f8403ec1e78b5a85418622801011009a1430d87f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c956ba45704d4a97f7a96923a307a6203bc0e7c4c532930d4c8ca261eaaff32a","impliedFormat":1},{"version":"ab0e88d33ccf15d8b3c891038b5a16094b0dd7e860ab0e2ba08da4384afce02b","impliedFormat":1},{"version":"954580f86c8e2a4abd5dcd1bcdf1a4c7e012495f1c39e058dc738bc93024642a","impliedFormat":1},{"version":"fa56be9b96f747e93b895d8dc2aa4fb9f0816743e6e2abb9d60705e88d4743a2","impliedFormat":1},{"version":"8257c55ff6bff6169142a35fce6811b511d857b4ae4f522cdb6ce20fd2116b2c","impliedFormat":1},{"version":"6d386bc0d7f3afa1d401afc3e00ed6b09205a354a9795196caed937494a713e6","impliedFormat":1},{"version":"3a9e5dddbd6ca9507d0c06a557535ba2224a94a2b0f3e146e8215f93b7e5b3a8","affectsGlobalScope":true,"impliedFormat":1},{"version":"94c4187083503a74f4544503b5a30e2bd7af0032dc739b0c9a7ce87f8bddc7b9","impliedFormat":1},{"version":"b1b6ee0d012aeebe11d776a155d8979730440082797695fc8e2a5c326285678f","impliedFormat":1},{"version":"45875bcae57270aeb3ebc73a5e3fb4c7b9d91d6b045f107c1d8513c28ece71c0","impliedFormat":1},{"version":"3c36ab47df4668254ccc170fc42e7d5116fd86a7e408d8dc220e559837cd2bbb","affectsGlobalScope":true,"impliedFormat":1},{"version":"6f6abdaf8764ef01a552a958f45e795b5e79153b87ddad3af5264b86d2681b72","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"c6b4e0a02545304935ecbf7de7a8e056a31bb50939b5b321c9d50a405b5a0bba","impliedFormat":1},{"version":"c86b9afa9b39b12db8e877d23b48888d80f26e1fe72a95f58552746a6e1fa4fe","impliedFormat":1},{"version":"e432b0e3761ca9ba734bdd41e19a75fec1454ca8e9769bfdf8b31011854cf06a","impliedFormat":1},{"version":"e1120271ebbc9952fdc7b2dd3e145560e52e06956345e6fdf91d70ca4886464f","impliedFormat":1},{"version":"15c5e91b5f08be34a78e3d976179bf5b7a9cc28dc0ef1ffebffeb3c7812a2dca","impliedFormat":1},{"version":"a8f06c2382a30b7cb89ad2dfc48fc3b2b490f3dafcd839dadc008e4e5d57031d","impliedFormat":1},{"version":"07b9d3b7204d931acc29269c98ac3aac87ebcba6e05141552d42a4c17f895aa4","impliedFormat":1},{"version":"269929a24b2816343a178008ac9ae9248304d92a8ba8e233055e0ed6dbe6ef71","impliedFormat":1},{"version":"93452d394fdd1dc551ec62f5042366f011a00d342d36d50793b3529bfc9bd633","impliedFormat":1},{"version":"1425f76ac97ce8617d1e2fa79e9a14e0fd1cfdaa155e13d4e92403a468177bc2","affectsGlobalScope":true,"impliedFormat":1},{"version":"2754d8221d77c7b382096651925eb476f1066b3348da4b73fe71ced7801edada","impliedFormat":1},{"version":"cca97c55398b8699fa3a96ef261b01d200ed2a44d2983586ab1a81d7d7b23cd9","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef91efa0baea5d0e0f0f27b574a8bc100ce62a6d7e70220a0d58af6acab5e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"f59493f68eade5200559e5016b5855f7d12e6381eb6cab9ad8a379af367b3b2d","impliedFormat":1},{"version":"125e3472965f529de239d2bc85b54579fed8e0b060d1d04de6576fb910a6ec7f","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"18f5c7c4ad71748cffdd42e829398acdfd2d150a887e5f07aae4f2acab68e71b","affectsGlobalScope":true,"impliedFormat":1},{"version":"72ed3074450a4a315063278f046637afdeea90aa72b2292a7976958ceafc344a","affectsGlobalScope":true,"impliedFormat":1},{"version":"a5c09990a37469b0311a92ce8feeb8682e83918723aedbd445bd7a0f510eaaa3","impliedFormat":1},{"version":"6b29aea17044029b257e5bd4e3e4f765cd72b8d3c11c753f363ab92cc3f9f947","impliedFormat":1},{"version":"ac5ed35e649cdd8143131964336ab9076937fa91802ec760b3ea63b59175c10a","impliedFormat":1},{"version":"d008cf1330c86b37a8128265c80795397c287cecff273bc3ce3a4883405f5112","affectsGlobalScope":true,"impliedFormat":1},{"version":"78dc0513cc4f1642906b74dda42146bcbd9df7401717d6e89ea6d72d12ecb539","impliedFormat":1},{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true,"impliedFormat":1},{"version":"f2b6058d3dd78c1b4dafc97083c5d44bdfbf4155194044bd17b8fcca554e766a","impliedFormat":1},{"version":"cdcc132f207d097d7d3aa75615ab9a2e71d6a478162dde8b67f88ea19f3e54de","impliedFormat":1},{"version":"0d14fa22c41fdc7277e6f71473b20ebc07f40f00e38875142335d5b63cdfc9d2","impliedFormat":1},{"version":"c085e9aa62d1ae1375794c1fb927a445fa105fed891a7e24edbb1c3300f7384a","impliedFormat":1},{"version":"f315e1e65a1f80992f0509e84e4ae2df15ecd9ef73df975f7c98813b71e4c8da","impliedFormat":1},{"version":"5b9586e9b0b6322e5bfbd2c29bd3b8e21ab9d871f82346cb71020e3d84bae73e","impliedFormat":1},{"version":"3e70a7e67c2cb16f8cd49097360c0309fe9d1e3210ff9222e9dac1f8df9d4fb6","impliedFormat":1},{"version":"ab68d2a3e3e8767c3fba8f80de099a1cfc18c0de79e42cb02ae66e22dfe14a66","impliedFormat":1},{"version":"d96cc6598148bf1a98fb2e8dcf01c63a4b3558bdaec6ef35e087fd0562eb40ec","impliedFormat":1},{"version":"e9b76bb505b61fdb2b4347398776a0c3d081877cee7669f7ca09846aeb325c63","affectsGlobalScope":true,"impliedFormat":1}],"root":[49,85,86,[89,91],104,105],"options":{"allowJs":true,"allowSyntheticDefaultImports":true,"declaration":true,"emitDecoratorMetadata":true,"esModuleInterop":true,"experimentalDecorators":true,"importHelpers":true,"inlineSources":true,"module":99,"noEmitOnError":true,"noImplicitAny":false,"outDir":"./","skipLibCheck":true,"sourceMap":true,"strict":true,"target":4,"useDefineForClassFields":false},"referencedMap":[[202,1],[205,2],[65,1],[66,1],[67,3],[60,1],[62,1],[63,1],[64,4],[61,1],[74,5],[76,1],[77,6],[75,1],[59,7],[50,1],[55,8],[53,9],[52,10],[54,1],[51,1],[58,1],[82,11],[81,12],[80,13],[79,1],[99,1],[96,1],[98,1],[100,1],[97,1],[101,1],[102,1],[103,14],[95,15],[94,15],[92,1],[93,16],[204,1],[210,17],[108,18],[109,18],[149,19],[150,20],[151,21],[152,22],[153,23],[154,24],[155,25],[156,26],[157,27],[158,28],[159,28],[161,29],[160,30],[162,31],[163,32],[164,33],[148,34],[200,1],[165,35],[166,36],[167,37],[168,38],[169,39],[170,40],[171,41],[172,42],[173,43],[174,44],[175,45],[176,46],[177,47],[178,47],[179,48],[180,1],[181,1],[182,49],[184,50],[183,51],[185,52],[186,53],[187,54],[188,55],[189,56],[190,57],[191,58],[107,59],[106,1],[201,60],[192,61],[193,62],[194,63],[195,64],[196,65],[197,66],[198,67],[199,68],[69,1],[110,1],[203,1],[209,69],[78,1],[207,70],[208,71],[71,72],[87,73],[68,74],[72,1],[70,75],[88,76],[73,77],[206,78],[57,13],[84,79],[83,13],[56,1],[48,1],[46,1],[47,1],[8,1],[9,1],[11,1],[10,1],[2,1],[12,1],[13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[19,1],[3,1],[20,1],[4,1],[21,1],[25,1],[22,1],[23,1],[24,1],[26,1],[27,1],[28,1],[5,1],[29,1],[30,1],[31,1],[32,1],[6,1],[36,1],[33,1],[34,1],[35,1],[37,1],[7,1],[38,1],[43,1],[44,1],[39,1],[40,1],[41,1],[42,1],[1,1],[45,1],[126,80],[136,81],[125,80],[146,82],[117,83],[116,84],[145,85],[139,86],[144,87],[119,88],[133,89],[118,90],[142,91],[114,92],[113,85],[143,93],[115,94],[120,95],[121,1],[124,95],[111,1],[147,96],[137,97],[128,98],[129,99],[131,100],[127,101],[130,102],[140,85],[122,103],[123,104],[132,105],[112,106],[135,97],[134,95],[138,1],[141,107],[85,108],[49,12],[91,109],[90,110],[105,111],[89,112],[86,113],[104,114]],"version":"5.6.3"}
@@ -0,0 +1,13 @@
1
+ interface BiometricVerificationResult {
2
+ verified: boolean;
3
+ message: string;
4
+ needsRegistration?: boolean;
5
+ }
6
+ /**
7
+ * Performs biometric verification for the current user.
8
+ * @param challengeUrl The URL to fetch the authentication challenge.
9
+ * @param verifyUrl The URL to send the authentication assertion for verification.
10
+ * @returns A promise that resolves to a BiometricVerificationResult.
11
+ */
12
+ export declare function verifyBiometric(challengeUrl?: string, verifyUrl?: string): Promise<BiometricVerificationResult>;
13
+ export {};
@@ -0,0 +1,72 @@
1
+ /*
2
+ // Usage example
3
+ async function performSensitiveAction() {
4
+ try {
5
+ const result = await verifyBiometric()
6
+ if (result.verified) {
7
+ console.log('Verification successful. Proceeding with sensitive action.')
8
+ // Perform the sensitive action here
9
+ } else if (result.needsRegistration) {
10
+ console.log('Biometric registration needed:', result.message)
11
+ // Redirect user to biometric registration page or show registration prompt
12
+ } else {
13
+ console.log('Verification failed:', result.message)
14
+ // Handle the failure (e.g., show an error message to the user)
15
+ }
16
+ } catch (error) {
17
+ console.error('Error during biometric verification:', error)
18
+ // Handle any unexpected errors
19
+ }
20
+ }
21
+ */
22
+ import { startAuthentication } from '@simplewebauthn/browser';
23
+ /**
24
+ * Performs biometric verification for the current user.
25
+ * @param challengeUrl The URL to fetch the authentication challenge.
26
+ * @param verifyUrl The URL to send the authentication assertion for verification.
27
+ * @returns A promise that resolves to a BiometricVerificationResult.
28
+ */
29
+ export async function verifyBiometric(challengeUrl = '/auth/verify-webauthn/challenge', verifyUrl = '/auth/verify-webauthn') {
30
+ try {
31
+ // 1. Get the challenge from the server
32
+ const challengeResponse = await fetch(challengeUrl);
33
+ if (!challengeResponse.ok) {
34
+ const errorData = await challengeResponse.json();
35
+ if (challengeResponse.status === 400 && errorData.error === 'No biometric credentials registered for this user') {
36
+ return {
37
+ verified: false,
38
+ message: 'Biometric authentication is not set up for this account. Please register first.',
39
+ needsRegistration: true
40
+ };
41
+ }
42
+ throw new Error(`Failed to get challenge: ${errorData.error || challengeResponse.statusText}`);
43
+ }
44
+ const options = await challengeResponse.json();
45
+ // 2. Start the authentication process
46
+ const assertion = await startAuthentication(options);
47
+ // 3. Send the assertion to the server for verification
48
+ const verificationResponse = await fetch(verifyUrl, {
49
+ method: 'POST',
50
+ headers: {
51
+ 'Content-Type': 'application/json'
52
+ },
53
+ body: JSON.stringify(assertion)
54
+ });
55
+ if (!verificationResponse.ok) {
56
+ throw new Error(`Verification failed: ${verificationResponse.statusText}`);
57
+ }
58
+ const verificationResult = await verificationResponse.json();
59
+ return {
60
+ verified: verificationResult.verified,
61
+ message: verificationResult.message || 'Biometric verification successful!'
62
+ };
63
+ }
64
+ catch (error) {
65
+ console.error('Biometric verification error:', error);
66
+ return {
67
+ verified: false,
68
+ message: `Error: ${error.message}`
69
+ };
70
+ }
71
+ }
72
+ //# sourceMappingURL=verify-webauthn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-webauthn.js","sourceRoot":"","sources":["../client/verify-webauthn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;EAoBE;AAEF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAQ7D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,eAAuB,iCAAiC,EACxD,YAAoB,uBAAuB;IAE3C,IAAI,CAAC;QACH,uCAAuC;QACvC,MAAM,iBAAiB,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,CAAA;QACnD,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,CAAA;YAChD,IAAI,iBAAiB,CAAC,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,KAAK,KAAK,mDAAmD,EAAE,CAAC;gBAChH,OAAO;oBACL,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,iFAAiF;oBAC1F,iBAAiB,EAAE,IAAI;iBACxB,CAAA;YACH,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,4BAA4B,SAAS,CAAC,KAAK,IAAI,iBAAiB,CAAC,UAAU,EAAE,CAAC,CAAA;QAChG,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,CAAA;QAE9C,sCAAsC;QACtC,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,CAAA;QAEpD,uDAAuD;QACvD,MAAM,oBAAoB,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;YAClD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;SAChC,CAAC,CAAA;QAEF,IAAI,CAAC,oBAAoB,CAAC,EAAE,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,wBAAwB,oBAAoB,CAAC,UAAU,EAAE,CAAC,CAAA;QAC5E,CAAC;QAED,MAAM,kBAAkB,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,CAAA;QAE5D,OAAO;YACL,QAAQ,EAAE,kBAAkB,CAAC,QAAQ;YACrC,OAAO,EAAE,kBAAkB,CAAC,OAAO,IAAI,oCAAoC;SAC5E,CAAA;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;QACrD,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,UAAU,KAAK,CAAC,OAAO,EAAE;SACnC,CAAA;IACH,CAAC;AACH,CAAC","sourcesContent":["/*\n// Usage example\nasync function performSensitiveAction() {\n try {\n const result = await verifyBiometric()\n if (result.verified) {\n console.log('Verification successful. Proceeding with sensitive action.')\n // Perform the sensitive action here\n } else if (result.needsRegistration) {\n console.log('Biometric registration needed:', result.message)\n // Redirect user to biometric registration page or show registration prompt\n } else {\n console.log('Verification failed:', result.message)\n // Handle the failure (e.g., show an error message to the user)\n }\n } catch (error) {\n console.error('Error during biometric verification:', error)\n // Handle any unexpected errors\n }\n}\n*/\n\nimport { startAuthentication } from '@simplewebauthn/browser'\n\ninterface BiometricVerificationResult {\n verified: boolean\n message: string\n needsRegistration?: boolean\n}\n\n/**\n * Performs biometric verification for the current user.\n * @param challengeUrl The URL to fetch the authentication challenge.\n * @param verifyUrl The URL to send the authentication assertion for verification.\n * @returns A promise that resolves to a BiometricVerificationResult.\n */\nexport async function verifyBiometric(\n challengeUrl: string = '/auth/verify-webauthn/challenge',\n verifyUrl: string = '/auth/verify-webauthn'\n): Promise<BiometricVerificationResult> {\n try {\n // 1. Get the challenge from the server\n const challengeResponse = await fetch(challengeUrl)\n if (!challengeResponse.ok) {\n const errorData = await challengeResponse.json()\n if (challengeResponse.status === 400 && errorData.error === 'No biometric credentials registered for this user') {\n return {\n verified: false,\n message: 'Biometric authentication is not set up for this account. Please register first.',\n needsRegistration: true\n }\n }\n throw new Error(`Failed to get challenge: ${errorData.error || challengeResponse.statusText}`)\n }\n const options = await challengeResponse.json()\n\n // 2. Start the authentication process\n const assertion = await startAuthentication(options)\n\n // 3. Send the assertion to the server for verification\n const verificationResponse = await fetch(verifyUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(assertion)\n })\n\n if (!verificationResponse.ok) {\n throw new Error(`Verification failed: ${verificationResponse.statusText}`)\n }\n\n const verificationResult = await verificationResponse.json()\n\n return {\n verified: verificationResult.verified,\n message: verificationResult.message || 'Biometric verification successful!'\n }\n } catch (error: any) {\n console.error('Biometric verification error:', error)\n return {\n verified: false,\n message: `Error: ${error.message}`\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"webauthn-middleware.js","sourceRoot":"","sources":["../../server/middlewares/webauthn-middleware.ts"],"names":[],"mappings":"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","sourcesContent":["import passport from 'koa-passport'\nimport { Strategy as CustomStrategy } from 'passport-custom'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { User } from '../service/user/user'\nimport { AuthError } from '../errors/auth-error'\n\nimport { WebAuthCredential } from '../service/web-auth-credential/web-auth-credential'\nimport { verifyRegistrationResponse, verifyAuthenticationResponse } from '@simplewebauthn/server'\n\nimport { AuthenticatorAssertionResponse } from '@simplewebauthn/types'\n\npassport.use(\n 'webauthn-register',\n new CustomStrategy(async (context, done) => {\n const { body, session, user, hostname, origin } = context as any\n\n const challenge = session.challenge\n\n const verification = await verifyRegistrationResponse({\n response: body,\n expectedChallenge: challenge,\n expectedOrigin: origin,\n expectedRPID: hostname,\n expectedType: 'webauthn.create',\n requireUserVerification: false\n })\n\n if (verification.verified) {\n const { registrationInfo } = verification\n const publicKey = Buffer.from(registrationInfo.credentialPublicKey).toString('base64')\n\n if (user) {\n const webAuthRepository = getRepository(WebAuthCredential)\n await webAuthRepository.save({\n user,\n credentialId: registrationInfo.credentialID,\n publicKey,\n counter: registrationInfo.counter,\n creator: user,\n updater: user\n })\n }\n\n return done(null, user)\n } else {\n return done(null, false)\n }\n })\n)\n\npassport.use(\n 'webauthn-login',\n new CustomStrategy(async (context, done) => {\n try {\n const { body, session, origin, hostname } = context as any\n\n const challenge = session.challenge\n \n const assertionResponse = body as {\n id: string\n response: AuthenticatorAssertionResponse\n }\n \n const credential = await getRepository(WebAuthCredential).findOne({\n where: {\n credentialId: assertionResponse.id\n },\n relations: ['user']\n })\n \n if (!credential) {\n return done(null, false)\n }\n \n const verification = await verifyAuthenticationResponse({\n response: body,\n expectedChallenge: challenge,\n expectedOrigin: origin,\n expectedRPID: hostname,\n requireUserVerification: false,\n authenticator: {\n credentialID: credential.credentialId,\n credentialPublicKey: new Uint8Array(Buffer.from(credential.publicKey, 'base64')),\n counter: credential.counter\n }\n })\n \n if (verification.verified) {\n const { authenticationInfo } = verification\n credential.counter = authenticationInfo.newCounter\n await getRepository(WebAuthCredential).save(credential)\n \n const user = credential.user\n return done(null, user)\n } else {\n return done(verification, false)\n }\n } catch(error) {\n return done(error, false)\n }\n })\n)\n\nexport function createWebAuthnMiddleware(strategy: 'webauthn-register' | 'webauthn-login') {\n return async function webAuthnMiddleware(context, next) {\n return passport.authenticate(\n strategy,\n { session: true, failureMessage: true, failWithError: true },\n async (err, user) => {\n if (err || !user) {\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.AUTHN_VERIFICATION_FAILED,\n detail: err\n })\n } else {\n context.state.user = user\n\n context.body = { user, verified: true }\n }\n\n await next()\n }\n )(context, next)\n }\n}\n"]}
1
+ {"version":3,"file":"webauthn-middleware.js","sourceRoot":"","sources":["../../server/middlewares/webauthn-middleware.ts"],"names":[],"mappings":"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","sourcesContent":["import passport from 'koa-passport'\nimport { Strategy as CustomStrategy } from 'passport-custom'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { AuthError } from '../errors/auth-error'\n\nimport { WebAuthCredential } from '../service/web-auth-credential/web-auth-credential'\nimport { verifyRegistrationResponse, verifyAuthenticationResponse } from '@simplewebauthn/server'\n\nimport { AuthenticatorAssertionResponse } from '@simplewebauthn/types'\n\npassport.use(\n 'webauthn-register',\n new CustomStrategy(async (context, done) => {\n const { body, session, user, hostname, origin } = context as any\n\n const challenge = session.challenge\n\n const verification = await verifyRegistrationResponse({\n response: body,\n expectedChallenge: challenge,\n expectedOrigin: origin,\n expectedRPID: hostname,\n expectedType: 'webauthn.create',\n requireUserVerification: false\n })\n\n if (verification.verified) {\n const { registrationInfo } = verification\n const publicKey = Buffer.from(registrationInfo.credentialPublicKey).toString('base64')\n\n if (user) {\n const webAuthRepository = getRepository(WebAuthCredential)\n await webAuthRepository.save({\n user,\n credentialId: registrationInfo.credentialID,\n publicKey,\n counter: registrationInfo.counter,\n creator: user,\n updater: user\n })\n }\n\n return done(null, user)\n } else {\n return done(null, false)\n }\n })\n)\n\npassport.use(\n 'webauthn-login',\n new CustomStrategy(async (context, done) => {\n try {\n const { body, session, origin, hostname } = context as any\n\n const challenge = session.challenge\n\n const assertionResponse = body as {\n id: string\n response: AuthenticatorAssertionResponse\n }\n\n const credential = await getRepository(WebAuthCredential).findOne({\n where: {\n credentialId: assertionResponse.id\n },\n relations: ['user']\n })\n\n if (!credential) {\n return done(null, false)\n }\n\n const verification = await verifyAuthenticationResponse({\n response: body,\n expectedChallenge: challenge,\n expectedOrigin: origin,\n expectedRPID: hostname,\n requireUserVerification: false,\n authenticator: {\n credentialID: credential.credentialId,\n credentialPublicKey: new Uint8Array(Buffer.from(credential.publicKey, 'base64')),\n counter: credential.counter\n }\n })\n\n if (verification.verified) {\n const { authenticationInfo } = verification\n credential.counter = authenticationInfo.newCounter\n await getRepository(WebAuthCredential).save(credential)\n\n const user = credential.user\n return done(null, user)\n } else {\n return done(verification, false)\n }\n } catch (error) {\n return done(error, false)\n }\n })\n)\n\nexport function createWebAuthnMiddleware(strategy: 'webauthn-register' | 'webauthn-login') {\n return async function webAuthnMiddleware(context, next) {\n return passport.authenticate(\n strategy,\n { session: true, failureMessage: true, failWithError: true },\n async (err, user) => {\n if (err || !user) {\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.AUTHN_VERIFICATION_FAILED,\n detail: err\n })\n } else {\n context.state.user = user\n\n context.body = { user, verified: true }\n }\n\n await next()\n }\n )(context, next)\n }\n}\n"]}
@@ -12,6 +12,53 @@ const webauthn_middleware_1 = require("../middlewares/webauthn-middleware");
12
12
  exports.webAuthnGlobalPublicRouter = new koa_router_1.default();
13
13
  exports.webAuthnGlobalPrivateRouter = new koa_router_1.default();
14
14
  const { name: rpName } = env_1.appPackage;
15
+ // Generate authentication challenge for the currently logged-in user
16
+ exports.webAuthnGlobalPrivateRouter.get('/auth/verify-webauthn/challenge', async (context, next) => {
17
+ const { user } = context.state;
18
+ const rpID = context.hostname;
19
+ if (!user) {
20
+ context.status = 401;
21
+ context.body = { error: 'User not authenticated' };
22
+ return;
23
+ }
24
+ const webAuthCredentials = await (0, shell_1.getRepository)(web_auth_credential_1.WebAuthCredential).find({
25
+ where: { user: { id: user.id } }
26
+ });
27
+ if (webAuthCredentials.length === 0) {
28
+ context.status = 400;
29
+ context.body = { error: 'No biometric credentials registered for this user' };
30
+ return;
31
+ }
32
+ const options = await (0, server_1.generateAuthenticationOptions)({
33
+ rpID,
34
+ userVerification: 'preferred',
35
+ allowCredentials: webAuthCredentials.map(credential => ({
36
+ id: credential.credentialId,
37
+ type: 'public-key'
38
+ }))
39
+ });
40
+ context.session.challenge = options.challenge;
41
+ context.body = options;
42
+ });
43
+ // Verify biometric authentication
44
+ exports.webAuthnGlobalPrivateRouter.post('/auth/verify-webauthn',
45
+ /* reuse webauthn-login as webauthn-verify strategy */
46
+ (0, webauthn_middleware_1.createWebAuthnMiddleware)('webauthn-login'), async (context, next) => {
47
+ const { user } = context.state;
48
+ const { request } = context;
49
+ const { body: reqBody } = request;
50
+ if (!user) {
51
+ context.status = 401;
52
+ context.body = { verified: false, message: 'User not authenticated' };
53
+ return;
54
+ }
55
+ context.body = {
56
+ verified: true,
57
+ message: 'Biometric authentication successful'
58
+ };
59
+ await next();
60
+ });
61
+ // Generate registration challenge for the currently logged-in user
15
62
  exports.webAuthnGlobalPrivateRouter.get('/auth/register-webauthn/challenge', async (context, next) => {
16
63
  const { user } = context.state;
17
64
  const rpID = context.hostname;
@@ -45,7 +92,9 @@ exports.webAuthnGlobalPrivateRouter.get('/auth/register-webauthn/challenge', asy
45
92
  context.session.challenge = options.challenge;
46
93
  context.body = options;
47
94
  });
95
+ // Verify registration
48
96
  exports.webAuthnGlobalPrivateRouter.post('/auth/verify-registration', (0, webauthn_middleware_1.createWebAuthnMiddleware)('webauthn-register'));
97
+ // Generate sign-in challenge
49
98
  exports.webAuthnGlobalPublicRouter.get('/auth/signin-webauthn/challenge', async (context, next) => {
50
99
  const rpID = context.hostname;
51
100
  const options = await (0, server_1.generateAuthenticationOptions)({
@@ -55,6 +104,7 @@ exports.webAuthnGlobalPublicRouter.get('/auth/signin-webauthn/challenge', async
55
104
  context.session.challenge = options.challenge;
56
105
  context.body = options;
57
106
  });
107
+ // Sign in with biometric authentication
58
108
  exports.webAuthnGlobalPublicRouter.post('/auth/signin-webauthn', (0, webauthn_middleware_1.createWebAuthnMiddleware)('webauthn-login'), async (context, next) => {
59
109
  const { domain, user } = context.state;
60
110
  const { request } = context;
@@ -62,7 +112,7 @@ exports.webAuthnGlobalPublicRouter.post('/auth/signin-webauthn', (0, webauthn_mi
62
112
  const token = await user.sign({ subdomain: domain === null || domain === void 0 ? void 0 : domain.subdomain });
63
113
  (0, access_token_cookie_1.setAccessTokenCookie)(context, token);
64
114
  var redirectURL = `/auth/checkin${domain ? '/' + domain.subdomain : ''}?redirect_to=${encodeURIComponent(reqBody.redirectTo || '/')}`;
65
- /* 2단계 인터렉션 때문에 브라우저에서 fetch(...) 진행될 것이므로, redirect(3xx) 응답으로 처리할 없다. 따라서, 데이타로 redirectURL를 응답한다. */
115
+ /* Due to the two-step interaction, it will be processed by fetch(...) in the browser, so it cannot be handled with a redirect(3xx) response. Therefore, respond with redirectURL as data. */
66
116
  context.body = { redirectURL, verified: true };
67
117
  await next();
68
118
  });
@@ -1 +1 @@
1
- {"version":3,"file":"webauthn-router.js","sourceRoot":"","sources":["../../server/router/webauthn-router.ts"],"names":[],"mappings":"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","sourcesContent":["import Router from 'koa-router'\nimport { getRepository } from '@things-factory/shell'\nimport { appPackage } from '@things-factory/env'\n\nimport { generateRegistrationOptions, generateAuthenticationOptions } from '@simplewebauthn/server'\n\nimport { WebAuthCredential } from '../service/web-auth-credential/web-auth-credential'\nimport {\n PublicKeyCredentialCreationOptionsJSON,\n} from '@simplewebauthn/server/script/deps'\nimport { setAccessTokenCookie } from '../utils/access-token-cookie'\nimport { createWebAuthnMiddleware } from '../middlewares/webauthn-middleware';\n\nexport const webAuthnGlobalPublicRouter = new Router()\nexport const webAuthnGlobalPrivateRouter = new Router()\n\nconst { name: rpName } = appPackage as any\n\nwebAuthnGlobalPrivateRouter.get('/auth/register-webauthn/challenge', async (context, next) => {\n const { user } = context.state\n const rpID = context.hostname\n\n const webAuthCredentials = await getRepository(WebAuthCredential).find({\n where: {\n user: { id: user.id }\n }\n })\n\n const options: PublicKeyCredentialCreationOptionsJSON = await generateRegistrationOptions({\n rpName,\n rpID,\n userName: user.email,\n userDisplayName: user.name,\n // Don't prompt users for additional information about the authenticator\n // (Recommended for smoother UX)\n attestationType: 'none',\n // Prevent users from re-registering existing authenticators\n excludeCredentials: webAuthCredentials.map(credential => ({\n id: credential.credentialId\n // Optional\n // transports: credential.transports\n })),\n authenticatorSelection: {\n // Defaults\n residentKey: 'preferred',\n userVerification: 'preferred',\n // Optional\n authenticatorAttachment: 'platform'\n }\n })\n\n context.session.challenge = options.challenge\n context.body = options\n})\n\nwebAuthnGlobalPrivateRouter.post('/auth/verify-registration', createWebAuthnMiddleware('webauthn-register'));\n\nwebAuthnGlobalPublicRouter.get('/auth/signin-webauthn/challenge', async (context, next) => {\n const rpID = context.hostname\n\n const options = await generateAuthenticationOptions({\n rpID,\n userVerification: 'preferred'\n })\n\n context.session.challenge = options.challenge\n context.body = options\n})\n\nwebAuthnGlobalPublicRouter.post(\n '/auth/signin-webauthn', createWebAuthnMiddleware('webauthn-login'),\n async (context, next) => {\n const { domain, user } = context. state\n const { request } = context\n const { body: reqBody } = request\n\n const token = await user.sign({ subdomain: domain?.subdomain })\n setAccessTokenCookie(context, token)\n\n var redirectURL = `/auth/checkin${domain ? '/' + domain.subdomain : ''}?redirect_to=${encodeURIComponent(reqBody.redirectTo || '/')}`\n\n /* 2단계 인터렉션 때문에 브라우저에서 fetch(...) 진행될 것이므로, redirect(3xx) 응답으로 처리할 없다. 따라서, 데이타로 redirectURL를 응답한다. */\n context.body = { redirectURL, verified: true }\n\n await next();\n }\n)\n"]}
1
+ {"version":3,"file":"webauthn-router.js","sourceRoot":"","sources":["../../server/router/webauthn-router.ts"],"names":[],"mappings":"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","sourcesContent":["import Router from 'koa-router'\nimport { getRepository } from '@things-factory/shell'\nimport { appPackage } from '@things-factory/env'\n\nimport { generateRegistrationOptions, generateAuthenticationOptions } from '@simplewebauthn/server'\n\nimport { WebAuthCredential } from '../service/web-auth-credential/web-auth-credential'\nimport { PublicKeyCredentialCreationOptionsJSON } from '@simplewebauthn/server/script/deps'\nimport { setAccessTokenCookie } from '../utils/access-token-cookie'\nimport { createWebAuthnMiddleware } from '../middlewares/webauthn-middleware'\n\nexport const webAuthnGlobalPublicRouter = new Router()\nexport const webAuthnGlobalPrivateRouter = new Router()\n\nconst { name: rpName } = appPackage as any\n\n// Generate authentication challenge for the currently logged-in user\nwebAuthnGlobalPrivateRouter.get('/auth/verify-webauthn/challenge', async (context, next) => {\n const { user } = context.state\n const rpID = context.hostname\n\n if (!user) {\n context.status = 401\n context.body = { error: 'User not authenticated' }\n return\n }\n\n const webAuthCredentials = await getRepository(WebAuthCredential).find({\n where: { user: { id: user.id } }\n })\n\n if (webAuthCredentials.length === 0) {\n context.status = 400\n context.body = { error: 'No biometric credentials registered for this user' }\n return\n }\n\n const options = await generateAuthenticationOptions({\n rpID,\n userVerification: 'preferred',\n allowCredentials: webAuthCredentials.map(credential => ({\n id: credential.credentialId,\n type: 'public-key'\n }))\n })\n\n context.session.challenge = options.challenge\n context.body = options\n})\n\n// Verify biometric authentication\nwebAuthnGlobalPrivateRouter.post(\n '/auth/verify-webauthn',\n /* reuse webauthn-login as webauthn-verify strategy */\n createWebAuthnMiddleware('webauthn-login'),\n async (context, next) => {\n const { user } = context.state\n const { request } = context\n const { body: reqBody } = request\n\n if (!user) {\n context.status = 401\n context.body = { verified: false, message: 'User not authenticated' }\n return\n }\n\n context.body = {\n verified: true,\n message: 'Biometric authentication successful'\n }\n\n await next()\n }\n)\n\n// Generate registration challenge for the currently logged-in user\nwebAuthnGlobalPrivateRouter.get('/auth/register-webauthn/challenge', async (context, next) => {\n const { user } = context.state\n const rpID = context.hostname\n\n const webAuthCredentials = await getRepository(WebAuthCredential).find({\n where: {\n user: { id: user.id }\n }\n })\n\n const options: PublicKeyCredentialCreationOptionsJSON = await generateRegistrationOptions({\n rpName,\n rpID,\n userName: user.email,\n userDisplayName: user.name,\n // Don't prompt users for additional information about the authenticator\n // (Recommended for smoother UX)\n attestationType: 'none',\n // Prevent users from re-registering existing authenticators\n excludeCredentials: webAuthCredentials.map(credential => ({\n id: credential.credentialId\n // Optional\n // transports: credential.transports\n })),\n authenticatorSelection: {\n // Defaults\n residentKey: 'preferred',\n userVerification: 'preferred',\n // Optional\n authenticatorAttachment: 'platform'\n }\n })\n\n context.session.challenge = options.challenge\n context.body = options\n})\n\n// Verify registration\nwebAuthnGlobalPrivateRouter.post('/auth/verify-registration', createWebAuthnMiddleware('webauthn-register'))\n\n// Generate sign-in challenge\nwebAuthnGlobalPublicRouter.get('/auth/signin-webauthn/challenge', async (context, next) => {\n const rpID = context.hostname\n\n const options = await generateAuthenticationOptions({\n rpID,\n userVerification: 'preferred'\n })\n\n context.session.challenge = options.challenge\n context.body = options\n})\n\n// Sign in with biometric authentication\nwebAuthnGlobalPublicRouter.post(\n '/auth/signin-webauthn',\n createWebAuthnMiddleware('webauthn-login'),\n async (context, next) => {\n const { domain, user } = context.state\n const { request } = context\n const { body: reqBody } = request\n\n const token = await user.sign({ subdomain: domain?.subdomain })\n setAccessTokenCookie(context, token)\n\n var redirectURL = `/auth/checkin${domain ? '/' + domain.subdomain : ''}?redirect_to=${encodeURIComponent(reqBody.redirectTo || '/')}`\n\n /* Due to the two-step interaction, it will be processed by fetch(...) in the browser, so it cannot be handled with a redirect(3xx) response. Therefore, respond with redirectURL as data. */\n context.body = { redirectURL, verified: true }\n\n await next()\n }\n)\n"]}