@nlabs/reaktor 0.8.1 → 0.10.0
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/.prettierrc.js +4 -0
- package/README.md +10 -1
- package/coverage/actions/groups.ts.html +1039 -0
- package/coverage/actions/images.ts.html +2500 -0
- package/coverage/actions/index.html +131 -0
- package/coverage/actions/tags.ts.html +1000 -0
- package/coverage/adapters/arangoAdapter.ts.html +151 -0
- package/coverage/adapters/index.html +146 -0
- package/coverage/adapters/reaktorAdapter.ts.html +127 -0
- package/coverage/adapters/tagAdapter.ts.html +160 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +6 -0
- package/coverage/coverage-final.json +1 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +221 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +101 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +0 -0
- package/coverage/mocks/file.ts.html +118 -0
- package/coverage/mocks/group.ts.html +145 -0
- package/coverage/mocks/image.ts.html +136 -0
- package/coverage/mocks/index.html +146 -0
- package/coverage/mocks/post.ts.html +169 -0
- package/coverage/mocks/tag.ts.html +121 -0
- package/coverage/mocks/user.ts.html +268 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/types/error.ts.html +145 -0
- package/coverage/types/index.html +116 -0
- package/coverage/utils/adapterUtils.ts.html +151 -0
- package/coverage/utils/analyticsUtils.ts.html +292 -0
- package/coverage/utils/arangodbUtils.ts.html +463 -0
- package/coverage/utils/index.html +146 -0
- package/dist/actions/apps.js +242 -0
- package/dist/actions/connections.js +90 -0
- package/dist/actions/conversations.js +350 -0
- package/dist/actions/dynamodb.js +150 -0
- package/dist/actions/email.js +152 -0
- package/dist/actions/files.js +283 -0
- package/dist/actions/groups.js +292 -0
- package/dist/actions/images.js +735 -0
- package/dist/actions/index.js +66 -0
- package/dist/actions/ios.js +164 -0
- package/dist/actions/locations.js +122 -0
- package/dist/actions/messages.js +208 -0
- package/dist/actions/notifications.js +59 -0
- package/dist/actions/payments.js +497 -0
- package/dist/actions/personas.js +110 -0
- package/dist/actions/posts.js +595 -0
- package/dist/actions/reactions.js +322 -0
- package/dist/actions/s3.js +133 -0
- package/dist/actions/search.js +90 -0
- package/dist/actions/sms.js +108 -0
- package/dist/actions/statistics.js +62 -0
- package/dist/actions/subscription.js +220 -0
- package/dist/actions/tags.js +292 -0
- package/dist/actions/users.js +784 -0
- package/dist/actions/websockets.js +174 -0
- package/dist/adapters/arangoAdapter.js +46 -0
- package/dist/adapters/fileAdapter.js +76 -0
- package/dist/adapters/imageAdapter.js +40 -0
- package/dist/adapters/messageAdapter.js +49 -0
- package/dist/adapters/postAdapter.js +70 -0
- package/dist/adapters/reaktorAdapter.js +44 -0
- package/dist/adapters/tagAdapter.js +50 -0
- package/dist/adapters/userAdapter.js +115 -0
- package/dist/config.js +125 -0
- package/dist/index.js +66 -0
- package/dist/lambdas/actions/websockets.js +132 -0
- package/dist/lambdas/authorizer.js +67 -0
- package/dist/lambdas/connection.js +91 -0
- package/dist/lambdas/utils/message.js +42 -0
- package/dist/lambdas/utils/websocket.js +105 -0
- package/dist/mocks/conversation.js +35 -0
- package/dist/mocks/file.js +38 -0
- package/dist/mocks/group.js +47 -0
- package/dist/mocks/image.js +44 -0
- package/dist/mocks/nlabs.png +0 -0
- package/dist/mocks/post.js +55 -0
- package/dist/mocks/tag.js +37 -0
- package/dist/mocks/user.js +88 -0
- package/dist/mutations/index.js +26 -0
- package/dist/mutations/locations.js +44 -0
- package/dist/mutations/messages.js +86 -0
- package/dist/mutations/personas.js +100 -0
- package/dist/mutations/posts.js +53 -0
- package/dist/mutations/reactions.js +51 -0
- package/dist/mutations/statistics.js +39 -0
- package/dist/mutations/subscriptions.js +56 -0
- package/dist/mutations/tags.js +120 -0
- package/dist/mutations/users.js +116 -0
- package/dist/objectTypes/app.js +173 -0
- package/dist/objectTypes/bankAccount.js +76 -0
- package/dist/objectTypes/connection.js +48 -0
- package/dist/objectTypes/conversation.js +77 -0
- package/dist/objectTypes/creditCard.js +86 -0
- package/dist/objectTypes/document.js +46 -0
- package/dist/objectTypes/error.js +46 -0
- package/dist/objectTypes/external.js +74 -0
- package/dist/objectTypes/file.js +100 -0
- package/dist/objectTypes/filter.js +43 -0
- package/dist/objectTypes/group.js +123 -0
- package/dist/objectTypes/iapSubscription.js +40 -0
- package/dist/objectTypes/image.js +129 -0
- package/dist/objectTypes/index.js +68 -0
- package/dist/objectTypes/location.js +109 -0
- package/dist/objectTypes/message.js +96 -0
- package/dist/objectTypes/passcode.js +42 -0
- package/dist/objectTypes/persona.js +87 -0
- package/dist/objectTypes/plan.js +95 -0
- package/dist/objectTypes/post.js +125 -0
- package/dist/objectTypes/reaction.js +61 -0
- package/dist/objectTypes/relation.js +49 -0
- package/dist/objectTypes/search.js +72 -0
- package/dist/objectTypes/statistics.js +39 -0
- package/dist/objectTypes/subscription.js +117 -0
- package/dist/objectTypes/tag.js +65 -0
- package/dist/objectTypes/user.js +144 -0
- package/dist/queries/index.js +33 -0
- package/dist/queries/locations.js +45 -0
- package/dist/queries/messages.js +52 -0
- package/dist/queries/posts.js +154 -0
- package/dist/queries/reactions.js +56 -0
- package/dist/queries/statistics.js +39 -0
- package/dist/queries/subscriptions.js +44 -0
- package/dist/queries/tags.js +75 -0
- package/dist/queries/users.js +64 -0
- package/dist/templates/email/layout.js +302 -0
- package/dist/templates/email/passwordForgot.js +38 -0
- package/dist/templates/email/passwordRecovery.js +35 -0
- package/dist/templates/email/verifyEmail.js +38 -0
- package/dist/templates/email/welcome.js +38 -0
- package/dist/templates/sms/passwordForgot.js +24 -0
- package/dist/templates/sms/passwordRecovery.js +24 -0
- package/dist/templates/sms/verifyEmail.js +24 -0
- package/dist/templates/sms/verifyPhone.js +24 -0
- package/dist/templates/sms/welcome.js +24 -0
- package/dist/types/apps.js +32 -0
- package/dist/types/arangodb.js +16 -0
- package/{lib → dist}/types/auth.js +1 -1
- package/{lib → dist}/types/connections.js +1 -1
- package/{lib → dist}/types/conversations.js +1 -1
- package/{lib → dist}/types/email.js +1 -1
- package/dist/types/error.js +44 -0
- package/{lib → dist}/types/files.js +1 -1
- package/dist/types/google.js +16 -0
- package/{lib → dist}/types/groups.js +1 -1
- package/dist/types/images.js +16 -0
- package/dist/types/index.js +60 -0
- package/{lib → dist}/types/locations.js +1 -1
- package/dist/types/messages.js +16 -0
- package/{lib → dist}/types/notifications.js +1 -1
- package/dist/types/payments.js +16 -0
- package/dist/types/personas.js +16 -0
- package/dist/types/posts.js +16 -0
- package/{lib → dist}/types/statistics.js +1 -1
- package/{lib → dist}/types/tags.js +1 -1
- package/dist/types/users.js +16 -0
- package/dist/types/websockets.js +16 -0
- package/dist/utils/adapterUtils.js +45 -0
- package/dist/utils/analyticsUtils.js +72 -0
- package/dist/utils/arangodbUtils.js +165 -0
- package/dist/utils/auth.js +57 -0
- package/dist/utils/index.js +30 -0
- package/dist/utils/session.js +60 -0
- package/jest.setup.js +0 -0
- package/jpg:- +0 -0
- package/lex.config.cjs +13 -0
- package/lib/actions/apps.d.ts +25 -0
- package/lib/actions/apps.js +242 -0
- package/lib/actions/connections.d.ts +4 -0
- package/lib/actions/connections.js +90 -0
- package/lib/actions/conversations.d.ts +12 -12
- package/lib/actions/conversations.js +147 -131
- package/lib/actions/dynamodb.d.ts +8 -8
- package/lib/actions/dynamodb.js +35 -32
- package/lib/actions/email.d.ts +3 -5
- package/lib/actions/email.js +33 -63
- package/lib/actions/files.d.ts +17 -14
- package/lib/actions/files.js +184 -202
- package/lib/actions/groups.d.ts +4 -4
- package/lib/actions/groups.js +47 -45
- package/lib/actions/images.d.ts +17 -13
- package/lib/actions/images.js +325 -264
- package/lib/actions/index.d.ts +3 -0
- package/lib/actions/index.js +7 -1
- package/lib/actions/ios.js +11 -10
- package/lib/actions/locations.d.ts +5 -2
- package/lib/actions/locations.js +41 -37
- package/lib/actions/messages.d.ts +4 -3
- package/lib/actions/messages.js +35 -32
- package/lib/actions/notifications.d.ts +2 -2
- package/lib/actions/notifications.js +1 -1
- package/lib/actions/payments.d.ts +2 -2
- package/lib/actions/payments.js +87 -83
- package/lib/actions/personas.d.ts +3 -0
- package/lib/actions/personas.js +110 -0
- package/lib/actions/posts.d.ts +11 -10
- package/lib/actions/posts.js +186 -152
- package/lib/actions/reactions.d.ts +5 -5
- package/lib/actions/reactions.js +30 -28
- package/lib/actions/s3.d.ts +7 -7
- package/lib/actions/s3.js +37 -32
- package/lib/actions/search.d.ts +3 -3
- package/lib/actions/search.js +13 -11
- package/lib/actions/sms.d.ts +9 -3
- package/lib/actions/sms.js +60 -34
- package/lib/actions/statistics.d.ts +3 -2
- package/lib/actions/statistics.js +21 -18
- package/lib/actions/subscription.d.ts +2 -2
- package/lib/actions/subscription.js +32 -39
- package/lib/actions/tags.d.ts +23 -20
- package/lib/actions/tags.js +161 -205
- package/lib/actions/users.d.ts +50 -22
- package/lib/actions/users.js +441 -217
- package/lib/actions/websockets.d.ts +19 -5
- package/lib/actions/websockets.js +89 -61
- package/lib/adapters/arangoAdapter.d.ts +2 -0
- package/lib/adapters/arangoAdapter.js +46 -0
- package/lib/adapters/fileAdapter.d.ts +3 -0
- package/lib/adapters/fileAdapter.js +76 -0
- package/lib/adapters/imageAdapter.d.ts +2 -0
- package/lib/adapters/imageAdapter.js +40 -0
- package/lib/adapters/messageAdapter.d.ts +2 -0
- package/lib/adapters/messageAdapter.js +49 -0
- package/lib/adapters/postAdapter.d.ts +2 -0
- package/lib/adapters/postAdapter.js +70 -0
- package/lib/adapters/reaktorAdapter.d.ts +6 -0
- package/lib/adapters/reaktorAdapter.js +44 -0
- package/lib/adapters/tagAdapter.d.ts +2 -0
- package/lib/adapters/tagAdapter.js +50 -0
- package/lib/adapters/userAdapter.d.ts +2 -0
- package/lib/adapters/userAdapter.js +115 -0
- package/lib/config.js +16 -17
- package/lib/index.d.ts +7 -0
- package/lib/index.js +44 -8
- package/lib/lambdas/actions/websockets.d.ts +7 -6
- package/lib/lambdas/actions/websockets.js +15 -11
- package/lib/lambdas/authorizer.js +4 -4
- package/lib/lambdas/connection.js +20 -20
- package/lib/lambdas/utils/message.js +1 -1
- package/lib/lambdas/utils/websocket.js +8 -7
- package/lib/mocks/conversation.d.ts +8 -0
- package/lib/mocks/conversation.js +35 -0
- package/lib/mocks/file.d.ts +11 -0
- package/lib/mocks/file.js +38 -0
- package/lib/mocks/group.d.ts +17 -0
- package/lib/mocks/group.js +47 -0
- package/lib/mocks/image.d.ts +3 -0
- package/lib/mocks/image.js +44 -0
- package/lib/mocks/nlabs.png +0 -0
- package/lib/mocks/post.d.ts +38 -0
- package/lib/mocks/post.js +55 -0
- package/lib/mocks/tag.d.ts +2 -0
- package/lib/mocks/tag.js +37 -0
- package/lib/mocks/user.d.ts +4 -0
- package/lib/mocks/user.js +88 -0
- package/lib/mutations/index.d.ts +3 -0
- package/lib/mutations/index.js +26 -0
- package/lib/mutations/locations.d.ts +2 -0
- package/lib/mutations/locations.js +44 -0
- package/lib/mutations/messages.d.ts +2 -0
- package/lib/mutations/messages.js +86 -0
- package/lib/mutations/personas.d.ts +2 -0
- package/lib/mutations/personas.js +100 -0
- package/lib/mutations/posts.d.ts +2 -0
- package/lib/mutations/posts.js +53 -0
- package/lib/mutations/reactions.d.ts +2 -0
- package/lib/mutations/reactions.js +51 -0
- package/lib/mutations/statistics.d.ts +2 -0
- package/lib/mutations/statistics.js +39 -0
- package/lib/mutations/subscriptions.d.ts +2 -0
- package/lib/mutations/subscriptions.js +56 -0
- package/lib/mutations/tags.d.ts +2 -0
- package/lib/mutations/tags.js +120 -0
- package/lib/mutations/users.d.ts +1 -0
- package/lib/mutations/users.js +116 -0
- package/lib/objectTypes/app.d.ts +3 -0
- package/lib/objectTypes/app.js +173 -0
- package/lib/objectTypes/bankAccount.d.ts +1 -0
- package/lib/objectTypes/bankAccount.js +76 -0
- package/lib/objectTypes/connection.d.ts +1 -0
- package/lib/objectTypes/connection.js +48 -0
- package/lib/objectTypes/conversation.d.ts +2 -0
- package/lib/objectTypes/conversation.js +77 -0
- package/lib/objectTypes/creditCard.d.ts +1 -0
- package/lib/objectTypes/creditCard.js +86 -0
- package/lib/objectTypes/document.d.ts +1 -0
- package/lib/objectTypes/document.js +46 -0
- package/lib/objectTypes/error.d.ts +1 -0
- package/lib/objectTypes/error.js +46 -0
- package/lib/objectTypes/external.d.ts +1 -0
- package/lib/objectTypes/external.js +74 -0
- package/lib/objectTypes/file.d.ts +2 -0
- package/lib/objectTypes/file.js +100 -0
- package/lib/objectTypes/filter.d.ts +1 -0
- package/lib/objectTypes/filter.js +43 -0
- package/lib/objectTypes/group.d.ts +3 -0
- package/lib/objectTypes/group.js +123 -0
- package/lib/objectTypes/iapSubscription.d.ts +1 -0
- package/lib/objectTypes/iapSubscription.js +40 -0
- package/lib/objectTypes/image.d.ts +2 -0
- package/lib/objectTypes/image.js +129 -0
- package/lib/objectTypes/index.d.ts +24 -0
- package/lib/objectTypes/index.js +68 -0
- package/lib/objectTypes/location.d.ts +2 -0
- package/lib/objectTypes/location.js +109 -0
- package/lib/objectTypes/message.d.ts +2 -0
- package/lib/objectTypes/message.js +96 -0
- package/lib/objectTypes/passcode.d.ts +1 -0
- package/lib/objectTypes/passcode.js +42 -0
- package/lib/objectTypes/persona.d.ts +3 -0
- package/lib/objectTypes/persona.js +87 -0
- package/lib/objectTypes/plan.d.ts +2 -0
- package/lib/objectTypes/plan.js +95 -0
- package/lib/objectTypes/post.d.ts +2 -0
- package/lib/objectTypes/post.js +125 -0
- package/lib/objectTypes/reaction.d.ts +2 -0
- package/lib/objectTypes/reaction.js +61 -0
- package/lib/objectTypes/relation.d.ts +1 -0
- package/lib/objectTypes/relation.js +49 -0
- package/lib/objectTypes/search.d.ts +1 -0
- package/lib/objectTypes/search.js +72 -0
- package/lib/objectTypes/statistics.d.ts +1 -0
- package/lib/objectTypes/statistics.js +39 -0
- package/lib/objectTypes/subscription.d.ts +2 -0
- package/lib/objectTypes/subscription.js +117 -0
- package/lib/objectTypes/tag.d.ts +2 -0
- package/lib/objectTypes/tag.js +65 -0
- package/lib/objectTypes/user.d.ts +4 -0
- package/lib/objectTypes/user.js +144 -0
- package/lib/queries/index.d.ts +3 -0
- package/lib/queries/index.js +33 -0
- package/lib/queries/locations.d.ts +2 -0
- package/lib/queries/locations.js +45 -0
- package/lib/queries/messages.d.ts +2 -0
- package/lib/queries/messages.js +52 -0
- package/lib/queries/posts.d.ts +2 -0
- package/lib/queries/posts.js +154 -0
- package/lib/queries/reactions.d.ts +2 -0
- package/lib/queries/reactions.js +56 -0
- package/lib/queries/statistics.d.ts +2 -0
- package/lib/queries/statistics.js +39 -0
- package/lib/queries/subscriptions.d.ts +2 -0
- package/lib/queries/subscriptions.js +44 -0
- package/lib/queries/tags.d.ts +2 -0
- package/lib/queries/tags.js +75 -0
- package/lib/queries/users.d.ts +1 -0
- package/lib/queries/users.js +64 -0
- package/lib/types/{apps.d.ts → apps.types.d.ts} +19 -17
- package/lib/types/apps.types.js +32 -0
- package/lib/types/arangodb.types.d.ts +34 -0
- package/lib/types/arangodb.types.js +16 -0
- package/lib/types/auth.types.d.ts +9 -0
- package/lib/types/auth.types.js +16 -0
- package/lib/types/connections.types.d.ts +5 -0
- package/lib/types/connections.types.js +16 -0
- package/lib/types/conversations.types.d.ts +27 -0
- package/lib/types/conversations.types.js +16 -0
- package/lib/types/email.types.d.ts +13 -0
- package/lib/types/email.types.js +16 -0
- package/lib/types/error.types.d.ts +20 -0
- package/lib/types/error.types.js +44 -0
- package/lib/types/{files.d.ts → files.types.d.ts} +9 -12
- package/lib/types/files.types.js +16 -0
- package/lib/types/google.types.d.ts +29 -0
- package/lib/types/google.types.js +16 -0
- package/lib/types/{groups.d.ts → groups.types.d.ts} +6 -10
- package/lib/types/groups.types.js +16 -0
- package/lib/types/images.types.d.ts +52 -0
- package/lib/types/images.types.js +16 -0
- package/lib/types/index.d.ts +20 -18
- package/lib/types/index.js +41 -37
- package/lib/types/{locations.d.ts → locations.types.d.ts} +4 -6
- package/lib/types/locations.types.js +16 -0
- package/lib/types/messages.types.d.ts +16 -0
- package/lib/types/messages.types.js +16 -0
- package/lib/types/notifications.types.d.ts +19 -0
- package/lib/types/notifications.types.js +16 -0
- package/lib/types/{payments.d.ts → payments.types.d.ts} +13 -19
- package/lib/types/payments.types.js +16 -0
- package/lib/types/personas.types.d.ts +32 -0
- package/lib/types/personas.types.js +16 -0
- package/lib/types/posts.types.d.ts +28 -0
- package/lib/types/posts.types.js +16 -0
- package/lib/types/statistics.types.d.ts +3 -0
- package/lib/types/statistics.types.js +16 -0
- package/lib/types/tags.types.d.ts +15 -0
- package/lib/types/tags.types.js +16 -0
- package/lib/types/{users.d.ts → users.types.d.ts} +21 -22
- package/lib/types/users.types.js +16 -0
- package/lib/types/{websocket.d.ts → websockets.types.d.ts} +7 -3
- package/lib/types/websockets.types.js +16 -0
- package/lib/utils/adapterUtils.d.ts +1 -0
- package/lib/utils/adapterUtils.js +45 -0
- package/lib/utils/analyticsUtils.d.ts +21 -0
- package/lib/utils/analyticsUtils.js +72 -0
- package/lib/utils/arangodbUtils.d.ts +66 -0
- package/lib/utils/arangodbUtils.js +165 -0
- package/lib/utils/auth.d.ts +19 -3
- package/lib/utils/auth.js +20 -30
- package/lib/utils/index.d.ts +3 -4
- package/lib/utils/index.js +7 -9
- package/lib/utils/session.d.ts +10 -10
- package/lib/utils/session.js +15 -3
- package/lib/utils/stripeUtils.d.ts +3 -0
- package/lib/utils/{graphql.js → stripeUtils.js} +12 -15
- package/package.json +38 -30
- package/lib/types/apps.js +0 -16
- package/lib/types/arangodb.d.ts +0 -17
- package/lib/types/arangodb.js +0 -16
- package/lib/types/auth.d.ts +0 -7
- package/lib/types/connections.d.ts +0 -8
- package/lib/types/conversations.d.ts +0 -16
- package/lib/types/email.d.ts +0 -12
- package/lib/types/google.d.ts +0 -27
- package/lib/types/google.js +0 -16
- package/lib/types/images.d.ts +0 -42
- package/lib/types/images.js +0 -16
- package/lib/types/messages.d.ts +0 -27
- package/lib/types/messages.js +0 -16
- package/lib/types/notifications.d.ts +0 -19
- package/lib/types/payments.js +0 -16
- package/lib/types/posts.d.ts +0 -47
- package/lib/types/posts.js +0 -16
- package/lib/types/statistics.d.ts +0 -3
- package/lib/types/tags.d.ts +0 -15
- package/lib/types/users.js +0 -16
- package/lib/types/websocket.js +0 -16
- package/lib/utils/analytics.d.ts +0 -14
- package/lib/utils/analytics.js +0 -88
- package/lib/utils/arangodb.d.ts +0 -9
- package/lib/utils/arangodb.js +0 -118
- package/lib/utils/graphql.d.ts +0 -1
- package/lib/utils/objects.d.ts +0 -3
- package/lib/utils/objects.js +0 -59
package/lib/actions/users.js
CHANGED
|
@@ -33,17 +33,21 @@ __export(users_exports, {
|
|
|
33
33
|
createToken: () => createToken,
|
|
34
34
|
deactivateUser: () => deactivateUser,
|
|
35
35
|
deleteUser: () => deleteUser,
|
|
36
|
+
forgotPassword: () => forgotPassword,
|
|
36
37
|
getActiveUserCount: () => getActiveUserCount,
|
|
37
38
|
getDisplayName: () => getDisplayName,
|
|
38
39
|
getSessionUser: () => getSessionUser,
|
|
39
40
|
getUser: () => getUser,
|
|
41
|
+
getUserByToken: () => getUserByToken,
|
|
40
42
|
getUserOptional: () => getUserOptional,
|
|
41
43
|
getUsers: () => getUsers,
|
|
44
|
+
getUsersByConnection: () => getUsersByConnection,
|
|
42
45
|
getUsersByLatest: () => getUsersByLatest,
|
|
43
46
|
getUsersByReactions: () => getUsersByReactions,
|
|
44
47
|
getUsersByTags: () => getUsersByTags,
|
|
45
48
|
parseUserOptions: () => parseUserOptions,
|
|
46
49
|
refreshSession: () => refreshSession,
|
|
50
|
+
resetPassword: () => resetPassword,
|
|
47
51
|
signIn: () => signIn,
|
|
48
52
|
signOut: () => signOut,
|
|
49
53
|
updateUser: () => updateUser
|
|
@@ -52,12 +56,17 @@ module.exports = __toCommonJS(users_exports);
|
|
|
52
56
|
var import_utils = require("@nlabs/utils");
|
|
53
57
|
var import_arangojs = require("arangojs");
|
|
54
58
|
var import_luxon = require("luxon");
|
|
55
|
-
var import_stripe = __toESM(require("stripe"));
|
|
59
|
+
var import_stripe = __toESM(require("stripe"), 1);
|
|
60
|
+
var import_userAdapter = require("../adapters/userAdapter");
|
|
56
61
|
var import_config = require("../config");
|
|
57
|
-
var
|
|
62
|
+
var import_email = require("./email");
|
|
63
|
+
var import_sms = require("./sms");
|
|
64
|
+
var import_error = require("../types/error.types");
|
|
65
|
+
var import_analyticsUtils = require("../utils/analyticsUtils");
|
|
66
|
+
var import_arangodbUtils = require("../utils/arangodbUtils");
|
|
58
67
|
var import_session = require("../utils/session");
|
|
59
68
|
const eventCategory = "users";
|
|
60
|
-
const
|
|
69
|
+
const STRIPE_API_VERSION = "2025-05-28.basil";
|
|
61
70
|
var UserAccess = /* @__PURE__ */ ((UserAccess2) => {
|
|
62
71
|
UserAccess2[UserAccess2["DEACTIVATED"] = 0] = "DEACTIVATED";
|
|
63
72
|
UserAccess2[UserAccess2["ACTIVE"] = 1] = "ACTIVE";
|
|
@@ -66,27 +75,29 @@ var UserAccess = /* @__PURE__ */ ((UserAccess2) => {
|
|
|
66
75
|
UserAccess2[UserAccess2["ADMIN"] = 4] = "ADMIN";
|
|
67
76
|
return UserAccess2;
|
|
68
77
|
})(UserAccess || {});
|
|
69
|
-
const createToken = (userId, username, userAccess,
|
|
78
|
+
const createToken = (userId, username, userAccess, expiresInMinutes = 15) => {
|
|
70
79
|
const now = import_luxon.DateTime.local();
|
|
71
|
-
const sessionExpires = now.plus({ minutes:
|
|
80
|
+
const sessionExpires = now.plus({ minutes: expiresInMinutes });
|
|
72
81
|
const iat = Math.floor(now.toSeconds());
|
|
73
82
|
const exp = Math.floor(sessionExpires.toSeconds());
|
|
74
83
|
const token = (0, import_session.setSession)({
|
|
75
84
|
exp,
|
|
76
85
|
iat,
|
|
77
|
-
username,
|
|
78
86
|
userAccess,
|
|
79
|
-
userId
|
|
87
|
+
userId,
|
|
88
|
+
username
|
|
80
89
|
});
|
|
81
90
|
return {
|
|
82
91
|
expires: sessionExpires.toMillis(),
|
|
83
92
|
issued: now.toMillis(),
|
|
84
|
-
token
|
|
93
|
+
token,
|
|
94
|
+
userId,
|
|
95
|
+
username
|
|
85
96
|
};
|
|
86
97
|
};
|
|
87
98
|
const getUserOptional = (fields = []) => fields.reduce((selects, field) => {
|
|
88
99
|
if (field.includes("Count")) {
|
|
89
|
-
return (0,
|
|
100
|
+
return (0, import_arangodbUtils.selectReactionCountByType)("users", "u", field, selects);
|
|
90
101
|
}
|
|
91
102
|
return selects;
|
|
92
103
|
}, { objects: [], queries: [] });
|
|
@@ -95,30 +106,37 @@ const parseUserOptions = (options = {}) => {
|
|
|
95
106
|
from = 0,
|
|
96
107
|
to = 30
|
|
97
108
|
} = options;
|
|
109
|
+
const limit = (0, import_arangodbUtils.getLimit)(from, to);
|
|
98
110
|
return {
|
|
99
111
|
...options,
|
|
100
|
-
limit
|
|
112
|
+
limit
|
|
101
113
|
};
|
|
102
114
|
};
|
|
103
|
-
const addUser = async (context,
|
|
115
|
+
const addUser = async (context, user) => {
|
|
104
116
|
const action = "addUser";
|
|
105
117
|
const { database } = context;
|
|
106
|
-
const {
|
|
107
|
-
const { email, password, phone, username } = user;
|
|
108
|
-
const salt = (0, import_utils.createHash)(`${username}${password}`, null);
|
|
109
|
-
const encryptedPassword = (0, import_utils.createPassword)(password, salt);
|
|
118
|
+
const { email, password, phone, username } = (0, import_userAdapter.parseUser)(user);
|
|
110
119
|
const formatUsername = (0, import_utils.parseUsername)(username);
|
|
111
120
|
const formatEmail = (0, import_utils.parseEmail)(email);
|
|
112
121
|
const formatPhone = (0, import_utils.parsePhone)(phone);
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
const formatPassword = (0, import_utils.parsePassword)(password);
|
|
123
|
+
const hasPassword = !!formatPassword;
|
|
124
|
+
const hasUsername = !!formatUsername || !!formatPhone || !!formatEmail;
|
|
125
|
+
if (!hasPassword || !hasUsername) {
|
|
126
|
+
return (0, import_analyticsUtils.logException)({
|
|
115
127
|
action,
|
|
116
|
-
args: { username },
|
|
117
128
|
category: eventCategory,
|
|
118
|
-
|
|
129
|
+
params: { username },
|
|
130
|
+
value: import_error.ErrorTypes.INVALID_ARGUMENTS
|
|
119
131
|
}, context);
|
|
120
132
|
}
|
|
121
|
-
const
|
|
133
|
+
const hashId = formatUsername || formatPhone || formatEmail;
|
|
134
|
+
const salt = (0, import_utils.createHash)(`${hashId}${formatPassword}`, null);
|
|
135
|
+
const encryptedPassword = (0, import_utils.createPassword)(formatPassword, salt);
|
|
136
|
+
const filters = [];
|
|
137
|
+
if (formatUsername) {
|
|
138
|
+
filters.push(`u.username == "${formatUsername}"`);
|
|
139
|
+
}
|
|
122
140
|
if (formatEmail) {
|
|
123
141
|
filters.push(`u.email == "${formatEmail}"`);
|
|
124
142
|
}
|
|
@@ -127,101 +145,222 @@ const addUser = async (context, args) => {
|
|
|
127
145
|
}
|
|
128
146
|
const checkQuery = `FOR u IN users
|
|
129
147
|
FILTER ${filters.join(" || ")}
|
|
148
|
+
LIMIT 1
|
|
130
149
|
RETURN u`;
|
|
131
|
-
|
|
132
|
-
(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
150
|
+
try {
|
|
151
|
+
const existingUsers = await database.query(checkQuery).then((cursor) => cursor.all());
|
|
152
|
+
if (existingUsers.length) {
|
|
153
|
+
return (0, import_analyticsUtils.logException)({
|
|
154
|
+
action,
|
|
155
|
+
category: eventCategory,
|
|
156
|
+
params: {
|
|
157
|
+
email: formatEmail,
|
|
158
|
+
phone: formatPhone,
|
|
159
|
+
username: formatUsername
|
|
160
|
+
},
|
|
161
|
+
value: import_error.ErrorTypes.EXISTING_ITEM
|
|
162
|
+
}, context);
|
|
163
|
+
}
|
|
164
|
+
} catch (error) {
|
|
165
|
+
return (0, import_analyticsUtils.logError)({
|
|
141
166
|
action,
|
|
142
|
-
args: { username },
|
|
143
167
|
category: eventCategory,
|
|
144
|
-
|
|
145
|
-
|
|
168
|
+
params: { username },
|
|
169
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
170
|
+
}, error, context);
|
|
146
171
|
}
|
|
147
172
|
const verifiedEmailCode = Math.floor(1e5 + Math.random() * 9e5);
|
|
148
173
|
const verifiedPhoneCode = Math.floor(1e5 + Math.random() * 9e5);
|
|
149
174
|
const insert = {
|
|
150
|
-
_key: (0, import_utils.createHash)(
|
|
175
|
+
_key: (0, import_utils.createHash)(formatUsername, null),
|
|
151
176
|
added: Date.now(),
|
|
152
177
|
email: formatEmail,
|
|
153
178
|
modified: Date.now(),
|
|
154
179
|
password: encryptedPassword,
|
|
155
180
|
phone: formatPhone,
|
|
156
181
|
salt,
|
|
157
|
-
username: formatUsername,
|
|
158
182
|
userAccess: 1,
|
|
183
|
+
username: formatUsername,
|
|
159
184
|
verifiedEmail: false,
|
|
160
185
|
verifiedEmailCode,
|
|
161
186
|
verifiedPhone: false,
|
|
162
187
|
verifiedPhoneCode
|
|
163
188
|
};
|
|
164
189
|
const insertQuery = import_arangojs.aql`INSERT ${insert} IN users RETURN NEW`;
|
|
165
|
-
return await database.query(insertQuery).then((cursor) => cursor.next()
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}, error, context).then(() => null)
|
|
172
|
-
);
|
|
190
|
+
return await database.query(insertQuery).then((cursor) => cursor.next()).catch((error) => (0, import_analyticsUtils.logError)({
|
|
191
|
+
action,
|
|
192
|
+
category: eventCategory,
|
|
193
|
+
params: { username },
|
|
194
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
195
|
+
}, error, context));
|
|
173
196
|
};
|
|
174
197
|
const updateUser = async (context, user) => {
|
|
175
198
|
const action = "updateUser";
|
|
176
|
-
const { database } = context;
|
|
177
|
-
const { _key, _id, id, tags = [], userId, ...updated } = user;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
199
|
+
const { database, session } = context;
|
|
200
|
+
const { _key, _id, id, tags = [], userId, ...updated } = (0, import_userAdapter.parseUser)(user);
|
|
201
|
+
if (!(0, import_session.isAdminUser)(session) && session?.userId !== userId) {
|
|
202
|
+
return (0, import_analyticsUtils.logException)({
|
|
203
|
+
action,
|
|
204
|
+
category: eventCategory,
|
|
205
|
+
params: { session },
|
|
206
|
+
value: import_error.ErrorTypes.INVALID_SESSION
|
|
207
|
+
}, context);
|
|
183
208
|
}
|
|
184
|
-
const userQuery = import_arangojs.aql`LET u = DOCUMENT(${
|
|
209
|
+
const userQuery = import_arangojs.aql`LET u = DOCUMENT(${id})
|
|
185
210
|
UPDATE u WITH ${updated} IN users
|
|
186
211
|
RETURN NEW`;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return
|
|
212
|
+
try {
|
|
213
|
+
const updatedUser = await database.query(userQuery).then((cursor) => cursor.next());
|
|
214
|
+
const tagCollection = database.collection("isTagged");
|
|
215
|
+
await Promise.all(tags.map(({ id: tagDocId, name }) => {
|
|
216
|
+
const tagQuery = import_arangojs.aql`FOR it IN isTagged
|
|
217
|
+
FILTER it._from == ${tagDocId} && it._to == ${id} && it.name == ${name}
|
|
218
|
+
LIMIT 1
|
|
219
|
+
RETURN it`;
|
|
220
|
+
return database.query(tagQuery).then((cursor) => cursor.next()).then((tagEdge) => {
|
|
221
|
+
if (!!tagEdge) {
|
|
222
|
+
return tagEdge;
|
|
223
|
+
}
|
|
224
|
+
const edge = {
|
|
225
|
+
_from: tagDocId,
|
|
226
|
+
_key: (0, import_utils.createHash)(`isTagged-${tagDocId}-${id}`),
|
|
227
|
+
_to: id,
|
|
228
|
+
added: Date.now(),
|
|
229
|
+
name
|
|
230
|
+
};
|
|
231
|
+
return tagCollection.save(edge, { returnNew: true }).then(() => edge);
|
|
232
|
+
});
|
|
233
|
+
}));
|
|
234
|
+
return updatedUser;
|
|
235
|
+
} catch (error) {
|
|
236
|
+
return (0, import_analyticsUtils.logError)({
|
|
237
|
+
action,
|
|
238
|
+
category: eventCategory,
|
|
239
|
+
params: { user },
|
|
240
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
241
|
+
}, error, context);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
const forgotPassword = async (context, { email, phone, username }) => {
|
|
245
|
+
const action = "forgotPassword";
|
|
246
|
+
const { app, database } = context;
|
|
247
|
+
const aqlQuery = import_arangojs.aql`FOR u IN users
|
|
248
|
+
FILTER u.email == ${email} || u.phone == ${phone} || u.username == ${username}
|
|
249
|
+
LIMIT 1
|
|
250
|
+
RETURN u`;
|
|
251
|
+
try {
|
|
252
|
+
return await database.query(aqlQuery).then(async (cursor) => {
|
|
253
|
+
const user = cursor.next();
|
|
254
|
+
if (user) {
|
|
255
|
+
const { email: email2, phone: phone2, verifiedEmail, verifiedPhone } = user;
|
|
256
|
+
const codeExpires = 1e3 * 60 * 15;
|
|
257
|
+
const code = Math.floor(1e5 + Math.random() * 9e5);
|
|
258
|
+
const userDocId = (0, import_arangodbUtils.getDocId)("users", user);
|
|
259
|
+
let update;
|
|
260
|
+
if (email2 && verifiedEmail) {
|
|
261
|
+
(0, import_email.sendEmail)({
|
|
262
|
+
app,
|
|
263
|
+
text: `Your code is ${code}`
|
|
264
|
+
});
|
|
265
|
+
update = { verifiedEmailCode: code, verifiedEmailExpires: codeExpires };
|
|
266
|
+
}
|
|
267
|
+
if (phone2 && verifiedPhone) {
|
|
268
|
+
(0, import_sms.sendSms)({
|
|
269
|
+
app,
|
|
270
|
+
text: `Your code is ${code}`
|
|
271
|
+
});
|
|
272
|
+
update = { verifiedPhoneCode: code, verifiedPhoneExpires: codeExpires };
|
|
273
|
+
}
|
|
274
|
+
if (update.verifiedEmailCode || update.verifiedPhoneCode) {
|
|
275
|
+
const updateQuery = import_arangojs.aql`UPDATE ${userDocId} WITH ${update} IN users`;
|
|
276
|
+
await database.query(updateQuery);
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
return false;
|
|
282
|
+
});
|
|
283
|
+
} catch (error) {
|
|
284
|
+
(0, import_analyticsUtils.logError)({
|
|
285
|
+
action,
|
|
286
|
+
category: eventCategory,
|
|
287
|
+
params: { email, phone, username },
|
|
288
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
289
|
+
}, error, context);
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
const resetPassword = async (context, {
|
|
294
|
+
code,
|
|
295
|
+
password,
|
|
296
|
+
type,
|
|
297
|
+
username
|
|
298
|
+
}) => {
|
|
299
|
+
const action = "resetPassword";
|
|
300
|
+
const { database } = context;
|
|
301
|
+
const formatPassword = (0, import_utils.parsePassword)(password);
|
|
302
|
+
const aqlQuery = import_arangojs.aql`FOR u IN users
|
|
303
|
+
FILTER u.username == ${username}
|
|
304
|
+
LIMIT 1
|
|
305
|
+
RETURN u`;
|
|
306
|
+
try {
|
|
307
|
+
return await database.query(aqlQuery).then(async (cursor) => {
|
|
308
|
+
const user = cursor.next();
|
|
309
|
+
if (user) {
|
|
310
|
+
const {
|
|
311
|
+
_id: userDocId,
|
|
312
|
+
salt,
|
|
313
|
+
verifiedEmailCode,
|
|
314
|
+
verifiedEmailExpires,
|
|
315
|
+
verifiedPhoneCode,
|
|
316
|
+
verifiedPhoneExpires
|
|
317
|
+
} = user;
|
|
318
|
+
const now = Date.now();
|
|
319
|
+
let update;
|
|
320
|
+
switch (type) {
|
|
321
|
+
case "email":
|
|
322
|
+
if (code === verifiedEmailCode && verifiedEmailExpires > now) {
|
|
323
|
+
const password2 = (0, import_utils.createPassword)(formatPassword, salt);
|
|
324
|
+
update = { password: password2 };
|
|
325
|
+
}
|
|
326
|
+
break;
|
|
327
|
+
case "phone":
|
|
328
|
+
if (code === verifiedPhoneCode && verifiedPhoneExpires > now) {
|
|
329
|
+
const password2 = (0, import_utils.createPassword)(formatPassword, salt);
|
|
330
|
+
update = { password: password2 };
|
|
331
|
+
}
|
|
332
|
+
break;
|
|
333
|
+
default:
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
if (update) {
|
|
337
|
+
const updateQuery = import_arangojs.aql`UPDATE ${userDocId} WITH ${update} IN users`;
|
|
338
|
+
await database.query(updateQuery);
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
207
341
|
}
|
|
208
|
-
return
|
|
209
|
-
})
|
|
342
|
+
return false;
|
|
343
|
+
});
|
|
344
|
+
} catch (error) {
|
|
345
|
+
(0, import_analyticsUtils.logError)({
|
|
210
346
|
action,
|
|
211
347
|
category: eventCategory,
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
348
|
+
params: { username },
|
|
349
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
350
|
+
}, error, context);
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
216
353
|
};
|
|
217
|
-
const confirmCode = async (context,
|
|
218
|
-
|
|
354
|
+
const confirmCode = async (context, {
|
|
355
|
+
code,
|
|
356
|
+
type
|
|
357
|
+
}) => {
|
|
358
|
+
const action = "confirmCode";
|
|
219
359
|
const { database, session: { userId: sessionId } } = context;
|
|
220
|
-
const
|
|
221
|
-
const userDocId = `users/${sessionId}`;
|
|
360
|
+
const userDocId = (0, import_arangodbUtils.getDocId)("users", { userId: sessionId });
|
|
222
361
|
const aqlQuery = import_arangojs.aql`LET u = DOCUMENT(${userDocId}) RETURN u`;
|
|
223
362
|
try {
|
|
224
|
-
return database.query(aqlQuery).then((cursor) => cursor.next()
|
|
363
|
+
return await database.query(aqlQuery).then((cursor) => cursor.next()).then(({ verifiedEmailCode, verifiedPhoneCode }) => {
|
|
225
364
|
switch (type) {
|
|
226
365
|
case "email":
|
|
227
366
|
return code === verifiedEmailCode;
|
|
@@ -230,65 +369,50 @@ const confirmCode = async (context, args) => {
|
|
|
230
369
|
default:
|
|
231
370
|
return false;
|
|
232
371
|
}
|
|
233
|
-
})
|
|
234
|
-
(error) => (0, import_utils2.logError)({
|
|
235
|
-
action,
|
|
236
|
-
args: { code, type, userId: sessionId },
|
|
237
|
-
category: eventCategory,
|
|
238
|
-
label: import_utils2.ErrorTypes.DATABASE_ERROR
|
|
239
|
-
}, error, context)
|
|
240
|
-
);
|
|
372
|
+
});
|
|
241
373
|
} catch (error) {
|
|
374
|
+
(0, import_analyticsUtils.logError)({
|
|
375
|
+
action,
|
|
376
|
+
category: eventCategory,
|
|
377
|
+
params: { code, type },
|
|
378
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
379
|
+
}, error, context);
|
|
242
380
|
return false;
|
|
243
381
|
}
|
|
244
382
|
};
|
|
245
|
-
const deleteUser = (context,
|
|
383
|
+
const deleteUser = (context, user) => {
|
|
246
384
|
const action = "deleteUser";
|
|
247
|
-
const { database
|
|
248
|
-
const { userId } =
|
|
249
|
-
const isAdmin = sessionAccess > 2;
|
|
250
|
-
if (!isAdmin && sessionId !== userId) {
|
|
251
|
-
(0, import_utils2.logException)({
|
|
252
|
-
action,
|
|
253
|
-
args,
|
|
254
|
-
category: eventCategory,
|
|
255
|
-
label: "unauthorized",
|
|
256
|
-
value: "invalid_session"
|
|
257
|
-
}, context);
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
385
|
+
const { database } = context;
|
|
386
|
+
const { userId } = (0, import_userAdapter.parseUser)(user);
|
|
260
387
|
const aqlQuery = import_arangojs.aql`FOR u IN users
|
|
261
388
|
FILTER u._key == ${userId}
|
|
262
389
|
LIMIT 1
|
|
263
390
|
REMOVE u IN users
|
|
264
391
|
RETURN OLD`;
|
|
265
|
-
const stripeClient = new import_stripe.default(import_config.Config.get("stripe.token"), { apiVersion, typescript: true });
|
|
266
|
-
return database.query(aqlQuery).then((cursor) => cursor.next()).then((
|
|
267
|
-
|
|
268
|
-
|
|
392
|
+
const stripeClient = new import_stripe.default(import_config.Config.get("stripe.token"), { apiVersion: STRIPE_API_VERSION, typescript: true });
|
|
393
|
+
return database.query(aqlQuery).then((cursor) => cursor.next()).then((deletedUser) => stripeClient.customers.del(deletedUser?.stripeCustomerId).then(() => stripeClient.accounts.del(deletedUser?.stripeAccountId)).then(() => deletedUser)).catch((error) => (0, import_analyticsUtils.logError)({
|
|
394
|
+
action,
|
|
395
|
+
category: eventCategory,
|
|
396
|
+
params: { userId },
|
|
397
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
398
|
+
}, error, context));
|
|
269
399
|
};
|
|
270
|
-
const deactivateUser = (context,
|
|
400
|
+
const deactivateUser = (context, user) => {
|
|
271
401
|
const action = "delete";
|
|
272
|
-
const { database
|
|
273
|
-
const
|
|
274
|
-
if (!isAdmin && sessionId !== userId) {
|
|
275
|
-
(0, import_utils2.logException)({
|
|
276
|
-
action,
|
|
277
|
-
category: eventCategory,
|
|
278
|
-
label: "unauthorized",
|
|
279
|
-
value: "invalid_session"
|
|
280
|
-
}, context);
|
|
281
|
-
return null;
|
|
282
|
-
}
|
|
402
|
+
const { database } = context;
|
|
403
|
+
const { userId } = (0, import_userAdapter.parseUser)(user);
|
|
283
404
|
const updated = {
|
|
284
405
|
userAccess: 0
|
|
285
406
|
};
|
|
286
407
|
const aqlQuery = import_arangojs.aql`UPDATE ${userId} WITH ${updated} IN users LIMIT 1 RETURN NEW`;
|
|
287
|
-
return database.query(aqlQuery).then((cursor) => cursor.next()).catch((error) => {
|
|
288
|
-
|
|
289
|
-
|
|
408
|
+
return database.query(aqlQuery).then((cursor) => cursor.next()).catch((error) => (0, import_analyticsUtils.logError)({
|
|
409
|
+
action,
|
|
410
|
+
category: eventCategory,
|
|
411
|
+
params: { userId },
|
|
412
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
413
|
+
}, error, context));
|
|
290
414
|
};
|
|
291
|
-
const getDisplayName = (user
|
|
415
|
+
const getDisplayName = (user) => {
|
|
292
416
|
const { first, last, name = "", username = "" } = user;
|
|
293
417
|
const fullname = [first, last].join(" ").trim();
|
|
294
418
|
if (name) {
|
|
@@ -302,35 +426,47 @@ const getDisplayName = (user = {}) => {
|
|
|
302
426
|
};
|
|
303
427
|
const getSessionUser = (context) => {
|
|
304
428
|
const action = "getSessionUser";
|
|
429
|
+
console.log("getSessionUser", { action, context });
|
|
305
430
|
const { database, fields, session: { userId: sessionId, username } } = context;
|
|
306
431
|
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
307
|
-
const
|
|
432
|
+
const formatSessionId = (0, import_utils.parseArangoId)(`users/${sessionId}`);
|
|
433
|
+
const aqlQuery = `LET u = DOCUMENT("${formatSessionId}")
|
|
308
434
|
${selectQueries.join("\n")}
|
|
309
435
|
RETURN MERGE(u, {${selectObjects.join(", ")}})`;
|
|
310
|
-
return database.query(aqlQuery).then((cursor) => cursor.next()).
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
436
|
+
return database.query(aqlQuery).then((cursor) => cursor.next()).catch((error) => {
|
|
437
|
+
(0, import_analyticsUtils.logError)({
|
|
438
|
+
action,
|
|
439
|
+
category: eventCategory,
|
|
440
|
+
params: { userId: sessionId, username },
|
|
441
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
442
|
+
}, error, context);
|
|
443
|
+
return null;
|
|
444
|
+
});
|
|
316
445
|
};
|
|
317
|
-
const getUser = (context,
|
|
446
|
+
const getUser = (context, user) => {
|
|
318
447
|
const action = "getUser";
|
|
319
|
-
const { userId } =
|
|
448
|
+
const { id, userId, username } = (0, import_userAdapter.parseUser)(user);
|
|
320
449
|
const { database, fields } = context;
|
|
321
|
-
const formatUserId = (0, import_utils.parseId)(userId);
|
|
322
450
|
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
323
|
-
|
|
451
|
+
let aqlQuery;
|
|
452
|
+
console.log({ id, userId, username });
|
|
453
|
+
if (id) {
|
|
454
|
+
aqlQuery = `LET u = DOCUMENT("${id}")
|
|
324
455
|
${selectQueries.join("\n")}
|
|
325
456
|
FILTER u.userAccess > 0
|
|
326
457
|
RETURN MERGE(u, {${selectObjects.join(", ")}})`;
|
|
327
|
-
|
|
458
|
+
} else if (username) {
|
|
459
|
+
aqlQuery = `FOR u IN users
|
|
460
|
+
FILTER u.username == "${username}"
|
|
461
|
+
${selectQueries.join("\n")}
|
|
462
|
+
RETURN MERGE(u, {${selectObjects.join(", ")}})`;
|
|
463
|
+
}
|
|
464
|
+
return database.query(aqlQuery).then((cursor) => cursor.next()).then((user2) => user2).catch((error) => (0, import_analyticsUtils.logError)({
|
|
328
465
|
action,
|
|
329
|
-
args,
|
|
330
466
|
category: eventCategory,
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}));
|
|
467
|
+
params: { id, userId, username },
|
|
468
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
469
|
+
}, error, context));
|
|
334
470
|
};
|
|
335
471
|
const getUsers = (context, options) => {
|
|
336
472
|
const action = "getUserList";
|
|
@@ -347,11 +483,14 @@ const getUsers = (context, options) => {
|
|
|
347
483
|
${limit.aql}
|
|
348
484
|
SORT u.username
|
|
349
485
|
RETURN MERGE(u, {${selectObjects.join(", ")}})`;
|
|
350
|
-
return database.query(aqlQuery).then((cursor) => cursor.all()).catch((error) =>
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
486
|
+
return database.query(aqlQuery).then((cursor) => cursor.all()).catch((error) => {
|
|
487
|
+
(0, import_analyticsUtils.logError)({
|
|
488
|
+
action,
|
|
489
|
+
category: eventCategory,
|
|
490
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
491
|
+
}, error, context);
|
|
492
|
+
return [];
|
|
493
|
+
});
|
|
355
494
|
};
|
|
356
495
|
const getUsersByReactions = (context, { reactions = [], username }, options) => {
|
|
357
496
|
const action = "getUsersByReactions";
|
|
@@ -361,27 +500,32 @@ const getUsersByReactions = (context, { reactions = [], username }, options) =>
|
|
|
361
500
|
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
362
501
|
const formatSessionId = `users/${sessionId}`;
|
|
363
502
|
const formatUsername = (0, import_utils.parseUsername)(username);
|
|
364
|
-
const filterBy = [
|
|
503
|
+
const filterBy = [
|
|
504
|
+
"u.userAccess > 0",
|
|
505
|
+
`POSITION(${JSON.stringify(formatReactions)}, LOWER(r.name))`
|
|
506
|
+
];
|
|
365
507
|
if (username) {
|
|
366
508
|
filterBy.push(`CONTAINS(u.username, "${formatUsername}")`);
|
|
367
509
|
}
|
|
368
510
|
const aqlQuery = `FOR u, r IN OUTBOUND "${formatSessionId}" hasReaction
|
|
369
511
|
OPTIONS {vertexCollections: "users"}
|
|
370
512
|
${selectQueries.join("\n")}
|
|
371
|
-
|
|
513
|
+
FILTER ${filterBy.join(" && ")}
|
|
372
514
|
${limit.aql}
|
|
373
515
|
RETURN MERGE(u, {${selectObjects.join(", ")}})`;
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
516
|
+
return database.query(aqlQuery).then((cursor) => cursor.all()).catch((error) => {
|
|
517
|
+
(0, import_analyticsUtils.logError)({
|
|
518
|
+
action,
|
|
519
|
+
category: eventCategory,
|
|
520
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
521
|
+
}, error, context);
|
|
522
|
+
return [];
|
|
523
|
+
});
|
|
380
524
|
};
|
|
381
525
|
const getUsersByTags = (context, { tags, username }, options) => {
|
|
382
526
|
const action = "getUsersByTags";
|
|
383
527
|
const { database, fields, session: { userId: sessionId } } = context;
|
|
384
|
-
const formatTags = tags
|
|
528
|
+
const formatTags = tags?.reduce((list, tagName) => {
|
|
385
529
|
if (tagName) {
|
|
386
530
|
list.push((0, import_utils.parseChar)(tagName, 32).toLowerCase());
|
|
387
531
|
}
|
|
@@ -390,7 +534,10 @@ const getUsersByTags = (context, { tags, username }, options) => {
|
|
|
390
534
|
const { limit } = parseUserOptions(options);
|
|
391
535
|
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
392
536
|
const formatUsername = (0, import_utils.parseUsername)(username);
|
|
393
|
-
const filterBy = [
|
|
537
|
+
const filterBy = [
|
|
538
|
+
`u._key != "${sessionId}"`,
|
|
539
|
+
"u.userAccess > 0"
|
|
540
|
+
];
|
|
394
541
|
if (username) {
|
|
395
542
|
filterBy.push(`CONTAINS(u.username, "${formatUsername}")`);
|
|
396
543
|
}
|
|
@@ -399,21 +546,26 @@ const getUsersByTags = (context, { tags, username }, options) => {
|
|
|
399
546
|
FOR u, it IN OUTBOUND t isTagged
|
|
400
547
|
OPTIONS {bfs: true, uniqueVertices: "global", vertexCollections: "users"}
|
|
401
548
|
${selectQueries.join("\n")}
|
|
402
|
-
|
|
549
|
+
FILTER ${filterBy.join(" && ")}
|
|
403
550
|
${limit.aql}
|
|
404
551
|
RETURN DISTINCT MERGE(u, {${selectObjects.join(", ")}})`;
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
552
|
+
return database.query(aqlQuery).then((cursor) => cursor.all()).catch((error) => {
|
|
553
|
+
(0, import_analyticsUtils.logError)({
|
|
554
|
+
action,
|
|
555
|
+
category: eventCategory,
|
|
556
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
557
|
+
}, error, context);
|
|
558
|
+
return [];
|
|
559
|
+
});
|
|
411
560
|
};
|
|
412
561
|
const getUsersByLatest = (context, { username }, options) => {
|
|
413
562
|
const action = "getUsersByLatest";
|
|
414
563
|
const { database, fields, session: { userId } } = context;
|
|
415
564
|
const { limit } = parseUserOptions(options);
|
|
416
|
-
const filter = [
|
|
565
|
+
const filter = [
|
|
566
|
+
"u._id != session._id",
|
|
567
|
+
"u.userAccess > 0"
|
|
568
|
+
];
|
|
417
569
|
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
418
570
|
if (username) {
|
|
419
571
|
filter.push(`CONTAINS(u.username, "${(0, import_utils.parseUsername)(username)}")`);
|
|
@@ -426,72 +578,131 @@ const getUsersByLatest = (context, { username }, options) => {
|
|
|
426
578
|
${limit.aql}
|
|
427
579
|
SORT distance ASC, u.added DESC
|
|
428
580
|
RETURN MERGE(u, {${selectObjects.join(", ")}})`;
|
|
429
|
-
return database.query(aqlQuery).then((cursor) => cursor.all()).catch((error) =>
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
581
|
+
return database.query(aqlQuery).then((cursor) => cursor.all()).catch((error) => {
|
|
582
|
+
(0, import_analyticsUtils.logError)({
|
|
583
|
+
action,
|
|
584
|
+
category: eventCategory,
|
|
585
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
586
|
+
}, error, context);
|
|
587
|
+
return [];
|
|
588
|
+
});
|
|
434
589
|
};
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
590
|
+
const getUsersByConnection = (context, { userId }, options) => {
|
|
591
|
+
const action = "getUsersByConnection";
|
|
592
|
+
const { database, fields } = context;
|
|
593
|
+
const { limit, username } = parseUserOptions(options);
|
|
594
|
+
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
595
|
+
const formatUserId = (0, import_utils.parseArangoId)(`users/${userId}`);
|
|
596
|
+
const filterBy = [
|
|
597
|
+
"u.userAccess > 0"
|
|
598
|
+
];
|
|
599
|
+
if (username) {
|
|
600
|
+
filterBy.push(`CONTAINS(u.username, "${(0, import_utils.parseUsername)(username)}")`);
|
|
439
601
|
}
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
602
|
+
const aqlQuery = `FOR cu IN users
|
|
603
|
+
LET session = DOCUMENT("${formatUserId}")
|
|
604
|
+
FOR u, connection IN OUTBOUND cu hasConnection
|
|
605
|
+
OPTIONS {bfs: true, uniqueVertices: "global", vertexCollections: "users"}
|
|
606
|
+
${selectQueries.join("\n")}
|
|
607
|
+
FILTER ${filterBy.join(" && ")}
|
|
608
|
+
${limit.aql}
|
|
609
|
+
RETURN DISTINCT MERGE(u, {${selectObjects.join(", ")}})`;
|
|
610
|
+
return database.query(aqlQuery).then((cursor) => cursor.all()).catch((error) => {
|
|
611
|
+
(0, import_analyticsUtils.logError)({
|
|
612
|
+
action,
|
|
613
|
+
category: eventCategory,
|
|
614
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
615
|
+
}, error, context);
|
|
616
|
+
return [];
|
|
617
|
+
});
|
|
618
|
+
};
|
|
619
|
+
const refreshSession = ({ expires, token }) => {
|
|
620
|
+
try {
|
|
621
|
+
const { userId, username, userAccess } = (0, import_session.getSession)(token);
|
|
443
622
|
return createToken(userId, username, userAccess, expires);
|
|
623
|
+
} catch (error) {
|
|
624
|
+
throw error;
|
|
444
625
|
}
|
|
445
|
-
return { errors: ["session_expired"] };
|
|
446
626
|
};
|
|
447
627
|
const signIn = async (context, args) => {
|
|
448
628
|
const action = "signIn";
|
|
449
|
-
const {
|
|
629
|
+
const { database } = context;
|
|
630
|
+
const { email, expires, password, phone, username } = args;
|
|
631
|
+
const formatEmail = (0, import_utils.parseEmail)(email);
|
|
450
632
|
const formatUsername = (0, import_utils.parseUsername)(username);
|
|
451
633
|
const formatPassword = (0, import_utils.parsePassword)(password);
|
|
634
|
+
const formatPhone = (0, import_utils.parsePhone)(phone);
|
|
452
635
|
const formatExpires = (0, import_utils.parseNum)(expires) || 15;
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
return (0, import_utils2.logException)({
|
|
636
|
+
if (!formatUsername && !formatEmail && !formatPhone || !formatPassword) {
|
|
637
|
+
(0, import_analyticsUtils.logException)({
|
|
456
638
|
action,
|
|
457
|
-
args: { username },
|
|
458
639
|
category: eventCategory,
|
|
459
|
-
|
|
640
|
+
params: { username },
|
|
641
|
+
value: import_error.ErrorTypes.INVALID_ARGUMENTS
|
|
460
642
|
}, context);
|
|
643
|
+
return null;
|
|
461
644
|
}
|
|
462
|
-
const
|
|
463
|
-
|
|
645
|
+
const filters = [];
|
|
646
|
+
if (formatEmail) {
|
|
647
|
+
filters.push(`u.email == "${formatEmail}"`);
|
|
648
|
+
}
|
|
649
|
+
if (formatPhone) {
|
|
650
|
+
filters.push(`u.phone == ${formatPhone}`);
|
|
651
|
+
}
|
|
652
|
+
if (formatUsername) {
|
|
653
|
+
filters.push(`u.username == "${formatUsername}"`);
|
|
654
|
+
}
|
|
655
|
+
const checkQuery = `FOR u IN users
|
|
656
|
+
FILTER ${filters.join(" || ")}
|
|
464
657
|
LIMIT 1
|
|
465
658
|
RETURN u`;
|
|
466
|
-
|
|
467
|
-
|
|
659
|
+
let checkUser;
|
|
660
|
+
try {
|
|
661
|
+
checkUser = await database.query(checkQuery).then((cursor) => cursor.next());
|
|
662
|
+
} catch (error) {
|
|
663
|
+
(0, import_analyticsUtils.logError)({
|
|
468
664
|
action,
|
|
469
|
-
args: { username: formatUsername },
|
|
470
665
|
category: eventCategory,
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
666
|
+
params: { username: formatUsername },
|
|
667
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
668
|
+
}, error, context);
|
|
669
|
+
return null;
|
|
670
|
+
}
|
|
474
671
|
if (!checkUser) {
|
|
475
|
-
|
|
672
|
+
(0, import_analyticsUtils.logException)({
|
|
476
673
|
action,
|
|
477
|
-
args: { username },
|
|
478
674
|
category: eventCategory,
|
|
479
|
-
|
|
675
|
+
params: { username },
|
|
676
|
+
value: import_error.ErrorTypes.INVALID_AUTHENTICATION
|
|
480
677
|
}, context);
|
|
678
|
+
return null;
|
|
481
679
|
}
|
|
482
|
-
const { _key: userId, salt, userAccess } = checkUser;
|
|
680
|
+
const { _key: userId, password: validPassword, salt, userAccess } = checkUser;
|
|
483
681
|
const authPassword = (0, import_utils.createPassword)(formatPassword, salt);
|
|
484
|
-
if (
|
|
485
|
-
|
|
682
|
+
if (validPassword !== authPassword) {
|
|
683
|
+
(0, import_analyticsUtils.logException)({
|
|
486
684
|
action,
|
|
487
|
-
args: { username },
|
|
488
685
|
category: eventCategory,
|
|
489
|
-
|
|
686
|
+
params: { userAccess, userId, username },
|
|
687
|
+
value: import_error.ErrorTypes.INVALID_AUTHENTICATION
|
|
490
688
|
}, context);
|
|
689
|
+
return null;
|
|
690
|
+
}
|
|
691
|
+
try {
|
|
692
|
+
console.log({ formatExpires, userAccess, userId, username });
|
|
693
|
+
const token = createToken(userId, username, userAccess, formatExpires);
|
|
694
|
+
console.log({ token });
|
|
695
|
+
return token;
|
|
696
|
+
} catch (error) {
|
|
697
|
+
(0, import_analyticsUtils.logError)({
|
|
698
|
+
action,
|
|
699
|
+
category: eventCategory,
|
|
700
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
701
|
+
}, error, context);
|
|
702
|
+
return null;
|
|
491
703
|
}
|
|
492
|
-
return createToken(userId, username, userAccess, formatExpires);
|
|
493
704
|
};
|
|
494
|
-
const signOut = async (context
|
|
705
|
+
const signOut = async (context) => {
|
|
495
706
|
const action = "signOut";
|
|
496
707
|
const { database, session: { userId: sessionId, username } } = context;
|
|
497
708
|
const userDocId = `users/${sessionId}`;
|
|
@@ -504,16 +715,14 @@ const signOut = async (context, args) => {
|
|
|
504
715
|
LIMIT 1
|
|
505
716
|
RETURN NEW`;
|
|
506
717
|
try {
|
|
507
|
-
await database.query(sessionQuery).then((cursor) => cursor.next())
|
|
508
|
-
(error) => (0, import_utils2.logError)({
|
|
509
|
-
action,
|
|
510
|
-
args: { username, userId: sessionId },
|
|
511
|
-
category: eventCategory,
|
|
512
|
-
label: import_utils2.ErrorTypes.DATABASE_ERROR
|
|
513
|
-
}, error, context)
|
|
514
|
-
);
|
|
718
|
+
await database.query(sessionQuery).then((cursor) => cursor.next());
|
|
515
719
|
} catch (error) {
|
|
516
|
-
|
|
720
|
+
await (0, import_analyticsUtils.logError)({
|
|
721
|
+
action,
|
|
722
|
+
category: eventCategory,
|
|
723
|
+
params: { userId: sessionId, username },
|
|
724
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
725
|
+
}, error, context);
|
|
517
726
|
}
|
|
518
727
|
return true;
|
|
519
728
|
};
|
|
@@ -526,13 +735,24 @@ const getActiveUserCount = (context) => {
|
|
|
526
735
|
RETURN u
|
|
527
736
|
)
|
|
528
737
|
RETURN LENGTH(docs)`;
|
|
529
|
-
return database.query(countQuery).then((cursor) => cursor.next()).catch(
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
738
|
+
return database.query(countQuery).then((cursor) => cursor.next()).catch((error) => (0, import_analyticsUtils.logError)({
|
|
739
|
+
action,
|
|
740
|
+
category: eventCategory,
|
|
741
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
742
|
+
}, error, context));
|
|
743
|
+
};
|
|
744
|
+
const getUserByToken = (context, token) => {
|
|
745
|
+
const action = "getUserByToken";
|
|
746
|
+
const { database } = context;
|
|
747
|
+
const { userId } = (0, import_session.getSession)(token);
|
|
748
|
+
const userDocId = (0, import_arangodbUtils.getDocId)("users", { userId });
|
|
749
|
+
const aqlQuery = import_arangojs.aql`LET u = DOCUMENT("${userDocId}") RETURN u`;
|
|
750
|
+
return database.query(aqlQuery).then((cursor) => cursor.next()).catch((error) => (0, import_analyticsUtils.logError)({
|
|
751
|
+
action,
|
|
752
|
+
category: eventCategory,
|
|
753
|
+
params: { userId },
|
|
754
|
+
value: import_error.ErrorTypes.DATABASE_ERROR
|
|
755
|
+
}, error, context));
|
|
536
756
|
};
|
|
537
757
|
// Annotate the CommonJS export names for ESM import in node:
|
|
538
758
|
0 && (module.exports = {
|
|
@@ -542,19 +762,23 @@ const getActiveUserCount = (context) => {
|
|
|
542
762
|
createToken,
|
|
543
763
|
deactivateUser,
|
|
544
764
|
deleteUser,
|
|
765
|
+
forgotPassword,
|
|
545
766
|
getActiveUserCount,
|
|
546
767
|
getDisplayName,
|
|
547
768
|
getSessionUser,
|
|
548
769
|
getUser,
|
|
770
|
+
getUserByToken,
|
|
549
771
|
getUserOptional,
|
|
550
772
|
getUsers,
|
|
773
|
+
getUsersByConnection,
|
|
551
774
|
getUsersByLatest,
|
|
552
775
|
getUsersByReactions,
|
|
553
776
|
getUsersByTags,
|
|
554
777
|
parseUserOptions,
|
|
555
778
|
refreshSession,
|
|
779
|
+
resetPassword,
|
|
556
780
|
signIn,
|
|
557
781
|
signOut,
|
|
558
782
|
updateUser
|
|
559
783
|
});
|
|
560
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FjdGlvbnMvdXNlcnMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE5LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG5pbXBvcnQge1xuICBjcmVhdGVIYXNoLFxuICBjcmVhdGVQYXNzd29yZCxcbiAgcGFyc2VDaGFyLFxuICBwYXJzZUVtYWlsLFxuICBwYXJzZUlkLFxuICBwYXJzZU51bSxcbiAgcGFyc2VQYXNzd29yZCxcbiAgcGFyc2VQaG9uZSxcbiAgcGFyc2VVc2VybmFtZVxufSBmcm9tICdAbmxhYnMvdXRpbHMnO1xuaW1wb3J0IHthcWx9IGZyb20gJ2FyYW5nb2pzJztcbmltcG9ydCB7QXFsUXVlcnl9IGZyb20gJ2FyYW5nb2pzL2FxbCc7XG5pbXBvcnQge0VkZ2VDb2xsZWN0aW9ufSBmcm9tICdhcmFuZ29qcy9jb2xsZWN0aW9uJztcbmltcG9ydCB7QXJyYXlDdXJzb3J9IGZyb20gJ2FyYW5nb2pzL2N1cnNvcic7XG5pbXBvcnQge0RhdGVUaW1lfSBmcm9tICdsdXhvbic7XG5pbXBvcnQgU3RyaXBlIGZyb20gJ3N0cmlwZSc7XG5cbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHtBcGlDb250ZXh0fSBmcm9tICcuLi90eXBlcy9hdXRoJztcbmltcG9ydCB7VXNlcn0gZnJvbSAnLi4vdHlwZXMvdXNlcnMnO1xuaW1wb3J0IHtFcnJvclR5cGVzLCBnZXRMaW1pdCwgbG9nRXJyb3IsIGxvZ0V4Y2VwdGlvbiwgc2VsZWN0UmVhY3Rpb25Db3VudEJ5VHlwZX0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHtnZXRTZXNzaW9uLCBTZXNzaW9uRXJyb3IsIFNlc3Npb25Ub2tlbiwgc2V0U2Vzc2lvbn0gZnJvbSAnLi4vdXRpbHMvc2Vzc2lvbic7XG5cbmNvbnN0IGV2ZW50Q2F0ZWdvcnk6IHN0cmluZyA9ICd1c2Vycyc7XG5jb25zdCBhcGlWZXJzaW9uOiBhbnkgPSAnMjAyMC0wMy0wMic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlck9wdGlvbnMge1xuICByZWFkb25seSBmcm9tPzogbnVtYmVyO1xuICByZWFkb25seSB0bz86IG51bWJlcjtcbiAgcmVhZG9ubHkgdXNlcm5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBlbnVtIFVzZXJBY2Nlc3Mge1xuICBERUFDVElWQVRFRCA9IDAsXG4gIEFDVElWRSA9IDEsXG4gIFBSRU1JVU0gPSAyLFxuICBDT05URU5UX0FETUlOID0gMyxcbiAgQURNSU4gPSA0XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVUb2tlbiA9IChcbiAgdXNlcklkOiBzdHJpbmcsXG4gIHVzZXJuYW1lOiBzdHJpbmcsXG4gIHVzZXJBY2Nlc3M6IG51bWJlcixcbiAgZXhwaXJlczogbnVtYmVyID0gMTVcbik6IFNlc3Npb25Ub2tlbiA9PiB7XG4gIGNvbnN0IG5vdzogRGF0ZVRpbWUgPSBEYXRlVGltZS5sb2NhbCgpO1xuICBjb25zdCBzZXNzaW9uRXhwaXJlczogRGF0ZVRpbWUgPSBub3cucGx1cyh7bWludXRlczogZXhwaXJlc30pO1xuICBjb25zdCBpYXQ6IG51bWJlciA9IE1hdGguZmxvb3Iobm93LnRvU2Vjb25kcygpKTtcbiAgY29uc3QgZXhwOiBudW1iZXIgPSBNYXRoLmZsb29yKHNlc3Npb25FeHBpcmVzLnRvU2Vjb25kcygpKTtcblxuICBjb25zdCB0b2tlbiA9IHNldFNlc3Npb24oe1xuICAgIGV4cCxcbiAgICBpYXQsXG4gICAgdXNlcm5hbWUsXG4gICAgdXNlckFjY2VzcyxcbiAgICB1c2VySWRcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBleHBpcmVzOiBzZXNzaW9uRXhwaXJlcy50b01pbGxpcygpLFxuICAgIGlzc3VlZDogbm93LnRvTWlsbGlzKCksXG4gICAgdG9rZW5cbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVc2VyT3B0aW9uYWwgPSAoZmllbGRzOiBzdHJpbmdbXSA9IFtdKSA9PlxuICBmaWVsZHMucmVkdWNlKChzZWxlY3RzOiBhbnksIGZpZWxkOiBzdHJpbmcpID0+IHtcbiAgICBpZihmaWVsZC5pbmNsdWRlcygnQ291bnQnKSkge1xuICAgICAgcmV0dXJuIHNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUoJ3VzZXJzJywgJ3UnLCBmaWVsZCwgc2VsZWN0cyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGVjdHM7XG4gIH0sIHtvYmplY3RzOiBbXSwgcXVlcmllczogW119KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXNlck9wdGlvbnMgPSAob3B0aW9uczogVXNlck9wdGlvbnMgPSB7fSkgPT4ge1xuICBjb25zdCB7XG4gICAgZnJvbSA9IDAsXG4gICAgdG8gPSAzMFxuICB9ID0gb3B0aW9ucztcblxuICByZXR1cm4ge1xuICAgIC4uLm9wdGlvbnMsXG4gICAgbGltaXQ6IGdldExpbWl0KGZyb20sIHRvKVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZFVzZXIgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgYXJnczogYW55KTogUHJvbWlzZTxVc2VyPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2FkZFVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2V9ID0gY29udGV4dDtcbiAgY29uc3Qge3VzZXJ9ID0gYXJncztcbiAgY29uc3Qge2VtYWlsLCBwYXNzd29yZCwgcGhvbmUsIHVzZXJuYW1lfSA9IHVzZXI7XG4gIGNvbnN0IHNhbHQ6IHN0cmluZyA9IGNyZWF0ZUhhc2goYCR7dXNlcm5hbWV9JHtwYXNzd29yZH1gLCBudWxsKTtcbiAgY29uc3QgZW5jcnlwdGVkUGFzc3dvcmQgPSBjcmVhdGVQYXNzd29yZChwYXNzd29yZCwgc2FsdCk7XG4gIGNvbnN0IGZvcm1hdFVzZXJuYW1lOiBzdHJpbmcgPSBwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKTtcbiAgY29uc3QgZm9ybWF0RW1haWw6IHN0cmluZyA9IHBhcnNlRW1haWwoZW1haWwpO1xuICBjb25zdCBmb3JtYXRQaG9uZTogc3RyaW5nID0gcGFyc2VQaG9uZShwaG9uZSk7XG5cbiAgaWYoIWZvcm1hdFVzZXJuYW1lIHx8ICFwYXNzd29yZCB8fCAoIWZvcm1hdFBob25lICYmICFmb3JtYXRFbWFpbCkpIHtcbiAgICByZXR1cm4gbG9nRXhjZXB0aW9uKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGFyZ3M6IHt1c2VybmFtZX0sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklOVkFMSURfQVJHVU1FTlRTXG4gICAgfSwgY29udGV4dCk7XG4gIH1cblxuICBjb25zdCBmaWx0ZXJzOiBzdHJpbmdbXSA9IFtgdS51c2VybmFtZSA9PSBcIiR7Zm9ybWF0VXNlcm5hbWV9XCJgXTtcblxuICBpZihmb3JtYXRFbWFpbCkge1xuICAgIGZpbHRlcnMucHVzaChgdS5lbWFpbCA9PSBcIiR7Zm9ybWF0RW1haWx9XCJgKTtcbiAgfVxuXG4gIGlmKGZvcm1hdFBob25lKSB7XG4gICAgZmlsdGVycy5wdXNoKGB1LnBob25lID09ICR7Zm9ybWF0UGhvbmV9YCk7XG4gIH1cblxuICBjb25zdCBjaGVja1F1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgJHtmaWx0ZXJzLmpvaW4oJyB8fCAnKX1cbiAgICBSRVRVUk4gdWA7XG4gIGNvbnN0IGV4aXN0aW5nVXNlcnMgPSBhd2FpdCBkYXRhYmFzZS5xdWVyeShjaGVja1F1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3I6IEFycmF5Q3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpXG4gICAgLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgYXJnczoge3VzZXJuYW1lfSxcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dClcbiAgICAgIC50aGVuKCgpID0+IG51bGwpXG4gICAgKTtcblxuICBpZihleGlzdGluZ1VzZXJzLmxlbmd0aCkge1xuICAgIHJldHVybiBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgYXJnczoge3VzZXJuYW1lfSxcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuRVhJU1RJTkdfVVNFUk5BTUVcbiAgICB9LCBjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IHZlcmlmaWVkRW1haWxDb2RlOiBudW1iZXIgPSBNYXRoLmZsb29yKDEwMDAwMCArIChNYXRoLnJhbmRvbSgpICogOTAwMDAwKSk7XG4gIGNvbnN0IHZlcmlmaWVkUGhvbmVDb2RlOiBudW1iZXIgPSBNYXRoLmZsb29yKDEwMDAwMCArIChNYXRoLnJhbmRvbSgpICogOTAwMDAwKSk7XG5cbiAgLy8gQWRkIG5ldyB1c2VyIHByb3BlcnRpZXNcbiAgY29uc3QgaW5zZXJ0OiBVc2VyID0ge1xuICAgIF9rZXk6IGNyZWF0ZUhhc2godXNlcm5hbWUsIG51bGwpLFxuICAgIGFkZGVkOiBEYXRlLm5vdygpLFxuICAgIGVtYWlsOiBmb3JtYXRFbWFpbCxcbiAgICBtb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgICBwYXNzd29yZDogZW5jcnlwdGVkUGFzc3dvcmQsXG4gICAgcGhvbmU6IGZvcm1hdFBob25lLFxuICAgIHNhbHQsXG4gICAgdXNlcm5hbWU6IGZvcm1hdFVzZXJuYW1lLFxuICAgIHVzZXJBY2Nlc3M6IDEsXG4gICAgdmVyaWZpZWRFbWFpbDogZmFsc2UsXG4gICAgdmVyaWZpZWRFbWFpbENvZGUsXG4gICAgdmVyaWZpZWRQaG9uZTogZmFsc2UsXG4gICAgdmVyaWZpZWRQaG9uZUNvZGVcbiAgfTtcblxuICAvLyBBZGQgbmV3IHVzZXIgaW4gQXJhbmdvREJcbiAgY29uc3QgaW5zZXJ0UXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYElOU0VSVCAke2luc2VydH0gSU4gdXNlcnMgUkVUVVJOIE5FV2A7XG4gIHJldHVybiBhd2FpdCBkYXRhYmFzZS5xdWVyeShpbnNlcnRRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yOiBBcnJheUN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSB8fCB7fSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBhcmdzOiB7dXNlcm5hbWV9LFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KVxuICAgICAgLnRoZW4oKCkgPT4gbnVsbClcbiAgICApO1xufTtcblxuZXhwb3J0IGNvbnN0IHVwZGF0ZVVzZXIgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlcik6IFByb21pc2U8YW55PiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ3VwZGF0ZVVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2V9ID0gY29udGV4dDtcbiAgY29uc3Qge19rZXksIF9pZCwgaWQsIHRhZ3MgPSBbXSwgdXNlcklkLCAuLi51cGRhdGVkfSA9IHVzZXI7XG4gIGxldCB1c2VyRG9jSWQ6IHN0cmluZztcblxuICBpZihfaWQgfHwgaWQpIHtcbiAgICB1c2VyRG9jSWQgPSBfaWQgfHwgaWQ7XG4gIH0gZWxzZSBpZihfa2V5IHx8IHVzZXJJZCkge1xuICAgIHVzZXJEb2NJZCA9IGB1c2Vycy8ke19rZXkgfHwgdXNlcklkfWA7XG4gIH1cblxuICBjb25zdCB1c2VyUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYExFVCB1ID0gRE9DVU1FTlQoJHt1c2VyRG9jSWR9KVxuICAgIFVQREFURSB1IFdJVEggJHt1cGRhdGVkfSBJTiB1c2Vyc1xuICAgIFJFVFVSTiBORVdgO1xuXG4gIGNvbnN0IHVwZGF0ZWRVc2VyID0gYXdhaXQgZGF0YWJhc2UucXVlcnkodXNlclF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xuXG4gIGNvbnN0IHRhZ0NvbGxlY3Rpb246IEVkZ2VDb2xsZWN0aW9uID0gZGF0YWJhc2UuY29sbGVjdGlvbignaXNUYWdnZWQnKTtcbiAgYXdhaXQgUHJvbWlzZS5hbGwodGFncy5tYXAoKHtpZDogdGFnRG9jSWQsIG5hbWV9KSA9PiB7XG4gICAgY29uc3QgZWRnZSA9IHtcbiAgICAgIF9mcm9tOiB0YWdEb2NJZCxcbiAgICAgIF9rZXk6IGNyZWF0ZUhhc2goYGlzVGFnZ2VkLSR7dGFnRG9jSWR9LSR7dXNlckRvY0lkfWApLFxuICAgICAgX3RvOiB1c2VyRG9jSWQsXG4gICAgICBhZGRlZDogRGF0ZS5ub3coKSxcbiAgICAgIG5hbWVcbiAgICB9O1xuICAgIGNvbnN0IHRhZ1F1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgaXQgSU4gaXNUYWdnZWRcbiAgICAgIEZJTFRFUiBpdC5fZnJvbSA9PSAke3RhZ0RvY0lkfSAmJiBpdC5fdG8gPT0gJHt1c2VyRG9jSWR9ICYmIGl0Lm5hbWUgPT0gJHtuYW1lfVxuICAgICAgTElNSVQgMVxuICAgICAgUkVUVVJOIGl0YDtcblxuICAgIHJldHVybiBkYXRhYmFzZS5xdWVyeSh0YWdRdWVyeSlcbiAgICAgIC50aGVuKChjdXJzb3I6IEFycmF5Q3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgICAgLnRoZW4oKHRhZ0VkZ2UpID0+IHtcbiAgICAgICAgaWYoISF0YWdFZGdlKSB7XG4gICAgICAgICAgcmV0dXJuIHRhZ0VkZ2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGFnQ29sbGVjdGlvbi5zYXZlKGVkZ2UsIHtyZXR1cm5OZXc6IHRydWV9KS50aGVuKCgpID0+IGVkZ2UpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIGxhYmVsOiAnZGJfZXJyb3InXG4gICAgICB9LCBlcnJvciwgY29udGV4dCkudGhlbigoKSA9PiBudWxsKSk7XG4gIH0pKTtcblxuICByZXR1cm4gdXBkYXRlZFVzZXI7XG59O1xuXG5leHBvcnQgY29uc3QgY29uZmlybUNvZGUgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgYXJncyk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdjb25maXJtRW1haWwnO1xuICBjb25zdCB7ZGF0YWJhc2UsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH19ID0gY29udGV4dDtcbiAgY29uc3Qge2NvZGUsIHR5cGV9ID0gYXJncztcbiAgY29uc3QgdXNlckRvY0lkOiBzdHJpbmcgPSBgdXNlcnMvJHtzZXNzaW9uSWR9YDtcblxuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIHUgPSBET0NVTUVOVCgke3VzZXJEb2NJZH0pIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRdWVyeSlcbiAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkgfHwge30pXG4gICAgICAudGhlbigoe3ZlcmlmaWVkRW1haWxDb2RlLCB2ZXJpZmllZFBob25lQ29kZX06IFVzZXIpID0+IHtcbiAgICAgICAgc3dpdGNoKHR5cGUpIHtcbiAgICAgICAgICBjYXNlICdlbWFpbCc6XG4gICAgICAgICAgICByZXR1cm4gY29kZSA9PT0gdmVyaWZpZWRFbWFpbENvZGU7XG4gICAgICAgICAgY2FzZSAncGhvbmUnOlxuICAgICAgICAgICAgcmV0dXJuIGNvZGUgPT09IHZlcmlmaWVkUGhvbmVDb2RlO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgYXJnczoge2NvZGUsIHR5cGUsIHVzZXJJZDogc2Vzc2lvbklkfSxcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dClcbiAgICAgICk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBkZWxldGVVc2VyID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIGFyZ3M6IGFueSk6IFByb21pc2U8YW55PiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2RlbGV0ZVVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2UsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlckFjY2Vzczogc2Vzc2lvbkFjY2Vzc319ID0gY29udGV4dDtcbiAgY29uc3Qge3VzZXJJZH0gPSBhcmdzO1xuICBjb25zdCBpc0FkbWluOiBib29sZWFuID0gc2Vzc2lvbkFjY2VzcyA+IDI7XG5cbiAgaWYoIWlzQWRtaW4gJiYgKHNlc3Npb25JZCAhPT0gdXNlcklkKSkge1xuICAgIGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBhcmdzLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBsYWJlbDogJ3VuYXV0aG9yaXplZCcsXG4gICAgICB2YWx1ZTogJ2ludmFsaWRfc2Vzc2lvbidcbiAgICB9LCBjb250ZXh0KTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiB1Ll9rZXkgPT0gJHt1c2VySWR9XG4gICAgTElNSVQgMVxuICAgIFJFTU9WRSB1IElOIHVzZXJzXG4gICAgUkVUVVJOIE9MRGA7XG5cbiAgLy8gU3RyaXBlXG4gIGNvbnN0IHN0cmlwZUNsaWVudCA9IG5ldyBTdHJpcGUoQ29uZmlnLmdldCgnc3RyaXBlLnRva2VuJyksIHthcGlWZXJzaW9uLCB0eXBlc2NyaXB0OiB0cnVlfSk7XG5cbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3I6IEFycmF5Q3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC50aGVuKCh1c2VyOiBVc2VyID0ge30pID0+IHN0cmlwZUNsaWVudC5jdXN0b21lcnMuZGVsKHVzZXIuc3RyaXBlQ3VzdG9tZXJJZClcbiAgICAgIC50aGVuKCgpID0+IHN0cmlwZUNsaWVudC5hY2NvdW50cy5kZWwodXNlci5zdHJpcGVBY2NvdW50SWQpKVxuICAgICAgLnRoZW4oKCkgPT4gdXNlcikpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGRlYWN0aXZhdGVVc2VyID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxVc2VyPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2RlbGV0ZSc7XG4gIGNvbnN0IHtkYXRhYmFzZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkLCB1c2VyQWNjZXNzOiBzZXNzaW9uQWNjZXNzfX0gPSBjb250ZXh0O1xuICBjb25zdCBpc0FkbWluOiBib29sZWFuID0gc2Vzc2lvbkFjY2VzcyA+IDI7XG5cbiAgaWYoIWlzQWRtaW4gJiYgKHNlc3Npb25JZCAhPT0gdXNlcklkKSkge1xuICAgIGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIGxhYmVsOiAndW5hdXRob3JpemVkJyxcbiAgICAgIHZhbHVlOiAnaW52YWxpZF9zZXNzaW9uJ1xuICAgIH0sIGNvbnRleHQpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgdXBkYXRlZDogVXNlciA9IHtcbiAgICB1c2VyQWNjZXNzOiAwXG4gIH07XG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBVUERBVEUgJHt1c2VySWR9IFdJVEggJHt1cGRhdGVkfSBJTiB1c2VycyBMSU1JVCAxIFJFVFVSTiBORVdgO1xuXG4gIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yOiBBcnJheUN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RGlzcGxheU5hbWUgPSAodXNlcjogVXNlciA9IHt9KTogc3RyaW5nID0+IHtcbiAgY29uc3Qge2ZpcnN0LCBsYXN0LCBuYW1lID0gJycsIHVzZXJuYW1lID0gJyd9ID0gdXNlcjtcbiAgY29uc3QgZnVsbG5hbWU6IHN0cmluZyA9IChbZmlyc3QsIGxhc3RdKS5qb2luKCcgJykudHJpbSgpO1xuXG4gIGlmKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfSBlbHNlIGlmKGZ1bGxuYW1lICE9PSAnJykge1xuICAgIHJldHVybiBmdWxsbmFtZTtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgcmV0dXJuIHVzZXJuYW1lO1xuICB9XG5cbiAgcmV0dXJuICdVbmtub3duJztcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRTZXNzaW9uVXNlciA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxVc2VyPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldFNlc3Npb25Vc2VyJztcbiAgY29uc3Qge2RhdGFiYXNlLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlcm5hbWV9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgTEVUIHUgPSBET0NVTUVOVChcInVzZXJzLyR7c2Vzc2lvbklkfVwiKVxuICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yOiBBcnJheUN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAudGhlbigodXNlciA9IHt9KSA9PiB1c2VyKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBhcmdzOiB7dXNlcm5hbWUsIHVzZXJJZDogc2Vzc2lvbklkfSxcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgYXJnczogYW55KTogUHJvbWlzZTxVc2VyPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldFVzZXInO1xuICBjb25zdCB7dXNlcklkfSA9IGFyZ3M7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzfSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdFVzZXJJZDogc3RyaW5nID0gcGFyc2VJZCh1c2VySWQpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcblxuICAvLyBHZXQgZGF0YSBmcm9tIGRhdGFiYXNlXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgTEVUIHUgPSBET0NVTUVOVChcInVzZXJzLyR7Zm9ybWF0VXNlcklkfVwiKVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBGSUxURVIgdS51c2VyQWNjZXNzID4gMFxuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yOiBBcnJheUN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAudGhlbigodXNlciA9IHt9KSA9PiB1c2VyKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBhcmdzLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KVxuICAgICAgLnRoZW4oKCkgPT4geyB9KSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnMgPSAoY29udGV4dDogQXBpQ29udGV4dCwgb3B0aW9ucz86IFVzZXJPcHRpb25zKTogUHJvbWlzZTxVc2VyW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0VXNlckxpc3QnO1xuICBjb25zdCB7ZGF0YWJhc2UsIGZpZWxkc30gPSBjb250ZXh0O1xuICBjb25zdCB7bGltaXQsIHVzZXJuYW1lfSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBmaWx0ZXJCeTogc3RyaW5nW10gPSBbJ3UudXNlckFjY2VzcyA+IDAnXTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlckJ5LnB1c2goYENPTlRBSU5TKHUudXNlcm5hbWUsIFwiJHtwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKX1cIilgKTtcbiAgfVxuXG4gIC8vIEdldCBkYXRhIGZyb20gZGF0YWJhc2VcbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiAke2ZpbHRlckJ5LmpvaW4oJyAmJiAnKX1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgJHtsaW1pdC5hcWx9XG4gICAgU09SVCB1LnVzZXJuYW1lXG4gICAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3I6IEFycmF5Q3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkudGhlbigoKSA9PiBbXSkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXJzQnlSZWFjdGlvbnMgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtyZWFjdGlvbnMgPSBbXSwgdXNlcm5hbWV9OiBhbnksXG4gIG9wdGlvbnM/OiBVc2VyT3B0aW9uc1xuKTogUHJvbWlzZTxVc2VyW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0VXNlcnNCeVJlYWN0aW9ucyc7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdFJlYWN0aW9uczogc3RyaW5nW10gPSAgcmVhY3Rpb25zLm1hcCgocmVhY3Rpb25OYW1lOiBzdHJpbmcpID0+IHBhcnNlQ2hhcihyZWFjdGlvbk5hbWUsIDMyKS50b0xvd2VyQ2FzZSgpKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuXG4gIGNvbnN0IGZvcm1hdFNlc3Npb25JZDogc3RyaW5nID0gYHVzZXJzLyR7c2Vzc2lvbklkfWA7XG4gIGNvbnN0IGZvcm1hdFVzZXJuYW1lOiBzdHJpbmcgPSBwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKTtcbiAgY29uc3QgZmlsdGVyQnk6IHN0cmluZ1tdID0gW2BQT1NJVElPTigke0pTT04uc3RyaW5naWZ5KGZvcm1hdFJlYWN0aW9ucyl9LCBMT1dFUihyLm5hbWUpKWBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke2Zvcm1hdFVzZXJuYW1lfVwiKWApO1xuICB9XG5cbiAgLy8gR2V0IGRhdGEgZnJvbSBkYXRhYmFzZVxuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB1LCByIElOIE9VVEJPVU5EIFwiJHtmb3JtYXRTZXNzaW9uSWR9XCIgaGFzUmVhY3Rpb25cbiAgICBPUFRJT05TIHt2ZXJ0ZXhDb2xsZWN0aW9uczogXCJ1c2Vyc1wifVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICAke2ZpbHRlckJ5Lmxlbmd0aCA/IGBGSUxURVIgJHtmaWx0ZXJCeS5qb2luKCcgJiYgJyl9YCA6ICcnfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIGNvbnNvbGUubG9nKHthcWxRdWVyeX0pO1xuICByZXR1cm4gZGF0YWJhc2UucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcjogQXJyYXlDdXJzb3IpID0+IGN1cnNvci5hbGwoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KS50aGVuKCgpID0+IFtdKSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeVRhZ3MgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt0YWdzLCB1c2VybmFtZX06IGFueSxcbiAgb3B0aW9ucz86IFVzZXJPcHRpb25zXG4pOiBQcm9taXNlPFVzZXJbXT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRVc2Vyc0J5VGFncyc7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdFRhZ3M6IHN0cmluZ1tdID0gIHRhZ3MucmVkdWNlKChsaXN0OiBzdHJpbmdbXSwgdGFnTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgaWYodGFnTmFtZSkge1xuICAgICAgbGlzdC5wdXNoKHBhcnNlQ2hhcih0YWdOYW1lLCAzMikudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpc3Q7XG4gIH0sIFtdKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuXG4gIGNvbnN0IGZvcm1hdFVzZXJuYW1lOiBzdHJpbmcgPSBwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKTtcbiAgY29uc3QgZmlsdGVyQnk6IHN0cmluZ1tdID0gW2B1Ll9rZXkgIT0gXCIke3Nlc3Npb25JZH1cImBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke2Zvcm1hdFVzZXJuYW1lfVwiKWApO1xuICB9XG5cbiAgLy8gR2V0IGRhdGEgZnJvbSBkYXRhYmFzZVxuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB0IElOIHRhZ3NcbiAgICBGSUxURVIgUE9TSVRJT04oJHtKU09OLnN0cmluZ2lmeShmb3JtYXRUYWdzKX0sIExPV0VSKHQubmFtZSkpXG4gICAgRk9SIHUsIGl0IElOIE9VVEJPVU5EIHQgaXNUYWdnZWRcbiAgICBPUFRJT05TIHtiZnM6IHRydWUsIHVuaXF1ZVZlcnRpY2VzOiBcImdsb2JhbFwiLCB2ZXJ0ZXhDb2xsZWN0aW9uczogXCJ1c2Vyc1wifVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICAke2ZpbHRlckJ5Lmxlbmd0aCA/IGBGSUxURVIgJHtmaWx0ZXJCeS5qb2luKCcgJiYgJyl9YCA6ICcnfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIGNvbnNvbGUubG9nKCdnZXRVc2Vyc0J5VGFncycsIGFxbFF1ZXJ5KTtcbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3I6IEFycmF5Q3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkudGhlbigoKSA9PiBbXSkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXJzQnlMYXRlc3QgPSAoY29udGV4dDogQXBpQ29udGV4dCwge3VzZXJuYW1lfSwgb3B0aW9ucz86IFVzZXJPcHRpb25zKTogUHJvbWlzZTxVc2VyW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0VXNlcnNCeUxhdGVzdCc7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkfX0gPSBjb250ZXh0O1xuICBjb25zdCB7bGltaXR9ID0gcGFyc2VVc2VyT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3QgZmlsdGVyID0gWyd1Ll9pZCAhPSBzZXNzaW9uLl9pZCddO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlci5wdXNoKGBDT05UQUlOUyh1LnVzZXJuYW1lLCBcIiR7cGFyc2VVc2VybmFtZSh1c2VybmFtZSl9XCIpYCk7XG4gIH1cblxuICAvLyBHZXQgZGF0YSBmcm9tIGRhdGFiYXNlXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBMRVQgc2Vzc2lvbiA9IERPQ1VNRU5UKFwidXNlcnMvJHt1c2VySWR9XCIpXG4gICAgRklMVEVSICR7ZmlsdGVyLmpvaW4oJyAmJiAnKX1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgTEVUIGRpc3RhbmNlID0gRElTVEFOQ0UodS5sYXRpdHVkZSB8fCAwLCB1LmxvbmdpdHVkZSB8fCAwLCBzZXNzaW9uLmxhdGl0dWRlIHx8IDAsIHNlc3Npb24ubG9uZ2l0dWRlIHx8IDApXG4gICAgJHtsaW1pdC5hcWx9XG4gICAgU09SVCBkaXN0YW5jZSBBU0MsIHUuYWRkZWQgREVTQ1xuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yOiBBcnJheUN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpLnRoZW4oKCkgPT4gW10pKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWZyZXNoU2Vzc2lvbiA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCB7ZXhwaXJlcywgdG9rZW59KTogUHJvbWlzZTxTZXNzaW9uVG9rZW4gfCBTZXNzaW9uRXJyb3I+ID0+IHtcbiAgY29uc3Qge2Vycm9yfSA9IGdldFNlc3Npb24odG9rZW4pO1xuXG4gIGlmKGVycm9yKSB7XG4gICAgcmV0dXJuIHtlcnJvcnM6IFtlcnJvcl19O1xuICB9XG5cbiAgY29uc3Qge2V4cCwgdXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2Vzc30gPSBnZXRTZXNzaW9uKHRva2VuKTtcbiAgY29uc3Qgbm93OiBudW1iZXIgPSBNYXRoLmNlaWwoRGF0ZVRpbWUubG9jYWwoKS50b1NlY29uZHMoKSk7XG5cbiAgaWYoZXhwID4gbm93KSB7XG4gICAgcmV0dXJuIGNyZWF0ZVRva2VuKHVzZXJJZCwgdXNlcm5hbWUsIHVzZXJBY2Nlc3MsIGV4cGlyZXMpO1xuICB9XG5cbiAgcmV0dXJuIHtlcnJvcnM6IFsnc2Vzc2lvbl9leHBpcmVkJ119O1xufTtcblxuZXhwb3J0IGNvbnN0IHNpZ25JbiA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCBhcmdzKTogUHJvbWlzZTxTZXNzaW9uVG9rZW4+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnc2lnbkluJztcbiAgY29uc3Qge2V4cGlyZXMsIHBhc3N3b3JkLCB1c2VybmFtZX0gPSBhcmdzO1xuICBjb25zdCBmb3JtYXRVc2VybmFtZTogc3RyaW5nID0gcGFyc2VVc2VybmFtZSh1c2VybmFtZSk7XG4gIGNvbnN0IGZvcm1hdFBhc3N3b3JkOiBzdHJpbmcgPSBwYXJzZVBhc3N3b3JkKHBhc3N3b3JkKTtcbiAgY29uc3QgZm9ybWF0RXhwaXJlczogbnVtYmVyID0gcGFyc2VOdW0oZXhwaXJlcykgfHwgMTU7XG4gIGNvbnN0IHtkYXRhYmFzZX0gPSBjb250ZXh0O1xuXG4gIGlmKCFmb3JtYXRVc2VybmFtZSB8fCAhZm9ybWF0UGFzc3dvcmQpIHtcbiAgICByZXR1cm4gbG9nRXhjZXB0aW9uKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGFyZ3M6IHt1c2VybmFtZX0sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklOVkFMSURfQVJHVU1FTlRTXG4gICAgfSwgY29udGV4dCk7XG4gIH1cblxuICBjb25zdCBjaGVja1F1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiB1LnVzZXJuYW1lID09ICR7Zm9ybWF0VXNlcm5hbWV9XG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiB1YDtcbiAgY29uc3QgY2hlY2tVc2VyOiBVc2VyID0gYXdhaXQgZGF0YWJhc2UucXVlcnkoY2hlY2tRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC5jYXRjaCgoZXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGFyZ3M6IHt1c2VybmFtZTogZm9ybWF0VXNlcm5hbWV9LFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KVxuICAgICAgLnRoZW4oKCkgPT4gbnVsbClcbiAgICApO1xuXG4gIGlmKCFjaGVja1VzZXIpIHtcbiAgICByZXR1cm4gbG9nRXhjZXB0aW9uKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGFyZ3M6IHt1c2VybmFtZX0sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklOVkFMSURfQVVUSEVOVElDQVRJT05cbiAgICB9LCBjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IHtfa2V5OiB1c2VySWQsIHNhbHQsIHVzZXJBY2Nlc3N9ID0gY2hlY2tVc2VyO1xuICBjb25zdCBhdXRoUGFzc3dvcmQ6IHN0cmluZyA9IGNyZWF0ZVBhc3N3b3JkKGZvcm1hdFBhc3N3b3JkLCBzYWx0KTtcblxuICBpZihjaGVja1VzZXIucGFzc3dvcmQgIT09IGF1dGhQYXNzd29yZCkge1xuICAgIHJldHVybiBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgYXJnczoge3VzZXJuYW1lfSxcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9BVVRIRU5USUNBVElPTlxuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZVRva2VuKHVzZXJJZCwgdXNlcm5hbWUsIHVzZXJBY2Nlc3MsIGZvcm1hdEV4cGlyZXMpO1xufTtcblxuZXhwb3J0IGNvbnN0IHNpZ25PdXQgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgYXJncyk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdzaWduT3V0JztcbiAgY29uc3Qge2RhdGFiYXNlLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWQsIHVzZXJuYW1lfX0gPSBjb250ZXh0O1xuICBjb25zdCB1c2VyRG9jSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuXG4gIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICBsYXN0T25saW5lOiBEYXRlLm5vdygpLFxuICAgIHNlc3Npb25JZDogbnVsbFxuICB9O1xuICBjb25zdCBzZXNzaW9uUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYExFVCB1ID0gRE9DVU1FTlQoJHt1c2VyRG9jSWR9KVxuICAgIFVQREFURSB1IFdJVEggJHt1cGRhdGV9IElOIHVzZXJzXG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiBORVdgO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgZGF0YWJhc2UucXVlcnkoc2Vzc2lvblF1ZXJ5KVxuICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBhcmdzOiB7dXNlcm5hbWUsIHVzZXJJZDogc2Vzc2lvbklkfSxcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dClcbiAgICAgICk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRBY3RpdmVVc2VyQ291bnQgPSAoY29udGV4dDogQXBpQ29udGV4dCkgPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRBY3RpdmVVc2VyQ291bnQnO1xuICBjb25zdCB7ZGF0YWJhc2V9ID0gY29udGV4dDtcbiAgY29uc3QgY291bnRRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIGRvY3MgPSAoXG4gICAgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS5hY3RpdmUgPT0gdHJ1ZVxuICAgIFJFVFVSTiB1XG4gIClcbiAgUkVUVVJOIExFTkdUSChkb2NzKWA7XG5cbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGNvdW50UXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpXG4gICAgICAudGhlbigoKSA9PiAwKVxuICAgICk7XG59O1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBSUEsbUJBVU87QUFDUCxzQkFBa0I7QUFJbEIsbUJBQXVCO0FBQ3ZCLG9CQUFtQjtBQUVuQixvQkFBcUI7QUFHckIsSUFBQUEsZ0JBQXNGO0FBQ3RGLHFCQUFpRTtBQUVqRSxNQUFNLGdCQUF3QjtBQUM5QixNQUFNLGFBQWtCO0FBUWpCLElBQUssYUFBTCxrQkFBS0MsZ0JBQUw7QUFDTCxFQUFBQSx3QkFBQSxpQkFBYyxLQUFkO0FBQ0EsRUFBQUEsd0JBQUEsWUFBUyxLQUFUO0FBQ0EsRUFBQUEsd0JBQUEsYUFBVSxLQUFWO0FBQ0EsRUFBQUEsd0JBQUEsbUJBQWdCLEtBQWhCO0FBQ0EsRUFBQUEsd0JBQUEsV0FBUSxLQUFSO0FBTFUsU0FBQUE7QUFBQSxHQUFBO0FBUUwsTUFBTSxjQUFjLENBQ3pCLFFBQ0EsVUFDQSxZQUNBLFVBQWtCLE9BQ0Q7QUFDakIsUUFBTSxNQUFnQixzQkFBUyxNQUFNO0FBQ3JDLFFBQU0saUJBQTJCLElBQUksS0FBSyxFQUFDLFNBQVMsUUFBTyxDQUFDO0FBQzVELFFBQU0sTUFBYyxLQUFLLE1BQU0sSUFBSSxVQUFVLENBQUM7QUFDOUMsUUFBTSxNQUFjLEtBQUssTUFBTSxlQUFlLFVBQVUsQ0FBQztBQUV6RCxRQUFNLFlBQVEsMkJBQVc7QUFB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
|
|
784
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FjdGlvbnMvdXNlcnMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE5LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG5pbXBvcnQge1xuICBjcmVhdGVIYXNoLFxuICBjcmVhdGVQYXNzd29yZCxcbiAgcGFyc2VBcmFuZ29JZCxcbiAgcGFyc2VDaGFyLFxuICBwYXJzZUVtYWlsLFxuICBwYXJzZU51bSxcbiAgcGFyc2VQYXNzd29yZCxcbiAgcGFyc2VQaG9uZSxcbiAgcGFyc2VVc2VybmFtZVxufSBmcm9tICdAbmxhYnMvdXRpbHMnO1xuaW1wb3J0IHthcWx9IGZyb20gJ2FyYW5nb2pzJztcbmltcG9ydCB7QXFsUXVlcnl9IGZyb20gJ2FyYW5nb2pzL2FxbCc7XG5pbXBvcnQge0RhdGVUaW1lfSBmcm9tICdsdXhvbic7XG5pbXBvcnQgU3RyaXBlIGZyb20gJ3N0cmlwZSc7XG5cbmltcG9ydCB7cGFyc2VVc2VyfSBmcm9tICcuLi9hZGFwdGVycy91c2VyQWRhcHRlcic7XG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7c2VuZEVtYWlsfSBmcm9tICcuL2VtYWlsJztcbmltcG9ydCB7c2VuZFNtc30gZnJvbSAnLi9zbXMnO1xuaW1wb3J0IHtFcnJvclR5cGVzLCBTZXNzaW9uRXJyb3J9IGZyb20gJy4uL3R5cGVzL2Vycm9yLnR5cGVzJztcbmltcG9ydCB7bG9nRXJyb3IsIGxvZ0V4Y2VwdGlvbn0gZnJvbSAnLi4vdXRpbHMvYW5hbHl0aWNzVXRpbHMnO1xuaW1wb3J0IHtnZXREb2NJZCwgZ2V0TGltaXQsIHNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGV9IGZyb20gJy4uL3V0aWxzL2FyYW5nb2RiVXRpbHMnO1xuaW1wb3J0IHtnZXRTZXNzaW9uLCBpc0FkbWluVXNlciwgU2Vzc2lvblRva2VuLCBzZXRTZXNzaW9ufSBmcm9tICcuLi91dGlscy9zZXNzaW9uJztcblxuaW1wb3J0IHR5cGUge0FwaUNvbnRleHR9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMnO1xuaW1wb3J0IHR5cGUge1VzZXJUeXBlfSBmcm9tICcuLi90eXBlcy91c2Vycy50eXBlcyc7XG5pbXBvcnQgdHlwZSB7RWRnZUNvbGxlY3Rpb259IGZyb20gJ2FyYW5nb2pzL2NvbGxlY3Rpb25zJztcblxuXG5jb25zdCBldmVudENhdGVnb3J5ID0gJ3VzZXJzJztcbmNvbnN0IFNUUklQRV9BUElfVkVSU0lPTiA9ICcyMDI1LTA1LTI4LmJhc2lsJztcblxuZXhwb3J0IGludGVyZmFjZSBVc2VyT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGZyb20/OiBudW1iZXI7XG4gIHJlYWRvbmx5IHRvPzogbnVtYmVyO1xuICByZWFkb25seSB1c2VybmFtZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGVudW0gVXNlckFjY2VzcyB7XG4gIERFQUNUSVZBVEVEID0gMCxcbiAgQUNUSVZFID0gMSxcbiAgUFJFTUlVTSA9IDIsXG4gIENPTlRFTlRfQURNSU4gPSAzLFxuICBBRE1JTiA9IDRcbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRva2VuID0gKFxuICB1c2VySWQ6IHN0cmluZyxcbiAgdXNlcm5hbWU6IHN0cmluZyxcbiAgdXNlckFjY2VzczogbnVtYmVyLFxuICBleHBpcmVzSW5NaW51dGVzOiBudW1iZXIgPSAxNVxuKTogU2Vzc2lvblRva2VuID0+IHtcbiAgY29uc3Qgbm93OiBEYXRlVGltZSA9IERhdGVUaW1lLmxvY2FsKCk7XG4gIGNvbnN0IHNlc3Npb25FeHBpcmVzOiBEYXRlVGltZSA9IG5vdy5wbHVzKHttaW51dGVzOiBleHBpcmVzSW5NaW51dGVzfSk7XG4gIGNvbnN0IGlhdDogbnVtYmVyID0gTWF0aC5mbG9vcihub3cudG9TZWNvbmRzKCkpO1xuICBjb25zdCBleHA6IG51bWJlciA9IE1hdGguZmxvb3Ioc2Vzc2lvbkV4cGlyZXMudG9TZWNvbmRzKCkpO1xuICBjb25zdCB0b2tlbiA9IHNldFNlc3Npb24oe1xuICAgIGV4cCxcbiAgICBpYXQsXG4gICAgdXNlckFjY2VzcyxcbiAgICB1c2VySWQsXG4gICAgdXNlcm5hbWVcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBleHBpcmVzOiBzZXNzaW9uRXhwaXJlcy50b01pbGxpcygpLFxuICAgIGlzc3VlZDogbm93LnRvTWlsbGlzKCksXG4gICAgdG9rZW4sXG4gICAgdXNlcklkLFxuICAgIHVzZXJuYW1lXG4gIH07XG59O1xuXG5pbnRlcmZhY2UgU2VsZWN0QWNjdW11bGF0b3Ige1xuICBvYmplY3RzOiBzdHJpbmdbXTtcbiAgcXVlcmllczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBjb25zdCBnZXRVc2VyT3B0aW9uYWwgPSAoZmllbGRzOiBzdHJpbmdbXSA9IFtdKTogU2VsZWN0QWNjdW11bGF0b3IgPT5cbiAgZmllbGRzLnJlZHVjZSgoc2VsZWN0czogU2VsZWN0QWNjdW11bGF0b3IsIGZpZWxkOiBzdHJpbmcpID0+IHtcbiAgICBpZihmaWVsZC5pbmNsdWRlcygnQ291bnQnKSkge1xuICAgICAgcmV0dXJuIHNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUoJ3VzZXJzJywgJ3UnLCBmaWVsZCwgc2VsZWN0cyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGVjdHM7XG4gIH0sIHtvYmplY3RzOiBbXSwgcXVlcmllczogW119KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXNlck9wdGlvbnMgPSAob3B0aW9uczogVXNlck9wdGlvbnMgPSB7fSkgPT4ge1xuICBjb25zdCB7XG4gICAgZnJvbSA9IDAsXG4gICAgdG8gPSAzMFxuICB9ID0gb3B0aW9ucztcbiAgY29uc3QgbGltaXQgPSBnZXRMaW1pdChmcm9tLCB0byk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGxpbWl0XG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgYWRkVXNlciA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCB1c2VyOiBVc2VyVHlwZSk6IFByb21pc2U8VXNlclR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2FkZFVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2V9ID0gY29udGV4dDtcbiAgY29uc3Qge2VtYWlsLCBwYXNzd29yZCwgcGhvbmUsIHVzZXJuYW1lfSA9IHBhcnNlVXNlcih1c2VyKTtcbiAgY29uc3QgZm9ybWF0VXNlcm5hbWU6IHN0cmluZyA9IHBhcnNlVXNlcm5hbWUodXNlcm5hbWUpO1xuICBjb25zdCBmb3JtYXRFbWFpbDogc3RyaW5nID0gcGFyc2VFbWFpbChlbWFpbCk7XG4gIGNvbnN0IGZvcm1hdFBob25lOiBzdHJpbmcgPSBwYXJzZVBob25lKHBob25lKTtcbiAgY29uc3QgZm9ybWF0UGFzc3dvcmQ6IHN0cmluZyA9IHBhcnNlUGFzc3dvcmQocGFzc3dvcmQpO1xuICBjb25zdCBoYXNQYXNzd29yZCA9ICEhZm9ybWF0UGFzc3dvcmQ7XG4gIGNvbnN0IGhhc1VzZXJuYW1lID0gISFmb3JtYXRVc2VybmFtZSB8fCAhIWZvcm1hdFBob25lIHx8ICEhZm9ybWF0RW1haWw7XG5cbiAgaWYoIWhhc1Bhc3N3b3JkIHx8ICFoYXNVc2VybmFtZSkge1xuICAgIHJldHVybiBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTlZBTElEX0FSR1VNRU5UU1xuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgaGFzaElkID0gZm9ybWF0VXNlcm5hbWUgfHwgZm9ybWF0UGhvbmUgfHwgZm9ybWF0RW1haWw7XG4gIGNvbnN0IHNhbHQ6IHN0cmluZyA9IGNyZWF0ZUhhc2goYCR7aGFzaElkfSR7Zm9ybWF0UGFzc3dvcmR9YCwgbnVsbCk7XG4gIGNvbnN0IGVuY3J5cHRlZFBhc3N3b3JkID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuICBjb25zdCBmaWx0ZXJzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGlmKGZvcm1hdFVzZXJuYW1lKSB7XG4gICAgZmlsdGVycy5wdXNoKGB1LnVzZXJuYW1lID09IFwiJHtmb3JtYXRVc2VybmFtZX1cImApO1xuICB9XG5cbiAgaWYoZm9ybWF0RW1haWwpIHtcbiAgICBmaWx0ZXJzLnB1c2goYHUuZW1haWwgPT0gXCIke2Zvcm1hdEVtYWlsfVwiYCk7XG4gIH1cblxuICBpZihmb3JtYXRQaG9uZSkge1xuICAgIGZpbHRlcnMucHVzaChgdS5waG9uZSA9PSAke2Zvcm1hdFBob25lfWApO1xuICB9XG5cbiAgY29uc3QgY2hlY2tRdWVyeTogc3RyaW5nID0gYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSICR7ZmlsdGVycy5qb2luKCcgfHwgJyl9XG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIGNvbnN0IGV4aXN0aW5nVXNlcnMgPSBhd2FpdCBkYXRhYmFzZS5xdWVyeShjaGVja1F1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSk7XG5cbiAgICBpZihleGlzdGluZ1VzZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGxvZ0V4Y2VwdGlvbih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGVtYWlsOiBmb3JtYXRFbWFpbCxcbiAgICAgICAgICBwaG9uZTogZm9ybWF0UGhvbmUsXG4gICAgICAgICAgdXNlcm5hbWU6IGZvcm1hdFVzZXJuYW1lXG4gICAgICAgIH0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkVYSVNUSU5HX0lURU1cbiAgICAgIH0sIGNvbnRleHQpO1xuICAgIH1cbiAgfSBjYXRjaChlcnJvcikge1xuICAgIHJldHVybiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgdmVyaWZpZWRFbWFpbENvZGU6IG51bWJlciA9IE1hdGguZmxvb3IoMTAwMDAwICsgKE1hdGgucmFuZG9tKCkgKiA5MDAwMDApKTtcbiAgY29uc3QgdmVyaWZpZWRQaG9uZUNvZGU6IG51bWJlciA9IE1hdGguZmxvb3IoMTAwMDAwICsgKE1hdGgucmFuZG9tKCkgKiA5MDAwMDApKTtcblxuICBjb25zdCBpbnNlcnQ6IFVzZXJUeXBlID0ge1xuICAgIF9rZXk6IGNyZWF0ZUhhc2goZm9ybWF0VXNlcm5hbWUsIG51bGwpLFxuICAgIGFkZGVkOiBEYXRlLm5vdygpLFxuICAgIGVtYWlsOiBmb3JtYXRFbWFpbCxcbiAgICBtb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgICBwYXNzd29yZDogZW5jcnlwdGVkUGFzc3dvcmQsXG4gICAgcGhvbmU6IGZvcm1hdFBob25lLFxuICAgIHNhbHQsXG4gICAgdXNlckFjY2VzczogMSxcbiAgICB1c2VybmFtZTogZm9ybWF0VXNlcm5hbWUsXG4gICAgdmVyaWZpZWRFbWFpbDogZmFsc2UsXG4gICAgdmVyaWZpZWRFbWFpbENvZGUsXG4gICAgdmVyaWZpZWRQaG9uZTogZmFsc2UsXG4gICAgdmVyaWZpZWRQaG9uZUNvZGVcbiAgfTtcblxuICBjb25zdCBpbnNlcnRRdWVyeTogQXFsUXVlcnkgPSBhcWxgSU5TRVJUICR7aW5zZXJ0fSBJTiB1c2VycyBSRVRVUk4gTkVXYDtcblxuICByZXR1cm4gYXdhaXQgZGF0YWJhc2UucXVlcnkoaW5zZXJ0UXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbn07XG5cbmV4cG9ydCBjb25zdCB1cGRhdGVVc2VyID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIHVzZXI6IFVzZXJUeXBlKTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAndXBkYXRlVXNlcic7XG4gIGNvbnN0IHtkYXRhYmFzZSwgc2Vzc2lvbn0gPSBjb250ZXh0O1xuICBjb25zdCB7X2tleSwgX2lkLCBpZCwgdGFncyA9IFtdLCB1c2VySWQsIC4uLnVwZGF0ZWR9ID0gcGFyc2VVc2VyKHVzZXIpO1xuXG4gIGlmKCFpc0FkbWluVXNlcihzZXNzaW9uKSAmJiAoc2Vzc2lvbj8udXNlcklkICE9PSB1c2VySWQpKSB7XG4gICAgcmV0dXJuIGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3Nlc3Npb259LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9TRVNTSU9OXG4gICAgfSwgY29udGV4dCk7XG4gIH1cblxuICBjb25zdCB1c2VyUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYExFVCB1ID0gRE9DVU1FTlQoJHtpZH0pXG4gICAgVVBEQVRFIHUgV0lUSCAke3VwZGF0ZWR9IElOIHVzZXJzXG4gICAgUkVUVVJOIE5FV2A7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB1cGRhdGVkVXNlciA9IGF3YWl0IGRhdGFiYXNlLnF1ZXJ5KHVzZXJRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKTtcbiAgICBjb25zdCB0YWdDb2xsZWN0aW9uOiBFZGdlQ29sbGVjdGlvbiA9IGRhdGFiYXNlLmNvbGxlY3Rpb24oJ2lzVGFnZ2VkJyk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbCh0YWdzLm1hcCgoe2lkOiB0YWdEb2NJZCwgbmFtZX0pID0+IHtcbiAgICAgIGNvbnN0IHRhZ1F1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgaXQgSU4gaXNUYWdnZWRcbiAgICAgICAgRklMVEVSIGl0Ll9mcm9tID09ICR7dGFnRG9jSWR9ICYmIGl0Ll90byA9PSAke2lkfSAmJiBpdC5uYW1lID09ICR7bmFtZX1cbiAgICAgICAgTElNSVQgMVxuICAgICAgICBSRVRVUk4gaXRgO1xuXG4gICAgICByZXR1cm4gZGF0YWJhc2UucXVlcnkodGFnUXVlcnkpXG4gICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgICAgIC50aGVuKCh0YWdFZGdlKSA9PiB7XG4gICAgICAgICAgaWYoISF0YWdFZGdlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGFnRWRnZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlZGdlID0ge1xuICAgICAgICAgICAgX2Zyb206IHRhZ0RvY0lkLFxuICAgICAgICAgICAgX2tleTogY3JlYXRlSGFzaChgaXNUYWdnZWQtJHt0YWdEb2NJZH0tJHtpZH1gKSxcbiAgICAgICAgICAgIF90bzogaWQsXG4gICAgICAgICAgICBhZGRlZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG5hbWVcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmV0dXJuIHRhZ0NvbGxlY3Rpb24uc2F2ZShlZGdlLCB7cmV0dXJuTmV3OiB0cnVlfSkudGhlbigoKSA9PiBlZGdlKTtcbiAgICAgICAgfSk7XG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIHVwZGF0ZWRVc2VyO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgcmV0dXJuIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7dXNlcn0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGZvcmdvdFBhc3N3b3JkID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIHtlbWFpbCwgcGhvbmUsIHVzZXJuYW1lfSk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZm9yZ290UGFzc3dvcmQnO1xuICBjb25zdCB7YXBwLCBkYXRhYmFzZX0gPSBjb250ZXh0O1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS5lbWFpbCA9PSAke2VtYWlsfSB8fCB1LnBob25lID09ICR7cGhvbmV9IHx8IHUudXNlcm5hbWUgPT0gJHt1c2VybmFtZX1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIHVgO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgICAgLnRoZW4oYXN5bmMgKGN1cnNvcikgPT4ge1xuICAgICAgICBjb25zdCB1c2VyID0gY3Vyc29yLm5leHQoKTtcblxuICAgICAgICBpZih1c2VyKSB7XG4gICAgICAgICAgY29uc3Qge2VtYWlsLCBwaG9uZSwgdmVyaWZpZWRFbWFpbCwgdmVyaWZpZWRQaG9uZX0gPSB1c2VyIGFzIFVzZXJUeXBlO1xuICAgICAgICAgIGNvbnN0IGNvZGVFeHBpcmVzID0gMTAwMCAqIDYwICogMTU7IC8vIDE1IG1pbnV0ZXNcbiAgICAgICAgICBjb25zdCBjb2RlID0gTWF0aC5mbG9vcigxMDAwMDAgKyAoTWF0aC5yYW5kb20oKSAqIDkwMDAwMCkpO1xuICAgICAgICAgIGNvbnN0IHVzZXJEb2NJZCA9IGdldERvY0lkKCd1c2VycycsIHVzZXIpO1xuICAgICAgICAgIGxldCB1cGRhdGU7XG5cbiAgICAgICAgICBpZihlbWFpbCAmJiB2ZXJpZmllZEVtYWlsKSB7XG4gICAgICAgICAgICBzZW5kRW1haWwoe1xuICAgICAgICAgICAgICBhcHAsXG4gICAgICAgICAgICAgIHRleHQ6IGBZb3VyIGNvZGUgaXMgJHtjb2RlfWBcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdXBkYXRlID0ge3ZlcmlmaWVkRW1haWxDb2RlOiBjb2RlLCB2ZXJpZmllZEVtYWlsRXhwaXJlczogY29kZUV4cGlyZXN9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmKHBob25lICYmIHZlcmlmaWVkUGhvbmUpIHtcbiAgICAgICAgICAgIHNlbmRTbXMoe1xuICAgICAgICAgICAgICBhcHAsXG4gICAgICAgICAgICAgIHRleHQ6IGBZb3VyIGNvZGUgaXMgJHtjb2RlfWBcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdXBkYXRlID0ge3ZlcmlmaWVkUGhvbmVDb2RlOiBjb2RlLCB2ZXJpZmllZFBob25lRXhwaXJlczogY29kZUV4cGlyZXN9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmKHVwZGF0ZS52ZXJpZmllZEVtYWlsQ29kZSB8fCB1cGRhdGUudmVyaWZpZWRQaG9uZUNvZGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZVF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBVUERBVEUgJHt1c2VyRG9jSWR9IFdJVEggJHt1cGRhdGV9IElOIHVzZXJzYDtcblxuICAgICAgICAgICAgYXdhaXQgZGF0YWJhc2UucXVlcnkodXBkYXRlUXVlcnkpO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7ZW1haWwsIHBob25lLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlc2V0UGFzc3dvcmQgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtcbiAgICBjb2RlLFxuICAgIHBhc3N3b3JkLFxuICAgIHR5cGUsXG4gICAgdXNlcm5hbWVcbiAgfToge1xuICAgIGNvZGU6IG51bWJlcixcbiAgICBwYXNzd29yZDogc3RyaW5nLFxuICAgIHR5cGU6ICdwaG9uZScgfCAnZW1haWwnLFxuICAgIHVzZXJuYW1lOiBzdHJpbmdcbiAgfVxuKTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdyZXNldFBhc3N3b3JkJztcbiAgY29uc3Qge2RhdGFiYXNlfSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdFBhc3N3b3JkOiBzdHJpbmcgPSBwYXJzZVBhc3N3b3JkKHBhc3N3b3JkKTtcbiAgY29uc3QgYXFsUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSIHUudXNlcm5hbWUgPT0gJHt1c2VybmFtZX1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIHVgO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgICAgLnRoZW4oYXN5bmMgKGN1cnNvcikgPT4ge1xuICAgICAgICBjb25zdCB1c2VyID0gY3Vyc29yLm5leHQoKTtcblxuICAgICAgICBpZih1c2VyKSB7XG4gICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgX2lkOiB1c2VyRG9jSWQsXG4gICAgICAgICAgICBzYWx0LFxuICAgICAgICAgICAgdmVyaWZpZWRFbWFpbENvZGUsXG4gICAgICAgICAgICB2ZXJpZmllZEVtYWlsRXhwaXJlcyxcbiAgICAgICAgICAgIHZlcmlmaWVkUGhvbmVDb2RlLFxuICAgICAgICAgICAgdmVyaWZpZWRQaG9uZUV4cGlyZXNcbiAgICAgICAgICB9ID0gdXNlciBhcyBVc2VyVHlwZTtcbiAgICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIGxldCB1cGRhdGU7XG5cbiAgICAgICAgICBzd2l0Y2godHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnZW1haWwnOlxuICAgICAgICAgICAgICBpZihjb2RlID09PSB2ZXJpZmllZEVtYWlsQ29kZSAmJiB2ZXJpZmllZEVtYWlsRXhwaXJlcyA+IG5vdykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhc3N3b3JkOiBzdHJpbmcgPSBjcmVhdGVQYXNzd29yZChmb3JtYXRQYXNzd29yZCwgc2FsdCk7XG4gICAgICAgICAgICAgICAgdXBkYXRlID0ge3Bhc3N3b3JkfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3Bob25lJzpcbiAgICAgICAgICAgICAgaWYoY29kZSA9PT0gdmVyaWZpZWRQaG9uZUNvZGUgJiYgdmVyaWZpZWRQaG9uZUV4cGlyZXMgPiBub3cpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXNzd29yZDogc3RyaW5nID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuICAgICAgICAgICAgICAgIHVwZGF0ZSA9IHtwYXNzd29yZH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYodXBkYXRlKSB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVRdWVyeTogQXFsUXVlcnkgPSBhcWxgVVBEQVRFICR7dXNlckRvY0lkfSBXSVRIICR7dXBkYXRlfSBJTiB1c2Vyc2A7XG5cbiAgICAgICAgICAgIGF3YWl0IGRhdGFiYXNlLnF1ZXJ5KHVwZGF0ZVF1ZXJ5KTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY29uZmlybUNvZGUgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtcbiAgICBjb2RlLFxuICAgIHR5cGVcbiAgfToge1xuICAgIGNvZGU6IG51bWJlcixcbiAgICB0eXBlOiAncGhvbmUnIHwgJ2VtYWlsJ1xuICB9XG4pOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2NvbmZpcm1Db2RlJztcbiAgY29uc3Qge2RhdGFiYXNlLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHVzZXJEb2NJZCA9IGdldERvY0lkKCd1c2VycycsIHt1c2VySWQ6IHNlc3Npb25JZH0pO1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIHUgPSBET0NVTUVOVCgke3VzZXJEb2NJZH0pIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBkYXRhYmFzZS5xdWVyeShhcWxRdWVyeSlcbiAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgICAudGhlbigoe3ZlcmlmaWVkRW1haWxDb2RlLCB2ZXJpZmllZFBob25lQ29kZX06IFVzZXJUeXBlKSA9PiB7XG4gICAgICAgIHN3aXRjaCh0eXBlKSB7XG4gICAgICAgICAgY2FzZSAnZW1haWwnOlxuICAgICAgICAgICAgcmV0dXJuIGNvZGUgPT09IHZlcmlmaWVkRW1haWxDb2RlO1xuICAgICAgICAgIGNhc2UgJ3Bob25lJzpcbiAgICAgICAgICAgIHJldHVybiBjb2RlID09PSB2ZXJpZmllZFBob25lQ29kZTtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7Y29kZSwgdHlwZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZVVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlclR5cGUpOiBQcm9taXNlPFVzZXJUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdkZWxldGVVc2VyJztcbiAgY29uc3Qge2RhdGFiYXNlfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHt1c2VySWR9ID0gcGFyc2VVc2VyKHVzZXIpO1xuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiB1Ll9rZXkgPT0gJHt1c2VySWR9XG4gICAgTElNSVQgMVxuICAgIFJFTU9WRSB1IElOIHVzZXJzXG4gICAgUkVUVVJOIE9MRGA7XG5cbiAgY29uc3Qgc3RyaXBlQ2xpZW50ID0gbmV3IFN0cmlwZShDb25maWcuZ2V0KCdzdHJpcGUudG9rZW4nKSwge2FwaVZlcnNpb246IFNUUklQRV9BUElfVkVSU0lPTiwgdHlwZXNjcmlwdDogdHJ1ZX0pO1xuXG4gIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC50aGVuKChkZWxldGVkVXNlcikgPT4gc3RyaXBlQ2xpZW50LmN1c3RvbWVycy5kZWwoZGVsZXRlZFVzZXI/LnN0cmlwZUN1c3RvbWVySWQpXG4gICAgICAudGhlbigoKSA9PiBzdHJpcGVDbGllbnQuYWNjb3VudHMuZGVsKGRlbGV0ZWRVc2VyPy5zdHJpcGVBY2NvdW50SWQpKVxuICAgICAgLnRoZW4oKCkgPT4gZGVsZXRlZFVzZXIpKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJJZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLGNvbnRleHQpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBkZWFjdGl2YXRlVXNlciA9IChjb250ZXh0OiBBcGlDb250ZXh0LCB1c2VyOiBVc2VyVHlwZSk6IFByb21pc2U8VXNlclR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2RlbGV0ZSc7XG4gIGNvbnN0IHtkYXRhYmFzZX0gPSBjb250ZXh0O1xuICBjb25zdCB7dXNlcklkfSA9IHBhcnNlVXNlcih1c2VyKTtcbiAgY29uc3QgdXBkYXRlZDogVXNlclR5cGUgPSB7XG4gICAgdXNlckFjY2VzczogMFxuICB9O1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgVVBEQVRFICR7dXNlcklkfSBXSVRIICR7dXBkYXRlZH0gSU4gdXNlcnMgTElNSVQgMSBSRVRVUk4gTkVXYDtcblxuICByZXR1cm4gZGF0YWJhc2UucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VySWR9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvcixjb250ZXh0KSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RGlzcGxheU5hbWUgPSAodXNlcjogVXNlclR5cGUpOiBzdHJpbmcgPT4ge1xuICBjb25zdCB7Zmlyc3QsIGxhc3QsIG5hbWUgPSAnJywgdXNlcm5hbWUgPSAnJ30gPSB1c2VyO1xuICBjb25zdCBmdWxsbmFtZSA9IChbZmlyc3QsIGxhc3RdKS5qb2luKCcgJykudHJpbSgpO1xuXG4gIGlmKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfSBlbHNlIGlmKGZ1bGxuYW1lICE9PSAnJykge1xuICAgIHJldHVybiBmdWxsbmFtZTtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgcmV0dXJuIHVzZXJuYW1lO1xuICB9XG5cbiAgcmV0dXJuICdVbmtub3duJztcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRTZXNzaW9uVXNlciA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0U2Vzc2lvblVzZXInO1xuICBjb25zb2xlLmxvZygnZ2V0U2Vzc2lvblVzZXInLCB7YWN0aW9uLCBjb250ZXh0fSk7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWQsIHVzZXJuYW1lfX0gPSBjb250ZXh0O1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcbiAgY29uc3QgZm9ybWF0U2Vzc2lvbklkID0gcGFyc2VBcmFuZ29JZChgdXNlcnMvJHtzZXNzaW9uSWR9YCk7XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBMRVQgdSA9IERPQ1VNRU5UKFwiJHtmb3JtYXRTZXNzaW9uSWR9XCIpXG4gICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkgYXMgdW5rbm93biBhcyBVc2VyVHlwZSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlcm5hbWV9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVc2VyID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIHVzZXI6IFVzZXJUeXBlKTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0VXNlcic7XG4gIGNvbnN0IHtpZCwgdXNlcklkLCB1c2VybmFtZX0gPSBwYXJzZVVzZXIodXNlcik7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuICBsZXQgYXFsUXVlcnk6IHN0cmluZztcblxuICBjb25zb2xlLmxvZyh7aWQsIHVzZXJJZCwgdXNlcm5hbWV9KTtcbiAgaWYoaWQpIHtcbiAgICBhcWxRdWVyeSA9IGBMRVQgdSA9IERPQ1VNRU5UKFwiJHtpZH1cIilcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSIHUudXNlckFjY2VzcyA+IDBcbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgYXFsUXVlcnkgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS51c2VybmFtZSA9PSBcIiR7dXNlcm5hbWV9XCJcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG4gIH1cblxuICByZXR1cm4gZGF0YWJhc2UucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAudGhlbigodXNlcikgPT4gdXNlcilcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHtpZCwgdXNlcklkLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnMgPSAoY29udGV4dDogQXBpQ29udGV4dCwgb3B0aW9ucz86IFVzZXJPcHRpb25zKTogUHJvbWlzZTxVc2VyVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2VyTGlzdCc7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsaW1pdCwgdXNlcm5hbWV9ID0gcGFyc2VVc2VyT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFsndS51c2VyQWNjZXNzID4gMCddO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke3BhcnNlVXNlcm5hbWUodXNlcm5hbWUpfVwiKWApO1xuICB9XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiAke2ZpbHRlckJ5LmpvaW4oJyAmJiAnKX1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgJHtsaW1pdC5hcWx9XG4gICAgU09SVCB1LnVzZXJuYW1lXG4gICAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeVJlYWN0aW9ucyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAge3JlYWN0aW9ucyA9IFtdLCB1c2VybmFtZX0sXG4gIG9wdGlvbnM/OiBVc2VyT3B0aW9uc1xuKTogUHJvbWlzZTxVc2VyVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2Vyc0J5UmVhY3Rpb25zJztcbiAgY29uc3Qge2RhdGFiYXNlLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH19ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0UmVhY3Rpb25zOiBzdHJpbmdbXSA9ICByZWFjdGlvbnMubWFwKChyZWFjdGlvbk5hbWU6IHN0cmluZykgPT4gcGFyc2VDaGFyKHJlYWN0aW9uTmFtZSwgMzIpLnRvTG93ZXJDYXNlKCkpO1xuICBjb25zdCB7bGltaXR9ID0gcGFyc2VVc2VyT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGZvcm1hdFNlc3Npb25JZDogc3RyaW5nID0gYHVzZXJzLyR7c2Vzc2lvbklkfWA7XG4gIGNvbnN0IGZvcm1hdFVzZXJuYW1lOiBzdHJpbmcgPSBwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKTtcbiAgY29uc3QgZmlsdGVyQnk6IHN0cmluZ1tdID0gW1xuICAgICd1LnVzZXJBY2Nlc3MgPiAwJyxcbiAgICBgUE9TSVRJT04oJHtKU09OLnN0cmluZ2lmeShmb3JtYXRSZWFjdGlvbnMpfSwgTE9XRVIoci5uYW1lKSlgXG4gIF07XG5cbiAgaWYodXNlcm5hbWUpIHtcbiAgICBmaWx0ZXJCeS5wdXNoKGBDT05UQUlOUyh1LnVzZXJuYW1lLCBcIiR7Zm9ybWF0VXNlcm5hbWV9XCIpYCk7XG4gIH1cblxuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB1LCByIElOIE9VVEJPVU5EIFwiJHtmb3JtYXRTZXNzaW9uSWR9XCIgaGFzUmVhY3Rpb25cbiAgICBPUFRJT05TIHt2ZXJ0ZXhDb2xsZWN0aW9uczogXCJ1c2Vyc1wifVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBGSUxURVIgJHtmaWx0ZXJCeS5qb2luKCcgJiYgJyl9XG4gICAgJHtsaW1pdC5hcWx9XG4gICAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeVRhZ3MgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt0YWdzLCB1c2VybmFtZX0sXG4gIG9wdGlvbnM/OiBVc2VyT3B0aW9uc1xuKTogUHJvbWlzZTxVc2VyVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2Vyc0J5VGFncyc7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdFRhZ3M6IHN0cmluZ1tdID0gIHRhZ3M/LnJlZHVjZSgobGlzdDogc3RyaW5nW10sIHRhZ05hbWU6IHN0cmluZykgPT4ge1xuICAgIGlmKHRhZ05hbWUpIHtcbiAgICAgIGxpc3QucHVzaChwYXJzZUNoYXIodGFnTmFtZSwgMzIpLnRvTG93ZXJDYXNlKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBsaXN0O1xuICB9LCBbXSk7XG4gIGNvbnN0IHtsaW1pdH0gPSBwYXJzZVVzZXJPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcbiAgY29uc3QgZm9ybWF0VXNlcm5hbWU6IHN0cmluZyA9IHBhcnNlVXNlcm5hbWUodXNlcm5hbWUpO1xuICBjb25zdCBmaWx0ZXJCeTogc3RyaW5nW10gPSBbXG4gICAgYHUuX2tleSAhPSBcIiR7c2Vzc2lvbklkfVwiYCxcbiAgICAndS51c2VyQWNjZXNzID4gMCdcbiAgXTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlckJ5LnB1c2goYENPTlRBSU5TKHUudXNlcm5hbWUsIFwiJHtmb3JtYXRVc2VybmFtZX1cIilgKTtcbiAgfVxuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgRk9SIHQgSU4gdGFnc1xuICAgIEZJTFRFUiBQT1NJVElPTigke0pTT04uc3RyaW5naWZ5KGZvcm1hdFRhZ3MpfSwgTE9XRVIodC5uYW1lKSlcbiAgICBGT1IgdSwgaXQgSU4gT1VUQk9VTkQgdCBpc1RhZ2dlZFxuICAgIE9QVElPTlMge2JmczogdHJ1ZSwgdW5pcXVlVmVydGljZXM6IFwiZ2xvYmFsXCIsIHZlcnRleENvbGxlY3Rpb25zOiBcInVzZXJzXCJ9XG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIEZJTFRFUiAke2ZpbHRlckJ5LmpvaW4oJyAmJiAnKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBSRVRVUk4gRElTVElOQ1QgTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gZGF0YWJhc2UucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgVXNlclR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgVXNlclR5cGVbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVc2Vyc0J5TGF0ZXN0ID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIHt1c2VybmFtZX0sIG9wdGlvbnM/OiBVc2VyT3B0aW9ucyk6IFByb21pc2U8VXNlclR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0VXNlcnNCeUxhdGVzdCc7XG4gIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkfX0gPSBjb250ZXh0O1xuICBjb25zdCB7bGltaXR9ID0gcGFyc2VVc2VyT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3QgZmlsdGVyID0gW1xuICAgICd1Ll9pZCAhPSBzZXNzaW9uLl9pZCcsXG4gICAgJ3UudXNlckFjY2VzcyA+IDAnXG4gIF07XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyLnB1c2goYENPTlRBSU5TKHUudXNlcm5hbWUsIFwiJHtwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKX1cIilgKTtcbiAgfVxuXG4gIC8vIEdldCBkYXRhIGZyb20gZGF0YWJhc2VcbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIExFVCBzZXNzaW9uID0gRE9DVU1FTlQoXCJ1c2Vycy8ke3VzZXJJZH1cIilcbiAgICBGSUxURVIgJHtmaWx0ZXIuam9pbignICYmICcpfVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBMRVQgZGlzdGFuY2UgPSBESVNUQU5DRSh1LmxhdGl0dWRlIHx8IDAsIHUubG9uZ2l0dWRlIHx8IDAsIHNlc3Npb24ubGF0aXR1ZGUgfHwgMCwgc2Vzc2lvbi5sb25naXR1ZGUgfHwgMClcbiAgICAke2xpbWl0LmFxbH1cbiAgICBTT1JUIGRpc3RhbmNlIEFTQywgdS5hZGRlZCBERVNDXG4gICAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeUNvbm5lY3Rpb24gPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt1c2VySWR9OiBVc2VyVHlwZSxcbiAgb3B0aW9ucz86IFVzZXJPcHRpb25zXG4pOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlDb25uZWN0aW9uJztcbiAgY29uc3Qge2RhdGFiYXNlLCBmaWVsZHN9ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0LCB1c2VybmFtZX0gPSBwYXJzZVVzZXJPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcbiAgY29uc3QgZm9ybWF0VXNlcklkOiBzdHJpbmcgPSBwYXJzZUFyYW5nb0lkKGB1c2Vycy8ke3VzZXJJZH1gKTtcbiAgY29uc3QgZmlsdGVyQnk6IHN0cmluZ1tdID0gW1xuICAgICd1LnVzZXJBY2Nlc3MgPiAwJ1xuICBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke3BhcnNlVXNlcm5hbWUodXNlcm5hbWUpfVwiKWApO1xuICB9XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgY3UgSU4gdXNlcnNcbiAgICBMRVQgc2Vzc2lvbiA9IERPQ1VNRU5UKFwiJHtmb3JtYXRVc2VySWR9XCIpXG4gICAgRk9SIHUsIGNvbm5lY3Rpb24gSU4gT1VUQk9VTkQgY3UgaGFzQ29ubmVjdGlvblxuICAgIE9QVElPTlMge2JmczogdHJ1ZSwgdW5pcXVlVmVydGljZXM6IFwiZ2xvYmFsXCIsIHZlcnRleENvbGxlY3Rpb25zOiBcInVzZXJzXCJ9XG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIEZJTFRFUiAke2ZpbHRlckJ5LmpvaW4oJyAmJiAnKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBSRVRVUk4gRElTVElOQ1QgTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gZGF0YWJhc2UucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgVXNlclR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgVXNlclR5cGVbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWZyZXNoU2Vzc2lvbiA9ICh7ZXhwaXJlcywgdG9rZW59KTogU2Vzc2lvblRva2VuIHwgU2Vzc2lvbkVycm9yID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7dXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2Vzc30gPSBnZXRTZXNzaW9uKHRva2VuKTtcbiAgICByZXR1cm4gY3JlYXRlVG9rZW4odXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2VzcywgZXhwaXJlcyk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBlcnJvcjsgLy8gUmUtdGhyb3cgdGhlIGVycm9yIGZyb20gZ2V0U2Vzc2lvblxuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbkluID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIGFyZ3MpOiBQcm9taXNlPFNlc3Npb25Ub2tlbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnc2lnbkluJztcbiAgY29uc3Qge2RhdGFiYXNlfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtlbWFpbCwgZXhwaXJlcywgcGFzc3dvcmQsIHBob25lLCB1c2VybmFtZX0gPSBhcmdzO1xuICBjb25zdCBmb3JtYXRFbWFpbDogc3RyaW5nID0gcGFyc2VFbWFpbChlbWFpbCk7XG4gIGNvbnN0IGZvcm1hdFVzZXJuYW1lOiBzdHJpbmcgPSBwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKTtcbiAgY29uc3QgZm9ybWF0UGFzc3dvcmQ6IHN0cmluZyA9IHBhcnNlUGFzc3dvcmQocGFzc3dvcmQpO1xuICBjb25zdCBmb3JtYXRQaG9uZTogc3RyaW5nID0gcGFyc2VQaG9uZShwaG9uZSk7XG4gIGNvbnN0IGZvcm1hdEV4cGlyZXM6IG51bWJlciA9IHBhcnNlTnVtKGV4cGlyZXMpIHx8IDE1O1xuXG4gIGlmKCghZm9ybWF0VXNlcm5hbWUgJiYgIWZvcm1hdEVtYWlsICYmICFmb3JtYXRQaG9uZSkgfHwgIWZvcm1hdFBhc3N3b3JkKSB7XG4gICAgbG9nRXhjZXB0aW9uKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7dXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9BUkdVTUVOVFNcbiAgICB9LCBjb250ZXh0KTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGZpbHRlcnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYoZm9ybWF0RW1haWwpIHtcbiAgICBmaWx0ZXJzLnB1c2goYHUuZW1haWwgPT0gXCIke2Zvcm1hdEVtYWlsfVwiYCk7XG4gIH1cblxuICBpZihmb3JtYXRQaG9uZSkge1xuICAgIGZpbHRlcnMucHVzaChgdS5waG9uZSA9PSAke2Zvcm1hdFBob25lfWApO1xuICB9XG5cbiAgaWYoZm9ybWF0VXNlcm5hbWUpIHtcbiAgICBmaWx0ZXJzLnB1c2goYHUudXNlcm5hbWUgPT0gXCIke2Zvcm1hdFVzZXJuYW1lfVwiYCk7XG4gIH1cblxuICBjb25zdCBjaGVja1F1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgJHtmaWx0ZXJzLmpvaW4oJyB8fCAnKX1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIHVgO1xuXG4gIGxldCBjaGVja1VzZXI6IFVzZXJUeXBlO1xuXG4gIHRyeSB7XG4gICAgY2hlY2tVc2VyID0gYXdhaXQgZGF0YWJhc2UucXVlcnkoY2hlY2tRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7dXNlcm5hbWU6IGZvcm1hdFVzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZighY2hlY2tVc2VyKSB7XG4gICAgbG9nRXhjZXB0aW9uKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7dXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9BVVRIRU5USUNBVElPTlxuICAgIH0sIGNvbnRleHQpO1xuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCB7X2tleTogdXNlcklkLCBwYXNzd29yZDogdmFsaWRQYXNzd29yZCwgc2FsdCwgdXNlckFjY2Vzc30gPSBjaGVja1VzZXI7XG4gIGNvbnN0IGF1dGhQYXNzd29yZDogc3RyaW5nID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuXG4gIGlmKHZhbGlkUGFzc3dvcmQgIT09IGF1dGhQYXNzd29yZCkge1xuICAgIGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJBY2Nlc3MsIHVzZXJJZCwgdXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9BVVRIRU5USUNBVElPTlxuICAgIH0sIGNvbnRleHQpO1xuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnNvbGUubG9nKHtmb3JtYXRFeHBpcmVzLCB1c2VyQWNjZXNzLCB1c2VySWQsIHVzZXJuYW1lfSk7XG4gICAgY29uc3QgdG9rZW4gPSBjcmVhdGVUb2tlbih1c2VySWQsIHVzZXJuYW1lLCB1c2VyQWNjZXNzLCBmb3JtYXRFeHBpcmVzKTtcbiAgICBjb25zb2xlLmxvZyh7dG9rZW59KTtcblxuICAgIHJldHVybiB0b2tlbjtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHNpZ25PdXQgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnc2lnbk91dCc7XG4gIGNvbnN0IHtkYXRhYmFzZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkLCB1c2VybmFtZX19ID0gY29udGV4dDtcbiAgY29uc3QgdXNlckRvY0lkOiBzdHJpbmcgPSBgdXNlcnMvJHtzZXNzaW9uSWR9YDtcblxuICBjb25zdCB1cGRhdGUgPSB7XG4gICAgbGFzdE9ubGluZTogRGF0ZS5ub3coKSxcbiAgICBzZXNzaW9uSWQ6IG51bGxcbiAgfTtcbiAgY29uc3Qgc2Vzc2lvblF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBMRVQgdSA9IERPQ1VNRU5UKCR7dXNlckRvY0lkfSlcbiAgICBVUERBVEUgdSBXSVRIICR7dXBkYXRlfSBJTiB1c2Vyc1xuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gTkVXYDtcblxuICB0cnkge1xuICAgIGF3YWl0IGRhdGFiYXNlLnF1ZXJ5KHNlc3Npb25RdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGF3YWl0IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7dXNlcklkOiBzZXNzaW9uSWQsIHVzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0QWN0aXZlVXNlckNvdW50ID0gKGNvbnRleHQ6IEFwaUNvbnRleHQpOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0QWN0aXZlVXNlckNvdW50JztcbiAgY29uc3Qge2RhdGFiYXNlfSA9IGNvbnRleHQ7XG4gIGNvbnN0IGNvdW50UXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYExFVCBkb2NzID0gKFxuICAgIEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSIHUuYWN0aXZlID09IHRydWVcbiAgICBSRVRVUk4gdVxuICApXG4gIFJFVFVSTiBMRU5HVEgoZG9jcylgO1xuXG4gIHJldHVybiBkYXRhYmFzZS5xdWVyeShjb3VudFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlckJ5VG9rZW4gPSAoY29udGV4dDogQXBpQ29udGV4dCwgdG9rZW46IHN0cmluZyk6IFByb21pc2U8VXNlclR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJCeVRva2VuJztcbiAgY29uc3Qge2RhdGFiYXNlfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHt1c2VySWR9ID0gZ2V0U2Vzc2lvbih0b2tlbik7XG4gIGNvbnN0IHVzZXJEb2NJZCA9IGdldERvY0lkKCd1c2VycycsIHt1c2VySWR9KTtcbiAgY29uc3QgYXFsUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYExFVCB1ID0gRE9DVU1FTlQoXCIke3VzZXJEb2NJZH1cIikgUkVUVVJOIHVgO1xuXG4gIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJJZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250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
|