@pipeline-builder/pipeline-data 0.0.1

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 (48) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +61 -0
  3. package/drizzle.config.ts +17 -0
  4. package/lib/api/access-control-builder.d.ts +148 -0
  5. package/lib/api/access-control-builder.js +199 -0
  6. package/lib/api/crud-service.d.ts +343 -0
  7. package/lib/api/crud-service.js +849 -0
  8. package/lib/api/query-builders.d.ts +82 -0
  9. package/lib/api/query-builders.js +460 -0
  10. package/lib/api/reporting-service.d.ts +685 -0
  11. package/lib/api/reporting-service.js +1564 -0
  12. package/lib/api/soft-delete-sweep.d.ts +65 -0
  13. package/lib/api/soft-delete-sweep.js +124 -0
  14. package/lib/api/viewer-context.d.ts +29 -0
  15. package/lib/api/viewer-context.js +63 -0
  16. package/lib/core/query-filters.d.ts +263 -0
  17. package/lib/core/query-filters.js +4 -0
  18. package/lib/database/drizzle-schema.d.ts +7357 -0
  19. package/lib/database/drizzle-schema.js +66 -0
  20. package/lib/database/index.d.ts +5 -0
  21. package/lib/database/index.js +8 -0
  22. package/lib/database/migrator.d.ts +20 -0
  23. package/lib/database/migrator.js +80 -0
  24. package/lib/database/postgres-connection.d.ts +201 -0
  25. package/lib/database/postgres-connection.js +413 -0
  26. package/lib/database/retry-strategy.d.ts +68 -0
  27. package/lib/database/retry-strategy.js +122 -0
  28. package/lib/database/schema/alert.d.ts +588 -0
  29. package/lib/database/schema/alert.js +130 -0
  30. package/lib/database/schema/compliance.d.ts +3319 -0
  31. package/lib/database/schema/compliance.js +377 -0
  32. package/lib/database/schema/dashboard.d.ts +474 -0
  33. package/lib/database/schema/dashboard.js +129 -0
  34. package/lib/database/schema/message-attachment.d.ts +183 -0
  35. package/lib/database/schema/message-attachment.js +40 -0
  36. package/lib/database/schema/message.d.ts +411 -0
  37. package/lib/database/schema/message.js +114 -0
  38. package/lib/database/schema/pipeline-template.d.ts +466 -0
  39. package/lib/database/schema/pipeline-template.js +80 -0
  40. package/lib/database/schema/pipeline.d.ts +1613 -0
  41. package/lib/database/schema/pipeline.js +332 -0
  42. package/lib/database/schema/plugin.d.ts +749 -0
  43. package/lib/database/schema/plugin.js +166 -0
  44. package/lib/database/tenancy.d.ts +103 -0
  45. package/lib/database/tenancy.js +167 -0
  46. package/lib/index.d.ts +32 -0
  47. package/lib/index.js +38 -0
  48. package/package.json +161 -0
@@ -0,0 +1,377 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { SYSTEM_ORG_ID } from '@pipeline-builder/api-core';
4
+ import { sql } from 'drizzle-orm';
5
+ import { boolean, integer, varchar, pgTable, text, timestamp, uuid, jsonb, index, uniqueIndex } from 'drizzle-orm/pg-core';
6
+ /**
7
+ * Compliance policies group rules into named sets that can be enabled/disabled together.
8
+ *
9
+ * @table compliance_policies
10
+ */
11
+ export const compliancePolicy = pgTable('compliance_policies', {
12
+ id: uuid('id').primaryKey().defaultRandom(),
13
+ orgId: varchar('org_id', { length: 255 }).default(SYSTEM_ORG_ID).notNull(),
14
+ createdBy: text('created_by').default('system').notNull(),
15
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
16
+ updatedBy: text('updated_by').default('system').notNull(),
17
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
18
+ name: varchar('name', { length: 255 }).notNull(),
19
+ description: text('description'),
20
+ version: varchar('version', { length: 50 }).default('1.0.0').notNull(),
21
+ isTemplate: boolean('is_template').default(false).notNull(),
22
+ // No sharing rung: compliance visibility is org + the system-org carve-out,
23
+ // applied in `buildCompliancePolicyConditions` / `buildComplianceRuleConditions`.
24
+ isDefault: boolean('is_default').default(false).notNull(),
25
+ isActive: boolean('is_active').default(true).notNull(),
26
+ deletedAt: timestamp('deleted_at', { withTimezone: true }),
27
+ deletedBy: text('deleted_by'),
28
+ // Soft-delete purge deadline: the retention sweep hard-deletes tombstoned
29
+ // rows once `purge_after` has passed (set on delete alongside deleted_at).
30
+ purgeAfter: timestamp('purge_after', { withTimezone: true }),
31
+ }, (table) => ({
32
+ purgeIdx: index('compliance_policy_purge_idx').on(table.purgeAfter).where(sql `deleted_at IS NOT NULL`),
33
+ orgActiveIdx: index('compliance_policy_org_active_idx').on(table.orgId, table.isActive),
34
+ templateIdx: index('compliance_policy_template_idx').on(table.isTemplate),
35
+ nameOrgVersionUnique: uniqueIndex('compliance_policy_name_org_version_unique')
36
+ .on(table.orgId, table.name, table.version),
37
+ }));
38
+ /**
39
+ * Compliance rules define individual checks against plugin/pipeline attributes.
40
+ *
41
+ * @table compliance_rules
42
+ */
43
+ export const complianceRule = pgTable('compliance_rules', {
44
+ id: uuid('id').primaryKey().defaultRandom(),
45
+ orgId: varchar('org_id', { length: 255 }).default(SYSTEM_ORG_ID).notNull(),
46
+ createdBy: text('created_by').default('system').notNull(),
47
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
48
+ updatedBy: text('updated_by').default('system').notNull(),
49
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
50
+ // Rule identity
51
+ name: varchar('name', { length: 255 }).notNull(),
52
+ description: text('description'),
53
+ policyId: uuid('policy_id').references(() => compliancePolicy.id, { onDelete: 'set null' }),
54
+ priority: integer('priority').default(0).notNull(),
55
+ target: varchar('target', { length: 20 }).$type().notNull(),
56
+ severity: varchar('severity', { length: 10 }).$type().default('error').notNull(),
57
+ // Categorization
58
+ tags: jsonb('tags').$type().default([]).notNull(),
59
+ // Scheduling
60
+ effectiveFrom: timestamp('effective_from', { withTimezone: true }),
61
+ effectiveUntil: timestamp('effective_until', { withTimezone: true }),
62
+ // Scope
63
+ scope: varchar('scope', { length: 10 }).$type().default('org').notNull(),
64
+ // Forking tracks which published rule this org rule was copied from
65
+ forkedFromRuleId: uuid('forked_from_rule_id'),
66
+ // Notification override
67
+ suppressNotification: boolean('suppress_notification').default(false).notNull(),
68
+ // Org → team hierarchy: when true, this (parent-org) rule is also enforced on
69
+ // descendant team orgs during their compliance evaluation.
70
+ propagateToChildren: boolean('propagate_to_children').default(false).notNull(),
71
+ // Single-field condition
72
+ field: varchar('field', { length: 100 }),
73
+ operator: varchar('operator', { length: 20 }).$type(),
74
+ value: jsonb('value'),
75
+ // Cross-field conditions (overrides single-field when present)
76
+ conditions: jsonb('conditions').$type(),
77
+ conditionMode: varchar('condition_mode', { length: 5 }).$type().default('all'),
78
+ // Access and visibility
79
+ // No sharing rung: compliance visibility is org + the system-org carve-out,
80
+ // applied in `buildCompliancePolicyConditions` / `buildComplianceRuleConditions`.
81
+ isDefault: boolean('is_default').default(false).notNull(),
82
+ isActive: boolean('is_active').default(true).notNull(),
83
+ deletedAt: timestamp('deleted_at', { withTimezone: true }),
84
+ deletedBy: text('deleted_by'),
85
+ // Soft-delete purge deadline: the retention sweep hard-deletes tombstoned
86
+ // rows once `purge_after` has passed (set on delete alongside deleted_at).
87
+ purgeAfter: timestamp('purge_after', { withTimezone: true }),
88
+ }, (table) => ({
89
+ purgeIdx: index('compliance_rule_purge_idx').on(table.purgeAfter).where(sql `deleted_at IS NOT NULL`),
90
+ orgTargetActiveIdx: index('compliance_rule_org_target_active_idx')
91
+ .on(table.orgId, table.target, table.isActive),
92
+ orgPolicyIdx: index('compliance_rule_org_policy_idx').on(table.orgId, table.policyId),
93
+ priorityIdx: index('compliance_rule_priority_idx').on(table.priority),
94
+ scopeIdx: index('compliance_rule_scope_idx').on(table.scope),
95
+ effectiveFromIdx: index('compliance_rule_effective_from_idx').on(table.effectiveFrom),
96
+ nameOrgUnique: uniqueIndex('compliance_rule_name_org_unique').on(table.orgId, table.name),
97
+ // Partial GIN index backing the curated-set lookup
98
+ // `findPublishedRuleIdsBySetTag` (subscription-service): a containment query
99
+ // `tags @> '["set:<x>"]'::jsonb` restricted to published rows. `jsonb_path_ops`
100
+ // is the smaller/faster opclass — it only supports `@>` (exactly this query),
101
+ // not key-existence, which we never run against `tags`. Scoped to
102
+ // `scope = 'published'` so only the curated catalog (a handful of rows) is
103
+ // indexed, not every org's private rule tags.
104
+ // MIGRATION REQUIRED: run `pnpm drizzle-kit generate` after pulling.
105
+ publishedTagsGinIdx: index('compliance_rule_published_tags_gin_idx')
106
+ .using('gin', table.tags.op('jsonb_path_ops'))
107
+ .where(sql `scope = 'published'`),
108
+ }));
109
+ /**
110
+ * Tracks every change to compliance rules for versioning and rollback.
111
+ *
112
+ * @table compliance_rule_history
113
+ */
114
+ export const complianceRuleHistory = pgTable('compliance_rule_history', {
115
+ id: uuid('id').primaryKey().defaultRandom(),
116
+ ruleId: uuid('rule_id').notNull().references(() => complianceRule.id, { onDelete: 'cascade' }),
117
+ orgId: varchar('org_id', { length: 255 }).notNull(),
118
+ changeType: varchar('change_type', { length: 20 }).notNull(), // created | updated | deleted | restored
119
+ previousState: jsonb('previous_state'), // full rule snapshot before change
120
+ changedBy: text('changed_by').notNull(),
121
+ changedAt: timestamp('changed_at', { withTimezone: true }).defaultNow().notNull(),
122
+ }, (table) => ({
123
+ ruleChangedAtIdx: index('compliance_rule_history_rule_changed_idx')
124
+ .on(table.ruleId, table.changedAt),
125
+ orgChangedAtIdx: index('compliance_rule_history_org_changed_idx')
126
+ .on(table.orgId, table.changedAt),
127
+ ruleIdIdx: index('compliance_rule_history_rule_id_idx')
128
+ .on(table.ruleId),
129
+ }));
130
+ /**
131
+ * Compliance audit log stores every compliance check result.
132
+ *
133
+ * @table compliance_audit_log
134
+ */
135
+ export const complianceAuditLog = pgTable('compliance_audit_log', {
136
+ id: uuid('id').primaryKey().defaultRandom(),
137
+ orgId: varchar('org_id', { length: 255 }).notNull(),
138
+ userId: text('user_id').notNull(),
139
+ target: varchar('target', { length: 20 }).$type().notNull(),
140
+ action: varchar('action', { length: 20 }).notNull(), // upload | deploy | create | update | scan
141
+ entityId: varchar('entity_id', { length: 255 }),
142
+ entityName: varchar('entity_name', { length: 255 }),
143
+ result: varchar('result', { length: 10 }).notNull(), // pass | warn | block
144
+ violations: jsonb('violations').$type().default([]),
145
+ ruleCount: integer('rule_count').notNull(),
146
+ scanId: uuid('scan_id'), // groups entries from the same bulk scan
147
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
148
+ }, (table) => ({
149
+ orgCreatedAtIdx: index('compliance_audit_org_created_idx').on(table.orgId, table.createdAt),
150
+ // DESC variant for the dominant "latest audit events per org" query
151
+ // pattern (audit log UIs sort newest-first). Postgres can use the asc
152
+ // index for desc scans, but a matching DESC index lets index-only scans
153
+ // satisfy `ORDER BY created_at DESC LIMIT n` without a reverse step.
154
+ // MIGRATION REQUIRED: run `pnpm drizzle-kit generate` after pulling.
155
+ orgCreatedAtDescIdx: index('compliance_audit_org_created_desc_idx')
156
+ .on(table.orgId, sql `${table.createdAt} DESC`),
157
+ orgTargetResultIdx: index('compliance_audit_org_target_result_idx')
158
+ .on(table.orgId, table.target, table.result),
159
+ scanIdIdx: index('compliance_audit_scan_id_idx').on(table.scanId),
160
+ }));
161
+ /**
162
+ * Per-entity exemptions from specific compliance rules.
163
+ *
164
+ * @table compliance_exemptions
165
+ */
166
+ export const complianceExemption = pgTable('compliance_exemptions', {
167
+ id: uuid('id').primaryKey().defaultRandom(),
168
+ orgId: varchar('org_id', { length: 255 }).notNull(),
169
+ ruleId: uuid('rule_id').notNull().references(() => complianceRule.id, { onDelete: 'cascade' }),
170
+ entityType: varchar('entity_type', { length: 20 }).$type().notNull(),
171
+ entityId: uuid('entity_id').notNull(),
172
+ entityName: varchar('entity_name', { length: 255 }),
173
+ reason: text('reason').notNull(),
174
+ approvedBy: text('approved_by'),
175
+ rejectionReason: text('rejection_reason'),
176
+ status: varchar('status', { length: 20 }).default('pending').notNull(), // pending | approved | rejected | expired
177
+ expiresAt: timestamp('expires_at', { withTimezone: true }),
178
+ createdBy: text('created_by').notNull(),
179
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
180
+ updatedBy: text('updated_by').notNull(),
181
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
182
+ }, (table) => ({
183
+ orgRuleEntityUnique: uniqueIndex('compliance_exemption_org_rule_entity_unique')
184
+ .on(table.orgId, table.ruleId, table.entityId),
185
+ orgStatusIdx: index('compliance_exemption_org_status_idx').on(table.orgId, table.status),
186
+ expiresAtIdx: index('compliance_exemption_expires_at_idx').on(table.expiresAt),
187
+ entityIdIdx: index('compliance_exemption_entity_id_idx').on(table.entityId),
188
+ }));
189
+ /**
190
+ * Tracks which orgs have opted into system-org published compliance rules.
191
+ *
192
+ * @table compliance_rule_subscriptions
193
+ */
194
+ export const complianceRuleSubscription = pgTable('compliance_rule_subscriptions', {
195
+ id: uuid('id').primaryKey().defaultRandom(),
196
+ orgId: varchar('org_id', { length: 255 }).notNull(),
197
+ ruleId: uuid('rule_id').notNull().references(() => complianceRule.id, { onDelete: 'cascade' }),
198
+ subscribedBy: text('subscribed_by').notNull(),
199
+ subscribedAt: timestamp('subscribed_at', { withTimezone: true }).defaultNow().notNull(),
200
+ isActive: boolean('is_active').default(true).notNull(),
201
+ pinnedVersion: jsonb('pinned_version').$type(),
202
+ unsubscribedAt: timestamp('unsubscribed_at', { withTimezone: true }),
203
+ unsubscribedBy: text('unsubscribed_by'),
204
+ }, (table) => ({
205
+ orgRuleUnique: uniqueIndex('compliance_rule_sub_org_rule_unique').on(table.orgId, table.ruleId),
206
+ orgActiveIdx: index('compliance_rule_sub_org_active_idx').on(table.orgId, table.isActive),
207
+ ruleIdx: index('compliance_rule_sub_rule_idx').on(table.ruleId),
208
+ }));
209
+ /**
210
+ * Bulk compliance scans tracks scheduled and on-demand scans.
211
+ *
212
+ * @table compliance_scans
213
+ */
214
+ export const complianceScan = pgTable('compliance_scans', {
215
+ id: uuid('id').primaryKey().defaultRandom(),
216
+ orgId: varchar('org_id', { length: 255 }).notNull(),
217
+ target: varchar('target', { length: 20 }).notNull(), // plugin | pipeline | all
218
+ filter: jsonb('filter'), // optional entity filter for partial scans
219
+ status: varchar('status', { length: 20 }).default('pending').notNull(), // pending | running | completed | failed | cancelled
220
+ triggeredBy: varchar('triggered_by', { length: 20 }).notNull(), // manual | scheduled | rule-change | rule-dry-run
221
+ userId: text('user_id').notNull(),
222
+ totalEntities: integer('total_entities').default(0).notNull(),
223
+ processedEntities: integer('processed_entities').default(0).notNull(),
224
+ passCount: integer('pass_count').default(0).notNull(),
225
+ warnCount: integer('warn_count').default(0).notNull(),
226
+ blockCount: integer('block_count').default(0).notNull(),
227
+ // True when the scan stopped early at a configured per-scan cap (so the
228
+ // counts above represent a subset, not the full entity universe). Surfaced
229
+ // in the scan-status UI so users know whether to widen the filter.
230
+ // MIGRATION REQUIRED: run `pnpm drizzle-kit generate` after pulling.
231
+ truncated: boolean('truncated').default(false).notNull(),
232
+ startedAt: timestamp('started_at', { withTimezone: true }),
233
+ completedAt: timestamp('completed_at', { withTimezone: true }),
234
+ cancelledAt: timestamp('cancelled_at', { withTimezone: true }),
235
+ cancelledBy: text('cancelled_by'),
236
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
237
+ }, (table) => ({
238
+ orgCreatedAtIdx: index('compliance_scan_org_created_idx').on(table.orgId, table.createdAt),
239
+ orgStatusIdx: index('compliance_scan_org_status_idx').on(table.orgId, table.status),
240
+ }));
241
+ /**
242
+ * Cron-based recurring scan schedules.
243
+ *
244
+ * @table compliance_scan_schedules
245
+ */
246
+ export const complianceScanSchedule = pgTable('compliance_scan_schedules', {
247
+ id: uuid('id').primaryKey().defaultRandom(),
248
+ orgId: varchar('org_id', { length: 255 }).notNull(),
249
+ target: varchar('target', { length: 20 }).notNull(), // plugin | pipeline | all
250
+ cronExpression: varchar('cron_expression', { length: 100 }).notNull(),
251
+ isActive: boolean('is_active').default(true).notNull(),
252
+ lastRunAt: timestamp('last_run_at', { withTimezone: true }),
253
+ nextRunAt: timestamp('next_run_at', { withTimezone: true }),
254
+ createdBy: text('created_by').notNull(),
255
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
256
+ updatedBy: text('updated_by').notNull(),
257
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
258
+ }, (table) => ({
259
+ activeNextRunIdx: index('compliance_scan_schedule_active_next_idx')
260
+ .on(table.isActive, table.nextRunAt),
261
+ orgIdx: index('compliance_scan_schedule_org_idx').on(table.orgId),
262
+ }));
263
+ /**
264
+ * Per-org notification settings for compliance events.
265
+ *
266
+ * @table compliance_notification_preferences
267
+ */
268
+ export const complianceNotificationPreference = pgTable('compliance_notification_preferences', {
269
+ id: uuid('id').primaryKey().defaultRandom(),
270
+ orgId: varchar('org_id', { length: 255 }).notNull().unique(),
271
+ notifyOnBlock: boolean('notify_on_block').default(true).notNull(),
272
+ notifyOnWarning: boolean('notify_on_warning').default(false).notNull(),
273
+ // Opt-in email delivery (to `targetUsers`, or all org admins when null).
274
+ emailEnabled: boolean('email_enabled').default(false).notNull(),
275
+ digestMode: varchar('digest_mode', { length: 20 }).default('immediate').notNull(), // immediate | daily | weekly
276
+ digestSchedule: varchar('digest_schedule', { length: 100 }),
277
+ lastDigestAt: timestamp('last_digest_at', { withTimezone: true }),
278
+ targetUsers: jsonb('target_users').$type(), // null = all org admins
279
+ webhookUrl: varchar('webhook_url', { length: 500 }),
280
+ webhookSecret: varchar('webhook_secret', { length: 255 }),
281
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
282
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
283
+ });
284
+ /**
285
+ * Log of all compliance notifications sent.
286
+ *
287
+ * @table compliance_notification_log
288
+ */
289
+ export const complianceNotificationLog = pgTable('compliance_notification_log', {
290
+ id: uuid('id').primaryKey().defaultRandom(),
291
+ orgId: varchar('org_id', { length: 255 }).notNull(),
292
+ channel: varchar('channel', { length: 20 }).notNull(), // in-app | webhook | digest
293
+ status: varchar('status', { length: 20 }).notNull(), // sent | failed | pending
294
+ payload: jsonb('payload').$type().notNull(),
295
+ webhookResponseCode: integer('webhook_response_code'),
296
+ webhookError: text('webhook_error'),
297
+ retryCount: integer('retry_count').default(0).notNull(),
298
+ nextRetryAt: timestamp('next_retry_at', { withTimezone: true }),
299
+ relatedAuditId: uuid('related_audit_id'),
300
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
301
+ }, (table) => ({
302
+ orgCreatedAtIdx: index('compliance_notification_org_created_idx')
303
+ .on(table.orgId, table.createdAt),
304
+ statusRetryIdx: index('compliance_notification_status_retry_idx')
305
+ .on(table.status, table.nextRetryAt),
306
+ relatedAuditIdx: index('compliance_notification_related_audit_idx')
307
+ .on(table.relatedAuditId),
308
+ }));
309
+ export const complianceRole = pgTable('compliance_roles', {
310
+ id: uuid('id').primaryKey().defaultRandom(),
311
+ orgId: varchar('org_id', { length: 255 }).notNull(),
312
+ userId: text('user_id').notNull(),
313
+ role: varchar('role', { length: 30 }).$type().notNull(),
314
+ grantedBy: text('granted_by').notNull(),
315
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
316
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
317
+ }, (table) => ({
318
+ orgUserUnique: uniqueIndex('compliance_role_org_user_unique').on(table.orgId, table.userId),
319
+ orgRoleIdx: index('compliance_role_org_role_idx').on(table.orgId, table.role),
320
+ }));
321
+ /**
322
+ * Generated compliance reports.
323
+ *
324
+ * @table compliance_reports
325
+ */
326
+ export const complianceReport = pgTable('compliance_reports', {
327
+ id: uuid('id').primaryKey().defaultRandom(),
328
+ orgId: varchar('org_id', { length: 255 }).notNull(),
329
+ reportType: varchar('report_type', { length: 30 }).notNull(), // summary | detailed | audit-trail | comparison
330
+ target: varchar('target', { length: 20 }).notNull(), // plugin | pipeline | all
331
+ dateFrom: timestamp('date_from', { withTimezone: true }),
332
+ dateTo: timestamp('date_to', { withTimezone: true }),
333
+ compareFrom: timestamp('compare_from', { withTimezone: true }),
334
+ compareTo: timestamp('compare_to', { withTimezone: true }),
335
+ data: jsonb('data').$type().notNull(),
336
+ format: varchar('format', { length: 10 }).default('json').notNull(), // json | csv
337
+ generatedBy: text('generated_by').notNull(),
338
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
339
+ }, (table) => ({
340
+ orgCreatedAtIdx: index('compliance_report_org_created_idx').on(table.orgId, table.createdAt),
341
+ }));
342
+ /**
343
+ * Cron-based recurring report generation schedules.
344
+ *
345
+ * @table compliance_report_schedules
346
+ */
347
+ export const complianceReportSchedule = pgTable('compliance_report_schedules', {
348
+ id: uuid('id').primaryKey().defaultRandom(),
349
+ orgId: varchar('org_id', { length: 255 }).notNull(),
350
+ reportType: varchar('report_type', { length: 30 }).notNull(), // summary | detailed
351
+ target: varchar('target', { length: 20 }).notNull(), // plugin | pipeline | all
352
+ format: varchar('format', { length: 10 }).default('json').notNull(),
353
+ cronExpression: varchar('cron_expression', { length: 100 }).notNull(),
354
+ isActive: boolean('is_active').default(true).notNull(),
355
+ lastRunAt: timestamp('last_run_at', { withTimezone: true }),
356
+ nextRunAt: timestamp('next_run_at', { withTimezone: true }),
357
+ deliverTo: jsonb('deliver_to').$type().default([]).notNull(), // userIds to notify
358
+ createdBy: text('created_by').notNull(),
359
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
360
+ updatedBy: text('updated_by').notNull(),
361
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
362
+ }, (table) => ({
363
+ activeNextRunIdx: index('compliance_report_schedule_active_next_idx')
364
+ .on(table.isActive, table.nextRunAt),
365
+ orgIdx: index('compliance_report_schedule_org_idx').on(table.orgId),
366
+ }));
367
+ // Per-org watermark for the billing→compliance entitlement sync
368
+ // (`PUT /entitlements/:orgId`). Billing stamps each push with `occurredAt`; the
369
+ // route skips any push not strictly newer than the stored value so out-of-order
370
+ // deliveries (concurrent purchase + drift reconciler, retries) can't revert a
371
+ // newer entitlement state. Sync metadata only — no tenant content, so no RLS.
372
+ // MIGRATION REQUIRED: run `pnpm drizzle-kit generate` after pulling.
373
+ export const complianceEntitlementWatermark = pgTable('compliance_entitlement_watermark', {
374
+ orgId: text('org_id').primaryKey(),
375
+ lastOccurredAt: timestamp('last_occurred_at', { withTimezone: true }).notNull(),
376
+ });
377
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxpYW5jZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kYXRhYmFzZS9zY2hlbWEvY29tcGxpYW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQWlEM0g7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRTtJQUM3RCxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLGFBQWEsRUFBRTtJQUMzQyxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFDMUUsU0FBUyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ3pELFNBQVMsRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxFQUFFO0lBQ2pGLFNBQVMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN6RCxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxF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QyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDYixnQkFBZ0IsRUFBRSxLQUFLLENBQUMsNENBQTRDLENBQUM7U0FDbEUsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQztJQUN0QyxNQUFNLEVBQUUsS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7Q0FDcEUsQ0FBQyxDQUFDLENBQUM7QUFFSixnRUFBZ0U7QUFDaEUsZ0ZBQWdGO0FBQ2hGLGdGQUFnRjtBQUNoRiw4RUFBOEU7QUFDOUUsOEVBQThFO0FBQzlFLHFFQUFxRTtBQUNyRSxNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRyxPQUFPLENBQUMsa0NBQWtDLEVBQUU7SUFDeEYsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxVQUFVLEVBQUU7SUFDbEMsY0FBYyxFQUFFLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRTtDQUNoRixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGJvb2xlYW4sIGludGVnZXIsIHZhcmNoYXIsIHBnVGFibGUsIHRleHQsIHRpbWVzdGFtcCwgdXVpZCwganNvbmIsIGluZGV4LCB1bmlxdWVJbmRleCB9IGZyb20gJ2RyaXp6bGUtb3JtL3BnLWNvcmUnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBDb21wbGlhbmNlIFNlcnZpY2UgVGFibGVzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ29tcGxpYW5jZSBydWxlIHNldmVyaXR5IGxldmVscy5cbiAqL1xuZXhwb3J0IHR5cGUgUnVsZVNldmVyaXR5ID0gJ3dhcm5pbmcnIHwgJ2Vycm9yJyB8ICdjcml0aWNhbCc7XG5cbi8qKlxuICogQ29tcGxpYW5jZSBydWxlIHRhcmdldCBlbnRpdHkgdHlwZXMuXG4gKi9cbmV4cG9ydCB0eXBlIFJ1bGVUYXJnZXQgPSAncGx1Z2luJyB8ICdwaXBlbGluZSc7XG5cbi8qKlxuICogQ29tcGxpYW5jZSBydWxlIG9wZXJhdG9ycyBmb3IgZmllbGQgZXZhbHVhdGlvbi5cbiAqL1xuZXhwb3J0IHR5cGUgUnVsZU9wZXJhdG9yID1cbiAgfCAnZXEnIHwgJ25lcSdcbiAgfCAnY29udGFpbnMnIHwgJ25vdENvbnRhaW5zJ1xuICB8ICdyZWdleCdcbiAgfCAnZ3QnIHwgJ2d0ZScgfCAnbHQnIHwgJ2x0ZSdcbiAgfCAnaW4nIHwgJ25vdEluJ1xuICB8ICdleGlzdHMnIHwgJ25vdEV4aXN0cycgfCAnbm90RW1wdHknXG4gIHwgJ2NvdW50R3QnIHwgJ2NvdW50THQnXG4gIHwgJ2xlbmd0aEd0JyB8ICdsZW5ndGhMdCc7XG5cbi8qKlxuICogQ3Jvc3MtZmllbGQgY29uZGl0aW9uIG1vZGUgZm9yIG11bHRpLWNvbmRpdGlvbiBydWxlcy5cbiAqL1xuZXhwb3J0IHR5cGUgUnVsZUNvbmRpdGlvbk1vZGUgPSAnYWxsJyB8ICdhbnknO1xuXG4vKipcbiAqIFJ1bGUgc2NvcGUgIG9yZy1sZXZlbCBvciBwdWJsaXNoZWQgKHN5c3RlbSBvcmcgb25seSwgb3B0LWluIHZpYSBzdWJzY3JpcHRpb24pLlxuICovXG5leHBvcnQgdHlwZSBSdWxlU2NvcGUgPSAnb3JnJyB8ICdwdWJsaXNoZWQnO1xuXG4vKipcbiAqIEEgc2luZ2xlIGNvbmRpdGlvbiBpbiBhIGNyb3NzLWZpZWxkIHJ1bGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZUNvbmRpdGlvbiB7XG4gIGZpZWxkPzogc3RyaW5nO1xuICBvcGVyYXRvcj86IFJ1bGVPcGVyYXRvcjtcbiAgdmFsdWU/OiB1bmtub3duO1xuICBkZXBlbmRzT25SdWxlPzogc3RyaW5nOyAvLyBydWxlIElEICBvbmx5IGV2YWx1YXRlIGlmIHJlZmVyZW5jZWQgcnVsZSBwYXNzZWRcbn1cblxuLyoqXG4gKiBDb21wbGlhbmNlIHBvbGljaWVzIGdyb3VwIHJ1bGVzIGludG8gbmFtZWQgc2V0cyB0aGF0IGNhbiBiZSBlbmFibGVkL2Rpc2FibGVkIHRvZ2V0aGVyLlxuICpcbiAqIEB0YWJsZSBjb21wbGlhbmNlX3BvbGljaWVzXG4gKi9cbmV4cG9ydCBjb25zdCBjb21wbGlhbmNlUG9saWN5ID0gcGdUYWJsZSgnY29tcGxpYW5jZV9wb2xpY2llcycsIHtcbiAgaWQ6IHV1aWQoJ2lkJykucHJpbWFyeUtleSgpLmRlZmF1bHRSYW5kb20oKSxcbiAgb3JnSWQ6IHZhcmNoYXIoJ29yZ19pZCcsIHsgbGVuZ3RoOiAyNTUgfSkuZGVmYXVsdChTWVNURU1fT1JHX0lEKS5ub3ROdWxsKCksXG4gIGNyZWF0ZWRCeTogdGV4dCgnY3JlYXRlZF9ieScpLmRlZmF1bHQoJ3N5c3RlbScpLm5vdE51bGwoKSxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXAoJ2NyZWF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICB1cGRhdGVkQnk6IHRleHQoJ3VwZGF0ZWRfYnknKS5kZWZhdWx0KCdzeXN0ZW0nKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRBdDogdGltZXN0YW1wKCd1cGRhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcblxuICBuYW1lOiB2YXJjaGFyKCduYW1lJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIGRlc2NyaXB0aW9uOiB0ZXh0KCdkZXNjcmlwdGlvbicpLFxuICB2ZXJzaW9uOiB2YXJjaGFyKCd2ZXJzaW9uJywgeyBsZW5ndGg6IDUwIH0pLmRlZmF1bHQoJzEuMC4wJykubm90TnVsbCgpLFxuICBpc1RlbXBsYXRlOiBib29sZWFuKCdpc190ZW1wbGF0ZScpLmRlZmF1bHQoZmFsc2UpLm5vdE51bGwoKSxcblxuICAvLyBObyBzaGFyaW5nIHJ1bmc6IGNvbXBsaWFuY2UgdmlzaWJpbGl0eSBpcyBvcmcgKyB0aGUgc3lzdGVtLW9yZyBjYXJ2ZS1vdXQsXG4gIC8vIGFwcGxpZWQgaW4gYGJ1aWxkQ29tcGxpYW5jZVBvbGljeUNvbmRpdGlvbnNgIC8gYGJ1aWxkQ29tcGxpYW5jZVJ1bGVDb25kaXRpb25zYC5cbiAgaXNEZWZhdWx0OiBib29sZWFuKCdpc19kZWZhdWx0JykuZGVmYXVsdChmYWxzZSkubm90TnVsbCgpLFxuICBpc0FjdGl2ZTogYm9vbGVhbignaXNfYWN0aXZlJykuZGVmYXVsdCh0cnVlKS5ub3ROdWxsKCksXG4gIGRlbGV0ZWRBdDogdGltZXN0YW1wKCdkZWxldGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIGRlbGV0ZWRCeTogdGV4dCgnZGVsZXRlZF9ieScpLFxuICAvLyBTb2Z0LWRlbGV0ZSBwdXJnZSBkZWFkbGluZTogdGhlIHJldGVudGlvbiBzd2VlcCBoYXJkLWRlbGV0ZXMgdG9tYnN0b25lZFxuICAvLyByb3dzIG9uY2UgYHB1cmdlX2FmdGVyYCBoYXMgcGFzc2VkIChzZXQgb24gZGVsZXRlIGFsb25nc2lkZSBkZWxldGVkX2F0KS5cbiAgcHVyZ2VBZnRlcjogdGltZXN0YW1wKCdwdXJnZV9hZnRlcicsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxufSwgKHRhYmxlKSA9PiAoe1xuICBwdXJnZUlkeDogaW5kZXgoJ2NvbXBsaWFuY2VfcG9saWN5X3B1cmdlX2lkeCcpLm9uKHRhYmxlLnB1cmdlQWZ0ZXIpLndoZXJlKHNxbGBkZWxldGVkX2F0IElTIE5PVCBOVUxMYCksXG4gIG9yZ0FjdGl2ZUlkeDogaW5kZXgoJ2NvbXBsaWFuY2VfcG9saWN5X29yZ19hY3RpdmVfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLmlzQWN0aXZlKSxcbiAgdGVtcGxhdGVJZHg6IGluZGV4KCdjb21wbGlhbmNlX3BvbGljeV90ZW1wbGF0ZV9pZHgnKS5vbih0YWJsZS5pc1RlbXBsYXRlKSxcbiAgbmFtZU9yZ1ZlcnNpb25VbmlxdWU6IHVuaXF1ZUluZGV4KCdjb21wbGlhbmNlX3BvbGljeV9uYW1lX29yZ192ZXJzaW9uX3VuaXF1ZScpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS5uYW1lLCB0YWJsZS52ZXJzaW9uKSxcbn0pKTtcblxuLyoqXG4gKiBDb21wbGlhbmNlIHJ1bGVzIGRlZmluZSBpbmRpdmlkdWFsIGNoZWNrcyBhZ2FpbnN0IHBsdWdpbi9waXBlbGluZSBhdHRyaWJ1dGVzLlxuICpcbiAqIEB0YWJsZSBjb21wbGlhbmNlX3J1bGVzXG4gKi9cbmV4cG9ydCBjb25zdCBjb21wbGlhbmNlUnVsZSA9IHBnVGFibGUoJ2NvbXBsaWFuY2VfcnVsZXMnLCB7XG4gIGlkOiB1dWlkKCdpZCcpLnByaW1hcnlLZXkoKS5kZWZhdWx0UmFuZG9tKCksXG4gIG9yZ0lkOiB2YXJjaGFyKCdvcmdfaWQnLCB7IGxlbmd0aDogMjU1IH0pLmRlZmF1bHQoU1lTVEVNX09SR19JRCkubm90TnVsbCgpLFxuICBjcmVhdGVkQnk6IHRleHQoJ2NyZWF0ZWRfYnknKS5kZWZhdWx0KCdzeXN0ZW0nKS5ub3ROdWxsKCksXG4gIGNyZWF0ZWRBdDogdGltZXN0YW1wKCdjcmVhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbiAgdXBkYXRlZEJ5OiB0ZXh0KCd1cGRhdGVkX2J5JykuZGVmYXVsdCgnc3lzdGVtJykubm90TnVsbCgpLFxuICB1cGRhdGVkQXQ6IHRpbWVzdGFtcCgndXBkYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG5cbiAgLy8gUnVsZSBpZGVudGl0eVxuICBuYW1lOiB2YXJjaGFyKCduYW1lJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIGRlc2NyaXB0aW9uOiB0ZXh0KCdkZXNjcmlwdGlvbicpLFxuICBwb2xpY3lJZDogdXVpZCgncG9saWN5X2lkJykucmVmZXJlbmNlcygoKSA9PiBjb21wbGlhbmNlUG9saWN5LmlkLCB7IG9uRGVsZXRlOiAnc2V0IG51bGwnIH0pLFxuICBwcmlvcml0eTogaW50ZWdlcigncHJpb3JpdHknKS5kZWZhdWx0KDApLm5vdE51bGwoKSxcbiAgdGFyZ2V0OiB2YXJjaGFyKCd0YXJnZXQnLCB7IGxlbmd0aDogMjAgfSkuJHR5cGU8UnVsZVRhcmdldD4oKS5ub3ROdWxsKCksXG4gIHNldmVyaXR5OiB2YXJjaGFyKCdzZXZlcml0eScsIHsgbGVuZ3RoOiAxMCB9KS4kdHlwZTxSdWxlU2V2ZXJpdHk+KCkuZGVmYXVsdCgnZXJyb3InKS5ub3ROdWxsKCksXG5cbiAgLy8gQ2F0ZWdvcml6YXRpb25cbiAgdGFnczoganNvbmIoJ3RhZ3MnKS4kdHlwZTxzdHJpbmdbXT4oKS5kZWZhdWx0KFtdKS5ub3ROdWxsKCksXG5cbiAgLy8gU2NoZWR1bGluZ1xuICBlZmZlY3RpdmVGcm9tOiB0aW1lc3RhbXAoJ2VmZmVjdGl2ZV9mcm9tJywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIGVmZmVjdGl2ZVVudGlsOiB0aW1lc3RhbXAoJ2VmZmVjdGl2ZV91bnRpbCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuXG4gIC8vIFNjb3BlXG4gIHNjb3BlOiB2YXJjaGFyKCdzY29wZScsIHsgbGVuZ3RoOiAxMCB9KS4kdHlwZTxSdWxlU2NvcGU+KCkuZGVmYXVsdCgnb3JnJykubm90TnVsbCgpLFxuXG4gIC8vIEZvcmtpbmcgIHRyYWNrcyB3aGljaCBwdWJsaXNoZWQgcnVsZSB0aGlzIG9yZyBydWxlIHdhcyBjb3BpZWQgZnJvbVxuICBmb3JrZWRGcm9tUnVsZUlkOiB1dWlkKCdmb3JrZWRfZnJvbV9ydWxlX2lkJyksXG5cbiAgLy8gTm90aWZpY2F0aW9uIG92ZXJyaWRlXG4gIHN1cHByZXNzTm90aWZpY2F0aW9uOiBib29sZWFuKCdzdXBwcmVzc19ub3RpZmljYXRpb24nKS5kZWZhdWx0KGZhbHNlKS5ub3ROdWxsKCksXG5cbiAgLy8gT3JnIOKGkiB0ZWFtIGhpZXJhcmNoeTogd2hlbiB0cnVlLCB0aGlzIChwYXJlbnQtb3JnKSBydWxlIGlzIGFsc28gZW5mb3JjZWQgb25cbiAgLy8gZGVzY2VuZGFudCB0ZWFtIG9yZ3MgZHVyaW5nIHRoZWlyIGNvbXBsaWFuY2UgZXZhbHVhdGlvbi5cbiAgcHJvcGFnYXRlVG9DaGlsZHJlbjogYm9vbGVhbigncHJvcGFnYXRlX3RvX2NoaWxkcmVuJykuZGVmYXVsdChmYWxzZSkubm90TnVsbCgpLFxuXG4gIC8vIFNpbmdsZS1maWVsZCBjb25kaXRpb25cbiAgZmllbGQ6IHZhcmNoYXIoJ2ZpZWxkJywgeyBsZW5ndGg6IDEwMCB9KSxcbiAgb3BlcmF0b3I6IHZhcmNoYXIoJ29wZXJhdG9yJywgeyBsZW5ndGg6IDIwIH0pLiR0eXBlPFJ1bGVPcGVyYXRvcj4oKSxcbiAgdmFsdWU6IGpzb25iKCd2YWx1ZScpLFxuXG4gIC8vIENyb3NzLWZpZWxkIGNvbmRpdGlvbnMgKG92ZXJyaWRlcyBzaW5nbGUtZmllbGQgd2hlbiBwcmVzZW50KVxuICBjb25kaXRpb25zOiBqc29uYignY29uZGl0aW9ucycpLiR0eXBlPFJ1bGVDb25kaXRpb25bXT4oKSxcbiAgY29uZGl0aW9uTW9kZTogdmFyY2hhcignY29uZGl0aW9uX21vZGUnLCB7IGxlbmd0aDogNSB9KS4kdHlwZTxSdWxlQ29uZGl0aW9uTW9kZT4oKS5kZWZhdWx0KCdhbGwnKSxcblxuICAvLyBBY2Nlc3MgYW5kIHZpc2liaWxpdHlcbiAgLy8gTm8gc2hhcmluZyBydW5nOiBjb21wbGlhbmNlIHZpc2liaWxpdHkgaXMgb3JnICsgdGhlIHN5c3RlbS1vcmcgY2FydmUtb3V0LFxuICAvLyBhcHBsaWVkIGluIGBidWlsZENvbXBsaWFuY2VQb2xpY3lDb25kaXRpb25zYCAvIGBidWlsZENvbXBsaWFuY2VSdWxlQ29uZGl0aW9uc2AuXG4gIGlzRGVmYXVsdDogYm9vbGVhbignaXNfZGVmYXVsdCcpLmRlZmF1bHQoZmFsc2UpLm5vdE51bGwoKSxcbiAgaXNBY3RpdmU6IGJvb2xlYW4oJ2lzX2FjdGl2ZScpLmRlZmF1bHQodHJ1ZSkubm90TnVsbCgpLFxuICBkZWxldGVkQXQ6IHRpbWVzdGFtcCgnZGVsZXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICBkZWxldGVkQnk6IHRleHQoJ2RlbGV0ZWRfYnknKSxcbiAgLy8gU29mdC1kZWxldGUgcHVyZ2UgZGVhZGxpbmU6IHRoZSByZXRlbnRpb24gc3dlZXAgaGFyZC1kZWxldGVzIHRvbWJzdG9uZWRcbiAgLy8gcm93cyBvbmNlIGBwdXJnZV9hZnRlcmAgaGFzIHBhc3NlZCAoc2V0IG9uIGRlbGV0ZSBhbG9uZ3NpZGUgZGVsZXRlZF9hdCkuXG4gIHB1cmdlQWZ0ZXI6IHRpbWVzdGFtcCgncHVyZ2VfYWZ0ZXInLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbn0sICh0YWJsZSkgPT4gKHtcbiAgcHVyZ2VJZHg6IGluZGV4KCdjb21wbGlhbmNlX3J1bGVfcHVyZ2VfaWR4Jykub24odGFibGUucHVyZ2VBZnRlcikud2hlcmUoc3FsYGRlbGV0ZWRfYXQgSVMgTk9UIE5VTExgKSxcbiAgb3JnVGFyZ2V0QWN0aXZlSWR4OiBpbmRleCgnY29tcGxpYW5jZV9ydWxlX29yZ190YXJnZXRfYWN0aXZlX2lkeCcpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS50YXJnZXQsIHRhYmxlLmlzQWN0aXZlKSxcbiAgb3JnUG9saWN5SWR4OiBpbmRleCgnY29tcGxpYW5jZV9ydWxlX29yZ19wb2xpY3lfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLnBvbGljeUlkKSxcbiAgcHJpb3JpdHlJZHg6IGluZGV4KCdjb21wbGlhbmNlX3J1bGVfcHJpb3JpdHlfaWR4Jykub24odGFibGUucHJpb3JpdHkpLFxuICBzY29wZUlkeDogaW5kZXgoJ2NvbXBsaWFuY2VfcnVsZV9zY29wZV9pZHgnKS5vbih0YWJsZS5zY29wZSksXG4gIGVmZmVjdGl2ZUZyb21JZHg6IGluZGV4KCdjb21wbGlhbmNlX3J1bGVfZWZmZWN0aXZlX2Zyb21faWR4Jykub24odGFibGUuZWZmZWN0aXZlRnJvbSksXG4gIG5hbWVPcmdVbmlxdWU6IHVuaXF1ZUluZGV4KCdjb21wbGlhbmNlX3J1bGVfbmFtZV9vcmdfdW5pcXVlJykub24odGFibGUub3JnSWQsIHRhYmxlLm5hbWUpLFxuICAvLyBQYXJ0aWFsIEdJTiBpbmRleCBiYWNraW5nIHRoZSBjdXJhdGVkLXNldCBsb29rdXBcbiAgLy8gYGZpbmRQdWJsaXNoZWRSdWxlSWRzQnlTZXRUYWdgIChzdWJzY3JpcHRpb24tc2VydmljZSk6IGEgY29udGFpbm1lbnQgcXVlcnlcbiAgLy8gYHRhZ3MgQD4gJ1tcInNldDo8eD5cIl0nOjpqc29uYmAgcmVzdHJpY3RlZCB0byBwdWJsaXNoZWQgcm93cy4gYGpzb25iX3BhdGhfb3BzYFxuICAvLyBpcyB0aGUgc21hbGxlci9mYXN0ZXIgb3BjbGFzcyDigJQgaXQgb25seSBzdXBwb3J0cyBgQD5gIChleGFjdGx5IHRoaXMgcXVlcnkpLFxuICAvLyBub3Qga2V5LWV4aXN0ZW5jZSwgd2hpY2ggd2UgbmV2ZXIgcnVuIGFnYWluc3QgYHRhZ3NgLiBTY29wZWQgdG9cbiAgLy8gYHNjb3BlID0gJ3B1Ymxpc2hlZCdgIHNvIG9ubHkgdGhlIGN1cmF0ZWQgY2F0YWxvZyAoYSBoYW5kZnVsIG9mIHJvd3MpIGlzXG4gIC8vIGluZGV4ZWQsIG5vdCBldmVyeSBvcmcncyBwcml2YXRlIHJ1bGUgdGFncy5cbiAgLy8gTUlHUkFUSU9OIFJFUVVJUkVEOiBydW4gYHBucG0gZHJpenpsZS1raXQgZ2VuZXJhdGVgIGFmdGVyIHB1bGxpbmcuXG4gIHB1Ymxpc2hlZFRhZ3NHaW5JZHg6IGluZGV4KCdjb21wbGlhbmNlX3J1bGVfcHVibGlzaGVkX3RhZ3NfZ2luX2lkeCcpXG4gICAgLnVzaW5nKCdnaW4nLCB0YWJsZS50YWdzLm9wKCdqc29uYl9wYXRoX29wcycpKVxuICAgIC53aGVyZShzcWxgc2NvcGUgPSAncHVibGlzaGVkJ2ApLFxufSkpO1xuXG4vKipcbiAqIFRyYWNrcyBldmVyeSBjaGFuZ2UgdG8gY29tcGxpYW5jZSBydWxlcyBmb3IgdmVyc2lvbmluZyBhbmQgcm9sbGJhY2suXG4gKlxuICogQHRhYmxlIGNvbXBsaWFuY2VfcnVsZV9oaXN0b3J5XG4gKi9cbmV4cG9ydCBjb25zdCBjb21wbGlhbmNlUnVsZUhpc3RvcnkgPSBwZ1RhYmxlKCdjb21wbGlhbmNlX3J1bGVfaGlzdG9yeScsIHtcbiAgaWQ6IHV1aWQoJ2lkJykucHJpbWFyeUtleSgpLmRlZmF1bHRSYW5kb20oKSxcbiAgcnVsZUlkOiB1dWlkKCdydWxlX2lkJykubm90TnVsbCgpLnJlZmVyZW5jZXMoKCkgPT4gY29tcGxpYW5jZVJ1bGUuaWQsIHsgb25EZWxldGU6ICdjYXNjYWRlJyB9KSxcbiAgb3JnSWQ6IHZhcmNoYXIoJ29yZ19pZCcsIHsgbGVuZ3RoOiAyNTUgfSkubm90TnVsbCgpLFxuICBjaGFuZ2VUeXBlOiB2YXJjaGFyKCdjaGFuZ2VfdHlwZScsIHsgbGVuZ3RoOiAyMCB9KS5ub3ROdWxsKCksIC8vIGNyZWF0ZWQgfCB1cGRhdGVkIHwgZGVsZXRlZCB8IHJlc3RvcmVkXG4gIHByZXZpb3VzU3RhdGU6IGpzb25iKCdwcmV2aW91c19zdGF0ZScpLCAvLyBmdWxsIHJ1bGUgc25hcHNob3QgYmVmb3JlIGNoYW5nZVxuICBjaGFuZ2VkQnk6IHRleHQoJ2NoYW5nZWRfYnknKS5ub3ROdWxsKCksXG4gIGNoYW5nZWRBdDogdGltZXN0YW1wKCdjaGFuZ2VkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbn0sICh0YWJsZSkgPT4gKHtcbiAgcnVsZUNoYW5nZWRBdElkeDogaW5kZXgoJ2NvbXBsaWFuY2VfcnVsZV9oaXN0b3J5X3J1bGVfY2hhbmdlZF9pZHgnKVxuICAgIC5vbih0YWJsZS5ydWxlSWQsIHRhYmxlLmNoYW5nZWRBdCksXG4gIG9yZ0NoYW5nZWRBdElkeDogaW5kZXgoJ2NvbXBsaWFuY2VfcnVsZV9oaXN0b3J5X29yZ19jaGFuZ2VkX2lkeCcpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS5jaGFuZ2VkQXQpLFxuICBydWxlSWRJZHg6IGluZGV4KCdjb21wbGlhbmNlX3J1bGVfaGlzdG9yeV9ydWxlX2lkX2lkeCcpXG4gICAgLm9uKHRhYmxlLnJ1bGVJZCksXG59KSk7XG5cbi8qKlxuICogQ29tcGxpYW5jZSBhdWRpdCBsb2cgIHN0b3JlcyBldmVyeSBjb21wbGlhbmNlIGNoZWNrIHJlc3VsdC5cbiAqXG4gKiBAdGFibGUgY29tcGxpYW5jZV9hdWRpdF9sb2dcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbXBsaWFuY2VBdWRpdExvZyA9IHBnVGFibGUoJ2NvbXBsaWFuY2VfYXVkaXRfbG9nJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHVzZXJJZDogdGV4dCgndXNlcl9pZCcpLm5vdE51bGwoKSxcbiAgdGFyZ2V0OiB2YXJjaGFyKCd0YXJnZXQnLCB7IGxlbmd0aDogMjAgfSkuJHR5cGU8UnVsZVRhcmdldD4oKS5ub3ROdWxsKCksXG4gIGFjdGlvbjogdmFyY2hhcignYWN0aW9uJywgeyBsZW5ndGg6IDIwIH0pLm5vdE51bGwoKSwgLy8gdXBsb2FkIHwgZGVwbG95IHwgY3JlYXRlIHwgdXBkYXRlIHwgc2NhblxuICBlbnRpdHlJZDogdmFyY2hhcignZW50aXR5X2lkJywgeyBsZW5ndGg6IDI1NSB9KSxcbiAgZW50aXR5TmFtZTogdmFyY2hhcignZW50aXR5X25hbWUnLCB7IGxlbmd0aDogMjU1IH0pLFxuICByZXN1bHQ6IHZhcmNoYXIoJ3Jlc3VsdCcsIHsgbGVuZ3RoOiAxMCB9KS5ub3ROdWxsKCksIC8vIHBhc3MgfCB3YXJuIHwgYmxvY2tcbiAgdmlvbGF0aW9uczoganNvbmIoJ3Zpb2xhdGlvbnMnKS4kdHlwZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPigpLmRlZmF1bHQoW10pLFxuICBydWxlQ291bnQ6IGludGVnZXIoJ3J1bGVfY291bnQnKS5ub3ROdWxsKCksXG4gIHNjYW5JZDogdXVpZCgnc2Nhbl9pZCcpLCAvLyBncm91cHMgZW50cmllcyBmcm9tIHRoZSBzYW1lIGJ1bGsgc2NhblxuICBjcmVhdGVkQXQ6IHRpbWVzdGFtcCgnY3JlYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG59LCAodGFibGUpID0+ICh7XG4gIG9yZ0NyZWF0ZWRBdElkeDogaW5kZXgoJ2NvbXBsaWFuY2VfYXVkaXRfb3JnX2NyZWF0ZWRfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLmNyZWF0ZWRBdCksXG4gIC8vIERFU0MgdmFyaWFudCBmb3IgdGhlIGRvbWluYW50IFwibGF0ZXN0IGF1ZGl0IGV2ZW50cyBwZXIgb3JnXCIgcXVlcnlcbiAgLy8gcGF0dGVybiAoYXVkaXQgbG9nIFVJcyBzb3J0IG5ld2VzdC1maXJzdCkuIFBvc3RncmVzIGNhbiB1c2UgdGhlIGFzY1xuICAvLyBpbmRleCBmb3IgZGVzYyBzY2FucywgYnV0IGEgbWF0Y2hpbmcgREVTQyBpbmRleCBsZXRzIGluZGV4LW9ubHkgc2NhbnNcbiAgLy8gc2F0aXNmeSBgT1JERVIgQlkgY3JlYXRlZF9hdCBERVNDIExJTUlUIG5gIHdpdGhvdXQgYSByZXZlcnNlIHN0ZXAuXG4gIC8vIE1JR1JBVElPTiBSRVFVSVJFRDogcnVuIGBwbnBtIGRyaXp6bGUta2l0IGdlbmVyYXRlYCBhZnRlciBwdWxsaW5nLlxuICBvcmdDcmVhdGVkQXREZXNjSWR4OiBpbmRleCgnY29tcGxpYW5jZV9hdWRpdF9vcmdfY3JlYXRlZF9kZXNjX2lkeCcpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCBzcWxgJHt0YWJsZS5jcmVhdGVkQXR9IERFU0NgKSxcbiAgb3JnVGFyZ2V0UmVzdWx0SWR4OiBpbmRleCgnY29tcGxpYW5jZV9hdWRpdF9vcmdfdGFyZ2V0X3Jlc3VsdF9pZHgnKVxuICAgIC5vbih0YWJsZS5vcmdJZCwgdGFibGUudGFyZ2V0LCB0YWJsZS5yZXN1bHQpLFxuICBzY2FuSWRJZHg6IGluZGV4KCdjb21wbGlhbmNlX2F1ZGl0X3NjYW5faWRfaWR4Jykub24odGFibGUuc2NhbklkKSxcbn0pKTtcblxuLyoqXG4gKiBQZXItZW50aXR5IGV4ZW1wdGlvbnMgZnJvbSBzcGVjaWZpYyBjb21wbGlhbmNlIHJ1bGVzLlxuICpcbiAqIEB0YWJsZSBjb21wbGlhbmNlX2V4ZW1wdGlvbnNcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbXBsaWFuY2VFeGVtcHRpb24gPSBwZ1RhYmxlKCdjb21wbGlhbmNlX2V4ZW1wdGlvbnMnLCB7XG4gIGlkOiB1dWlkKCdpZCcpLnByaW1hcnlLZXkoKS5kZWZhdWx0UmFuZG9tKCksXG4gIG9yZ0lkOiB2YXJjaGFyKCdvcmdfaWQnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcbiAgcnVsZUlkOiB1dWlkKCdydWxlX2lkJykubm90TnVsbCgpLnJlZmVyZW5jZXMoKCkgPT4gY29tcGxpYW5jZVJ1bGUuaWQsIHsgb25EZWxldGU6ICdjYXNjYWRlJyB9KSxcbiAgZW50aXR5VHlwZTogdmFyY2hhcignZW50aXR5X3R5cGUnLCB7IGxlbmd0aDogMjAgfSkuJHR5cGU8UnVsZVRhcmdldD4oKS5ub3ROdWxsKCksXG4gIGVudGl0eUlkOiB1dWlkKCdlbnRpdHlfaWQnKS5ub3ROdWxsKCksXG4gIGVudGl0eU5hbWU6IHZhcmNoYXIoJ2VudGl0eV9uYW1lJywgeyBsZW5ndGg6IDI1NSB9KSxcbiAgcmVhc29uOiB0ZXh0KCdyZWFzb24nKS5ub3ROdWxsKCksXG4gIGFwcHJvdmVkQnk6IHRleHQoJ2FwcHJvdmVkX2J5JyksXG4gIHJlamVjdGlvblJlYXNvbjogdGV4dCgncmVqZWN0aW9uX3JlYXNvbicpLFxuICBzdGF0dXM6IHZhcmNoYXIoJ3N0YXR1cycsIHsgbGVuZ3RoOiAyMCB9KS5kZWZhdWx0KCdwZW5kaW5nJykubm90TnVsbCgpLCAvLyBwZW5kaW5nIHwgYXBwcm92ZWQgfCByZWplY3RlZCB8IGV4cGlyZWRcbiAgZXhwaXJlc0F0OiB0aW1lc3RhbXAoJ2V4cGlyZXNfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgY3JlYXRlZEJ5OiB0ZXh0KCdjcmVhdGVkX2J5Jykubm90TnVsbCgpLFxuICBjcmVhdGVkQXQ6IHRpbWVzdGFtcCgnY3JlYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRCeTogdGV4dCgndXBkYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgdXBkYXRlZEF0OiB0aW1lc3RhbXAoJ3VwZGF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxufSwgKHRhYmxlKSA9PiAoe1xuICBvcmdSdWxlRW50aXR5VW5pcXVlOiB1bmlxdWVJbmRleCgnY29tcGxpYW5jZV9leGVtcHRpb25fb3JnX3J1bGVfZW50aXR5X3VuaXF1ZScpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS5ydWxlSWQsIHRhYmxlLmVudGl0eUlkKSxcbiAgb3JnU3RhdHVzSWR4OiBpbmRleCgnY29tcGxpYW5jZV9leGVtcHRpb25fb3JnX3N0YXR1c19pZHgnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUuc3RhdHVzKSxcbiAgZXhwaXJlc0F0SWR4OiBpbmRleCgnY29tcGxpYW5jZV9leGVtcHRpb25fZXhwaXJlc19hdF9pZHgnKS5vbih0YWJsZS5leHBpcmVzQXQpLFxuICBlbnRpdHlJZElkeDogaW5kZXgoJ2NvbXBsaWFuY2VfZXhlbXB0aW9uX2VudGl0eV9pZF9pZHgnKS5vbih0YWJsZS5lbnRpdHlJZCksXG59KSk7XG5cbi8qKlxuICogVHJhY2tzIHdoaWNoIG9yZ3MgaGF2ZSBvcHRlZCBpbnRvIHN5c3RlbS1vcmcgcHVibGlzaGVkIGNvbXBsaWFuY2UgcnVsZXMuXG4gKlxuICogQHRhYmxlIGNvbXBsaWFuY2VfcnVsZV9zdWJzY3JpcHRpb25zXG4gKi9cbmV4cG9ydCBjb25zdCBjb21wbGlhbmNlUnVsZVN1YnNjcmlwdGlvbiA9IHBnVGFibGUoJ2NvbXBsaWFuY2VfcnVsZV9zdWJzY3JpcHRpb25zJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHJ1bGVJZDogdXVpZCgncnVsZV9pZCcpLm5vdE51bGwoKS5yZWZlcmVuY2VzKCgpID0+IGNvbXBsaWFuY2VSdWxlLmlkLCB7IG9uRGVsZXRlOiAnY2FzY2FkZScgfSksXG4gIHN1YnNjcmliZWRCeTogdGV4dCgnc3Vic2NyaWJlZF9ieScpLm5vdE51bGwoKSxcbiAgc3Vic2NyaWJlZEF0OiB0aW1lc3RhbXAoJ3N1YnNjcmliZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICBpc0FjdGl2ZTogYm9vbGVhbignaXNfYWN0aXZlJykuZGVmYXVsdCh0cnVlKS5ub3ROdWxsKCksXG4gIHBpbm5lZFZlcnNpb246IGpzb25iKCdwaW5uZWRfdmVyc2lvbicpLiR0eXBlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpLFxuICB1bnN1YnNjcmliZWRBdDogdGltZXN0YW1wKCd1bnN1YnNjcmliZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgdW5zdWJzY3JpYmVkQnk6IHRleHQoJ3Vuc3Vic2NyaWJlZF9ieScpLFxufSwgKHRhYmxlKSA9PiAoe1xuICBvcmdSdWxlVW5pcXVlOiB1bmlxdWVJbmRleCgnY29tcGxpYW5jZV9ydWxlX3N1Yl9vcmdfcnVsZV91bmlxdWUnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUucnVsZUlkKSxcbiAgb3JnQWN0aXZlSWR4OiBpbmRleCgnY29tcGxpYW5jZV9ydWxlX3N1Yl9vcmdfYWN0aXZlX2lkeCcpLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS5pc0FjdGl2ZSksXG4gIHJ1bGVJZHg6IGluZGV4KCdjb21wbGlhbmNlX3J1bGVfc3ViX3J1bGVfaWR4Jykub24odGFibGUucnVsZUlkKSxcbn0pKTtcblxuLyoqXG4gKiBCdWxrIGNvbXBsaWFuY2Ugc2NhbnMgIHRyYWNrcyBzY2hlZHVsZWQgYW5kIG9uLWRlbWFuZCBzY2Fucy5cbiAqXG4gKiBAdGFibGUgY29tcGxpYW5jZV9zY2Fuc1xuICovXG5leHBvcnQgY29uc3QgY29tcGxpYW5jZVNjYW4gPSBwZ1RhYmxlKCdjb21wbGlhbmNlX3NjYW5zJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHRhcmdldDogdmFyY2hhcigndGFyZ2V0JywgeyBsZW5ndGg6IDIwIH0pLm5vdE51bGwoKSwgLy8gcGx1Z2luIHwgcGlwZWxpbmUgfCBhbGxcbiAgZmlsdGVyOiBqc29uYignZmlsdGVyJyksIC8vIG9wdGlvbmFsIGVudGl0eSBmaWx0ZXIgZm9yIHBhcnRpYWwgc2NhbnNcbiAgc3RhdHVzOiB2YXJjaGFyKCdzdGF0dXMnLCB7IGxlbmd0aDogMjAgfSkuZGVmYXVsdCgncGVuZGluZycpLm5vdE51bGwoKSwgLy8gcGVuZGluZyB8IHJ1bm5pbmcgfCBjb21wbGV0ZWQgfCBmYWlsZWQgfCBjYW5jZWxsZWRcbiAgdHJpZ2dlcmVkQnk6IHZhcmNoYXIoJ3RyaWdnZXJlZF9ieScsIHsgbGVuZ3RoOiAyMCB9KS5ub3ROdWxsKCksIC8vIG1hbnVhbCB8IHNjaGVkdWxlZCB8IHJ1bGUtY2hhbmdlIHwgcnVsZS1kcnktcnVuXG4gIHVzZXJJZDogdGV4dCgndXNlcl9pZCcpLm5vdE51bGwoKSxcbiAgdG90YWxFbnRpdGllczogaW50ZWdlcigndG90YWxfZW50aXRpZXMnKS5kZWZhdWx0KDApLm5vdE51bGwoKSxcbiAgcHJvY2Vzc2VkRW50aXRpZXM6IGludGVnZXIoJ3Byb2Nlc3NlZF9lbnRpdGllcycpLmRlZmF1bHQoMCkubm90TnVsbCgpLFxuICBwYXNzQ291bnQ6IGludGVnZXIoJ3Bhc3NfY291bnQnKS5kZWZhdWx0KDApLm5vdE51bGwoKSxcbiAgd2FybkNvdW50OiBpbnRlZ2VyKCd3YXJuX2NvdW50JykuZGVmYXVsdCgwKS5ub3ROdWxsKCksXG4gIGJsb2NrQ291bnQ6IGludGVnZXIoJ2Jsb2NrX2NvdW50JykuZGVmYXVsdCgwKS5ub3ROdWxsKCksXG4gIC8vIFRydWUgd2hlbiB0aGUgc2NhbiBzdG9wcGVkIGVhcmx5IGF0IGEgY29uZmlndXJlZCBwZXItc2NhbiBjYXAgKHNvIHRoZVxuICAvLyBjb3VudHMgYWJvdmUgcmVwcmVzZW50IGEgc3Vic2V0LCBub3QgdGhlIGZ1bGwgZW50aXR5IHVuaXZlcnNlKS4gU3VyZmFjZWRcbiAgLy8gaW4gdGhlIHNjYW4tc3RhdHVzIFVJIHNvIHVzZXJzIGtub3cgd2hldGhlciB0byB3aWRlbiB0aGUgZmlsdGVyLlxuICAvLyBNSUdSQVRJT04gUkVRVUlSRUQ6IHJ1biBgcG5wbSBkcml6emxlLWtpdCBnZW5lcmF0ZWAgYWZ0ZXIgcHVsbGluZy5cbiAgdHJ1bmNhdGVkOiBib29sZWFuKCd0cnVuY2F0ZWQnKS5kZWZhdWx0KGZhbHNlKS5ub3ROdWxsKCksXG4gIHN0YXJ0ZWRBdDogdGltZXN0YW1wKCdzdGFydGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIGNvbXBsZXRlZEF0OiB0aW1lc3RhbXAoJ2NvbXBsZXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICBjYW5jZWxsZWRBdDogdGltZXN0YW1wKCdjYW5jZWxsZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgY2FuY2VsbGVkQnk6IHRleHQoJ2NhbmNlbGxlZF9ieScpLFxuICBjcmVhdGVkQXQ6IHRpbWVzdGFtcCgnY3JlYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG59LCAodGFibGUpID0+ICh7XG4gIG9yZ0NyZWF0ZWRBdElkeDogaW5kZXgoJ2NvbXBsaWFuY2Vfc2Nhbl9vcmdfY3JlYXRlZF9pZHgnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUuY3JlYXRlZEF0KSxcbiAgb3JnU3RhdHVzSWR4OiBpbmRleCgnY29tcGxpYW5jZV9zY2FuX29yZ19zdGF0dXNfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLnN0YXR1cyksXG59KSk7XG5cbi8qKlxuICogQ3Jvbi1iYXNlZCByZWN1cnJpbmcgc2NhbiBzY2hlZHVsZXMuXG4gKlxuICogQHRhYmxlIGNvbXBsaWFuY2Vfc2Nhbl9zY2hlZHVsZXNcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbXBsaWFuY2VTY2FuU2NoZWR1bGUgPSBwZ1RhYmxlKCdjb21wbGlhbmNlX3NjYW5fc2NoZWR1bGVzJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHRhcmdldDogdmFyY2hhcigndGFyZ2V0JywgeyBsZW5ndGg6IDIwIH0pLm5vdE51bGwoKSwgLy8gcGx1Z2luIHwgcGlwZWxpbmUgfCBhbGxcbiAgY3JvbkV4cHJlc3Npb246IHZhcmNoYXIoJ2Nyb25fZXhwcmVzc2lvbicsIHsgbGVuZ3RoOiAxMDAgfSkubm90TnVsbCgpLFxuICBpc0FjdGl2ZTogYm9vbGVhbignaXNfYWN0aXZlJykuZGVmYXVsdCh0cnVlKS5ub3ROdWxsKCksXG4gIGxhc3RSdW5BdDogdGltZXN0YW1wKCdsYXN0X3J1bl9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICBuZXh0UnVuQXQ6IHRpbWVzdGFtcCgnbmV4dF9ydW5fYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgY3JlYXRlZEJ5OiB0ZXh0KCdjcmVhdGVkX2J5Jykubm90TnVsbCgpLFxuICBjcmVhdGVkQXQ6IHRpbWVzdGFtcCgnY3JlYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRCeTogdGV4dCgndXBkYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgdXBkYXRlZEF0OiB0aW1lc3RhbXAoJ3VwZGF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxufSwgKHRhYmxlKSA9PiAoe1xuICBhY3RpdmVOZXh0UnVuSWR4OiBpbmRleCgnY29tcGxpYW5jZV9zY2FuX3NjaGVkdWxlX2FjdGl2ZV9uZXh0X2lkeCcpXG4gICAgLm9uKHRhYmxlLmlzQWN0aXZlLCB0YWJsZS5uZXh0UnVuQXQpLFxuICBvcmdJZHg6IGluZGV4KCdjb21wbGlhbmNlX3NjYW5fc2NoZWR1bGVfb3JnX2lkeCcpLm9uKHRhYmxlLm9yZ0lkKSxcbn0pKTtcblxuLyoqXG4gKiBQZXItb3JnIG5vdGlmaWNhdGlvbiBzZXR0aW5ncyBmb3IgY29tcGxpYW5jZSBldmVudHMuXG4gKlxuICogQHRhYmxlIGNvbXBsaWFuY2Vfbm90aWZpY2F0aW9uX3ByZWZlcmVuY2VzXG4gKi9cbmV4cG9ydCBjb25zdCBjb21wbGlhbmNlTm90aWZpY2F0aW9uUHJlZmVyZW5jZSA9IHBnVGFibGUoJ2NvbXBsaWFuY2Vfbm90aWZpY2F0aW9uX3ByZWZlcmVuY2VzJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCkudW5pcXVlKCksXG4gIG5vdGlmeU9uQmxvY2s6IGJvb2xlYW4oJ25vdGlmeV9vbl9ibG9jaycpLmRlZmF1bHQodHJ1ZSkubm90TnVsbCgpLFxuICBub3RpZnlPbldhcm5pbmc6IGJvb2xlYW4oJ25vdGlmeV9vbl93YXJuaW5nJykuZGVmYXVsdChmYWxzZSkubm90TnVsbCgpLFxuICAvLyBPcHQtaW4gZW1haWwgZGVsaXZlcnkgKHRvIGB0YXJnZXRVc2Vyc2AsIG9yIGFsbCBvcmcgYWRtaW5zIHdoZW4gbnVsbCkuXG4gIGVtYWlsRW5hYmxlZDogYm9vbGVhbignZW1haWxfZW5hYmxlZCcpLmRlZmF1bHQoZmFsc2UpLm5vdE51bGwoKSxcbiAgZGlnZXN0TW9kZTogdmFyY2hhcignZGlnZXN0X21vZGUnLCB7IGxlbmd0aDogMjAgfSkuZGVmYXVsdCgnaW1tZWRpYXRlJykubm90TnVsbCgpLCAvLyBpbW1lZGlhdGUgfCBkYWlseSB8IHdlZWtseVxuICBkaWdlc3RTY2hlZHVsZTogdmFyY2hhcignZGlnZXN0X3NjaGVkdWxlJywgeyBsZW5ndGg6IDEwMCB9KSxcbiAgbGFzdERpZ2VzdEF0OiB0aW1lc3RhbXAoJ2xhc3RfZGlnZXN0X2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIHRhcmdldFVzZXJzOiBqc29uYigndGFyZ2V0X3VzZXJzJykuJHR5cGU8c3RyaW5nW10+KCksIC8vIG51bGwgPSBhbGwgb3JnIGFkbWluc1xuICB3ZWJob29rVXJsOiB2YXJjaGFyKCd3ZWJob29rX3VybCcsIHsgbGVuZ3RoOiA1MDAgfSksXG4gIHdlYmhvb2tTZWNyZXQ6IHZhcmNoYXIoJ3dlYmhvb2tfc2VjcmV0JywgeyBsZW5ndGg6IDI1NSB9KSxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXAoJ2NyZWF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICB1cGRhdGVkQXQ6IHRpbWVzdGFtcCgndXBkYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG59KTtcblxuLyoqXG4gKiBMb2cgb2YgYWxsIGNvbXBsaWFuY2Ugbm90aWZpY2F0aW9ucyBzZW50LlxuICpcbiAqIEB0YWJsZSBjb21wbGlhbmNlX25vdGlmaWNhdGlvbl9sb2dcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbXBsaWFuY2VOb3RpZmljYXRpb25Mb2cgPSBwZ1RhYmxlKCdjb21wbGlhbmNlX25vdGlmaWNhdGlvbl9sb2cnLCB7XG4gIGlkOiB1dWlkKCdpZCcpLnByaW1hcnlLZXkoKS5kZWZhdWx0UmFuZG9tKCksXG4gIG9yZ0lkOiB2YXJjaGFyKCdvcmdfaWQnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcbiAgY2hhbm5lbDogdmFyY2hhcignY2hhbm5lbCcsIHsgbGVuZ3RoOiAyMCB9KS5ub3ROdWxsKCksIC8vIGluLWFwcCB8IHdlYmhvb2sgfCBkaWdlc3RcbiAgc3RhdHVzOiB2YXJjaGFyKCdzdGF0dXMnLCB7IGxlbmd0aDogMjAgfSkubm90TnVsbCgpLCAvLyBzZW50IHwgZmFpbGVkIHwgcGVuZGluZ1xuICBwYXlsb2FkOiBqc29uYigncGF5bG9hZCcpLiR0eXBlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpLm5vdE51bGwoKSxcbiAgd2ViaG9va1Jlc3BvbnNlQ29kZTogaW50ZWdlcignd2ViaG9va19yZXNwb25zZV9jb2RlJyksXG4gIHdlYmhvb2tFcnJvcjogdGV4dCgnd2ViaG9va19lcnJvcicpLFxuICByZXRyeUNvdW50OiBpbnRlZ2VyKCdyZXRyeV9jb3VudCcpLmRlZmF1bHQoMCkubm90TnVsbCgpLFxuICBuZXh0UmV0cnlBdDogdGltZXN0YW1wKCduZXh0X3JldHJ5X2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIHJlbGF0ZWRBdWRpdElkOiB1dWlkKCdyZWxhdGVkX2F1ZGl0X2lkJyksXG4gIGNyZWF0ZWRBdDogdGltZXN0YW1wKCdjcmVhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbn0sICh0YWJsZSkgPT4gKHtcbiAgb3JnQ3JlYXRlZEF0SWR4OiBpbmRleCgnY29tcGxpYW5jZV9ub3RpZmljYXRpb25fb3JnX2NyZWF0ZWRfaWR4JylcbiAgICAub24odGFibGUub3JnSWQsIHRhYmxlLmNyZWF0ZWRBdCksXG4gIHN0YXR1c1JldHJ5SWR4OiBpbmRleCgnY29tcGxpYW5jZV9ub3RpZmljYXRpb25fc3RhdHVzX3JldHJ5X2lkeCcpXG4gICAgLm9uKHRhYmxlLnN0YXR1cywgdGFibGUubmV4dFJldHJ5QXQpLFxuICByZWxhdGVkQXVkaXRJZHg6IGluZGV4KCdjb21wbGlhbmNlX25vdGlmaWNhdGlvbl9yZWxhdGVkX2F1ZGl0X2lkeCcpXG4gICAgLm9uKHRhYmxlLnJlbGF0ZWRBdWRpdElkKSxcbn0pKTtcblxuLyoqXG4gKiBDb21wbGlhbmNlLXNwZWNpZmljIFJCQUMgcm9sZXMuXG4gKlxuICogQHRhYmxlIGNvbXBsaWFuY2Vfcm9sZXNcbiAqL1xuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVJvbGVUeXBlID0gJ2NvbXBsaWFuY2Utdmlld2VyJyB8ICdjb21wbGlhbmNlLWVkaXRvcicgfCAnY29tcGxpYW5jZS1hZG1pbic7XG5cbmV4cG9ydCBjb25zdCBjb21wbGlhbmNlUm9sZSA9IHBnVGFibGUoJ2NvbXBsaWFuY2Vfcm9sZXMnLCB7XG4gIGlkOiB1dWlkKCdpZCcpLnByaW1hcnlLZXkoKS5kZWZhdWx0UmFuZG9tKCksXG4gIG9yZ0lkOiB2YXJjaGFyKCdvcmdfaWQnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcbiAgdXNlcklkOiB0ZXh0KCd1c2VyX2lkJykubm90TnVsbCgpLFxuICByb2xlOiB2YXJjaGFyKCdyb2xlJywgeyBsZW5ndGg6IDMwIH0pLiR0eXBlPENvbXBsaWFuY2VSb2xlVHlwZT4oKS5ub3ROdWxsKCksXG4gIGdyYW50ZWRCeTogdGV4dCgnZ3JhbnRlZF9ieScpLm5vdE51bGwoKSxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXAoJ2NyZWF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICB1cGRhdGVkQXQ6IHRpbWVzdGFtcCgndXBkYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG59LCAodGFibGUpID0+ICh7XG4gIG9yZ1VzZXJVbmlxdWU6IHVuaXF1ZUluZGV4KCdjb21wbGlhbmNlX3JvbGVfb3JnX3VzZXJfdW5pcXVlJykub24odGFibGUub3JnSWQsIHRhYmxlLnVzZXJJZCksXG4gIG9yZ1JvbGVJZHg6IGluZGV4KCdjb21wbGlhbmNlX3JvbGVfb3JnX3JvbGVfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLnJvbGUpLFxufSkpO1xuXG4vKipcbiAqIEdlbmVyYXRlZCBjb21wbGlhbmNlIHJlcG9ydHMuXG4gKlxuICogQHRhYmxlIGNvbXBsaWFuY2VfcmVwb3J0c1xuICovXG5leHBvcnQgY29uc3QgY29tcGxpYW5jZVJlcG9ydCA9IHBnVGFibGUoJ2NvbXBsaWFuY2VfcmVwb3J0cycsIHtcbiAgaWQ6IHV1aWQoJ2lkJykucHJpbWFyeUtleSgpLmRlZmF1bHRSYW5kb20oKSxcbiAgb3JnSWQ6IHZhcmNoYXIoJ29yZ19pZCcsIHsgbGVuZ3RoOiAyNTUgfSkubm90TnVsbCgpLFxuICByZXBvcnRUeXBlOiB2YXJjaGFyKCdyZXBvcnRfdHlwZScsIHsgbGVuZ3RoOiAzMCB9KS5ub3ROdWxsKCksIC8vIHN1bW1hcnkgfCBkZXRhaWxlZCB8IGF1ZGl0LXRyYWlsIHwgY29tcGFyaXNvblxuICB0YXJnZXQ6IHZhcmNoYXIoJ3RhcmdldCcsIHsgbGVuZ3RoOiAyMCB9KS5ub3ROdWxsKCksIC8vIHBsdWdpbiB8IHBpcGVsaW5lIHwgYWxsXG4gIGRhdGVGcm9tOiB0aW1lc3RhbXAoJ2RhdGVfZnJvbScsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICBkYXRlVG86IHRpbWVzdGFtcCgnZGF0ZV90bycsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICBjb21wYXJlRnJvbTogdGltZXN0YW1wKCdjb21wYXJlX2Zyb20nLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgY29tcGFyZVRvOiB0aW1lc3RhbXAoJ2NvbXBhcmVfdG8nLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgZGF0YToganNvbmIoJ2RhdGEnKS4kdHlwZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oKS5ub3ROdWxsKCksXG4gIGZvcm1hdDogdmFyY2hhcignZm9ybWF0JywgeyBsZW5ndGg6IDEwIH0pLmRlZmF1bHQoJ2pzb24nKS5ub3ROdWxsKCksIC8vIGpzb24gfCBjc3ZcbiAgZ2VuZXJhdGVkQnk6IHRleHQoJ2dlbmVyYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXAoJ2NyZWF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxufSwgKHRhYmxlKSA9PiAoe1xuICBvcmdDcmVhdGVkQXRJZHg6IGluZGV4KCdjb21wbGlhbmNlX3JlcG9ydF9vcmdfY3JlYXRlZF9pZHgnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUuY3JlYXRlZEF0KSxcbn0pKTtcblxuLyoqXG4gKiBDcm9uLWJhc2VkIHJlY3VycmluZyByZXBvcnQgZ2VuZXJhdGlvbiBzY2hlZHVsZXMuXG4gKlxuICogQHRhYmxlIGNvbXBsaWFuY2VfcmVwb3J0X3NjaGVkdWxlc1xuICovXG5leHBvcnQgY29uc3QgY29tcGxpYW5jZVJlcG9ydFNjaGVkdWxlID0gcGdUYWJsZSgnY29tcGxpYW5jZV9yZXBvcnRfc2NoZWR1bGVzJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHJlcG9ydFR5cGU6IHZhcmNoYXIoJ3JlcG9ydF90eXBlJywgeyBsZW5ndGg6IDMwIH0pLm5vdE51bGwoKSwgLy8gc3VtbWFyeSB8IGRldGFpbGVkXG4gIHRhcmdldDogdmFyY2hhcigndGFyZ2V0JywgeyBsZW5ndGg6IDIwIH0pLm5vdE51bGwoKSwgLy8gcGx1Z2luIHwgcGlwZWxpbmUgfCBhbGxcbiAgZm9ybWF0OiB2YXJjaGFyKCdmb3JtYXQnLCB7IGxlbmd0aDogMTAgfSkuZGVmYXVsdCgnanNvbicpLm5vdE51bGwoKSxcbiAgY3JvbkV4cHJlc3Npb246IHZhcmNoYXIoJ2Nyb25fZXhwcmVzc2lvbicsIHsgbGVuZ3RoOiAxMDAgfSkubm90TnVsbCgpLFxuICBpc0FjdGl2ZTogYm9vbGVhbignaXNfYWN0aXZlJykuZGVmYXVsdCh0cnVlKS5ub3ROdWxsKCksXG4gIGxhc3RSdW5BdDogdGltZXN0YW1wKCdsYXN0X3J1bl9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICBuZXh0UnVuQXQ6IHRpbWVzdGFtcCgnbmV4dF9ydW5fYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgZGVsaXZlclRvOiBqc29uYignZGVsaXZlcl90bycpLiR0eXBlPHN0cmluZ1tdPigpLmRlZmF1bHQoW10pLm5vdE51bGwoKSwgLy8gdXNlcklkcyB0byBub3RpZnlcbiAgY3JlYXRlZEJ5OiB0ZXh0KCdjcmVhdGVkX2J5Jykubm90TnVsbCgpLFxuICBjcmVhdGVkQXQ6IHRpbWVzdGFtcCgnY3JlYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRCeTogdGV4dCgndXBkYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgdXBkYXRlZEF0OiB0aW1lc3RhbXAoJ3VwZGF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxufSwgKHRhYmxlKSA9PiAoe1xuICBhY3RpdmVOZXh0UnVuSWR4OiBpbmRleCgnY29tcGxpYW5jZV9yZXBvcnRfc2NoZWR1bGVfYWN0aXZlX25leHRfaWR4JylcbiAgICAub24odGFibGUuaXNBY3RpdmUsIHRhYmxlLm5leHRSdW5BdCksXG4gIG9yZ0lkeDogaW5kZXgoJ2NvbXBsaWFuY2VfcmVwb3J0X3NjaGVkdWxlX29yZ19pZHgnKS5vbih0YWJsZS5vcmdJZCksXG59KSk7XG5cbi8vIFBlci1vcmcgd2F0ZXJtYXJrIGZvciB0aGUgYmlsbGluZ+KGkmNvbXBsaWFuY2UgZW50aXRsZW1lbnQgc3luY1xuLy8gKGBQVVQgL2VudGl0bGVtZW50cy86b3JnSWRgKS4gQmlsbGluZyBzdGFtcHMgZWFjaCBwdXNoIHdpdGggYG9jY3VycmVkQXRgOyB0aGVcbi8vIHJvdXRlIHNraXBzIGFueSBwdXNoIG5vdCBzdHJpY3RseSBuZXdlciB0aGFuIHRoZSBzdG9yZWQgdmFsdWUgc28gb3V0LW9mLW9yZGVyXG4vLyBkZWxpdmVyaWVzIChjb25jdXJyZW50IHB1cmNoYXNlICsgZHJpZnQgcmVjb25jaWxlciwgcmV0cmllcykgY2FuJ3QgcmV2ZXJ0IGFcbi8vIG5ld2VyIGVudGl0bGVtZW50IHN0YXRlLiBTeW5jIG1ldGFkYXRhIG9ubHkg4oCUIG5vIHRlbmFudCBjb250ZW50LCBzbyBubyBSTFMuXG4vLyBNSUdSQVRJT04gUkVRVUlSRUQ6IHJ1biBgcG5wbSBkcml6emxlLWtpdCBnZW5lcmF0ZWAgYWZ0ZXIgcHVsbGluZy5cbmV4cG9ydCBjb25zdCBjb21wbGlhbmNlRW50aXRsZW1lbnRXYXRlcm1hcmsgPSBwZ1RhYmxlKCdjb21wbGlhbmNlX2VudGl0bGVtZW50X3dhdGVybWFyaycsIHtcbiAgb3JnSWQ6IHRleHQoJ29yZ19pZCcpLnByaW1hcnlLZXkoKSxcbiAgbGFzdE9jY3VycmVkQXQ6IHRpbWVzdGFtcCgnbGFzdF9vY2N1cnJlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLm5vdE51bGwoKSxcbn0pO1xuXG4vLyBDb21wbGlhbmNlIHR5cGVzXG5leHBvcnQgdHlwZSBDb21wbGlhbmNlRW50aXRsZW1lbnRXYXRlcm1hcmsgPSB0eXBlb2YgY29tcGxpYW5jZUVudGl0bGVtZW50V2F0ZXJtYXJrLiRpbmZlclNlbGVjdDtcblxuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVBvbGljeSA9IHR5cGVvZiBjb21wbGlhbmNlUG9saWN5LiRpbmZlclNlbGVjdDtcbmV4cG9ydCB0eXBlIENvbXBsaWFuY2VQb2xpY3lJbnNlcnQgPSB0eXBlb2YgY29tcGxpYW5jZVBvbGljeS4kaW5mZXJJbnNlcnQ7XG5cbmV4cG9ydCB0eXBlIENvbXBsaWFuY2VSdWxlID0gdHlwZW9mIGNvbXBsaWFuY2VSdWxlLiRpbmZlclNlbGVjdDtcbmV4cG9ydCB0eXBlIENvbXBsaWFuY2VSdWxlSW5zZXJ0ID0gdHlwZW9mIGNvbXBsaWFuY2VSdWxlLiRpbmZlckluc2VydDtcblxuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVJ1bGVIaXN0b3J5ID0gdHlwZW9mIGNvbXBsaWFuY2VSdWxlSGlzdG9yeS4kaW5mZXJTZWxlY3Q7XG5leHBvcnQgdHlwZSBDb21wbGlhbmNlUnVsZUhpc3RvcnlJbnNlcnQgPSB0eXBlb2YgY29tcGxpYW5jZVJ1bGVIaXN0b3J5LiRpbmZlckluc2VydDtcblxuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZUF1ZGl0TG9nID0gdHlwZW9mIGNvbXBsaWFuY2VBdWRpdExvZy4kaW5mZXJTZWxlY3Q7XG5leHBvcnQgdHlwZSBDb21wbGlhbmNlQXVkaXRMb2dJbnNlcnQgPSB0eXBlb2YgY29tcGxpYW5jZUF1ZGl0TG9nLiRpbmZlckluc2VydDtcblxuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZUV4ZW1wdGlvbiA9IHR5cGVvZiBjb21wbGlhbmNlRXhlbXB0aW9uLiRpbmZlclNlbGVjdDtcbmV4cG9ydCB0eXBlIENvbXBsaWFuY2VFeGVtcHRpb25JbnNlcnQgPSB0eXBlb2YgY29tcGxpYW5jZUV4ZW1wdGlvbi4kaW5mZXJJbnNlcnQ7XG5cbmV4cG9ydCB0eXBlIENvbXBsaWFuY2VSdWxlU3Vic2NyaXB0aW9uID0gdHlwZW9mIGNvbXBsaWFuY2VSdWxlU3Vic2NyaXB0aW9uLiRpbmZlclNlbGVjdDtcbmV4cG9ydCB0eXBlIENvbXBsaWFuY2VSdWxlU3Vic2NyaXB0aW9uSW5zZXJ0ID0gdHlwZW9mIGNvbXBsaWFuY2VSdWxlU3Vic2NyaXB0aW9uLiRpbmZlckluc2VydDtcblxuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVNjYW4gPSB0eXBlb2YgY29tcGxpYW5jZVNjYW4uJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVNjYW5JbnNlcnQgPSB0eXBlb2YgY29tcGxpYW5jZVNjYW4uJGluZmVySW5zZXJ0O1xuXG5leHBvcnQgdHlwZSBDb21wbGlhbmNlU2NhblNjaGVkdWxlID0gdHlwZW9mIGNvbXBsaWFuY2VTY2FuU2NoZWR1bGUuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVNjYW5TY2hlZHVsZUluc2VydCA9IHR5cGVvZiBjb21wbGlhbmNlU2NhblNjaGVkdWxlLiRpbmZlckluc2VydDtcblxuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZU5vdGlmaWNhdGlvblByZWZlcmVuY2UgPSB0eXBlb2YgY29tcGxpYW5jZU5vdGlmaWNhdGlvblByZWZlcmVuY2UuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZU5vdGlmaWNhdGlvblByZWZlcmVuY2VJbnNlcnQgPSB0eXBlb2YgY29tcGxpYW5jZU5vdGlmaWNhdGlvblByZWZlcmVuY2UuJGluZmVySW5zZXJ0O1xuXG5leHBvcnQgdHlwZSBDb21wbGlhbmNlTm90aWZpY2F0aW9uTG9nID0gdHlwZW9mIGNvbXBsaWFuY2VOb3RpZmljYXRpb25Mb2cuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZU5vdGlmaWNhdGlvbkxvZ0luc2VydCA9IHR5cGVvZiBjb21wbGlhbmNlTm90aWZpY2F0aW9uTG9nLiRpbmZlckluc2VydDtcblxuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVJvbGUgPSB0eXBlb2YgY29tcGxpYW5jZVJvbGUuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVJvbGVJbnNlcnQgPSB0eXBlb2YgY29tcGxpYW5jZVJvbGUuJGluZmVySW5zZXJ0O1xuXG5leHBvcnQgdHlwZSBDb21wbGlhbmNlUmVwb3J0ID0gdHlwZW9mIGNvbXBsaWFuY2VSZXBvcnQuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVJlcG9ydEluc2VydCA9IHR5cGVvZiBjb21wbGlhbmNlUmVwb3J0LiRpbmZlckluc2VydDtcblxuZXhwb3J0IHR5cGUgQ29tcGxpYW5jZVJlcG9ydFNjaGVkdWxlID0gdHlwZW9mIGNvbXBsaWFuY2VSZXBvcnRTY2hlZHVsZS4kaW5mZXJTZWxlY3Q7XG5leHBvcnQgdHlwZSBDb21wbGlhbmNlUmVwb3J0U2NoZWR1bGVJbnNlcnQgPSB0eXBlb2YgY29tcGxpYW5jZVJlcG9ydFNjaGVkdWxlLiRpbmZlckluc2VydDtcbiJdfQ==