sonamu 0.9.3 → 0.9.5

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.
Files changed (99) hide show
  1. package/dist/ai/providers/rtzr/utils.js +2 -2
  2. package/dist/api/config.d.ts +0 -8
  3. package/dist/api/config.d.ts.map +1 -1
  4. package/dist/api/config.js +1 -1
  5. package/dist/api/sonamu.d.ts +0 -1
  6. package/dist/api/sonamu.d.ts.map +1 -1
  7. package/dist/api/sonamu.js +2 -41
  8. package/dist/auth/audit-log/builders.d.ts +216 -0
  9. package/dist/auth/audit-log/builders.d.ts.map +1 -0
  10. package/dist/auth/audit-log/builders.js +307 -0
  11. package/dist/auth/audit-log/events.d.ts +143 -0
  12. package/dist/auth/audit-log/events.d.ts.map +1 -0
  13. package/dist/auth/audit-log/events.js +74 -0
  14. package/dist/auth/audit-log/plugin.d.ts +11 -0
  15. package/dist/auth/audit-log/plugin.d.ts.map +1 -0
  16. package/dist/auth/audit-log/plugin.js +427 -0
  17. package/dist/auth/audit-log-ingestor.d.ts +3 -3
  18. package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
  19. package/dist/auth/audit-log-ingestor.js +44 -50
  20. package/dist/auth/index.d.ts +2 -0
  21. package/dist/auth/index.d.ts.map +1 -1
  22. package/dist/auth/index.js +4 -4
  23. package/dist/auth/plugins/entity-definitions/admin.d.ts +1 -1
  24. package/dist/auth/plugins/entity-definitions/admin.js +4 -4
  25. package/dist/auth/plugins/entity-definitions/audit-log.d.ts +2 -2
  26. package/dist/auth/plugins/entity-definitions/audit-log.js +3 -3
  27. package/dist/auth/plugins/wrappers/admin.d.ts +2 -2
  28. package/dist/auth/plugins/wrappers/sso.d.ts +1 -1
  29. package/dist/bin/fixture.d.ts.map +1 -1
  30. package/dist/bin/fixture.js +111 -1
  31. package/dist/database/_batch_update.d.ts +1 -1
  32. package/dist/database/_batch_update.js +2 -2
  33. package/dist/database/upsert-builder.js +4 -4
  34. package/dist/dict/sonamu-dictionary.js +2 -2
  35. package/dist/entity/entity-manager.d.ts +2 -2
  36. package/dist/entity/entity-manager.d.ts.map +1 -1
  37. package/dist/entity/entity-manager.js +14 -4
  38. package/dist/index.js +4 -3
  39. package/dist/migration/code-generation.d.ts.map +1 -1
  40. package/dist/migration/code-generation.js +2 -3
  41. package/dist/syncer/syncer.d.ts.map +1 -1
  42. package/dist/syncer/syncer.js +2 -9
  43. package/dist/template/implementations/entry-server.template.js +3 -2
  44. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  45. package/dist/template/implementations/generated.template.js +2 -1
  46. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  47. package/dist/template/implementations/generated_sso.template.js +2 -1
  48. package/dist/template/implementations/queries.template.d.ts.map +1 -1
  49. package/dist/template/implementations/queries.template.js +3 -1
  50. package/dist/template/implementations/sd.template.js +3 -2
  51. package/dist/template/implementations/services.template.d.ts.map +1 -1
  52. package/dist/template/implementations/services.template.js +44 -7
  53. package/dist/template/zod-converter.d.ts.map +1 -1
  54. package/dist/template/zod-converter.js +2 -2
  55. package/dist/testing/data-explorer.d.ts.map +1 -1
  56. package/dist/testing/data-explorer.js +5 -3
  57. package/dist/types/types.d.ts +14 -14
  58. package/dist/ui/api.d.ts.map +1 -1
  59. package/dist/ui/api.js +3 -2
  60. package/dist/ui-web/assets/index-D4rYm-Xz.css +1 -0
  61. package/dist/ui-web/assets/{index-DrTfl0Ts.js → index-DzZ7vBk4.js} +47 -47
  62. package/dist/ui-web/index.html +2 -2
  63. package/dist/utils/fs-utils.d.ts.map +1 -1
  64. package/dist/utils/fs-utils.js +4 -4
  65. package/package.json +4 -5
  66. package/src/ai/providers/rtzr/utils.ts +1 -1
  67. package/src/api/config.ts +0 -8
  68. package/src/api/sonamu.ts +1 -51
  69. package/src/auth/audit-log/builders.ts +791 -0
  70. package/src/auth/audit-log/events.ts +149 -0
  71. package/src/auth/audit-log/plugin.ts +913 -0
  72. package/src/auth/audit-log-ingestor.ts +3 -4
  73. package/src/auth/index.ts +2 -0
  74. package/src/auth/plugins/entity-definitions/admin.ts +3 -3
  75. package/src/auth/plugins/entity-definitions/audit-log.ts +2 -2
  76. package/src/bin/fixture.ts +143 -0
  77. package/src/database/_batch_update.ts +1 -1
  78. package/src/database/upsert-builder.ts +3 -3
  79. package/src/dict/sonamu-dictionary.ts +1 -1
  80. package/src/entity/entity-manager.ts +10 -3
  81. package/src/migration/code-generation.ts +1 -6
  82. package/src/shared/app.shared.ts.txt +60 -6
  83. package/src/shared/web.shared.ts.txt +60 -5
  84. package/src/syncer/syncer.ts +1 -11
  85. package/src/template/implementations/entry-server.template.ts +1 -1
  86. package/src/template/implementations/generated.template.ts +1 -0
  87. package/src/template/implementations/generated_sso.template.ts +1 -0
  88. package/src/template/implementations/queries.template.ts +10 -1
  89. package/src/template/implementations/sd.template.ts +1 -1
  90. package/src/template/implementations/services.template.ts +62 -6
  91. package/src/template/zod-converter.ts +2 -1
  92. package/src/testing/data-explorer.ts +3 -2
  93. package/src/ui/api.ts +10 -1
  94. package/src/utils/fs-utils.ts +6 -4
  95. package/dist/auth/audit-log-proxy-types.d.ts +0 -23
  96. package/dist/auth/audit-log-proxy-types.d.ts.map +0 -1
  97. package/dist/auth/audit-log-proxy-types.js +0 -1
  98. package/dist/ui-web/assets/index-Dr8pRJC_.css +0 -1
  99. package/src/auth/audit-log-proxy-types.ts +0 -23
@@ -0,0 +1,216 @@
1
+ import { type AccountSnapshot, type Builder, type BuilderLocation, type BuilderTrigger, type InvitationSnapshot, type MemberSnapshot, type OrganizationSnapshot, type SessionSnapshot, type TeamSnapshot, type UserProfileLite, type UserSnapshot, type VerificationSnapshot } from "./events";
2
+ export type AccountEventBuilders = {
3
+ trackAccountLinking: Builder<[
4
+ AccountSnapshot,
5
+ UserProfileLite,
6
+ BuilderTrigger,
7
+ BuilderLocation | undefined
8
+ ]>;
9
+ trackAccountUnlink: Builder<[
10
+ AccountSnapshot,
11
+ UserProfileLite,
12
+ BuilderTrigger,
13
+ BuilderLocation | undefined
14
+ ]>;
15
+ trackAccountPasswordChange: Builder<[
16
+ AccountSnapshot,
17
+ UserProfileLite,
18
+ BuilderTrigger,
19
+ BuilderLocation | undefined
20
+ ]>;
21
+ };
22
+ export type SessionEventBuilders = {
23
+ trackUserSignedIn: Builder<[
24
+ SessionSnapshot,
25
+ UserProfileLite,
26
+ BuilderTrigger,
27
+ BuilderLocation | undefined
28
+ ]>;
29
+ trackUserSignedOut: Builder<[
30
+ SessionSnapshot,
31
+ UserProfileLite,
32
+ BuilderTrigger,
33
+ BuilderLocation | undefined
34
+ ]>;
35
+ trackSessionCreated: Builder<[
36
+ SessionSnapshot,
37
+ UserProfileLite,
38
+ BuilderTrigger,
39
+ BuilderLocation | undefined
40
+ ]>;
41
+ trackSessionRevoked: Builder<[
42
+ SessionSnapshot,
43
+ UserProfileLite,
44
+ BuilderTrigger,
45
+ BuilderLocation | undefined
46
+ ]>;
47
+ trackSessionRevokedAll: Builder<[SessionSnapshot, UserProfileLite, BuilderTrigger]>;
48
+ trackUserImpersonated: Builder<[
49
+ SessionSnapshot,
50
+ UserProfileLite,
51
+ UserProfileLite,
52
+ BuilderTrigger,
53
+ BuilderLocation | undefined
54
+ ]>;
55
+ trackUserImpersonationStop: Builder<[
56
+ SessionSnapshot,
57
+ UserProfileLite,
58
+ UserProfileLite,
59
+ BuilderTrigger,
60
+ BuilderLocation | undefined
61
+ ]>;
62
+ trackEmailVerificationSent: Builder<[
63
+ SessionSnapshot,
64
+ {
65
+ name?: string;
66
+ email?: string;
67
+ },
68
+ BuilderTrigger
69
+ ]>;
70
+ trackEmailSignInAttempt: Builder<[
71
+ {
72
+ email: string;
73
+ loginMethod: string | null;
74
+ },
75
+ UserProfileLite,
76
+ BuilderTrigger,
77
+ BuilderLocation | undefined
78
+ ]>;
79
+ trackSocialSignInAttempt: Builder<[
80
+ {
81
+ loginMethod: string | null;
82
+ },
83
+ UserProfileLite,
84
+ BuilderTrigger,
85
+ BuilderLocation | undefined
86
+ ]>;
87
+ trackSocialSignInRedirectionAttempt: Builder<[
88
+ {
89
+ loginMethod: string | null;
90
+ },
91
+ UserProfileLite,
92
+ BuilderTrigger,
93
+ BuilderLocation | undefined
94
+ ]>;
95
+ };
96
+ export type UserEventBuilders = {
97
+ trackUserSignedUp: Builder<[UserSnapshot, BuilderTrigger, BuilderLocation | undefined]>;
98
+ trackUserDeleted: Builder<[UserSnapshot, BuilderTrigger, BuilderLocation | undefined]>;
99
+ trackUserProfileUpdated: Builder<[
100
+ UserSnapshot,
101
+ string[],
102
+ BuilderTrigger,
103
+ BuilderLocation | undefined
104
+ ]>;
105
+ trackUserProfileImageUpdated: Builder<[
106
+ UserSnapshot,
107
+ BuilderTrigger,
108
+ BuilderLocation | undefined
109
+ ]>;
110
+ trackUserBanned: Builder<[UserSnapshot, BuilderTrigger, BuilderLocation | undefined]>;
111
+ trackUserUnBanned: Builder<[UserSnapshot, BuilderTrigger, BuilderLocation | undefined]>;
112
+ trackUserEmailVerified: Builder<[UserSnapshot, BuilderTrigger, BuilderLocation | undefined]>;
113
+ };
114
+ export type VerificationEventBuilders = {
115
+ trackPasswordResetRequest: Builder<[
116
+ VerificationSnapshot,
117
+ UserProfileLite,
118
+ BuilderTrigger,
119
+ BuilderLocation | undefined
120
+ ]>;
121
+ trackPasswordResetRequestCompletion: Builder<[
122
+ VerificationSnapshot,
123
+ UserProfileLite,
124
+ BuilderTrigger,
125
+ BuilderLocation | undefined
126
+ ]>;
127
+ };
128
+ export type OrganizationEventBuilders = {
129
+ trackOrganizationCreated: Builder<[OrganizationSnapshot, BuilderTrigger]>;
130
+ trackOrganizationUpdated: Builder<[OrganizationSnapshot, BuilderTrigger]>;
131
+ };
132
+ export type TeamEventBuilders = {
133
+ trackOrganizationTeamCreated: Builder<[OrganizationSnapshot, TeamSnapshot, BuilderTrigger]>;
134
+ trackOrganizationTeamUpdated: Builder<[OrganizationSnapshot, TeamSnapshot, BuilderTrigger]>;
135
+ trackOrganizationTeamDeleted: Builder<[OrganizationSnapshot, TeamSnapshot, BuilderTrigger]>;
136
+ trackOrganizationTeamMemberAdded: Builder<[
137
+ OrganizationSnapshot,
138
+ TeamSnapshot,
139
+ UserSnapshot,
140
+ {
141
+ teamId: string;
142
+ userId: string;
143
+ },
144
+ BuilderTrigger
145
+ ]>;
146
+ trackOrganizationTeamMemberRemoved: Builder<[
147
+ OrganizationSnapshot,
148
+ TeamSnapshot,
149
+ UserSnapshot,
150
+ {
151
+ teamId: string;
152
+ userId: string;
153
+ },
154
+ BuilderTrigger
155
+ ]>;
156
+ };
157
+ export type MemberEventBuilders = {
158
+ trackOrganizationMemberAdded: Builder<[
159
+ OrganizationSnapshot,
160
+ MemberSnapshot,
161
+ UserSnapshot,
162
+ BuilderTrigger
163
+ ]>;
164
+ trackOrganizationMemberRemoved: Builder<[
165
+ OrganizationSnapshot,
166
+ MemberSnapshot,
167
+ UserSnapshot,
168
+ BuilderTrigger
169
+ ]>;
170
+ trackOrganizationMemberRoleUpdated: Builder<[
171
+ OrganizationSnapshot,
172
+ MemberSnapshot,
173
+ UserSnapshot,
174
+ string,
175
+ BuilderTrigger
176
+ ]>;
177
+ };
178
+ export type InvitationEventBuilders = {
179
+ trackOrganizationMemberInvited: Builder<[
180
+ OrganizationSnapshot,
181
+ InvitationSnapshot,
182
+ UserSnapshot,
183
+ BuilderTrigger
184
+ ]>;
185
+ trackOrganizationMemberInviteAccepted: Builder<[
186
+ OrganizationSnapshot,
187
+ InvitationSnapshot,
188
+ MemberSnapshot,
189
+ UserSnapshot,
190
+ BuilderTrigger
191
+ ]>;
192
+ trackOrganizationMemberInviteRejected: Builder<[
193
+ OrganizationSnapshot,
194
+ InvitationSnapshot,
195
+ UserSnapshot,
196
+ BuilderTrigger
197
+ ]>;
198
+ trackOrganizationMemberInviteCanceled: Builder<[
199
+ OrganizationSnapshot,
200
+ InvitationSnapshot,
201
+ UserSnapshot,
202
+ BuilderTrigger
203
+ ]>;
204
+ };
205
+ export type AuditEventBuilderCatalog = {
206
+ account: AccountEventBuilders;
207
+ session: SessionEventBuilders;
208
+ user: UserEventBuilders;
209
+ verification: VerificationEventBuilders;
210
+ organization: OrganizationEventBuilders;
211
+ team: TeamEventBuilders;
212
+ member: MemberEventBuilders;
213
+ invitation: InvitationEventBuilders;
214
+ };
215
+ export declare const buildAuditEventCatalog: () => AuditEventBuilderCatalog;
216
+ //# sourceMappingURL=builders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../../src/auth/audit-log/builders.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,307 @@
1
+ import { EVENT_TYPES, ORGANIZATION_EVENT_TYPES } from "./events.js";
2
+
3
+ //#region src/auth/audit-log/builders.ts
4
+ const createEvent = (base, data, trigger, location) => ({
5
+ ...base,
6
+ eventData: {
7
+ ...data,
8
+ triggeredBy: trigger.triggeredBy,
9
+ triggerContext: trigger.triggerContext
10
+ },
11
+ ipAddress: location?.ipAddress,
12
+ city: location?.city,
13
+ country: location?.country,
14
+ countryCode: location?.countryCode
15
+ });
16
+ const buildAccountEvent = (eventType, eventDisplayName, account, user, trigger, location) => createEvent({
17
+ eventKey: account.userId,
18
+ eventType,
19
+ eventDisplayName
20
+ }, {
21
+ userId: account.userId,
22
+ userEmail: user?.email ?? "unknown",
23
+ userName: user?.name ?? "unknown",
24
+ accountId: account.id,
25
+ providerId: account.providerId
26
+ }, trigger, location);
27
+ const buildAccountEvents = () => ({
28
+ trackAccountLinking: (account, user, trigger, location) => buildAccountEvent(EVENT_TYPES.ACCOUNT_LINKED, `Linked ${account.providerId} account`, account, user, trigger, location),
29
+ trackAccountUnlink: (account, user, trigger, location) => buildAccountEvent(EVENT_TYPES.ACCOUNT_UNLINKED, `Unlinked ${account.providerId} account`, account, user, trigger, location),
30
+ trackAccountPasswordChange: (account, user, trigger, location) => buildAccountEvent(EVENT_TYPES.PASSWORD_CHANGED, "Password changed", account, user, trigger, location)
31
+ });
32
+ const sessionLifecycleData = (session, user) => ({
33
+ userId: session.userId,
34
+ userName: user?.name ?? "unknown",
35
+ userEmail: user?.email ?? "unknown",
36
+ sessionId: session.id,
37
+ loginMethod: session.loginMethod ?? "unknown",
38
+ userAgent: session.userAgent
39
+ });
40
+ const buildSessionLifecycleEvent = (eventType, eventDisplayName, session, user, trigger, location) => createEvent({
41
+ eventKey: session.userId,
42
+ eventType,
43
+ eventDisplayName
44
+ }, sessionLifecycleData(session, user), trigger, location);
45
+ const buildImpersonationEvent = (eventType, eventDisplayName, session, user, impersonator, trigger, location) => createEvent({
46
+ eventKey: session.userId,
47
+ eventType,
48
+ eventDisplayName
49
+ }, {
50
+ ...sessionLifecycleData(session, user),
51
+ impersonatedBy: impersonator?.name ?? impersonator?.email ?? session.impersonatedBy,
52
+ impersonatedById: session.impersonatedBy
53
+ }, trigger, location);
54
+ const SIGN_IN_FAILED_DISPLAY = "User sign-in attempt failed";
55
+ const buildSessionEvents = () => ({
56
+ trackUserSignedIn: (session, user, trigger, location) => buildSessionLifecycleEvent(EVENT_TYPES.USER_SIGNED_IN, `Signed in via ${session.loginMethod ?? "unknown"}`, session, user, trigger, location),
57
+ trackUserSignedOut: (session, user, trigger, location) => buildSessionLifecycleEvent(EVENT_TYPES.USER_SIGNED_OUT, "User signed out", session, user, trigger, location),
58
+ trackSessionCreated: (session, user, trigger, location) => buildSessionLifecycleEvent(EVENT_TYPES.SESSION_CREATED, "Session created", session, user, trigger, location),
59
+ trackSessionRevoked: (session, user, trigger, location) => buildSessionLifecycleEvent(EVENT_TYPES.SESSION_REVOKED, "Session revoked", session, user, trigger, location),
60
+ trackSessionRevokedAll: (session, user, trigger) => createEvent({
61
+ eventKey: session.userId,
62
+ eventType: EVENT_TYPES.ALL_SESSIONS_REVOKED,
63
+ eventDisplayName: "All sessions revoked"
64
+ }, {
65
+ userId: session.userId,
66
+ userName: user?.name ?? "unknown",
67
+ userEmail: user?.email ?? "unknown"
68
+ }, trigger),
69
+ trackUserImpersonated: (session, user, impersonator, trigger, location) => buildImpersonationEvent(EVENT_TYPES.USER_IMPERSONATED, "User impersonated", session, user, impersonator, trigger, location),
70
+ trackUserImpersonationStop: (session, user, impersonator, trigger, location) => buildImpersonationEvent(EVENT_TYPES.USER_IMPERSONATED_STOPPED, "User impersonation stopped", session, user, impersonator, trigger, location),
71
+ trackEmailVerificationSent: (session, user, trigger) => createEvent({
72
+ eventKey: session.userId,
73
+ eventType: EVENT_TYPES.EMAIL_VERIFICATION_SENT,
74
+ eventDisplayName: "Verification email sent"
75
+ }, {
76
+ userId: session.userId,
77
+ userName: user.name,
78
+ userEmail: user.email,
79
+ sessionId: session.id
80
+ }, trigger),
81
+ trackEmailSignInAttempt: (attempt, user, trigger, location) => createEvent({
82
+ eventKey: user?.id ?? "unknown",
83
+ eventType: EVENT_TYPES.USER_SIGN_IN_FAILED,
84
+ eventDisplayName: SIGN_IN_FAILED_DISPLAY
85
+ }, {
86
+ userId: user?.id ?? "unknown",
87
+ nameName: user?.name ?? "unknown",
88
+ userEmail: attempt.email,
89
+ loginMethod: attempt.loginMethod
90
+ }, {
91
+ triggeredBy: user?.id ?? trigger.triggeredBy,
92
+ triggerContext: trigger.triggerContext
93
+ }, location),
94
+ trackSocialSignInAttempt: (attempt, user, trigger, location) => createEvent({
95
+ eventKey: user?.id ?? "unknown",
96
+ eventType: EVENT_TYPES.USER_SIGN_IN_FAILED,
97
+ eventDisplayName: SIGN_IN_FAILED_DISPLAY
98
+ }, {
99
+ userId: user?.id ?? "unknown",
100
+ userName: user?.name ?? "unknown",
101
+ userEmail: user?.email ?? "unknown",
102
+ loginMethod: attempt.loginMethod
103
+ }, {
104
+ triggeredBy: user?.id ?? trigger.triggeredBy,
105
+ triggerContext: trigger.triggerContext
106
+ }, location),
107
+ trackSocialSignInRedirectionAttempt: (attempt, user, trigger, location) => createEvent({
108
+ eventKey: user?.id ?? "unknown",
109
+ eventType: EVENT_TYPES.USER_SIGN_IN_FAILED,
110
+ eventDisplayName: SIGN_IN_FAILED_DISPLAY
111
+ }, {
112
+ userId: user?.id ?? "unknown",
113
+ userName: user?.name ?? "unknown",
114
+ userEmail: user?.id ?? "unknown",
115
+ loginMethod: attempt.loginMethod
116
+ }, trigger, location)
117
+ });
118
+ const userIdentityData = (user) => ({
119
+ userId: user.id,
120
+ userEmail: user.email,
121
+ userName: user.name
122
+ });
123
+ const buildUserEvent = (eventType, eventDisplayName, user, trigger, location, extra) => createEvent({
124
+ eventKey: user.id,
125
+ eventType,
126
+ eventDisplayName
127
+ }, {
128
+ ...userIdentityData(user),
129
+ ...extra
130
+ }, trigger, location);
131
+ const buildUserEvents = () => ({
132
+ trackUserSignedUp: (user, trigger, location) => buildUserEvent(EVENT_TYPES.USER_CREATED, `${user.name || user.email} signed up`, user, trigger, location),
133
+ trackUserDeleted: (user, trigger, location) => buildUserEvent(EVENT_TYPES.USER_DELETED, "User deleted", user, trigger, location),
134
+ trackUserProfileUpdated: (user, updatedFields, trigger, location) => buildUserEvent(EVENT_TYPES.PROFILE_UPDATED, "Profile updated", user, trigger, location, { updatedFields }),
135
+ trackUserProfileImageUpdated: (user, trigger, location) => buildUserEvent(EVENT_TYPES.PROFILE_IMAGE_UPDATED, "Profile image updated", user, trigger, location),
136
+ trackUserBanned: (user, trigger, location) => {
137
+ const reasonSuffix = user.banReason ? `: ${user.banReason}` : "";
138
+ const expiresSuffix = user.banExpires ? ` (until ${user.banExpires.toISOString()})` : "";
139
+ return buildUserEvent(EVENT_TYPES.USER_BANNED, `User banned${reasonSuffix}${expiresSuffix}`, user, trigger, location, {
140
+ banned: user.banned,
141
+ banReason: user.banReason,
142
+ banExpires: user.banExpires
143
+ });
144
+ },
145
+ trackUserUnBanned: (user, trigger, location) => buildUserEvent(EVENT_TYPES.USER_UNBANNED, "User unbanned", user, trigger, location, { banned: user.banned }),
146
+ trackUserEmailVerified: (user, trigger, location) => buildUserEvent(EVENT_TYPES.EMAIL_VERIFIED, "Email verified", user, trigger, location)
147
+ });
148
+ const buildVerificationEvent = (eventType, eventDisplayName, verification, user, trigger, location) => createEvent({
149
+ eventKey: verification.value,
150
+ eventType,
151
+ eventDisplayName
152
+ }, {
153
+ userId: verification.value,
154
+ userName: user?.name ?? "unknown",
155
+ userEmail: user?.email ?? "unknown"
156
+ }, trigger, location);
157
+ const buildVerificationEvents = () => ({
158
+ trackPasswordResetRequest: (verification, user, trigger, location) => buildVerificationEvent(EVENT_TYPES.PASSWORD_RESET_REQUESTED, "Password reset requested", verification, user, trigger, location),
159
+ trackPasswordResetRequestCompletion: (verification, user, trigger, location) => buildVerificationEvent(EVENT_TYPES.PASSWORD_RESET_COMPLETED, "Password reset completed", verification, user, trigger, location)
160
+ });
161
+ const organizationIdentityData = (organization) => ({
162
+ organizationId: organization.id,
163
+ organizationSlug: organization.slug,
164
+ organizationName: organization.name
165
+ });
166
+ const buildOrganizationEvent = (eventType, eventDisplayName, organization, trigger) => createEvent({
167
+ eventKey: organization.id,
168
+ eventType,
169
+ eventDisplayName
170
+ }, organizationIdentityData(organization), trigger);
171
+ const buildOrganizationEvents = () => ({
172
+ trackOrganizationCreated: (organization, trigger) => buildOrganizationEvent(ORGANIZATION_EVENT_TYPES.ORGANIZATION_CREATED, "Organization Created", organization, trigger),
173
+ trackOrganizationUpdated: (organization, trigger) => buildOrganizationEvent(ORGANIZATION_EVENT_TYPES.ORGANIZATION_UPDATED, "Organization Updated", organization, trigger)
174
+ });
175
+ const buildTeamLifecycleEvent = (eventType, eventDisplayName, organization, team, trigger) => createEvent({
176
+ eventKey: organization.id,
177
+ eventType,
178
+ eventDisplayName
179
+ }, {
180
+ ...organizationIdentityData(organization),
181
+ teamId: team.id,
182
+ teamName: team.name
183
+ }, trigger);
184
+ const buildTeamMemberEvent = (eventType, eventDisplayName, organization, team, user, teamMember, trigger) => createEvent({
185
+ eventKey: organization.id,
186
+ eventType,
187
+ eventDisplayName
188
+ }, {
189
+ ...organizationIdentityData(organization),
190
+ teamId: teamMember.teamId,
191
+ teamName: team.name,
192
+ userid: teamMember.userId,
193
+ memberName: user.name
194
+ }, trigger);
195
+ const buildTeamEvents = () => ({
196
+ trackOrganizationTeamCreated: (organization, team, trigger) => buildTeamLifecycleEvent(ORGANIZATION_EVENT_TYPES.ORGANIZATION_TEAM_CREATED, "Organization team created", organization, team, trigger),
197
+ trackOrganizationTeamUpdated: (organization, team, trigger) => buildTeamLifecycleEvent(ORGANIZATION_EVENT_TYPES.ORGANIZATION_TEAM_UPDATED, "Organization team updated", organization, team, trigger),
198
+ trackOrganizationTeamDeleted: (organization, team, trigger) => buildTeamLifecycleEvent(ORGANIZATION_EVENT_TYPES.ORGANIZATION_TEAM_DELETED, "Organization team deleted", organization, team, trigger),
199
+ trackOrganizationTeamMemberAdded: (organization, team, user, teamMember, trigger) => buildTeamMemberEvent(ORGANIZATION_EVENT_TYPES.ORGANIZATION_TEAM_MEMBER_ADDED, "User added to organization team", organization, team, user, teamMember, trigger),
200
+ trackOrganizationTeamMemberRemoved: (organization, team, user, teamMember, trigger) => buildTeamMemberEvent(ORGANIZATION_EVENT_TYPES.ORGANIZATION_TEAM_MEMBER_REMOVED, "User removed from organization team", organization, team, user, teamMember, trigger)
201
+ });
202
+ const memberCoreData = (member, user) => ({
203
+ userId: member.userId,
204
+ memberName: user.name,
205
+ role: member.role,
206
+ memberId: member.id,
207
+ memberEmail: user.email
208
+ });
209
+ const buildMemberEvents = () => ({
210
+ trackOrganizationMemberAdded: (organization, member, user, trigger) => createEvent({
211
+ eventKey: organization.id,
212
+ eventType: ORGANIZATION_EVENT_TYPES.ORGANIZATION_MEMBER_ADDED,
213
+ eventDisplayName: "Member added to organization"
214
+ }, {
215
+ ...organizationIdentityData(organization),
216
+ ...memberCoreData(member, user)
217
+ }, trigger),
218
+ trackOrganizationMemberRemoved: (organization, member, user, trigger) => createEvent({
219
+ eventKey: organization.id,
220
+ eventType: ORGANIZATION_EVENT_TYPES.ORGANIZATION_MEMBER_REMOVED,
221
+ eventDisplayName: "Member removed from organization"
222
+ }, {
223
+ ...organizationIdentityData(organization),
224
+ ...memberCoreData(member, user)
225
+ }, trigger),
226
+ trackOrganizationMemberRoleUpdated: (organization, member, user, previousRole, trigger) => createEvent({
227
+ eventKey: organization.id,
228
+ eventType: ORGANIZATION_EVENT_TYPES.ORGANIZATION_MEMBER_ROLE_UPDATED,
229
+ eventDisplayName: "Organization member role updated"
230
+ }, {
231
+ ...organizationIdentityData(organization),
232
+ userId: member.userId,
233
+ memberName: user.name,
234
+ newRole: member.role,
235
+ oldRole: previousRole,
236
+ memberId: member.id,
237
+ memberEmail: user.email
238
+ }, trigger)
239
+ });
240
+ const inviteeData = (invitation) => ({
241
+ inviteeId: invitation.id,
242
+ inviteeEmail: invitation.email,
243
+ inviteeRole: invitation.role,
244
+ inviteeTeamId: invitation.teamId
245
+ });
246
+ const buildInvitationEvents = () => ({
247
+ trackOrganizationMemberInvited: (organization, invitation, inviter, trigger) => createEvent({
248
+ eventKey: organization.id,
249
+ eventType: ORGANIZATION_EVENT_TYPES.ORGANIZATION_MEMBER_INVITED,
250
+ eventDisplayName: "User invited to organization"
251
+ }, {
252
+ ...organizationIdentityData(organization),
253
+ ...inviteeData(invitation),
254
+ inviterId: inviter.id,
255
+ inviterName: inviter.name,
256
+ inviterEmail: inviter.email
257
+ }, trigger),
258
+ trackOrganizationMemberInviteAccepted: (organization, invitation, member, acceptedBy, trigger) => createEvent({
259
+ eventKey: organization.id,
260
+ eventType: ORGANIZATION_EVENT_TYPES.ORGANIZATION_MEMBER_INVITE_ACCEPTED,
261
+ eventDisplayName: "User accepted invite organization invite"
262
+ }, {
263
+ ...organizationIdentityData(organization),
264
+ ...inviteeData(invitation),
265
+ acceptedById: acceptedBy.id,
266
+ acceptedByEmail: acceptedBy.email,
267
+ acceptedByName: acceptedBy.name,
268
+ memberId: member.id,
269
+ memberRole: member.role
270
+ }, trigger),
271
+ trackOrganizationMemberInviteRejected: (organization, invitation, rejectedBy, trigger) => createEvent({
272
+ eventKey: organization.id,
273
+ eventType: ORGANIZATION_EVENT_TYPES.ORGANIZATION_MEMBER_INVITE_REJECTED,
274
+ eventDisplayName: "User rejected organization invite"
275
+ }, {
276
+ ...organizationIdentityData(organization),
277
+ ...inviteeData(invitation),
278
+ rejectedById: rejectedBy.id,
279
+ rejectedByEmail: rejectedBy.email,
280
+ rejectedByName: rejectedBy.name
281
+ }, trigger),
282
+ trackOrganizationMemberInviteCanceled: (organization, invitation, cancelledBy, trigger) => createEvent({
283
+ eventKey: organization.id,
284
+ eventType: ORGANIZATION_EVENT_TYPES.ORGANIZATION_MEMBER_INVITE_CANCELED,
285
+ eventDisplayName: "Organization invite cancelled"
286
+ }, {
287
+ ...organizationIdentityData(organization),
288
+ ...inviteeData(invitation),
289
+ cancelledById: cancelledBy.id,
290
+ cancelledByName: cancelledBy.name,
291
+ cancelledByEmail: cancelledBy.email
292
+ }, trigger)
293
+ });
294
+ const buildAuditEventCatalog = () => ({
295
+ account: buildAccountEvents(),
296
+ session: buildSessionEvents(),
297
+ user: buildUserEvents(),
298
+ verification: buildVerificationEvents(),
299
+ organization: buildOrganizationEvents(),
300
+ team: buildTeamEvents(),
301
+ member: buildMemberEvents(),
302
+ invitation: buildInvitationEvents()
303
+ });
304
+
305
+ //#endregion
306
+ export { buildAuditEventCatalog };
307
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlcnMuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2F1dGgvYXVkaXQtbG9nL2J1aWxkZXJzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIHR5cGUgQWNjb3VudFNuYXBzaG90LFxuICB0eXBlIEF1ZGl0TG9nRXZlbnQsXG4gIHR5cGUgQnVpbGRlcixcbiAgdHlwZSBCdWlsZGVyTG9jYXRpb24sXG4gIHR5cGUgQnVpbGRlclRyaWdnZXIsXG4gIEVWRU5UX1RZUEVTLFxuICB0eXBlIEludml0YXRpb25TbmFwc2hvdCxcbiAgdHlwZSBNZW1iZXJTbmFwc2hvdCxcbiAgT1JHQU5JWkFUSU9OX0VWRU5UX1RZUEVTLFxuICB0eXBlIE9yZ2FuaXphdGlvblNuYXBzaG90LFxuICB0eXBlIFNlc3Npb25TbmFwc2hvdCxcbiAgdHlwZSBUZWFtU25hcHNob3QsXG4gIHR5cGUgVXNlclByb2ZpbGVMaXRlLFxuICB0eXBlIFVzZXJTbmFwc2hvdCxcbiAgdHlwZSBWZXJpZmljYXRpb25TbmFwc2hvdCxcbn0gZnJvbSBcIi4vZXZlbnRzXCI7XG5cbi8vIOuqqOuToCDruYzrjZQg6rO17Ya1IO2VhOuTnCh0cmlnZ2VyZWRCeS90cmlnZ2VyQ29udGV4dCwgaXBBZGRyZXNzL2NpdHkvY291bnRyeS9jb3VudHJ5Q29kZSnrpbwg7ZWp7ISx7ZWc64ukLlxuY29uc3QgY3JlYXRlRXZlbnQgPSAoXG4gIGJhc2U6IHsgZXZlbnRLZXk6IHN0cmluZzsgZXZlbnRUeXBlOiBzdHJpbmc7IGV2ZW50RGlzcGxheU5hbWU/OiBzdHJpbmcgfSxcbiAgZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHRyaWdnZXI6IEJ1aWxkZXJUcmlnZ2VyLFxuICBsb2NhdGlvbj86IEJ1aWxkZXJMb2NhdGlvbixcbik6IEF1ZGl0TG9nRXZlbnQgPT4gKHtcbiAgLi4uYmFzZSxcbiAgZXZlbnREYXRhOiB7XG4gICAgLi4uZGF0YSxcbiAgICB0cmlnZ2VyZWRCeTogdHJpZ2dlci50cmlnZ2VyZWRCeSxcbiAgICB0cmlnZ2VyQ29udGV4dDogdHJpZ2dlci50cmlnZ2VyQ29udGV4dCxcbiAgfSxcbiAgaXBBZGRyZXNzOiBsb2NhdGlvbj8uaXBBZGRyZXNzLFxuICBjaXR5OiBsb2NhdGlvbj8uY2l0eSxcbiAgY291bnRyeTogbG9jYXRpb24/LmNvdW50cnksXG4gIGNvdW50cnlDb2RlOiBsb2NhdGlvbj8uY291bnRyeUNvZGUsXG59KTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQWNjb3VudCDruYzrjZRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmV4cG9ydCB0eXBlIEFjY291bnRFdmVudEJ1aWxkZXJzID0ge1xuICB0cmFja0FjY291bnRMaW5raW5nOiBCdWlsZGVyPFxuICAgIFtBY2NvdW50U25hcHNob3QsIFVzZXJQcm9maWxlTGl0ZSwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF1cbiAgPjtcbiAgdHJhY2tBY2NvdW50VW5saW5rOiBCdWlsZGVyPFxuICAgIFtBY2NvdW50U25hcHNob3QsIFVzZXJQcm9maWxlTGl0ZSwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF1cbiAgPjtcbiAgdHJhY2tBY2NvdW50UGFzc3dvcmRDaGFuZ2U6IEJ1aWxkZXI8XG4gICAgW0FjY291bnRTbmFwc2hvdCwgVXNlclByb2ZpbGVMaXRlLCBCdWlsZGVyVHJpZ2dlciwgQnVpbGRlckxvY2F0aW9uIHwgdW5kZWZpbmVkXVxuICA+O1xufTtcblxuY29uc3QgYnVpbGRBY2NvdW50RXZlbnQgPSAoXG4gIGV2ZW50VHlwZTogc3RyaW5nLFxuICBldmVudERpc3BsYXlOYW1lOiBzdHJpbmcsXG4gIGFjY291bnQ6IEFjY291bnRTbmFwc2hvdCxcbiAgdXNlcjogVXNlclByb2ZpbGVMaXRlLFxuICB0cmlnZ2VyOiBCdWlsZGVyVHJpZ2dlcixcbiAgbG9jYXRpb246IEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZCxcbik6IEF1ZGl0TG9nRXZlbnQgPT5cbiAgY3JlYXRlRXZlbnQoXG4gICAgeyBldmVudEtleTogYWNjb3VudC51c2VySWQsIGV2ZW50VHlwZSwgZXZlbnREaXNwbGF5TmFtZSB9LFxuICAgIHtcbiAgICAgIHVzZXJJZDogYWNjb3VudC51c2VySWQsXG4gICAgICB1c2VyRW1haWw6IHVzZXI/LmVtYWlsID8/IFwidW5rbm93blwiLFxuICAgICAgdXNlck5hbWU6IHVzZXI/Lm5hbWUgPz8gXCJ1bmtub3duXCIsXG4gICAgICBhY2NvdW50SWQ6IGFjY291bnQuaWQsXG4gICAgICBwcm92aWRlcklkOiBhY2NvdW50LnByb3ZpZGVySWQsXG4gICAgfSxcbiAgICB0cmlnZ2VyLFxuICAgIGxvY2F0aW9uLFxuICApO1xuXG5jb25zdCBidWlsZEFjY291bnRFdmVudHMgPSAoKTogQWNjb3VudEV2ZW50QnVpbGRlcnMgPT4gKHtcbiAgdHJhY2tBY2NvdW50TGlua2luZzogKGFjY291bnQsIHVzZXIsIHRyaWdnZXIsIGxvY2F0aW9uKSA9PlxuICAgIGJ1aWxkQWNjb3VudEV2ZW50KFxuICAgICAgRVZFTlRfVFlQRVMuQUNDT1VOVF9MSU5LRUQsXG4gICAgICBgTGlua2VkICR7YWNjb3VudC5wcm92aWRlcklkfSBhY2NvdW50YCxcbiAgICAgIGFjY291bnQsXG4gICAgICB1c2VyLFxuICAgICAgdHJpZ2dlcixcbiAgICAgIGxvY2F0aW9uLFxuICAgICksXG4gIHRyYWNrQWNjb3VudFVubGluazogKGFjY291bnQsIHVzZXIsIHRyaWdnZXIsIGxvY2F0aW9uKSA9PlxuICAgIGJ1aWxkQWNjb3VudEV2ZW50KFxuICAgICAgRVZFTlRfVFlQRVMuQUNDT1VOVF9VTkxJTktFRCxcbiAgICAgIGBVbmxpbmtlZCAke2FjY291bnQucHJvdmlkZXJJZH0gYWNjb3VudGAsXG4gICAgICBhY2NvdW50LFxuICAgICAgdXNlcixcbiAgICAgIHRyaWdnZXIsXG4gICAgICBsb2NhdGlvbixcbiAgICApLFxuICB0cmFja0FjY291bnRQYXNzd29yZENoYW5nZTogKGFjY291bnQsIHVzZXIsIHRyaWdnZXIsIGxvY2F0aW9uKSA9PlxuICAgIGJ1aWxkQWNjb3VudEV2ZW50KFxuICAgICAgRVZFTlRfVFlQRVMuUEFTU1dPUkRfQ0hBTkdFRCxcbiAgICAgIFwiUGFzc3dvcmQgY2hhbmdlZFwiLFxuICAgICAgYWNjb3VudCxcbiAgICAgIHVzZXIsXG4gICAgICB0cmlnZ2VyLFxuICAgICAgbG9jYXRpb24sXG4gICAgKSxcbn0pO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBTZXNzaW9uIOu5jOuNlFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuZXhwb3J0IHR5cGUgU2Vzc2lvbkV2ZW50QnVpbGRlcnMgPSB7XG4gIHRyYWNrVXNlclNpZ25lZEluOiBCdWlsZGVyPFxuICAgIFtTZXNzaW9uU25hcHNob3QsIFVzZXJQcm9maWxlTGl0ZSwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF1cbiAgPjtcbiAgdHJhY2tVc2VyU2lnbmVkT3V0OiBCdWlsZGVyPFxuICAgIFtTZXNzaW9uU25hcHNob3QsIFVzZXJQcm9maWxlTGl0ZSwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF1cbiAgPjtcbiAgdHJhY2tTZXNzaW9uQ3JlYXRlZDogQnVpbGRlcjxcbiAgICBbU2Vzc2lvblNuYXBzaG90LCBVc2VyUHJvZmlsZUxpdGUsIEJ1aWxkZXJUcmlnZ2VyLCBCdWlsZGVyTG9jYXRpb24gfCB1bmRlZmluZWRdXG4gID47XG4gIHRyYWNrU2Vzc2lvblJldm9rZWQ6IEJ1aWxkZXI8XG4gICAgW1Nlc3Npb25TbmFwc2hvdCwgVXNlclByb2ZpbGVMaXRlLCBCdWlsZGVyVHJpZ2dlciwgQnVpbGRlckxvY2F0aW9uIHwgdW5kZWZpbmVkXVxuICA+O1xuICB0cmFja1Nlc3Npb25SZXZva2VkQWxsOiBCdWlsZGVyPFtTZXNzaW9uU25hcHNob3QsIFVzZXJQcm9maWxlTGl0ZSwgQnVpbGRlclRyaWdnZXJdPjtcbiAgdHJhY2tVc2VySW1wZXJzb25hdGVkOiBCdWlsZGVyPFxuICAgIFtTZXNzaW9uU25hcHNob3QsIFVzZXJQcm9maWxlTGl0ZSwgVXNlclByb2ZpbGVMaXRlLCBCdWlsZGVyVHJpZ2dlciwgQnVpbGRlckxvY2F0aW9uIHwgdW5kZWZpbmVkXVxuICA+O1xuICB0cmFja1VzZXJJbXBlcnNvbmF0aW9uU3RvcDogQnVpbGRlcjxcbiAgICBbU2Vzc2lvblNuYXBzaG90LCBVc2VyUHJvZmlsZUxpdGUsIFVzZXJQcm9maWxlTGl0ZSwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF1cbiAgPjtcbiAgdHJhY2tFbWFpbFZlcmlmaWNhdGlvblNlbnQ6IEJ1aWxkZXI8XG4gICAgW1Nlc3Npb25TbmFwc2hvdCwgeyBuYW1lPzogc3RyaW5nOyBlbWFpbD86IHN0cmluZyB9LCBCdWlsZGVyVHJpZ2dlcl1cbiAgPjtcbiAgdHJhY2tFbWFpbFNpZ25JbkF0dGVtcHQ6IEJ1aWxkZXI8XG4gICAgW1xuICAgICAgeyBlbWFpbDogc3RyaW5nOyBsb2dpbk1ldGhvZDogc3RyaW5nIHwgbnVsbCB9LFxuICAgICAgVXNlclByb2ZpbGVMaXRlLFxuICAgICAgQnVpbGRlclRyaWdnZXIsXG4gICAgICBCdWlsZGVyTG9jYXRpb24gfCB1bmRlZmluZWQsXG4gICAgXVxuICA+O1xuICB0cmFja1NvY2lhbFNpZ25JbkF0dGVtcHQ6IEJ1aWxkZXI8XG4gICAgW3sgbG9naW5NZXRob2Q6IHN0cmluZyB8IG51bGwgfSwgVXNlclByb2ZpbGVMaXRlLCBCdWlsZGVyVHJpZ2dlciwgQnVpbGRlckxvY2F0aW9uIHwgdW5kZWZpbmVkXVxuICA+O1xuICB0cmFja1NvY2lhbFNpZ25JblJlZGlyZWN0aW9uQXR0ZW1wdDogQnVpbGRlcjxcbiAgICBbeyBsb2dpbk1ldGhvZDogc3RyaW5nIHwgbnVsbCB9LCBVc2VyUHJvZmlsZUxpdGUsIEJ1aWxkZXJUcmlnZ2VyLCBCdWlsZGVyTG9jYXRpb24gfCB1bmRlZmluZWRdXG4gID47XG59O1xuXG5jb25zdCBzZXNzaW9uTGlmZWN5Y2xlRGF0YSA9IChzZXNzaW9uOiBTZXNzaW9uU25hcHNob3QsIHVzZXI6IFVzZXJQcm9maWxlTGl0ZSkgPT4gKHtcbiAgdXNlcklkOiBzZXNzaW9uLnVzZXJJZCxcbiAgdXNlck5hbWU6IHVzZXI/Lm5hbWUgPz8gXCJ1bmtub3duXCIsXG4gIHVzZXJFbWFpbDogdXNlcj8uZW1haWwgPz8gXCJ1bmtub3duXCIsXG4gIHNlc3Npb25JZDogc2Vzc2lvbi5pZCxcbiAgbG9naW5NZXRob2Q6IHNlc3Npb24ubG9naW5NZXRob2QgPz8gXCJ1bmtub3duXCIsXG4gIHVzZXJBZ2VudDogc2Vzc2lvbi51c2VyQWdlbnQsXG59KTtcblxuY29uc3QgYnVpbGRTZXNzaW9uTGlmZWN5Y2xlRXZlbnQgPSAoXG4gIGV2ZW50VHlwZTogc3RyaW5nLFxuICBldmVudERpc3BsYXlOYW1lOiBzdHJpbmcsXG4gIHNlc3Npb246IFNlc3Npb25TbmFwc2hvdCxcbiAgdXNlcjogVXNlclByb2ZpbGVMaXRlLFxuICB0cmlnZ2VyOiBCdWlsZGVyVHJpZ2dlcixcbiAgbG9jYXRpb246IEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZCxcbik6IEF1ZGl0TG9nRXZlbnQgPT5cbiAgY3JlYXRlRXZlbnQoXG4gICAgeyBldmVudEtleTogc2Vzc2lvbi51c2VySWQsIGV2ZW50VHlwZSwgZXZlbnREaXNwbGF5TmFtZSB9LFxuICAgIHNlc3Npb25MaWZlY3ljbGVEYXRhKHNlc3Npb24sIHVzZXIpLFxuICAgIHRyaWdnZXIsXG4gICAgbG9jYXRpb24sXG4gICk7XG5cbmNvbnN0IGJ1aWxkSW1wZXJzb25hdGlvbkV2ZW50ID0gKFxuICBldmVudFR5cGU6IHN0cmluZyxcbiAgZXZlbnREaXNwbGF5TmFtZTogc3RyaW5nLFxuICBzZXNzaW9uOiBTZXNzaW9uU25hcHNob3QsXG4gIHVzZXI6IFVzZXJQcm9maWxlTGl0ZSxcbiAgaW1wZXJzb25hdG9yOiBVc2VyUHJvZmlsZUxpdGUsXG4gIHRyaWdnZXI6IEJ1aWxkZXJUcmlnZ2VyLFxuICBsb2NhdGlvbjogQnVpbGRlckxvY2F0aW9uIHwgdW5kZWZpbmVkLFxuKTogQXVkaXRMb2dFdmVudCA9PlxuICBjcmVhdGVFdmVudChcbiAgICB7IGV2ZW50S2V5OiBzZXNzaW9uLnVzZXJJZCwgZXZlbnRUeXBlLCBldmVudERpc3BsYXlOYW1lIH0sXG4gICAge1xuICAgICAgLi4uc2Vzc2lvbkxpZmVjeWNsZURhdGEoc2Vzc2lvbiwgdXNlciksXG4gICAgICBpbXBlcnNvbmF0ZWRCeTogaW1wZXJzb25hdG9yPy5uYW1lID8/IGltcGVyc29uYXRvcj8uZW1haWwgPz8gc2Vzc2lvbi5pbXBlcnNvbmF0ZWRCeSxcbiAgICAgIGltcGVyc29uYXRlZEJ5SWQ6IHNlc3Npb24uaW1wZXJzb25hdGVkQnksXG4gICAgfSxcbiAgICB0cmlnZ2VyLFxuICAgIGxvY2F0aW9uLFxuICApO1xuXG5jb25zdCBTSUdOX0lOX0ZBSUxFRF9ESVNQTEFZID0gXCJVc2VyIHNpZ24taW4gYXR0ZW1wdCBmYWlsZWRcIjtcblxuY29uc3QgYnVpbGRTZXNzaW9uRXZlbnRzID0gKCk6IFNlc3Npb25FdmVudEJ1aWxkZXJzID0+ICh7XG4gIHRyYWNrVXNlclNpZ25lZEluOiAoc2Vzc2lvbiwgdXNlciwgdHJpZ2dlciwgbG9jYXRpb24pID0+XG4gICAgYnVpbGRTZXNzaW9uTGlmZWN5Y2xlRXZlbnQoXG4gICAgICBFVkVOVF9UWVBFUy5VU0VSX1NJR05FRF9JTixcbiAgICAgIGBTaWduZWQgaW4gdmlhICR7c2Vzc2lvbi5sb2dpbk1ldGhvZCA/PyBcInVua25vd25cIn1gLFxuICAgICAgc2Vzc2lvbixcbiAgICAgIHVzZXIsXG4gICAgICB0cmlnZ2VyLFxuICAgICAgbG9jYXRpb24sXG4gICAgKSxcbiAgdHJhY2tVc2VyU2lnbmVkT3V0OiAoc2Vzc2lvbiwgdXNlciwgdHJpZ2dlciwgbG9jYXRpb24pID0+XG4gICAgYnVpbGRTZXNzaW9uTGlmZWN5Y2xlRXZlbnQoXG4gICAgICBFVkVOVF9UWVBFUy5VU0VSX1NJR05FRF9PVVQsXG4gICAgICBcIlVzZXIgc2lnbmVkIG91dFwiLFxuICAgICAgc2Vzc2lvbixcbiAgICAgIHVzZXIsXG4gICAgICB0cmlnZ2VyLFxuICAgICAgbG9jYXRpb24sXG4gICAgKSxcbiAgdHJhY2tTZXNzaW9uQ3JlYXRlZDogKHNlc3Npb24sIHVzZXIsIHRyaWdnZXIsIGxvY2F0aW9uKSA9PlxuICAgIGJ1aWxkU2Vzc2lvbkxpZmVjeWNsZUV2ZW50KFxuICAgICAgRVZFTlRfVFlQRVMuU0VTU0lPTl9DUkVBVEVELFxuICAgICAgXCJTZXNzaW9uIGNyZWF0ZWRcIixcbiAgICAgIHNlc3Npb24sXG4gICAgICB1c2VyLFxuICAgICAgdHJpZ2dlcixcbiAgICAgIGxvY2F0aW9uLFxuICAgICksXG4gIHRyYWNrU2Vzc2lvblJldm9rZWQ6IChzZXNzaW9uLCB1c2VyLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT5cbiAgICBidWlsZFNlc3Npb25MaWZlY3ljbGVFdmVudChcbiAgICAgIEVWRU5UX1RZUEVTLlNFU1NJT05fUkVWT0tFRCxcbiAgICAgIFwiU2Vzc2lvbiByZXZva2VkXCIsXG4gICAgICBzZXNzaW9uLFxuICAgICAgdXNlcixcbiAgICAgIHRyaWdnZXIsXG4gICAgICBsb2NhdGlvbixcbiAgICApLFxuICB0cmFja1Nlc3Npb25SZXZva2VkQWxsOiAoc2Vzc2lvbiwgdXNlciwgdHJpZ2dlcikgPT5cbiAgICBjcmVhdGVFdmVudChcbiAgICAgIHtcbiAgICAgICAgZXZlbnRLZXk6IHNlc3Npb24udXNlcklkLFxuICAgICAgICBldmVudFR5cGU6IEVWRU5UX1RZUEVTLkFMTF9TRVNTSU9OU19SRVZPS0VELFxuICAgICAgICBldmVudERpc3BsYXlOYW1lOiBcIkFsbCBzZXNzaW9ucyByZXZva2VkXCIsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB1c2VySWQ6IHNlc3Npb24udXNlcklkLFxuICAgICAgICB1c2VyTmFtZTogdXNlcj8ubmFtZSA/PyBcInVua25vd25cIixcbiAgICAgICAgdXNlckVtYWlsOiB1c2VyPy5lbWFpbCA/PyBcInVua25vd25cIixcbiAgICAgIH0sXG4gICAgICB0cmlnZ2VyLFxuICAgICksXG4gIHRyYWNrVXNlckltcGVyc29uYXRlZDogKHNlc3Npb24sIHVzZXIsIGltcGVyc29uYXRvciwgdHJpZ2dlciwgbG9jYXRpb24pID0+XG4gICAgYnVpbGRJbXBlcnNvbmF0aW9uRXZlbnQoXG4gICAgICBFVkVOVF9UWVBFUy5VU0VSX0lNUEVSU09OQVRFRCxcbiAgICAgIFwiVXNlciBpbXBlcnNvbmF0ZWRcIixcbiAgICAgIHNlc3Npb24sXG4gICAgICB1c2VyLFxuICAgICAgaW1wZXJzb25hdG9yLFxuICAgICAgdHJpZ2dlcixcbiAgICAgIGxvY2F0aW9uLFxuICAgICksXG4gIHRyYWNrVXNlckltcGVyc29uYXRpb25TdG9wOiAoc2Vzc2lvbiwgdXNlciwgaW1wZXJzb25hdG9yLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT5cbiAgICBidWlsZEltcGVyc29uYXRpb25FdmVudChcbiAgICAgIEVWRU5UX1RZUEVTLlVTRVJfSU1QRVJTT05BVEVEX1NUT1BQRUQsXG4gICAgICBcIlVzZXIgaW1wZXJzb25hdGlvbiBzdG9wcGVkXCIsXG4gICAgICBzZXNzaW9uLFxuICAgICAgdXNlcixcbiAgICAgIGltcGVyc29uYXRvcixcbiAgICAgIHRyaWdnZXIsXG4gICAgICBsb2NhdGlvbixcbiAgICApLFxuICB0cmFja0VtYWlsVmVyaWZpY2F0aW9uU2VudDogKHNlc3Npb24sIHVzZXIsIHRyaWdnZXIpID0+XG4gICAgY3JlYXRlRXZlbnQoXG4gICAgICB7XG4gICAgICAgIGV2ZW50S2V5OiBzZXNzaW9uLnVzZXJJZCxcbiAgICAgICAgZXZlbnRUeXBlOiBFVkVOVF9UWVBFUy5FTUFJTF9WRVJJRklDQVRJT05fU0VOVCxcbiAgICAgICAgZXZlbnREaXNwbGF5TmFtZTogXCJWZXJpZmljYXRpb24gZW1haWwgc2VudFwiLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdXNlcklkOiBzZXNzaW9uLnVzZXJJZCxcbiAgICAgICAgdXNlck5hbWU6IHVzZXIubmFtZSxcbiAgICAgICAgdXNlckVtYWlsOiB1c2VyLmVtYWlsLFxuICAgICAgICBzZXNzaW9uSWQ6IHNlc3Npb24uaWQsXG4gICAgICB9LFxuICAgICAgdHJpZ2dlcixcbiAgICApLFxuICAvLyDso7zsnZg6IOq4sOyhtCDrj5nsnpEg7Jyg7KeAIOKAlCBgbmFtZU5hbWVgIOyYpO2DgCDtlYTrk5zrqoXrj4Qg6re464yA66GcIOuztOyhtO2VnOuLpC5cbiAgdHJhY2tFbWFpbFNpZ25JbkF0dGVtcHQ6IChhdHRlbXB0LCB1c2VyLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT5cbiAgICBjcmVhdGVFdmVudChcbiAgICAgIHtcbiAgICAgICAgZXZlbnRLZXk6IHVzZXI/LmlkID8/IFwidW5rbm93blwiLFxuICAgICAgICBldmVudFR5cGU6IEVWRU5UX1RZUEVTLlVTRVJfU0lHTl9JTl9GQUlMRUQsXG4gICAgICAgIGV2ZW50RGlzcGxheU5hbWU6IFNJR05fSU5fRkFJTEVEX0RJU1BMQVksXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB1c2VySWQ6IHVzZXI/LmlkID8/IFwidW5rbm93blwiLFxuICAgICAgICBuYW1lTmFtZTogdXNlcj8ubmFtZSA/PyBcInVua25vd25cIixcbiAgICAgICAgdXNlckVtYWlsOiBhdHRlbXB0LmVtYWlsLFxuICAgICAgICBsb2dpbk1ldGhvZDogYXR0ZW1wdC5sb2dpbk1ldGhvZCxcbiAgICAgIH0sXG4gICAgICB7IHRyaWdnZXJlZEJ5OiB1c2VyPy5pZCA/PyB0cmlnZ2VyLnRyaWdnZXJlZEJ5LCB0cmlnZ2VyQ29udGV4dDogdHJpZ2dlci50cmlnZ2VyQ29udGV4dCB9LFxuICAgICAgbG9jYXRpb24sXG4gICAgKSxcbiAgdHJhY2tTb2NpYWxTaWduSW5BdHRlbXB0OiAoYXR0ZW1wdCwgdXNlciwgdHJpZ2dlciwgbG9jYXRpb24pID0+XG4gICAgY3JlYXRlRXZlbnQoXG4gICAgICB7XG4gICAgICAgIGV2ZW50S2V5OiB1c2VyPy5pZCA/PyBcInVua25vd25cIixcbiAgICAgICAgZXZlbnRUeXBlOiBFVkVOVF9UWVBFUy5VU0VSX1NJR05fSU5fRkFJTEVELFxuICAgICAgICBldmVudERpc3BsYXlOYW1lOiBTSUdOX0lOX0ZBSUxFRF9ESVNQTEFZLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdXNlcklkOiB1c2VyPy5pZCA/PyBcInVua25vd25cIixcbiAgICAgICAgdXNlck5hbWU6IHVzZXI/Lm5hbWUgPz8gXCJ1bmtub3duXCIsXG4gICAgICAgIHVzZXJFbWFpbDogdXNlcj8uZW1haWwgPz8gXCJ1bmtub3duXCIsXG4gICAgICAgIGxvZ2luTWV0aG9kOiBhdHRlbXB0LmxvZ2luTWV0aG9kLFxuICAgICAgfSxcbiAgICAgIHsgdHJpZ2dlcmVkQnk6IHVzZXI/LmlkID8/IHRyaWdnZXIudHJpZ2dlcmVkQnksIHRyaWdnZXJDb250ZXh0OiB0cmlnZ2VyLnRyaWdnZXJDb250ZXh0IH0sXG4gICAgICBsb2NhdGlvbixcbiAgICApLFxuICAvLyDso7zsnZg6IOq4sOyhtCDrj5nsnpEg7Jyg7KeAIOKAlCB1c2VyRW1haWwg6rCS7J20IHVzZXI/Lmlk66GcIOyEpOygleuQmOuKlCDquLDsobQg64+Z7J6R64+EIOq3uOuMgOuhnCDrs7TsobTtlZzri6QuXG4gIHRyYWNrU29jaWFsU2lnbkluUmVkaXJlY3Rpb25BdHRlbXB0OiAoYXR0ZW1wdCwgdXNlciwgdHJpZ2dlciwgbG9jYXRpb24pID0+XG4gICAgY3JlYXRlRXZlbnQoXG4gICAgICB7XG4gICAgICAgIGV2ZW50S2V5OiB1c2VyPy5pZCA/PyBcInVua25vd25cIixcbiAgICAgICAgZXZlbnRUeXBlOiBFVkVOVF9UWVBFUy5VU0VSX1NJR05fSU5fRkFJTEVELFxuICAgICAgICBldmVudERpc3BsYXlOYW1lOiBTSUdOX0lOX0ZBSUxFRF9ESVNQTEFZLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdXNlcklkOiB1c2VyPy5pZCA/PyBcInVua25vd25cIixcbiAgICAgICAgdXNlck5hbWU6IHVzZXI/Lm5hbWUgPz8gXCJ1bmtub3duXCIsXG4gICAgICAgIHVzZXJFbWFpbDogdXNlcj8uaWQgPz8gXCJ1bmtub3duXCIsXG4gICAgICAgIGxvZ2luTWV0aG9kOiBhdHRlbXB0LmxvZ2luTWV0aG9kLFxuICAgICAgfSxcbiAgICAgIHRyaWdnZXIsXG4gICAgICBsb2NhdGlvbixcbiAgICApLFxufSk7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFVzZXIg67mM642UXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5leHBvcnQgdHlwZSBVc2VyRXZlbnRCdWlsZGVycyA9IHtcbiAgdHJhY2tVc2VyU2lnbmVkVXA6IEJ1aWxkZXI8W1VzZXJTbmFwc2hvdCwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF0+O1xuICB0cmFja1VzZXJEZWxldGVkOiBCdWlsZGVyPFtVc2VyU25hcHNob3QsIEJ1aWxkZXJUcmlnZ2VyLCBCdWlsZGVyTG9jYXRpb24gfCB1bmRlZmluZWRdPjtcbiAgdHJhY2tVc2VyUHJvZmlsZVVwZGF0ZWQ6IEJ1aWxkZXI8XG4gICAgW1VzZXJTbmFwc2hvdCwgc3RyaW5nW10sIEJ1aWxkZXJUcmlnZ2VyLCBCdWlsZGVyTG9jYXRpb24gfCB1bmRlZmluZWRdXG4gID47XG4gIHRyYWNrVXNlclByb2ZpbGVJbWFnZVVwZGF0ZWQ6IEJ1aWxkZXI8XG4gICAgW1VzZXJTbmFwc2hvdCwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF1cbiAgPjtcbiAgdHJhY2tVc2VyQmFubmVkOiBCdWlsZGVyPFtVc2VyU25hcHNob3QsIEJ1aWxkZXJUcmlnZ2VyLCBCdWlsZGVyTG9jYXRpb24gfCB1bmRlZmluZWRdPjtcbiAgdHJhY2tVc2VyVW5CYW5uZWQ6IEJ1aWxkZXI8W1VzZXJTbmFwc2hvdCwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF0+O1xuICB0cmFja1VzZXJFbWFpbFZlcmlmaWVkOiBCdWlsZGVyPFtVc2VyU25hcHNob3QsIEJ1aWxkZXJUcmlnZ2VyLCBCdWlsZGVyTG9jYXRpb24gfCB1bmRlZmluZWRdPjtcbn07XG5cbmNvbnN0IHVzZXJJZGVudGl0eURhdGEgPSAodXNlcjogVXNlclNuYXBzaG90KSA9PiAoe1xuICB1c2VySWQ6IHVzZXIuaWQsXG4gIHVzZXJFbWFpbDogdXNlci5lbWFpbCxcbiAgdXNlck5hbWU6IHVzZXIubmFtZSxcbn0pO1xuXG5jb25zdCBidWlsZFVzZXJFdmVudCA9IChcbiAgZXZlbnRUeXBlOiBzdHJpbmcsXG4gIGV2ZW50RGlzcGxheU5hbWU6IHN0cmluZyxcbiAgdXNlcjogVXNlclNuYXBzaG90LFxuICB0cmlnZ2VyOiBCdWlsZGVyVHJpZ2dlcixcbiAgbG9jYXRpb246IEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZCxcbiAgZXh0cmE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbik6IEF1ZGl0TG9nRXZlbnQgPT5cbiAgY3JlYXRlRXZlbnQoXG4gICAgeyBldmVudEtleTogdXNlci5pZCwgZXZlbnRUeXBlLCBldmVudERpc3BsYXlOYW1lIH0sXG4gICAgeyAuLi51c2VySWRlbnRpdHlEYXRhKHVzZXIpLCAuLi5leHRyYSB9LFxuICAgIHRyaWdnZXIsXG4gICAgbG9jYXRpb24sXG4gICk7XG5cbmNvbnN0IGJ1aWxkVXNlckV2ZW50cyA9ICgpOiBVc2VyRXZlbnRCdWlsZGVycyA9PiAoe1xuICB0cmFja1VzZXJTaWduZWRVcDogKHVzZXIsIHRyaWdnZXIsIGxvY2F0aW9uKSA9PlxuICAgIGJ1aWxkVXNlckV2ZW50KFxuICAgICAgRVZFTlRfVFlQRVMuVVNFUl9DUkVBVEVELFxuICAgICAgYCR7dXNlci5uYW1lIHx8IHVzZXIuZW1haWx9IHNpZ25lZCB1cGAsXG4gICAgICB1c2VyLFxuICAgICAgdHJpZ2dlcixcbiAgICAgIGxvY2F0aW9uLFxuICAgICksXG4gIHRyYWNrVXNlckRlbGV0ZWQ6ICh1c2VyLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT5cbiAgICBidWlsZFVzZXJFdmVudChFVkVOVF9UWVBFUy5VU0VSX0RFTEVURUQsIFwiVXNlciBkZWxldGVkXCIsIHVzZXIsIHRyaWdnZXIsIGxvY2F0aW9uKSxcbiAgdHJhY2tVc2VyUHJvZmlsZVVwZGF0ZWQ6ICh1c2VyLCB1cGRhdGVkRmllbGRzLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT5cbiAgICBidWlsZFVzZXJFdmVudChFVkVOVF9UWVBFUy5QUk9GSUxFX1VQREFURUQsIFwiUHJvZmlsZSB1cGRhdGVkXCIsIHVzZXIsIHRyaWdnZXIsIGxvY2F0aW9uLCB7XG4gICAgICB1cGRhdGVkRmllbGRzLFxuICAgIH0pLFxuICB0cmFja1VzZXJQcm9maWxlSW1hZ2VVcGRhdGVkOiAodXNlciwgdHJpZ2dlciwgbG9jYXRpb24pID0+XG4gICAgYnVpbGRVc2VyRXZlbnQoXG4gICAgICBFVkVOVF9UWVBFUy5QUk9GSUxFX0lNQUdFX1VQREFURUQsXG4gICAgICBcIlByb2ZpbGUgaW1hZ2UgdXBkYXRlZFwiLFxuICAgICAgdXNlcixcbiAgICAgIHRyaWdnZXIsXG4gICAgICBsb2NhdGlvbixcbiAgICApLFxuICB0cmFja1VzZXJCYW5uZWQ6ICh1c2VyLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT4ge1xuICAgIGNvbnN0IHJlYXNvblN1ZmZpeCA9IHVzZXIuYmFuUmVhc29uID8gYDogJHt1c2VyLmJhblJlYXNvbn1gIDogXCJcIjtcbiAgICBjb25zdCBleHBpcmVzU3VmZml4ID0gdXNlci5iYW5FeHBpcmVzID8gYCAodW50aWwgJHt1c2VyLmJhbkV4cGlyZXMudG9JU09TdHJpbmcoKX0pYCA6IFwiXCI7XG4gICAgcmV0dXJuIGJ1aWxkVXNlckV2ZW50KFxuICAgICAgRVZFTlRfVFlQRVMuVVNFUl9CQU5ORUQsXG4gICAgICBgVXNlciBiYW5uZWQke3JlYXNvblN1ZmZpeH0ke2V4cGlyZXNTdWZmaXh9YCxcbiAgICAgIHVzZXIsXG4gICAgICB0cmlnZ2VyLFxuICAgICAgbG9jYXRpb24sXG4gICAgICB7XG4gICAgICAgIGJhbm5lZDogdXNlci5iYW5uZWQsXG4gICAgICAgIGJhblJlYXNvbjogdXNlci5iYW5SZWFzb24sXG4gICAgICAgIGJhbkV4cGlyZXM6IHVzZXIuYmFuRXhwaXJlcyxcbiAgICAgIH0sXG4gICAgKTtcbiAgfSxcbiAgdHJhY2tVc2VyVW5CYW5uZWQ6ICh1c2VyLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT5cbiAgICBidWlsZFVzZXJFdmVudChFVkVOVF9UWVBFUy5VU0VSX1VOQkFOTkVELCBcIlVzZXIgdW5iYW5uZWRcIiwgdXNlciwgdHJpZ2dlciwgbG9jYXRpb24sIHtcbiAgICAgIGJhbm5lZDogdXNlci5iYW5uZWQsXG4gICAgfSksXG4gIHRyYWNrVXNlckVtYWlsVmVyaWZpZWQ6ICh1c2VyLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT5cbiAgICBidWlsZFVzZXJFdmVudChFVkVOVF9UWVBFUy5FTUFJTF9WRVJJRklFRCwgXCJFbWFpbCB2ZXJpZmllZFwiLCB1c2VyLCB0cmlnZ2VyLCBsb2NhdGlvbiksXG59KTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVmVyaWZpY2F0aW9uIOu5jOuNlFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuZXhwb3J0IHR5cGUgVmVyaWZpY2F0aW9uRXZlbnRCdWlsZGVycyA9IHtcbiAgdHJhY2tQYXNzd29yZFJlc2V0UmVxdWVzdDogQnVpbGRlcjxcbiAgICBbVmVyaWZpY2F0aW9uU25hcHNob3QsIFVzZXJQcm9maWxlTGl0ZSwgQnVpbGRlclRyaWdnZXIsIEJ1aWxkZXJMb2NhdGlvbiB8IHVuZGVmaW5lZF1cbiAgPjtcbiAgdHJhY2tQYXNzd29yZFJlc2V0UmVxdWVzdENvbXBsZXRpb246IEJ1aWxkZXI8XG4gICAgW1ZlcmlmaWNhdGlvblNuYXBzaG90LCBVc2VyUHJvZmlsZUxpdGUsIEJ1aWxkZXJUcmlnZ2VyLCBCdWlsZGVyTG9jYXRpb24gfCB1bmRlZmluZWRdXG4gID47XG59O1xuXG5jb25zdCBidWlsZFZlcmlmaWNhdGlvbkV2ZW50ID0gKFxuICBldmVudFR5cGU6IHN0cmluZyxcbiAgZXZlbnREaXNwbGF5TmFtZTogc3RyaW5nLFxuICB2ZXJpZmljYXRpb246IFZlcmlmaWNhdGlvblNuYXBzaG90LFxuICB1c2VyOiBVc2VyUHJvZmlsZUxpdGUsXG4gIHRyaWdnZXI6IEJ1aWxkZXJUcmlnZ2VyLFxuICBsb2NhdGlvbjogQnVpbGRlckxvY2F0aW9uIHwgdW5kZWZpbmVkLFxuKTogQXVkaXRMb2dFdmVudCA9PlxuICBjcmVhdGVFdmVudChcbiAgICB7IGV2ZW50S2V5OiB2ZXJpZmljYXRpb24udmFsdWUsIGV2ZW50VHlwZSwgZXZlbnREaXNwbGF5TmFtZSB9LFxuICAgIHtcbiAgICAgIHVzZXJJZDogdmVyaWZpY2F0aW9uLnZhbHVlLFxuICAgICAgdXNlck5hbWU6IHVzZXI/Lm5hbWUgPz8gXCJ1bmtub3duXCIsXG4gICAgICB1c2VyRW1haWw6IHVzZXI/LmVtYWlsID8/IFwidW5rbm93blwiLFxuICAgIH0sXG4gICAgdHJpZ2dlcixcbiAgICBsb2NhdGlvbixcbiAgKTtcblxuY29uc3QgYnVpbGRWZXJpZmljYXRpb25FdmVudHMgPSAoKTogVmVyaWZpY2F0aW9uRXZlbnRCdWlsZGVycyA9PiAoe1xuICB0cmFja1Bhc3N3b3JkUmVzZXRSZXF1ZXN0OiAodmVyaWZpY2F0aW9uLCB1c2VyLCB0cmlnZ2VyLCBsb2NhdGlvbikgPT5cbiAgICBidWlsZFZlcmlmaWNhdGlvbkV2ZW50KFxuICAgICAgRVZFTlRfVFlQRVMuUEFTU1dPUkRfUkVTRVRfUkVRVUVTVEVELFxuICAgICAgXCJQYXNzd29yZCByZXNldCByZXF1ZXN0ZWRcIixcbiAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIHVzZXIsXG4gICAgICB0cmlnZ2VyLFxuICAgICAgbG9jYXRpb24sXG4gICAgKSxcbiAgdHJhY2tQYXNzd29yZFJlc2V0UmVxdWVzdENvbXBsZXRpb246ICh2ZXJpZmljYXRpb24sIHVzZXIsIHRyaWdnZXIsIGxvY2F0aW9uKSA9PlxuICAgIGJ1aWxkVmVyaWZpY2F0aW9uRXZlbnQoXG4gICAgICBFVkVOVF9UWVBFUy5QQVNTV09SRF9SRVNFVF9DT01QTEVURUQsXG4gICAgICBcIlBhc3N3b3JkIHJlc2V0IGNvbXBsZXRlZFwiLFxuICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgdXNlcixcbiAgICAgIHRyaWdnZXIsXG4gICAgICBsb2NhdGlvbixcbiAgICApLFxufSk7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIE9yZ2FuaXphdGlvbiAvIFRlYW0gLyBNZW1iZXIgLyBJbnZpdGF0aW9uIOu5jOuNlFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuY29uc3Qgb3JnYW5pemF0aW9uSWRlbnRpdHlEYXRhID0gKG9yZ2FuaXphdGlvbjogT3JnYW5pemF0aW9uU25hcHNob3QpID0+ICh7XG4gIG9yZ2FuaXphdGlvbklkOiBvcmdhbml6YXRpb24uaWQsXG4gIG9yZ2FuaXphdGlvblNsdWc6IG9yZ2FuaXphdGlvbi5zbHVnLFxuICBvcmdhbml6YXRpb25OYW1lOiBvcmdhbml6YXRpb24ubmFtZSxcbn0pO1xuXG5leHBvcnQgdHlwZSBPcmdhbml6YXRpb25FdmVudEJ1aWxkZXJzID0ge1xuICB0cmFja09yZ2FuaXphdGlvbkNyZWF0ZWQ6IEJ1aWxkZXI8W09yZ2FuaXphdGlvblNuYXBzaG90LCBCdWlsZGVyVHJpZ2dlcl0+O1xuICB0cmFja09yZ2FuaXphdGlvblVwZGF0ZWQ6IEJ1aWxkZXI8W09yZ2FuaXphdGlvblNuYXBzaG90LCBCdWlsZGVyVHJpZ2dlcl0+O1xufTtcblxuY29uc3QgYnVpbGRPcmdhbml6YXRpb25FdmVudCA9IChcbiAgZXZlbnRUeXBlOiBzdHJpbmcsXG4gIGV2ZW50RGlzcGxheU5hbWU6IHN0cmluZyxcbiAgb3JnYW5pemF0aW9uOiBPcmdhbml6YXRpb25TbmFwc2hvdCxcbiAgdHJpZ2dlcjogQnVpbGRlclRyaWdnZXIsXG4pOiBBdWRpdExvZ0V2ZW50ID0+XG4gIGNyZWF0ZUV2ZW50KFxuICAgIHsgZXZlbnRLZXk6IG9yZ2FuaXphdGlvbi5pZCwgZXZlbnRUeXBlLCBldmVudERpc3BsYXlOYW1lIH0sXG4gICAgb3JnYW5pemF0aW9uSWRlbnRpdHlEYXRhKG9yZ2FuaXphdGlvbiksXG4gICAgdHJpZ2dlcixcbiAgKTtcblxuY29uc3QgYnVpbGRPcmdhbml6YXRpb25FdmVudHMgPSAoKTogT3JnYW5pemF0aW9uRXZlbnRCdWlsZGVycyA9PiAoe1xuICB0cmFja09yZ2FuaXphdGlvbkNyZWF0ZWQ6IChvcmdhbml6YXRpb24sIHRyaWdnZXIpID0+XG4gICAgYnVpbGRPcmdhbml6YXRpb25FdmVudChcbiAgICAgIE9SR0FOSVpBVElPTl9FVkVOVF9UWVBFUy5PUkdBTklaQVRJT05fQ1JFQVRFRCxcbiAgICAgIFwiT3JnYW5pemF0aW9uIENyZWF0ZWRcIixcbiAgICAgIG9yZ2FuaXphdGlvbixcbiAgICAgIHRyaWdnZXIsXG4gICAgKSxcbiAgdHJhY2tPcmdhbml6YXRpb25VcGRhdGVkOiAob3JnYW5pemF0aW9uLCB0cmlnZ2VyKSA9PlxuICAgIGJ1aWxkT3JnYW5pemF0aW9uRXZlbnQoXG4gICAgICBPUkdBTklaQVRJT05fRVZFTlRfVFlQRVMuT1JHQU5JWkFUSU9OX1VQREFURUQsXG4gICAgICBcIk9yZ2FuaXphdGlvbiBVcGRhdGVkXCIsXG4gICAgICBvcmdhbml6YXRpb24sXG4gICAgICB0cmlnZ2VyLFxuICAgICksXG59KTtcblxuZXhwb3J0IHR5cGUgVGVhbUV2ZW50QnVpbGRlcnMgPSB7XG4gIHRyYWNrT3JnYW5pemF0aW9uVGVhbUNyZWF0ZWQ6IEJ1aWxkZXI8W09yZ2FuaXphdGlvblNuYXBzaG90LCBUZWFtU25hcHNob3QsIEJ1aWxkZXJUcmlnZ2VyXT47XG4gIHRyYWNrT3JnYW5pemF0aW9uVGVhbVVwZGF0ZWQ6IEJ1aWxkZXI8W09yZ2FuaXphdGlvblNuYXBzaG90LCBUZWFtU25hcHNob3QsIEJ1aWxkZXJUcmlnZ2VyXT47XG4gIHRyYWNrT3JnYW5pemF0aW9uVGVhbURlbGV0ZWQ6IEJ1aWxkZXI8W09yZ2FuaXphdGlvblNuYXBzaG90LCBUZWFtU25hcHNob3QsIEJ1aWxkZXJUcmlnZ2VyXT47XG4gIHRyYWNrT3JnYW5pemF0aW9uVGVhbU1lbWJlckFkZGVkOiBCdWlsZGVyPFxuICAgIFtcbiAgICAgIE9yZ2FuaXphdGlvblNuYXBzaG90LFxuICAgICAgVGVhbVNuYXBzaG90LFxuICAgICAgVXNlclNuYXBzaG90LFxuICAgICAgeyB0ZWFtSWQ6IHN0cmluZzsgdXNlcklkOiBzdHJpbmcgfSxcbiAgICAgIEJ1aWxkZXJUcmlnZ2VyLFxuICAgIF1cbiAgPjtcbiAgdHJhY2tPcmdhbml6YXRpb25UZWFtTWVtYmVyUmVtb3ZlZDogQnVpbGRlcjxcbiAgICBbXG4gICAgICBPcmdhbml6YXRpb25TbmFwc2hvdCxcbiAgICAgIFRlYW1TbmFwc2hvdCxcbiAgICAgIFVzZXJTbmFwc2hvdCxcbiAgICAgIHsgdGVhbUlkOiBzdHJpbmc7IHVzZXJJZDogc3RyaW5nIH0sXG4gICAgICBCdWlsZGVyVHJpZ2dlcixcbiAgICBdXG4gID47XG59O1xuXG5jb25zdCBidWlsZFRlYW1MaWZlY3ljbGVFdmVudCA9IChcbiAgZXZlbnRUeXBlOiBzdHJpbmcsXG4gIGV2ZW50RGlzcGxheU5hbWU6IHN0cmluZyxcbiAgb3JnYW5pemF0aW9uOiBPcmdhbml6YXRpb25TbmFwc2hvdCxcbiAgdGVhbTogVGVhbVNuYXBzaG90LFxuICB0cmlnZ2VyOiBCdWlsZGVyVHJpZ2dlcixcbik6IEF1ZGl0TG9nRXZlbnQgPT5cbiAgY3JlYXRlRXZlbnQoXG4gICAgeyBldmVudEtleTogb3JnYW5pemF0aW9uLmlkLCBldmVudFR5cGUsIGV2ZW50RGlzcGxheU5hbWUgfSxcbiAgICB7IC4uLm9yZ2FuaXphdGlvbklkZW50aXR5RGF0YShvcmdhbml6YXRpb24pLCB0ZWFtSWQ6IHRlYW0uaWQsIHRlYW1OYW1lOiB0ZWFtLm5hbWUgfSxcbiAgICB0cmlnZ2VyLFxuICApO1xuXG5jb25zdCBidWlsZFRlYW1NZW1iZXJFdmVudCA9IChcbiAgZXZlbnRUeXBlOiBzdHJpbmcsXG4gIGV2ZW50RGlzcGxheU5hbWU6IHN0cmluZyxcbiAgb3JnYW5pemF0aW9uOiBPcmdhbml6YXRpb25TbmFwc2hvdCxcbiAgdGVhbTogVGVhbVNuYXBzaG90LFxuICB1c2VyOiBVc2VyU25hcHNob3QsXG4gIHRlYW1NZW1iZXI6IHsgdGVhbUlkOiBzdHJpbmc7IHVzZXJJZDogc3RyaW5nIH0sXG4gIHRyaWdnZXI6IEJ1aWxkZXJUcmlnZ2VyLFxuKTogQXVkaXRMb2dFdmVudCA9PlxuICBjcmVhdGVFdmVudChcbiAgICB7IGV2ZW50S2V5OiBvcmdhbml6YXRpb24uaWQsIGV2ZW50VHlwZSwgZXZlbnREaXNwbGF5TmFtZSB9LFxuICAgIHtcbiAgICAgIC4uLm9yZ2FuaXphdGlvbklkZW50aXR5RGF0YShvcmdhbml6YXRpb24pLFxuICAgICAgdGVhbUlkOiB0ZWFtTWVtYmVyLnRlYW1JZCxcbiAgICAgIHRlYW1OYW1lOiB0ZWFtLm5hbWUsXG4gICAgICB1c2VyaWQ6IHRlYW1NZW1iZXIudXNlcklkLFxuICAgICAgbWVtYmVyTmFtZTogdXNlci5uYW1lLFxuICAgIH0sXG4gICAgdHJpZ2dlcixcbiAgKTtcblxuY29uc3QgYnVpbGRUZWFtRXZlbnRzID0gKCk6IFRlYW1FdmVudEJ1aWxkZXJzID0+ICh7XG4gIHRyYWNrT3JnYW5pemF0aW9uVGVhbUNyZWF0ZWQ6IChvcmdhbml6YXRpb24sIHRlYW0sIHRyaWdnZXIpID0+XG4gICAgYnVpbGRUZWFtTGlmZWN5Y2xlRXZlbnQoXG4gICAgICBPUkdBTklaQVRJT05fRVZFTlRfVFlQRVMuT1JHQU5JWkFUSU9OX1RFQU1fQ1JFQVRFRCxcbiAgICAgIFwiT3JnYW5pemF0aW9uIHRlYW0gY3JlYXRlZFwiLFxuICAgICAgb3JnYW5pemF0aW9uLFxuICAgICAgdGVhbSxcbiAgICAgIHRyaWdnZXIsXG4gICAgKSxcbiAgdHJhY2tPcmdhbml6YXRpb25UZWFtVXBkYXRlZDogKG9yZ2FuaXphdGlvbiwgdGVhbSwgdHJpZ2dlcikgPT5cbiAgICBidWlsZFRlYW1MaWZlY3ljbGVFdmVudChcbiAgICAgIE9SR0FOSVpBVElPTl9FVkVOVF9UWVBFUy5PUkdBTklaQVRJT05fVEVBTV9VUERBVEVELFxuICAgICAgXCJPcmdhbml6YXRpb24gdGVhbSB1cGRhdGVkXCIsXG4gICAgICBvcmdhbml6YXRpb24sXG4gICAgICB0ZWFtLFxuICAgICAgdHJpZ2dlcixcbiAgICApLFxuICB0cmFja09yZ2FuaXphdGlvblRlYW1EZWxldGVkOiAob3JnYW5pemF0aW9uLCB0ZWFtLCB0cmlnZ2VyKSA9PlxuICAgIGJ1aWxkVGVhbUxpZmVjeWNsZUV2ZW50KFxuICAgICAgT1JHQU5JWkFUSU9OX0VWRU5UX1RZUEVTLk9SR0FOSVpBVElPTl9URUFNX0RFTEVURUQsXG4gICAgICBcIk9yZ2FuaXphdGlvbiB0ZWFtIGRlbGV0ZWRcIixcbiAgICAgIG9yZ2FuaXphdGlvbixcbiAgICAgIHRlYW0sXG4gICAgICB0cmlnZ2VyLFxuICAgICksXG4gIHRyYWNrT3JnYW5pemF0aW9uVGVhbU1lbWJlckFkZGVkOiAob3JnYW5pemF0aW9uLCB0ZWFtLCB1c2VyLCB0ZWFtTWVtYmVyLCB0cmlnZ2VyKSA9PlxuICAgIGJ1aWxkVGVhbU1lbWJlckV2ZW50KFxuICAgICAgT1JHQU5JWkFUSU9OX0VWRU5UX1RZUEVTLk9SR0FOSVpBVElPTl9URUFNX01FTUJFUl9BRERFRCxcbiAgICAgIFwiVXNlciBhZGRlZCB0byBvcmdhbml6YXRpb24gdGVhbVwiLFxuICAgICAgb3JnYW5pemF0aW9uLFxuICAgICAgdGVhbSxcbiAgICAgIHVzZXIsXG4gICAgICB0ZWFtTWVtYmVyLFxuICAgICAgdHJpZ2dlcixcbiAgICApLFxuICB0cmFja09yZ2FuaXphdGlvblRlYW1NZW1iZXJSZW1vdmVkOiAob3JnYW5pemF0aW9uLCB0ZWFtLCB1c2VyLCB0ZWFtTWVtYmVyLCB0cmlnZ2VyKSA9PlxuICAgIGJ1aWxkVGVhbU1lbWJlckV2ZW50KFxuICAgICAgT1JHQU5JWkFUSU9OX0VWRU5UX1RZUEVTLk9SR0FOSVpBVElPTl9URUFNX01FTUJFUl9SRU1PVkVELFxuICAgICAgXCJVc2VyIHJlbW92ZWQgZnJvbSBvcmdhbml6YXRpb24gdGVhbVwiLFxuICAgICAgb3JnYW5pemF0aW9uLFxuICAgICAgdGVhbSxcbiAgICAgIHVzZXIsXG4gICAgICB0ZWFtTWVtYmVyLFxuICAgICAgdHJpZ2dlcixcbiAgICApLFxufSk7XG5cbmV4cG9ydCB0eXBlIE1lbWJlckV2ZW50QnVpbGRlcnMgPSB7XG4gIHRyYWNrT3JnYW5pemF0aW9uTWVtYmVyQWRkZWQ6IEJ1aWxkZXI8XG4gICAgW09yZ2FuaXphdGlvblNuYXBzaG90LCBNZW1iZXJTbmFwc2hvdCwgVXNlclNuYXBzaG90LCBCdWlsZGVyVHJpZ2dlcl1cbiAgPjtcbiAgdHJhY2tPcmdhbml6YXRpb25NZW1iZXJSZW1vdmVkOiBCdWlsZGVyPFxuICAgIFtPcmdhbml6YXRpb25TbmFwc2hvdCwgTWVtYmVyU25hcHNob3QsIFVzZXJTbmFwc2hvdCwgQnVpbGRlclRyaWdnZXJdXG4gID47XG4gIHRyYWNrT3JnYW5pemF0aW9uTWVtYmVyUm9sZVVwZGF0ZWQ6IEJ1aWxkZXI8XG4gICAgW09yZ2FuaXphdGlvblNuYXBzaG90LCBNZW1iZXJTbmFwc2hvdCwgVXNlclNuYXBzaG90LCBzdHJpbmcsIEJ1aWxkZXJUcmlnZ2VyXVxuICA+O1xufTtcblxuY29uc3QgbWVtYmVyQ29yZURhdGEgPSAobWVtYmVyOiBNZW1iZXJTbmFwc2hvdCwgdXNlcjogVXNlclNuYXBzaG90KSA9PiAoe1xuICB1c2VySWQ6IG1lbWJlci51c2VySWQsXG4gIG1lbWJlck5hbWU6IHVzZXIubmFtZSxcbiAgcm9sZTogbWVtYmVyLnJvbGUsXG4gIG1lbWJlcklkOiBtZW1iZXIuaWQsXG4gIG1lbWJlckVtYWlsOiB1c2VyLmVtYWlsLFxufSk7XG5cbmNvbnN0IGJ1aWxkTWVtYmVyRXZlbnRzID0gKCk6IE1lbWJlckV2ZW50QnVpbGRlcnMgPT4gKHtcbiAgdHJhY2tPcmdhbml6YXRpb25NZW1iZXJBZGRlZDogKG9yZ2FuaXphdGlvbiwgbWVtYmVyLCB1c2VyLCB0cmlnZ2VyKSA9PlxuICAgIGNyZWF0ZUV2ZW50KFxuICAgICAge1xuICAgICAgICBldmVudEtleTogb3JnYW5pemF0aW9uLmlkLFxuICAgICAgICBldmVudFR5cGU6IE9SR0FOSVpBVElPTl9FVkVOVF9UWVBFUy5PUkdBTklaQVRJT05fTUVNQkVSX0FEREVELFxuICAgICAgICBldmVudERpc3BsYXlOYW1lOiBcIk1lbWJlciBhZGRlZCB0byBvcmdhbml6YXRpb25cIixcbiAgICAgIH0sXG4gICAgICB7IC4uLm9yZ2FuaXphdGlvbklkZW50aXR5RGF0YShvcmdhbml6YXRpb24pLCAuLi5tZW1iZXJDb3JlRGF0YShtZW1iZXIsIHVzZXIpIH0sXG4gICAgICB0cmlnZ2VyLFxuICAgICksXG4gIHRyYWNrT3JnYW5pemF0aW9uTWVtYmVyUmVtb3ZlZDogKG9yZ2FuaXphdGlvbiwgbWVtYmVyLCB1c2VyLCB0cmlnZ2VyKSA9PlxuICAgIGNyZWF0ZUV2ZW50KFxuICAgICAge1xuICAgICAgICBldmVudEtleTogb3JnYW5pemF0aW9uLmlkLFxuICAgICAgICBldmVudFR5cGU6IE9SR0FOSVpBVElPTl9FVkVOVF9UWVBFUy5PUkdBTklaQVRJT05fTUVNQkVSX1JFTU9WRUQsXG4gICAgICAgIGV2ZW50RGlzcGxheU5hbWU6IFwiTWVtYmVyIHJlbW92ZWQgZnJvbSBvcmdhbml6YXRpb25cIixcbiAgICAgIH0sXG4gICAgICB7IC4uLm9yZ2FuaXphdGlvbklkZW50aXR5RGF0YShvcmdhbml6YXRpb24pLCAuLi5tZW1iZXJDb3JlRGF0YShtZW1iZXIsIHVzZXIpIH0sXG4gICAgICB0cmlnZ2VyLFxuICAgICksXG4gIHRyYWNrT3JnYW5pemF0aW9uTWVtYmVyUm9sZVVwZGF0ZWQ6IChvcmdhbml6YXRpb24sIG1lbWJlciwgdXNlciwgcHJldmlvdXNSb2xlLCB0cmlnZ2VyKSA9PlxuICAgIGNyZWF0ZUV2ZW50KFxuICAgICAge1xuICAgICAgICBldmVudEtleTogb3JnYW5pemF0aW9uLmlkLFxuICAgICAgICBldmVudFR5cGU6IE9SR0FOSVpBVElPTl9FVkVOVF9UWVBFUy5PUkdBTklaQVRJT05fTUVNQkVSX1JPTEVfVVBEQVRFRCxcbiAgICAgICAgZXZlbnREaXNwbGF5TmFtZTogXCJPcmdhbml6YXRpb24gbWVtYmVyIHJvbGUgdXBkYXRlZFwiLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgLi4ub3JnYW5pemF0aW9uSWRlbnRpdHlEYXRhKG9yZ2FuaXphdGlvbiksXG4gICAgICAgIHVzZXJJZDogbWVtYmVyLnVzZXJJZCxcbiAgICAgICAgbWVtYmVyTmFtZTogdXNlci5uYW1lLFxuICAgICAgICBuZXdSb2xlOiBtZW1iZXIucm9sZSxcbiAgICAgICAgb2xkUm9sZTogcHJldmlvdXNSb2xlLFxuICAgICAgICBtZW1iZXJJZDogbWVtYmVyLmlkLFxuICAgICAgICBtZW1iZXJFbWFpbDogdXNlci5lbWFpbCxcbiAgICAgIH0sXG4gICAgICB0cmlnZ2VyLFxuICAgICksXG59KTtcblxuZXhwb3J0IHR5cGUgSW52aXRhdGlvbkV2ZW50QnVpbGRlcnMgPSB7XG4gIHRyYWNrT3JnYW5pemF0aW9uTWVtYmVySW52aXRlZDogQnVpbGRlcjxcbiAgICBbT3JnYW5pemF0aW9uU25hcHNob3QsIEludml0YXRpb25TbmFwc2hvdCwgVXNlclNuYXBzaG90LCBCdWlsZGVyVHJpZ2dlcl1cbiAgPjtcbiAgdHJhY2tPcmdhbml6YXRpb25NZW1iZXJJbnZpdGVBY2NlcHRlZDogQnVpbGRlcjxcbiAgICBbT3JnYW5pemF0aW9uU25hcHNob3QsIEludml0YXRpb25TbmFwc2hvdCwgTWVtYmVyU25hcHNob3QsIFVzZXJTbmFwc2hvdCwgQnVpbGRlclRyaWdnZXJdXG4gID47XG4gIHRyYWNrT3JnYW5pemF0aW9uTWVtYmVySW52aXRlUmVqZWN0ZWQ6IEJ1aWxkZXI8XG4gICAgW09yZ2FuaXphdGlvblNuYXBzaG90LCBJbnZpdGF0aW9uU25hcHNob3QsIFVzZXJTbmFwc2hvdCwgQnVpbGRlclRyaWdnZXJdXG4gID47XG4gIHRyYWNrT3JnYW5pemF0aW9uTWVtYmVySW52aXRlQ2FuY2VsZWQ6IEJ1aWxkZXI8XG4gICAgW09yZ2FuaXphdGlvblNuYXBzaG90LCBJbnZpdGF0aW9uU25hcHNob3QsIFVzZXJTbmFwc2hvdCwgQnVpbGRlclRyaWdnZXJdXG4gID47XG59O1xuXG5jb25zdCBpbnZpdGVlRGF0YSA9IChpbnZpdGF0aW9uOiBJbnZpdGF0aW9uU25hcHNob3QpID0+ICh7XG4gIGludml0ZWVJZDogaW52aXRhdGlvbi5pZCxcbiAgaW52aXRlZUVtYWlsOiBpbnZpdGF0aW9uLmVtYWlsLFxuICBpbnZpdGVlUm9sZTogaW52aXRhdGlvbi5yb2xlLFxuICBpbnZpdGVlVGVhbUlkOiBpbnZpdGF0aW9uLnRlYW1JZCxcbn0pO1xuXG5jb25zdCBidWlsZEludml0YXRpb25FdmVudHMgPSAoKTogSW52aXRhdGlvbkV2ZW50QnVpbGRlcnMgPT4gKHtcbiAgdHJhY2tPcmdhbml6YXRpb25NZW1iZXJJbnZpdGVkOiAob3JnYW5pemF0aW9uLCBpbnZpdGF0aW9uLCBpbnZpdGVyLCB0cmlnZ2VyKSA9PlxuICAgIGNyZWF0ZUV2ZW50KFxuICAgICAge1xuICAgICAgICBldmVudEtleTogb3JnYW5pemF0aW9uLmlkLFxuICAgICAgICBldmVudFR5cGU6IE9SR0FOSVpBVElPTl9FVkVOVF9UWVBFUy5PUkdBTklaQVRJT05fTUVNQkVSX0lOVklURUQsXG4gICAgICAgIGV2ZW50RGlzcGxheU5hbWU6IFwiVXNlciBpbnZpdGVkIHRvIG9yZ2FuaXphdGlvblwiLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgLi4ub3JnYW5pemF0aW9uSWRlbnRpdHlEYXRhKG9yZ2FuaXphdGlvbiksXG4gICAgICAgIC4uLmludml0ZWVEYXRhKGludml0YXRpb24pLFxuICAgICAgICBpbnZpdGVySWQ6IGludml0ZXIuaWQsXG4gICAgICAgIGludml0ZXJOYW1lOiBpbnZpdGVyLm5hbWUsXG4gICAgICAgIGludml0ZXJFbWFpbDogaW52aXRlci5lbWFpbCxcbiAgICAgIH0sXG4gICAgICB0cmlnZ2VyLFxuICAgICksXG4gIHRyYWNrT3JnYW5pemF0aW9uTWVtYmVySW52aXRlQWNjZXB0ZWQ6IChvcmdhbml6YXRpb24sIGludml0YXRpb24sIG1lbWJlciwgYWNjZXB0ZWRCeSwgdHJpZ2dlcikgPT5cbiAgICBjcmVhdGVFdmVudChcbiAgICAgIHtcbiAgICAgICAgZXZlbnRLZXk6IG9yZ2FuaXphdGlvbi5pZCxcbiAgICAgICAgZXZlbnRUeXBlOiBPUkdBTklaQVRJT05fRVZFTlRfVFlQRVMuT1JHQU5JWkFUSU9OX01FTUJFUl9JTlZJVEVfQUNDRVBURUQsXG4gICAgICAgIGV2ZW50RGlzcGxheU5hbWU6IFwiVXNlciBhY2NlcHRlZCBpbnZpdGUgb3JnYW5pemF0aW9uIGludml0ZVwiLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgLi4ub3JnYW5pemF0aW9uSWRlbnRpdHlEYXRhKG9yZ2FuaXphdGlvbiksXG4gICAgICAgIC4uLmludml0ZWVEYXRhKGludml0YXRpb24pLFxuICAgICAgICBhY2NlcHRlZEJ5SWQ6IGFjY2VwdGVkQnkuaWQsXG4gICAgICAgIGFjY2VwdGVkQnlFbWFpbDogYWNjZXB0ZWRCeS5lbWFpbCxcbiAgICAgICAgYWNjZXB0ZWRCeU5hbWU6IGFjY2VwdGVkQnkubmFtZSxcbiAgICAgICAgbWVtYmVySWQ6IG1lbWJlci5pZCxcbiAgICAgICAgbWVtYmVyUm9sZTogbWVtYmVyLnJvbGUsXG4gICAgICB9LFxuICAgICAgdHJpZ2dlcixcbiAgICApLFxuICB0cmFja09yZ2FuaXphdGlvbk1lbWJlckludml0ZVJlamVjdGVkOiAob3JnYW5pemF0aW9uLCBpbnZpdGF0aW9uLCByZWplY3RlZEJ5LCB0cmlnZ2VyKSA9PlxuICAgIGNyZWF0ZUV2ZW50KFxuICAgICAge1xuICAgICAgICBldmVudEtleTogb3JnYW5pemF0aW9uLmlkLFxuICAgICAgICBldmVudFR5cGU6IE9SR0FOSVpBVElPTl9FVkVOVF9UWVBFUy5PUkdBTklaQVRJT05fTUVNQkVSX0lOVklURV9SRUpFQ1RFRCxcbiAgICAgICAgZXZlbnREaXNwbGF5TmFtZTogXCJVc2VyIHJlamVjdGVkIG9yZ2FuaXphdGlvbiBpbnZpdGVcIixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIC4uLm9yZ2FuaXphdGlvbklkZW50aXR5RGF0YShvcmdhbml6YXRpb24pLFxuICAgICAgICAuLi5pbnZpdGVlRGF0YShpbnZpdGF0aW9uKSxcbiAgICAgICAgcmVqZWN0ZWRCeUlkOiByZWplY3RlZEJ5LmlkLFxuICAgICAgICByZWplY3RlZEJ5RW1haWw6IHJlamVjdGVkQnkuZW1haWwsXG4gICAgICAgIHJlamVjdGVkQnlOYW1lOiByZWplY3RlZEJ5Lm5hbWUsXG4gICAgICB9LFxuICAgICAgdHJpZ2dlcixcbiAgICApLFxuICB0cmFja09yZ2FuaXphdGlvbk1lbWJlckludml0ZUNhbmNlbGVkOiAob3JnYW5pemF0aW9uLCBpbnZpdGF0aW9uLCBjYW5jZWxsZWRCeSwgdHJpZ2dlcikgPT5cbiAgICBjcmVhdGVFdmVudChcbiAgICAgIHtcbiAgICAgICAgZXZlbnRLZXk6IG9yZ2FuaXphdGlvbi5pZCxcbiAgICAgICAgZXZlbnRUeXBlOiBPUkdBTklaQVRJT05fRVZFTlRfVFlQRVMuT1JHQU5JWkFUSU9OX01FTUJFUl9JTlZJVEVfQ0FOQ0VMRUQsXG4gICAgICAgIGV2ZW50RGlzcGxheU5hbWU6IFwiT3JnYW5pemF0aW9uIGludml0ZSBjYW5jZWxsZWRcIixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIC4uLm9yZ2FuaXphdGlvbklkZW50aXR5RGF0YShvcmdhbml6YXRpb24pLFxuICAgICAgICAuLi5pbnZpdGVlRGF0YShpbnZpdGF0aW9uKSxcbiAgICAgICAgY2FuY2VsbGVkQnlJZDogY2FuY2VsbGVkQnkuaWQsXG4gICAgICAgIGNhbmNlbGxlZEJ5TmFtZTogY2FuY2VsbGVkQnkubmFtZSxcbiAgICAgICAgY2FuY2VsbGVkQnlFbWFpbDogY2FuY2VsbGVkQnkuZW1haWwsXG4gICAgICB9LFxuICAgICAgdHJpZ2dlcixcbiAgICApLFxufSk7XG5cbi8vIFRPRE8oc2VjdXJpdHkpOiBzb25hbXUuY29uZmln7J2YIHNlY3VyaXR5IOyYteyFmOydtCDrj4TsnoXrkJjrqbRcbi8vIFNlY3VyaXR5RXZlbnRCdWlsZGVycyAodHJhY2tTZWN1cml0eUJsb2NrZWQvQWxsb3dlZC9DaGFsbGVuZ2VkL1N0YWxlQWNjb3VudCkg7IS57IWY7J2EIOy2lOqwgO2VnOuLpC5cbi8vIGRhc2jsnZggY3JlYXRlU2VjdXJpdHlDbGllbnQvb25TZWN1cml0eUV2ZW50IOq1rO2YhOydgCDtmITsnqwgc2NvcGUgb3V0IChSMSkuXG5cbmV4cG9ydCB0eXBlIEF1ZGl0RXZlbnRCdWlsZGVyQ2F0YWxvZyA9IHtcbiAgYWNjb3VudDogQWNjb3VudEV2ZW50QnVpbGRlcnM7XG4gIHNlc3Npb246IFNlc3Npb25FdmVudEJ1aWxkZXJzO1xuICB1c2VyOiBVc2VyRXZlbnRCdWlsZGVycztcbiAgdmVyaWZpY2F0aW9uOiBWZXJpZmljYXRpb25FdmVudEJ1aWxkZXJzO1xuICBvcmdhbml6YXRpb246IE9yZ2FuaXphdGlvbkV2ZW50QnVpbGRlcnM7XG4gIHRlYW06IFRlYW1FdmVudEJ1aWxkZXJzO1xuICBtZW1iZXI6IE1lbWJlckV2ZW50QnVpbGRlcnM7XG4gIGludml0YXRpb246IEludml0YXRpb25FdmVudEJ1aWxkZXJzO1xufTtcblxuZXhwb3J0IGNvbnN0IGJ1aWxkQXVkaXRFdmVudENhdGFsb2cgPSAoKTogQXVkaXRFdmVudEJ1aWxkZXJDYXRhbG9nID0+ICh7XG4gIGFjY291bnQ6IGJ1aWxkQWNjb3VudEV2ZW50cygpLFxuICBzZXNzaW9uOiBidWlsZFNlc3Npb25FdmVudHMoKSxcbiAgdXNlcjogYnVpbGRVc2VyRXZlbnRzKCksXG4gIHZlcmlmaWNhdGlvbjogYnVpbGRWZXJpZmljYXRpb25FdmVudHMoKSxcbiAgb3JnYW5pemF0aW9uOiBidWlsZE9yZ2FuaXphdGlvbkV2ZW50cygpLFxuICB0ZWFtOiBidWlsZFRlYW1FdmVudHMoKSxcbiAgbWVtYmVyOiBidWlsZE1lbWJlckV2ZW50cygpLFxuICBpbnZpdGF0aW9uOiBidWlsZEludml0YXRpb25FdmVudHMoKSxcbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7QUFtQkEsTUFBTSxlQUNKLE1BQ0EsTUFDQSxTQUNBLGNBQ21CO0NBQ25CLEdBQUc7Q0FDSCxXQUFXO0VBQ1QsR0FBRztFQUNILGFBQWEsUUFBUTtFQUNyQixnQkFBZ0IsUUFBUTtFQUN6QjtDQUNELFdBQVcsVUFBVTtDQUNyQixNQUFNLFVBQVU7Q0FDaEIsU0FBUyxVQUFVO0NBQ25CLGFBQWEsVUFBVTtDQUN4QjtBQWlCRCxNQUFNLHFCQUNKLFdBQ0Esa0JBQ0EsU0FDQSxNQUNB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