@pipeline-builder/pipeline-data 4.1.24 → 4.1.26

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 (64) hide show
  1. package/lib/api/alert-destinations.d.ts +17 -0
  2. package/lib/api/alert-destinations.js +36 -0
  3. package/lib/api/reporting/analytics-queries.d.ts +274 -0
  4. package/lib/api/reporting/analytics-queries.js +598 -0
  5. package/lib/api/reporting/daily-rollup.d.ts +41 -0
  6. package/lib/api/reporting/daily-rollup.js +173 -0
  7. package/lib/api/reporting/deploy-rollup.d.ts +78 -0
  8. package/lib/api/reporting/deploy-rollup.js +203 -0
  9. package/lib/api/reporting/dora-scoring.d.ts +14 -0
  10. package/lib/api/reporting/dora-scoring.js +25 -1
  11. package/lib/api/reporting/dora.js +30 -6
  12. package/lib/api/reporting/failure-classifier.d.ts +54 -0
  13. package/lib/api/reporting/failure-classifier.js +179 -0
  14. package/lib/api/reporting/ingest.d.ts +2 -2
  15. package/lib/api/reporting/ingest.js +129 -4
  16. package/lib/api/reporting/last-deploy.d.ts +31 -0
  17. package/lib/api/reporting/last-deploy.js +93 -0
  18. package/lib/api/reporting/needs-attention.d.ts +93 -0
  19. package/lib/api/reporting/needs-attention.js +152 -0
  20. package/lib/api/reporting/plugin-exposure.d.ts +129 -0
  21. package/lib/api/reporting/plugin-exposure.js +312 -0
  22. package/lib/api/reporting/retention-sweep.js +9 -1
  23. package/lib/api/reporting/sql-helpers.d.ts +35 -2
  24. package/lib/api/reporting/sql-helpers.js +39 -1
  25. package/lib/api/reporting/stakeholder/compose.d.ts +115 -0
  26. package/lib/api/reporting/stakeholder/compose.js +234 -0
  27. package/lib/api/reporting/stakeholder/index.d.ts +14 -0
  28. package/lib/api/reporting/stakeholder/index.js +17 -0
  29. package/lib/api/reporting/stakeholder/period.d.ts +102 -0
  30. package/lib/api/reporting/stakeholder/period.js +273 -0
  31. package/lib/api/reporting/stakeholder/report-html.d.ts +93 -0
  32. package/lib/api/reporting/stakeholder/report-html.js +208 -0
  33. package/lib/api/reporting/stakeholder/sections.d.ts +117 -0
  34. package/lib/api/reporting/stakeholder/sections.js +249 -0
  35. package/lib/api/reporting/stakeholder/store.d.ts +450 -0
  36. package/lib/api/reporting/stakeholder/store.js +981 -0
  37. package/lib/api/reporting/stakeholder/templates.d.ts +21 -0
  38. package/lib/api/reporting/stakeholder/templates.js +104 -0
  39. package/lib/api/reporting/types.d.ts +73 -0
  40. package/lib/api/reporting/types.js +1 -1
  41. package/lib/api/reporting-service.d.ts +94 -5
  42. package/lib/api/reporting-service.js +169 -10
  43. package/lib/api/soft-delete-sweep.d.ts +11 -2
  44. package/lib/api/soft-delete-sweep.js +17 -6
  45. package/lib/database/drizzle-schema.d.ts +2244 -385
  46. package/lib/database/drizzle-schema.js +18 -7
  47. package/lib/database/index.d.ts +1 -1
  48. package/lib/database/index.js +4 -2
  49. package/lib/database/schema/compliance.d.ts +0 -682
  50. package/lib/database/schema/compliance.js +6 -66
  51. package/lib/database/schema/ecosystem.d.ts +20 -157
  52. package/lib/database/schema/ecosystem.js +23 -16
  53. package/lib/database/schema/pipeline.d.ts +200 -0
  54. package/lib/database/schema/pipeline.js +100 -1
  55. package/lib/database/schema/plugin.d.ts +20 -1
  56. package/lib/database/schema/plugin.js +13 -1
  57. package/lib/database/schema/reporting-analytics.d.ts +1212 -0
  58. package/lib/database/schema/reporting-analytics.js +250 -0
  59. package/lib/database/schema/reporting-stakeholder.d.ts +1373 -0
  60. package/lib/database/schema/reporting-stakeholder.js +251 -0
  61. package/lib/index.d.ts +10 -1
  62. package/lib/index.js +15 -1
  63. package/lib/testing/exports.json +67 -4
  64. package/package.json +4 -3
@@ -0,0 +1,250 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * The analytics layer every report section and dashboard reads instead of raw
5
+ * events.
6
+ *
7
+ * Reporting has been scanning `pipeline_events` directly. That worked while the
8
+ * only consumer was one dashboard over a 30-day window, and stops working for
9
+ * this feature: a quarterly report over a 90-day window, for an org with a
10
+ * thousand executions a day, re-derives the same aggregates on every read, and
11
+ * the retention sweep then deletes the rows the numbers came from. Two tables fix
12
+ * both problems:
13
+ *
14
+ * - `dora_deployments` — ONE ROW PER DEPLOY, written at ingest. Lead time is
15
+ * stored per execution here, never recomputed per event, because the
16
+ * per-event form double-counts: a deploy stage emits a STAGE event and an
17
+ * ACTION event, and both carry the same commit range.
18
+ * - `execution_daily_rollups` — one row per org, pipeline, stage and day. Every
19
+ * section that says "runs", "success rate", "p95" or "build minutes" reads
20
+ * these, so a report costs a few hundred rows instead of a few hundred
21
+ * thousand.
22
+ *
23
+ * Both are DERIVED: they can be rebuilt from events while the events exist, and
24
+ * they outlive them afterwards. That is the point — they are the retained form.
25
+ *
26
+ * The other two tables here answer "what is actually running", which the report's
27
+ * plugin sections need and no existing table can answer:
28
+ *
29
+ * - `pipeline_plugin_resolution` — what a pipeline's DECLARED plugin versions
30
+ * resolve to, recomputed on write rather than resolved per read.
31
+ * - `plugin_vuln_exposure` — which pipelines are exposed to which vulnerable
32
+ * plugin version, opened by a rescan and closed by a fixing deploy.
33
+ */
34
+ import { sql } from 'drizzle-orm';
35
+ import { boolean, index, integer, jsonb, pgTable, primaryKey, text, timestamp, uniqueIndex, varchar } from 'drizzle-orm/pg-core';
36
+ /**
37
+ * Why a deploy's lead time could not be measured. Recorded rather than left NULL
38
+ * with no explanation, because the three causes need different fixes and the
39
+ * report shows the reason: no SCM token for the source, the provider rate-limited
40
+ * the range walk, or the source type has no range API at all.
41
+ */
42
+ export const LEAD_TIME_GAPS = ['no_token', 'rate_limited', 'unsupported_source', 'no_commit_data'];
43
+ /**
44
+ * How confidently an incident was attributed to a deploy. Shown beside change
45
+ * failure rate and time to restore, because "this deploy broke production" and
46
+ * "an incident opened some hours after this deploy" are different claims and a
47
+ * manager acts differently on each.
48
+ */
49
+ export const CORRELATION_CONFIDENCES = ['high', 'medium', 'low'];
50
+ /**
51
+ * How a pipeline came to exist. For the adoption section: an org whose pipelines
52
+ * are all hand-built is a different adoption story from one templating them.
53
+ */
54
+ export const PIPELINE_CREATION_SOURCES = ['manual', 'template', 'ai', 'bulk', 'cdk'];
55
+ /**
56
+ * What kind of thing broke. Assigned at ingest by the classifier
57
+ * (`api/reporting/src/services/failure-classifier.ts`), which is rules over the
58
+ * action's type and error text — deliberately data, not code, so the taxonomy can
59
+ * grow without a deploy.
60
+ *
61
+ * The categories overlap the plugin-build taxonomy on purpose: a dependency
62
+ * failure is a dependency failure whether it happened building a plugin or
63
+ * running one, and two vocabularies for the same thing would make the report and
64
+ * the build queue disagree.
65
+ */
66
+ export const FAILURE_CATEGORIES = [
67
+ 'source_checkout', 'dependency', 'build', 'unit_test', 'integration_test',
68
+ 'security_scan', 'infrastructure', 'deployment', 'authentication', 'permissions',
69
+ 'configuration', 'timeout', 'resource_exhaustion', 'external_service', 'other',
70
+ ];
71
+ /** Where a plugin-version exposure was observed. */
72
+ export const EXPOSURE_SOURCES = ['declared', 'deployed'];
73
+ /**
74
+ * What an org decided about an exposure. `open` until someone looks;
75
+ * `accepted` is a time-boxed decision with a reason and an owner, never a
76
+ * permanent mute; `false_positive` is a scanner disagreement worth recording so
77
+ * the same finding stops being re-raised as news.
78
+ */
79
+ export const EXPOSURE_TRIAGE_STATES = ['open', 'accepted', 'false_positive', 'fixed'];
80
+ /**
81
+ * One deployment: an execution that reached an environment.
82
+ *
83
+ * Written at ingest, one row per (execution, environment). Everything DORA
84
+ * reports is here, so `/dora`, the trend and the report sections stop scanning
85
+ * raw events — and keep working after the events are swept.
86
+ *
87
+ * @table dora_deployments
88
+ */
89
+ export const doraDeployment = pgTable('dora_deployments', {
90
+ orgId: varchar('org_id', { length: 255 }).notNull(),
91
+ executionId: varchar('execution_id', { length: 255 }).notNull(),
92
+ environment: varchar('environment', { length: 255 }).notNull(),
93
+ pipelineId: varchar('pipeline_id', { length: 255 }),
94
+ /** When the deploy stage completed. The deploy's own timestamp, not the run's. */
95
+ deployedAt: timestamp('deployed_at', { withTimezone: true }).notNull(),
96
+ succeeded: boolean('succeeded').notNull(),
97
+ /**
98
+ * The OLDEST unshipped commit in this deploy's range. Lead time is
99
+ * `deployedAt - earliestCommitAt`, computed once and stored, because the
100
+ * per-event form double-counts a deploy that emits both a STAGE and an ACTION
101
+ * event carrying the same range.
102
+ */
103
+ earliestCommitAt: timestamp('earliest_commit_at', { withTimezone: true }),
104
+ leadTimeSeconds: integer('lead_time_seconds'),
105
+ commitCount: integer('commit_count'),
106
+ commitSha: varchar('commit_sha', { length: 255 }),
107
+ /** Why lead time is absent, when it is. NULL when it was measured. */
108
+ leadTimeGap: varchar('lead_time_gap', { length: 30 }).$type(),
109
+ /**
110
+ * Post-deploy outcome markers, denormalized onto the deploy so change-failure
111
+ * rate and time-to-restore are one scan rather than a join per window.
112
+ */
113
+ failedAt: timestamp('failed_at', { withTimezone: true }),
114
+ restoredAt: timestamp('restored_at', { withTimezone: true }),
115
+ /** How the incident→deploy link was judged. NULL when nothing was correlated. */
116
+ correlationConfidence: varchar('correlation_confidence', { length: 10 }).$type(),
117
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
118
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
119
+ }, (table) => ({
120
+ // One row per execution per environment: a redelivered event upserts rather
121
+ // than inserting a second deploy (EventBridge → SQS is at-least-once).
122
+ pk: primaryKey({ columns: [table.executionId, table.environment] }),
123
+ // The window scan every DORA read does.
124
+ orgEnvDeployedIdx: index('dora_deployment_org_env_deployed_idx')
125
+ .on(table.orgId, table.environment, table.deployedAt),
126
+ orgDeployedIdx: index('dora_deployment_org_deployed_idx').on(table.orgId, table.deployedAt),
127
+ pipelineIdx: index('dora_deployment_pipeline_idx').on(table.pipelineId, table.deployedAt),
128
+ // The promotion view: one commit's path across environments.
129
+ commitIdx: index('dora_deployment_commit_idx').on(table.orgId, table.commitSha)
130
+ .where(sql `commit_sha IS NOT NULL`),
131
+ }));
132
+ /**
133
+ * Pre-aggregated execution counts and timings, one row per org, pipeline, stage
134
+ * and UTC day.
135
+ *
136
+ * Rebuilt for a day when late events arrive, so the rollup and the events agree
137
+ * while both exist. `failuresByCategory` is a JSON map rather than a column per
138
+ * category because the taxonomy grows.
139
+ *
140
+ * @table execution_daily_rollups
141
+ */
142
+ export const executionDailyRollup = pgTable('execution_daily_rollups', {
143
+ orgId: varchar('org_id', { length: 255 }).notNull(),
144
+ /** The UTC date this row aggregates. Report periods re-bucket in the report's
145
+ * own timezone by summing days — which is why the grain is a DAY. */
146
+ day: timestamp('day', { withTimezone: true }).notNull(),
147
+ pipelineId: varchar('pipeline_id', { length: 255 }).notNull(),
148
+ /** `''` for the pipeline-level row; a stage name for a stage-level row. */
149
+ stageName: varchar('stage_name', { length: 255 }).default('').notNull(),
150
+ runs: integer('runs').default(0).notNull(),
151
+ succeeded: integer('succeeded').default(0).notNull(),
152
+ failed: integer('failed').default(0).notNull(),
153
+ /** category → count. Feeds the failure-analysis section. */
154
+ failuresByCategory: jsonb('failures_by_category').$type().default({}).notNull(),
155
+ p50Ms: integer('p50_ms'),
156
+ p90Ms: integer('p90_ms'),
157
+ p95Ms: integer('p95_ms'),
158
+ /** Summed execution duration, in seconds. The resource-consumption section's
159
+ * only input; deliberately NOT converted to money anywhere. */
160
+ buildSeconds: integer('build_seconds').default(0).notNull(),
161
+ /** When this row was last rebuilt, so a late-event rebuild is visible. */
162
+ computedAt: timestamp('computed_at', { withTimezone: true }).defaultNow().notNull(),
163
+ }, (table) => ({
164
+ pk: primaryKey({ columns: [table.orgId, table.day, table.pipelineId, table.stageName] }),
165
+ orgDayIdx: index('execution_rollup_org_day_idx').on(table.orgId, table.day),
166
+ pipelineDayIdx: index('execution_rollup_pipeline_day_idx').on(table.pipelineId, table.day),
167
+ }));
168
+ /**
169
+ * What a pipeline's declared plugin steps resolve to.
170
+ *
171
+ * Recomputed on pipeline write and on plugin publish, rather than resolved at
172
+ * read time: the outdated-plugin section compares "in use" against "latest
173
+ * available" for every step of every pipeline, and doing that resolution per read
174
+ * made it a query nobody could afford to put in a report.
175
+ *
176
+ * @table pipeline_plugin_resolution
177
+ */
178
+ export const pipelinePluginResolution = pgTable('pipeline_plugin_resolution', {
179
+ orgId: varchar('org_id', { length: 255 }).notNull(),
180
+ pipelineId: varchar('pipeline_id', { length: 255 }).notNull(),
181
+ stageName: varchar('stage_name', { length: 255 }).notNull(),
182
+ stepName: varchar('step_name', { length: 255 }).notNull(),
183
+ pluginPublisher: varchar('plugin_publisher', { length: 39 }),
184
+ pluginName: varchar('plugin_name', { length: 255 }).notNull(),
185
+ /** What the config asked for — a range, a pin, or nothing. */
186
+ declaredVersion: varchar('declared_version', { length: 50 }),
187
+ /** What that resolves to today. NULL when nothing satisfies it. */
188
+ resolvedVersion: varchar('resolved_version', { length: 50 }),
189
+ /** The newest version the org is entitled to install, for the "gap" column. */
190
+ latestVersion: varchar('latest_version', { length: 50 }),
191
+ /** `major` / `minor` / `patch` / `none`, from resolved → latest. */
192
+ versionGap: varchar('version_gap', { length: 10 }),
193
+ /** False when the resolved version is outside the org's consumption policy. */
194
+ withinPolicy: boolean('within_policy').default(true).notNull(),
195
+ computedAt: timestamp('computed_at', { withTimezone: true }).defaultNow().notNull(),
196
+ }, (table) => ({
197
+ pk: primaryKey({ columns: [table.pipelineId, table.stageName, table.stepName] }),
198
+ orgIdx: index('pipeline_plugin_resolution_org_idx').on(table.orgId),
199
+ pluginIdx: index('pipeline_plugin_resolution_plugin_idx').on(table.pluginPublisher, table.pluginName),
200
+ // "Which pipelines are behind?" — the outdated section's driving scan.
201
+ gapIdx: index('pipeline_plugin_resolution_gap_idx').on(table.orgId, table.versionGap),
202
+ }));
203
+ /**
204
+ * One pipeline's exposure to one vulnerable plugin version.
205
+ *
206
+ * Opened by the nightly rescan when a version in use has fixable Critical/High
207
+ * findings, and CLOSED by a deploy that moves the pipeline off it. It is a
208
+ * per-pipeline row rather than a per-version one because the question a manager
209
+ * asks is "which of our pipelines is exposed", and answering that from a
210
+ * version-level table means re-deriving the pipeline set on every read.
211
+ *
212
+ * Keyed by IMAGE DIGEST, not version string: a version rebuilt on a patched base
213
+ * image is a different artifact with different findings, and keying on the string
214
+ * would report the old one forever.
215
+ *
216
+ * @table plugin_vuln_exposure
217
+ */
218
+ export const pluginVulnExposure = pgTable('plugin_vuln_exposure', {
219
+ id: varchar('id', { length: 255 }).primaryKey(),
220
+ orgId: varchar('org_id', { length: 255 }).notNull(),
221
+ pipelineId: varchar('pipeline_id', { length: 255 }).notNull(),
222
+ pluginPublisher: varchar('plugin_publisher', { length: 39 }),
223
+ pluginName: varchar('plugin_name', { length: 255 }).notNull(),
224
+ pluginVersion: varchar('plugin_version', { length: 50 }).notNull(),
225
+ imageDigest: varchar('image_digest', { length: 71 }),
226
+ source: varchar('source', { length: 10 }).$type().notNull(),
227
+ criticalCount: integer('critical_count').default(0).notNull(),
228
+ highCount: integer('high_count').default(0).notNull(),
229
+ /** The findings themselves: CVE id, package, fixed-in version. Capped by the writer. */
230
+ topFindings: jsonb('top_findings').$type().default([]).notNull(),
231
+ flaggedAt: timestamp('flagged_at', { withTimezone: true }).defaultNow().notNull(),
232
+ /** Set when a deploy moved the pipeline onto a version without the findings. */
233
+ fixedAt: timestamp('fixed_at', { withTimezone: true }),
234
+ triageState: varchar('triage_state', { length: 20 }).$type().default('open').notNull(),
235
+ /** An acceptance is time-boxed: a permanent mute is how a finding is forgotten. */
236
+ acceptedUntil: timestamp('accepted_until', { withTimezone: true }),
237
+ triageReason: text('triage_reason'),
238
+ triagedBy: text('triaged_by'),
239
+ triagedAt: timestamp('triaged_at', { withTimezone: true }),
240
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
241
+ }, (table) => ({
242
+ // One live exposure per (pipeline, plugin version, digest, source): a nightly
243
+ // rescan refreshes counts rather than opening a new row every night.
244
+ exposureUnique: uniqueIndex('plugin_vuln_exposure_unique')
245
+ .on(table.pipelineId, table.pluginName, table.pluginVersion, table.source),
246
+ orgOpenIdx: index('plugin_vuln_exposure_org_open_idx').on(table.orgId, table.triageState)
247
+ .where(sql `fixed_at IS NULL`),
248
+ digestIdx: index('plugin_vuln_exposure_digest_idx').on(table.imageDigest),
249
+ }));
250
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLWFuYWx5dGljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kYXRhYmFzZS9zY2hlbWEvcmVwb3J0aW5nLWFuYWx5dGljcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Qkc7QUFFSCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVqSTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxDQUFDLFVBQVUsRUFBRSxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsZ0JBQWdCLENBQVUsQ0FBQztBQUc1Rzs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQVUsQ0FBQztBQUcxRTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQVUsQ0FBQztBQUc5Rjs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUc7SUFDaEMsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsa0JBQWtCO0lBQ3pFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYTtJQUNoRixlQUFlLEVBQUUsU0FBUyxFQUFFLHFCQUFxQixFQUFFLGtCQUFrQixFQUFFLE9BQU87Q0FD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RUFBdUIsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQzNHLG1GQUFtRjtJQUNuRixhQUFhLEVBQUUsU0FBUyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ2xFLFlBQVksRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ25DLFNBQVMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzdCLFNBQVMsRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQzFELFNBQVMsRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxFQUFFO0NBQ2xGLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDYiw4RUFBOEU7SUFDOUUscUVBQXFFO0lBQ3JFLGNBQWMsRUFBRSxXQUFXLENBQUMsNkJBQTZCLENBQUM7U0FDdkQsRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDNUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxXQUFXLENBQUM7U0FDdEYsS0FBSyxDQUFDLEdBQUcsQ0FBQSxrQkFBa0IsQ0FBQztJQUMvQixTQUFTLEVBQUUsS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUM7Q0FDMUUsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBUaGUgYW5hbHl0aWNzIGxheWVyIGV2ZXJ5IHJlcG9ydCBzZWN0aW9uIGFuZCBkYXNoYm9hcmQgcmVhZHMgaW5zdGVhZCBvZiByYXdcbiAqIGV2ZW50cy5cbiAqXG4gKiBSZXBvcnRpbmcgaGFzIGJlZW4gc2Nhbm5pbmcgYHBpcGVsaW5lX2V2ZW50c2AgZGlyZWN0bHkuIFRoYXQgd29ya2VkIHdoaWxlIHRoZVxuICogb25seSBjb25zdW1lciB3YXMgb25lIGRhc2hib2FyZCBvdmVyIGEgMzAtZGF5IHdpbmRvdywgYW5kIHN0b3BzIHdvcmtpbmcgZm9yXG4gKiB0aGlzIGZlYXR1cmU6IGEgcXVhcnRlcmx5IHJlcG9ydCBvdmVyIGEgOTAtZGF5IHdpbmRvdywgZm9yIGFuIG9yZyB3aXRoIGFcbiAqIHRob3VzYW5kIGV4ZWN1dGlvbnMgYSBkYXksIHJlLWRlcml2ZXMgdGhlIHNhbWUgYWdncmVnYXRlcyBvbiBldmVyeSByZWFkLCBhbmRcbiAqIHRoZSByZXRlbnRpb24gc3dlZXAgdGhlbiBkZWxldGVzIHRoZSByb3dzIHRoZSBudW1iZXJzIGNhbWUgZnJvbS4gVHdvIHRhYmxlcyBmaXhcbiAqIGJvdGggcHJvYmxlbXM6XG4gKlxuICogIC0gYGRvcmFfZGVwbG95bWVudHNgIOKAlCBPTkUgUk9XIFBFUiBERVBMT1ksIHdyaXR0ZW4gYXQgaW5nZXN0LiBMZWFkIHRpbWUgaXNcbiAqICAgIHN0b3JlZCBwZXIgZXhlY3V0aW9uIGhlcmUsIG5ldmVyIHJlY29tcHV0ZWQgcGVyIGV2ZW50LCBiZWNhdXNlIHRoZVxuICogICAgcGVyLWV2ZW50IGZvcm0gZG91YmxlLWNvdW50czogYSBkZXBsb3kgc3RhZ2UgZW1pdHMgYSBTVEFHRSBldmVudCBhbmQgYW5cbiAqICAgIEFDVElPTiBldmVudCwgYW5kIGJvdGggY2FycnkgdGhlIHNhbWUgY29tbWl0IHJhbmdlLlxuICogIC0gYGV4ZWN1dGlvbl9kYWlseV9yb2xsdXBzYCDigJQgb25lIHJvdyBwZXIgb3JnLCBwaXBlbGluZSwgc3RhZ2UgYW5kIGRheS4gRXZlcnlcbiAqICAgIHNlY3Rpb24gdGhhdCBzYXlzIFwicnVuc1wiLCBcInN1Y2Nlc3MgcmF0ZVwiLCBcInA5NVwiIG9yIFwiYnVpbGQgbWludXRlc1wiIHJlYWRzXG4gKiAgICB0aGVzZSwgc28gYSByZXBvcnQgY29zdHMgYSBmZXcgaHVuZHJlZCByb3dzIGluc3RlYWQgb2YgYSBmZXcgaHVuZHJlZFxuICogICAgdGhvdXNhbmQuXG4gKlxuICogQm90aCBhcmUgREVSSVZFRDogdGhleSBjYW4gYmUgcmVidWlsdCBmcm9tIGV2ZW50cyB3aGlsZSB0aGUgZXZlbnRzIGV4aXN0LCBhbmRcbiAqIHRoZXkgb3V0bGl2ZSB0aGVtIGFmdGVyd2FyZHMuIFRoYXQgaXMgdGhlIHBvaW50IOKAlCB0aGV5IGFyZSB0aGUgcmV0YWluZWQgZm9ybS5cbiAqXG4gKiBUaGUgb3RoZXIgdHdvIHRhYmxlcyBoZXJlIGFuc3dlciBcIndoYXQgaXMgYWN0dWFsbHkgcnVubmluZ1wiLCB3aGljaCB0aGUgcmVwb3J0J3NcbiAqIHBsdWdpbiBzZWN0aW9ucyBuZWVkIGFuZCBubyBleGlzdGluZyB0YWJsZSBjYW4gYW5zd2VyOlxuICpcbiAqICAtIGBwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvbmAg4oCUIHdoYXQgYSBwaXBlbGluZSdzIERFQ0xBUkVEIHBsdWdpbiB2ZXJzaW9uc1xuICogICAgcmVzb2x2ZSB0bywgcmVjb21wdXRlZCBvbiB3cml0ZSByYXRoZXIgdGhhbiByZXNvbHZlZCBwZXIgcmVhZC5cbiAqICAtIGBwbHVnaW5fdnVsbl9leHBvc3VyZWAg4oCUIHdoaWNoIHBpcGVsaW5lcyBhcmUgZXhwb3NlZCB0byB3aGljaCB2dWxuZXJhYmxlXG4gKiAgICBwbHVnaW4gdmVyc2lvbiwgb3BlbmVkIGJ5IGEgcmVzY2FuIGFuZCBjbG9zZWQgYnkgYSBmaXhpbmcgZGVwbG95LlxuICovXG5cbmltcG9ydCB7IHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGJvb2xlYW4sIGluZGV4LCBpbnRlZ2VyLCBqc29uYiwgcGdUYWJsZSwgcHJpbWFyeUtleSwgdGV4dCwgdGltZXN0YW1wLCB1bmlxdWVJbmRleCwgdmFyY2hhciB9IGZyb20gJ2RyaXp6bGUtb3JtL3BnLWNvcmUnO1xuXG4vKipcbiAqIFdoeSBhIGRlcGxveSdzIGxlYWQgdGltZSBjb3VsZCBub3QgYmUgbWVhc3VyZWQuIFJlY29yZGVkIHJhdGhlciB0aGFuIGxlZnQgTlVMTFxuICogd2l0aCBubyBleHBsYW5hdGlvbiwgYmVjYXVzZSB0aGUgdGhyZWUgY2F1c2VzIG5lZWQgZGlmZmVyZW50IGZpeGVzIGFuZCB0aGVcbiAqIHJlcG9ydCBzaG93cyB0aGUgcmVhc29uOiBubyBTQ00gdG9rZW4gZm9yIHRoZSBzb3VyY2UsIHRoZSBwcm92aWRlciByYXRlLWxpbWl0ZWRcbiAqIHRoZSByYW5nZSB3YWxrLCBvciB0aGUgc291cmNlIHR5cGUgaGFzIG5vIHJhbmdlIEFQSSBhdCBhbGwuXG4gKi9cbmV4cG9ydCBjb25zdCBMRUFEX1RJTUVfR0FQUyA9IFsnbm9fdG9rZW4nLCAncmF0ZV9saW1pdGVkJywgJ3Vuc3VwcG9ydGVkX3NvdXJjZScsICdub19jb21taXRfZGF0YSddIGFzIGNvbnN0O1xuZXhwb3J0IHR5cGUgTGVhZFRpbWVHYXAgPSAodHlwZW9mIExFQURfVElNRV9HQVBTKVtudW1iZXJdO1xuXG4vKipcbiAqIEhvdyBjb25maWRlbnRseSBhbiBpbmNpZGVudCB3YXMgYXR0cmlidXRlZCB0byBhIGRlcGxveS4gU2hvd24gYmVzaWRlIGNoYW5nZVxuICogZmFpbHVyZSByYXRlIGFuZCB0aW1lIHRvIHJlc3RvcmUsIGJlY2F1c2UgXCJ0aGlzIGRlcGxveSBicm9rZSBwcm9kdWN0aW9uXCIgYW5kXG4gKiBcImFuIGluY2lkZW50IG9wZW5lZCBzb21lIGhvdXJzIGFmdGVyIHRoaXMgZGVwbG95XCIgYXJlIGRpZmZlcmVudCBjbGFpbXMgYW5kIGFcbiAqIG1hbmFnZXIgYWN0cyBkaWZmZXJlbnRseSBvbiBlYWNoLlxuICovXG5leHBvcnQgY29uc3QgQ09SUkVMQVRJT05fQ09ORklERU5DRVMgPSBbJ2hpZ2gnLCAnbWVkaXVtJywgJ2xvdyddIGFzIGNvbnN0O1xuZXhwb3J0IHR5cGUgQ29ycmVsYXRpb25Db25maWRlbmNlID0gKHR5cGVvZiBDT1JSRUxBVElPTl9DT05GSURFTkNFUylbbnVtYmVyXTtcblxuLyoqXG4gKiBIb3cgYSBwaXBlbGluZSBjYW1lIHRvIGV4aXN0LiBGb3IgdGhlIGFkb3B0aW9uIHNlY3Rpb246IGFuIG9yZyB3aG9zZSBwaXBlbGluZXNcbiAqIGFyZSBhbGwgaGFuZC1idWlsdCBpcyBhIGRpZmZlcmVudCBhZG9wdGlvbiBzdG9yeSBmcm9tIG9uZSB0ZW1wbGF0aW5nIHRoZW0uXG4gKi9cbmV4cG9ydCBjb25zdCBQSVBFTElORV9DUkVBVElPTl9TT1VSQ0VTID0gWydtYW51YWwnLCAndGVtcGxhdGUnLCAnYWknLCAnYnVsaycsICdjZGsnXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIFBpcGVsaW5lQ3JlYXRpb25Tb3VyY2UgPSAodHlwZW9mIFBJUEVMSU5FX0NSRUFUSU9OX1NPVVJDRVMpW251bWJlcl07XG5cbi8qKlxuICogV2hhdCBraW5kIG9mIHRoaW5nIGJyb2tlLiBBc3NpZ25lZCBhdCBpbmdlc3QgYnkgdGhlIGNsYXNzaWZpZXJcbiAqIChgYXBpL3JlcG9ydGluZy9zcmMvc2VydmljZXMvZmFpbHVyZS1jbGFzc2lmaWVyLnRzYCksIHdoaWNoIGlzIHJ1bGVzIG92ZXIgdGhlXG4gKiBhY3Rpb24ncyB0eXBlIGFuZCBlcnJvciB0ZXh0IOKAlCBkZWxpYmVyYXRlbHkgZGF0YSwgbm90IGNvZGUsIHNvIHRoZSB0YXhvbm9teSBjYW5cbiAqIGdyb3cgd2l0aG91dCBhIGRlcGxveS5cbiAqXG4gKiBUaGUgY2F0ZWdvcmllcyBvdmVybGFwIHRoZSBwbHVnaW4tYnVpbGQgdGF4b25vbXkgb24gcHVycG9zZTogYSBkZXBlbmRlbmN5XG4gKiBmYWlsdXJlIGlzIGEgZGVwZW5kZW5jeSBmYWlsdXJlIHdoZXRoZXIgaXQgaGFwcGVuZWQgYnVpbGRpbmcgYSBwbHVnaW4gb3JcbiAqIHJ1bm5pbmcgb25lLCBhbmQgdHdvIHZvY2FidWxhcmllcyBmb3IgdGhlIHNhbWUgdGhpbmcgd291bGQgbWFrZSB0aGUgcmVwb3J0IGFuZFxuICogdGhlIGJ1aWxkIHF1ZXVlIGRpc2FncmVlLlxuICovXG5leHBvcnQgY29uc3QgRkFJTFVSRV9DQVRFR09SSUVTID0gW1xuICAnc291cmNlX2NoZWNrb3V0JywgJ2RlcGVuZGVuY3knLCAnYnVpbGQnLCAndW5pdF90ZXN0JywgJ2ludGVncmF0aW9uX3Rlc3QnLFxuICAnc2VjdXJpdHlfc2NhbicsICdpbmZyYXN0cnVjdHVyZScsICdkZXBsb3ltZW50JywgJ2F1dGhlbnRpY2F0aW9uJywgJ3Blcm1pc3Npb25zJyxcbiAgJ2NvbmZpZ3VyYXRpb24nLCAndGltZW91dCcsICdyZXNvdXJjZV9leGhhdXN0aW9uJywgJ2V4dGVybmFsX3NlcnZpY2UnLCAnb3RoZXInLFxuXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIEZhaWx1cmVDYXRlZ29yeSA9ICh0eXBlb2YgRkFJTFVSRV9DQVRFR09SSUVTKVtudW1iZXJdO1xuXG4vKiogV2hlcmUgYSBwbHVnaW4tdmVyc2lvbiBleHBvc3VyZSB3YXMgb2JzZXJ2ZWQuICovXG5leHBvcnQgY29uc3QgRVhQT1NVUkVfU09VUkNFUyA9IFsnZGVjbGFyZWQnLCAnZGVwbG95ZWQnXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIEV4cG9zdXJlU291cmNlID0gKHR5cGVvZiBFWFBPU1VSRV9TT1VSQ0VTKVtudW1iZXJdO1xuXG4vKipcbiAqIFdoYXQgYW4gb3JnIGRlY2lkZWQgYWJvdXQgYW4gZXhwb3N1cmUuIGBvcGVuYCB1bnRpbCBzb21lb25lIGxvb2tzO1xuICogYGFjY2VwdGVkYCBpcyBhIHRpbWUtYm94ZWQgZGVjaXNpb24gd2l0aCBhIHJlYXNvbiBhbmQgYW4gb3duZXIsIG5ldmVyIGFcbiAqIHBlcm1hbmVudCBtdXRlOyBgZmFsc2VfcG9zaXRpdmVgIGlzIGEgc2Nhbm5lciBkaXNhZ3JlZW1lbnQgd29ydGggcmVjb3JkaW5nIHNvXG4gKiB0aGUgc2FtZSBmaW5kaW5nIHN0b3BzIGJlaW5nIHJlLXJhaXNlZCBhcyBuZXdzLlxuICovXG5leHBvcnQgY29uc3QgRVhQT1NVUkVfVFJJQUdFX1NUQVRFUyA9IFsnb3BlbicsICdhY2NlcHRlZCcsICdmYWxzZV9wb3NpdGl2ZScsICdmaXhlZCddIGFzIGNvbnN0O1xuZXhwb3J0IHR5cGUgRXhwb3N1cmVUcmlhZ2VTdGF0ZSA9ICh0eXBlb2YgRVhQT1NVUkVfVFJJQUdFX1NUQVRFUylbbnVtYmVyXTtcblxuLyoqXG4gKiBPbmUgZGVwbG95bWVudDogYW4gZXhlY3V0aW9uIHRoYXQgcmVhY2hlZCBhbiBlbnZpcm9ubWVudC5cbiAqXG4gKiBXcml0dGVuIGF0IGluZ2VzdCwgb25lIHJvdyBwZXIgKGV4ZWN1dGlvbiwgZW52aXJvbm1lbnQpLiBFdmVyeXRoaW5nIERPUkFcbiAqIHJlcG9ydHMgaXMgaGVyZSwgc28gYC9kb3JhYCwgdGhlIHRyZW5kIGFuZCB0aGUgcmVwb3J0IHNlY3Rpb25zIHN0b3Agc2Nhbm5pbmdcbiAqIHJhdyBldmVudHMg4oCUIGFuZCBrZWVwIHdvcmtpbmcgYWZ0ZXIgdGhlIGV2ZW50cyBhcmUgc3dlcHQuXG4gKlxuICogQHRhYmxlIGRvcmFfZGVwbG95bWVudHNcbiAqL1xuZXhwb3J0IGNvbnN0IGRvcmFEZXBsb3ltZW50ID0gcGdUYWJsZSgnZG9yYV9kZXBsb3ltZW50cycsIHtcbiAgb3JnSWQ6IHZhcmNoYXIoJ29yZ19pZCcsIHsgbGVuZ3RoOiAyNTUgfSkubm90TnVsbCgpLFxuICBleGVjdXRpb25JZDogdmFyY2hhcignZXhlY3V0aW9uX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIGVudmlyb25tZW50OiB2YXJjaGFyKCdlbnZpcm9ubWVudCcsIHsgbGVuZ3RoOiAyNTUgfSkubm90TnVsbCgpLFxuICBwaXBlbGluZUlkOiB2YXJjaGFyKCdwaXBlbGluZV9pZCcsIHsgbGVuZ3RoOiAyNTUgfSksXG4gIC8qKiBXaGVuIHRoZSBkZXBsb3kgc3RhZ2UgY29tcGxldGVkLiBUaGUgZGVwbG95J3Mgb3duIHRpbWVzdGFtcCwgbm90IHRoZSBydW4ncy4gKi9cbiAgZGVwbG95ZWRBdDogdGltZXN0YW1wKCdkZXBsb3llZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLm5vdE51bGwoKSxcbiAgc3VjY2VlZGVkOiBib29sZWFuKCdzdWNjZWVkZWQnKS5ub3ROdWxsKCksXG4gIC8qKlxuICAgKiBUaGUgT0xERVNUIHVuc2hpcHBlZCBjb21taXQgaW4gdGhpcyBkZXBsb3kncyByYW5nZS4gTGVhZCB0aW1lIGlzXG4gICAqIGBkZXBsb3llZEF0IC0gZWFybGllc3RDb21taXRBdGAsIGNvbXB1dGVkIG9uY2UgYW5kIHN0b3JlZCwgYmVjYXVzZSB0aGVcbiAgICogcGVyLWV2ZW50IGZvcm0gZG91YmxlLWNvdW50cyBhIGRlcGxveSB0aGF0IGVtaXRzIGJvdGggYSBTVEFHRSBhbmQgYW4gQUNUSU9OXG4gICAqIGV2ZW50IGNhcnJ5aW5nIHRoZSBzYW1lIHJhbmdlLlxuICAgKi9cbiAgZWFybGllc3RDb21taXRBdDogdGltZXN0YW1wKCdlYXJsaWVzdF9jb21taXRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgbGVhZFRpbWVTZWNvbmRzOiBpbnRlZ2VyKCdsZWFkX3RpbWVfc2Vjb25kcycpLFxuICBjb21taXRDb3VudDogaW50ZWdlcignY29tbWl0X2NvdW50JyksXG4gIGNvbW1pdFNoYTogdmFyY2hhcignY29tbWl0X3NoYScsIHsgbGVuZ3RoOiAyNTUgfSksXG4gIC8qKiBXaHkgbGVhZCB0aW1lIGlzIGFic2VudCwgd2hlbiBpdCBpcy4gTlVMTCB3aGVuIGl0IHdhcyBtZWFzdXJlZC4gKi9cbiAgbGVhZFRpbWVHYXA6IHZhcmNoYXIoJ2xlYWRfdGltZV9nYXAnLCB7IGxlbmd0aDogMzAgfSkuJHR5cGU8TGVhZFRpbWVHYXA+KCksXG4gIC8qKlxuICAgKiBQb3N0LWRlcGxveSBvdXRjb21lIG1hcmtlcnMsIGRlbm9ybWFsaXplZCBvbnRvIHRoZSBkZXBsb3kgc28gY2hhbmdlLWZhaWx1cmVcbiAgICogcmF0ZSBhbmQgdGltZS10by1yZXN0b3JlIGFyZSBvbmUgc2NhbiByYXRoZXIgdGhhbiBhIGpvaW4gcGVyIHdpbmRvdy5cbiAgICovXG4gIGZhaWxlZEF0OiB0aW1lc3RhbXAoJ2ZhaWxlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICByZXN0b3JlZEF0OiB0aW1lc3RhbXAoJ3Jlc3RvcmVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIC8qKiBIb3cgdGhlIGluY2lkZW504oaSZGVwbG95IGxpbmsgd2FzIGp1ZGdlZC4gTlVMTCB3aGVuIG5vdGhpbmcgd2FzIGNvcnJlbGF0ZWQuICovXG4gIGNvcnJlbGF0aW9uQ29uZmlkZW5jZTogdmFyY2hhcignY29ycmVsYXRpb25fY29uZmlkZW5jZScsIHsgbGVuZ3RoOiAxMCB9KS4kdHlwZTxDb3JyZWxhdGlvbkNvbmZpZGVuY2U+KCksXG4gIGNyZWF0ZWRBdDogdGltZXN0YW1wKCdjcmVhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbiAgdXBkYXRlZEF0OiB0aW1lc3RhbXAoJ3VwZGF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxufSwgKHRhYmxlKSA9PiAoe1xuICAvLyBPbmUgcm93IHBlciBleGVjdXRpb24gcGVyIGVudmlyb25tZW50OiBhIHJlZGVsaXZlcmVkIGV2ZW50IHVwc2VydHMgcmF0aGVyXG4gIC8vIHRoYW4gaW5zZXJ0aW5nIGEgc2Vjb25kIGRlcGxveSAoRXZlbnRCcmlkZ2Ug4oaSIFNRUyBpcyBhdC1sZWFzdC1vbmNlKS5cbiAgcGs6IHByaW1hcnlLZXkoeyBjb2x1bW5zOiBbdGFibGUuZXhlY3V0aW9uSWQsIHRhYmxlLmVudmlyb25tZW50XSB9KSxcbiAgLy8gVGhlIHdpbmRvdyBzY2FuIGV2ZXJ5IERPUkEgcmVhZCBkb2VzLlxuICBvcmdFbnZEZXBsb3llZElkeDogaW5kZXgoJ2RvcmFfZGVwbG95bWVudF9vcmdfZW52X2RlcGxveWVkX2lkeCcpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS5lbnZpcm9ubWVudCwgdGFibGUuZGVwbG95ZWRBdCksXG4gIG9yZ0RlcGxveWVkSWR4OiBpbmRleCgnZG9yYV9kZXBsb3ltZW50X29yZ19kZXBsb3llZF9pZHgnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUuZGVwbG95ZWRBdCksXG4gIHBpcGVsaW5lSWR4OiBpbmRleCgnZG9yYV9kZXBsb3ltZW50X3BpcGVsaW5lX2lkeCcpLm9uKHRhYmxlLnBpcGVsaW5lSWQsIHRhYmxlLmRlcGxveWVkQXQpLFxuICAvLyBUaGUgcHJvbW90aW9uIHZpZXc6IG9uZSBjb21taXQncyBwYXRoIGFjcm9zcyBlbnZpcm9ubWVudHMuXG4gIGNvbW1pdElkeDogaW5kZXgoJ2RvcmFfZGVwbG95bWVudF9jb21taXRfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLmNvbW1pdFNoYSlcbiAgICAud2hlcmUoc3FsYGNvbW1pdF9zaGEgSVMgTk9UIE5VTExgKSxcbn0pKTtcblxuLyoqXG4gKiBQcmUtYWdncmVnYXRlZCBleGVjdXRpb24gY291bnRzIGFuZCB0aW1pbmdzLCBvbmUgcm93IHBlciBvcmcsIHBpcGVsaW5lLCBzdGFnZVxuICogYW5kIFVUQyBkYXkuXG4gKlxuICogUmVidWlsdCBmb3IgYSBkYXkgd2hlbiBsYXRlIGV2ZW50cyBhcnJpdmUsIHNvIHRoZSByb2xsdXAgYW5kIHRoZSBldmVudHMgYWdyZWVcbiAqIHdoaWxlIGJvdGggZXhpc3QuIGBmYWlsdXJlc0J5Q2F0ZWdvcnlgIGlzIGEgSlNPTiBtYXAgcmF0aGVyIHRoYW4gYSBjb2x1bW4gcGVyXG4gKiBjYXRlZ29yeSBiZWNhdXNlIHRoZSB0YXhvbm9teSBncm93cy5cbiAqXG4gKiBAdGFibGUgZXhlY3V0aW9uX2RhaWx5X3JvbGx1cHNcbiAqL1xuZXhwb3J0IGNvbnN0IGV4ZWN1dGlvbkRhaWx5Um9sbHVwID0gcGdUYWJsZSgnZXhlY3V0aW9uX2RhaWx5X3JvbGx1cHMnLCB7XG4gIG9yZ0lkOiB2YXJjaGFyKCdvcmdfaWQnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcbiAgLyoqIFRoZSBVVEMgZGF0ZSB0aGlzIHJvdyBhZ2dyZWdhdGVzLiBSZXBvcnQgcGVyaW9kcyByZS1idWNrZXQgaW4gdGhlIHJlcG9ydCdzXG4gICAqICBvd24gdGltZXpvbmUgYnkgc3VtbWluZyBkYXlzIOKAlCB3aGljaCBpcyB3aHkgdGhlIGdyYWluIGlzIGEgREFZLiAqL1xuICBkYXk6IHRpbWVzdGFtcCgnZGF5JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkubm90TnVsbCgpLFxuICBwaXBlbGluZUlkOiB2YXJjaGFyKCdwaXBlbGluZV9pZCcsIHsgbGVuZ3RoOiAyNTUgfSkubm90TnVsbCgpLFxuICAvKiogYCcnYCBmb3IgdGhlIHBpcGVsaW5lLWxldmVsIHJvdzsgYSBzdGFnZSBuYW1lIGZvciBhIHN0YWdlLWxldmVsIHJvdy4gKi9cbiAgc3RhZ2VOYW1lOiB2YXJjaGFyKCdzdGFnZV9uYW1lJywgeyBsZW5ndGg6IDI1NSB9KS5kZWZhdWx0KCcnKS5ub3ROdWxsKCksXG4gIHJ1bnM6IGludGVnZXIoJ3J1bnMnKS5kZWZhdWx0KDApLm5vdE51bGwoKSxcbiAgc3VjY2VlZGVkOiBpbnRlZ2VyKCdzdWNjZWVkZWQnKS5kZWZhdWx0KDApLm5vdE51bGwoKSxcbiAgZmFpbGVkOiBpbnRlZ2VyKCdmYWlsZWQnKS5kZWZhdWx0KDApLm5vdE51bGwoKSxcbiAgLyoqIGNhdGVnb3J5IOKGkiBjb3VudC4gRmVlZHMgdGhlIGZhaWx1cmUtYW5hbHlzaXMgc2VjdGlvbi4gKi9cbiAgZmFpbHVyZXNCeUNhdGVnb3J5OiBqc29uYignZmFpbHVyZXNfYnlfY2F0ZWdvcnknKS4kdHlwZTxSZWNvcmQ8c3RyaW5nLCBudW1iZXI+PigpLmRlZmF1bHQoe30pLm5vdE51bGwoKSxcbiAgcDUwTXM6IGludGVnZXIoJ3A1MF9tcycpLFxuICBwOTBNczogaW50ZWdlcigncDkwX21zJyksXG4gIHA5NU1zOiBpbnRlZ2VyKCdwOTVfbXMnKSxcbiAgLyoqIFN1bW1lZCBleGVjdXRpb24gZHVyYXRpb24sIGluIHNlY29uZHMuIFRoZSByZXNvdXJjZS1jb25zdW1wdGlvbiBzZWN0aW9uJ3NcbiAgICogIG9ubHkgaW5wdXQ7IGRlbGliZXJhdGVseSBOT1QgY29udmVydGVkIHRvIG1vbmV5IGFueXdoZXJlLiAqL1xuICBidWlsZFNlY29uZHM6IGludGVnZXIoJ2J1aWxkX3NlY29uZHMnKS5kZWZhdWx0KDApLm5vdE51bGwoKSxcbiAgLyoqIFdoZW4gdGhpcyByb3cgd2FzIGxhc3QgcmVidWlsdCwgc28gYSBsYXRlLWV2ZW50IHJlYnVpbGQgaXMgdmlzaWJsZS4gKi9cbiAgY29tcHV0ZWRBdDogdGltZXN0YW1wKCdjb21wdXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG59LCAodGFibGUpID0+ICh7XG4gIHBrOiBwcmltYXJ5S2V5KHsgY29sdW1uczogW3RhYmxlLm9yZ0lkLCB0YWJsZS5kYXksIHRhYmxlLnBpcGVsaW5lSWQsIHRhYmxlLnN0YWdlTmFtZV0gfSksXG4gIG9yZ0RheUlkeDogaW5kZXgoJ2V4ZWN1dGlvbl9yb2xsdXBfb3JnX2RheV9pZHgnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUuZGF5KSxcbiAgcGlwZWxpbmVEYXlJZHg6IGluZGV4KCdleGVjdXRpb25fcm9sbHVwX3BpcGVsaW5lX2RheV9pZHgnKS5vbih0YWJsZS5waXBlbGluZUlkLCB0YWJsZS5kYXkpLFxufSkpO1xuXG4vKipcbiAqIFdoYXQgYSBwaXBlbGluZSdzIGRlY2xhcmVkIHBsdWdpbiBzdGVwcyByZXNvbHZlIHRvLlxuICpcbiAqIFJlY29tcHV0ZWQgb24gcGlwZWxpbmUgd3JpdGUgYW5kIG9uIHBsdWdpbiBwdWJsaXNoLCByYXRoZXIgdGhhbiByZXNvbHZlZCBhdFxuICogcmVhZCB0aW1lOiB0aGUgb3V0ZGF0ZWQtcGx1Z2luIHNlY3Rpb24gY29tcGFyZXMgXCJpbiB1c2VcIiBhZ2FpbnN0IFwibGF0ZXN0XG4gKiBhdmFpbGFibGVcIiBmb3IgZXZlcnkgc3RlcCBvZiBldmVyeSBwaXBlbGluZSwgYW5kIGRvaW5nIHRoYXQgcmVzb2x1dGlvbiBwZXIgcmVhZFxuICogbWFkZSBpdCBhIHF1ZXJ5IG5vYm9keSBjb3VsZCBhZmZvcmQgdG8gcHV0IGluIGEgcmVwb3J0LlxuICpcbiAqIEB0YWJsZSBwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvblxuICovXG5leHBvcnQgY29uc3QgcGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uID0gcGdUYWJsZSgncGlwZWxpbmVfcGx1Z2luX3Jlc29sdXRpb24nLCB7XG4gIG9yZ0lkOiB2YXJjaGFyKCdvcmdfaWQnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcbiAgcGlwZWxpbmVJZDogdmFyY2hhcigncGlwZWxpbmVfaWQnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcbiAgc3RhZ2VOYW1lOiB2YXJjaGFyKCdzdGFnZV9uYW1lJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHN0ZXBOYW1lOiB2YXJjaGFyKCdzdGVwX25hbWUnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcbiAgcGx1Z2luUHVibGlzaGVyOiB2YXJjaGFyKCdwbHVnaW5fcHVibGlzaGVyJywgeyBsZW5ndGg6IDM5IH0pLFxuICBwbHVnaW5OYW1lOiB2YXJjaGFyKCdwbHVnaW5fbmFtZScsIHsgbGVuZ3RoOiAyNTUgfSkubm90TnVsbCgpLFxuICAvKiogV2hhdCB0aGUgY29uZmlnIGFza2VkIGZvciDigJQgYSByYW5nZSwgYSBwaW4sIG9yIG5vdGhpbmcuICovXG4gIGRlY2xhcmVkVmVyc2lvbjogdmFyY2hhcignZGVjbGFyZWRfdmVyc2lvbicsIHsgbGVuZ3RoOiA1MCB9KSxcbiAgLyoqIFdoYXQgdGhhdCByZXNvbHZlcyB0byB0b2RheS4gTlVMTCB3aGVuIG5vdGhpbmcgc2F0aXNmaWVzIGl0LiAqL1xuICByZXNvbHZlZFZlcnNpb246IHZhcmNoYXIoJ3Jlc29sdmVkX3ZlcnNpb24nLCB7IGxlbmd0aDogNTAgfSksXG4gIC8qKiBUaGUgbmV3ZXN0IHZlcnNpb24gdGhlIG9yZyBpcyBlbnRpdGxlZCB0byBpbnN0YWxsLCBmb3IgdGhlIFwiZ2FwXCIgY29sdW1uLiAqL1xuICBsYXRlc3RWZXJzaW9uOiB2YXJjaGFyKCdsYXRlc3RfdmVyc2lvbicsIHsgbGVuZ3RoOiA1MCB9KSxcbiAgLyoqIGBtYWpvcmAgLyBgbWlub3JgIC8gYHBhdGNoYCAvIGBub25lYCwgZnJvbSByZXNvbHZlZCDihpIgbGF0ZXN0LiAqL1xuICB2ZXJzaW9uR2FwOiB2YXJjaGFyKCd2ZXJzaW9uX2dhcCcsIHsgbGVuZ3RoOiAxMCB9KSxcbiAgLyoqIEZhbHNlIHdoZW4gdGhlIHJlc29sdmVkIHZlcnNpb24gaXMgb3V0c2lkZSB0aGUgb3JnJ3MgY29uc3VtcHRpb24gcG9saWN5LiAqL1xuICB3aXRoaW5Qb2xpY3k6IGJvb2xlYW4oJ3dpdGhpbl9wb2xpY3knKS5kZWZhdWx0KHRydWUpLm5vdE51bGwoKSxcbiAgY29tcHV0ZWRBdDogdGltZXN0YW1wKCdjb21wdXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG59LCAodGFibGUpID0+ICh7XG4gIHBrOiBwcmltYXJ5S2V5KHsgY29sdW1uczogW3RhYmxlLnBpcGVsaW5lSWQsIHRhYmxlLnN0YWdlTmFtZSwgdGFibGUuc3RlcE5hbWVdIH0pLFxuICBvcmdJZHg6IGluZGV4KCdwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvbl9vcmdfaWR4Jykub24odGFibGUub3JnSWQpLFxuICBwbHVnaW5JZHg6IGluZGV4KCdwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvbl9wbHVnaW5faWR4Jykub24odGFibGUucGx1Z2luUHVibGlzaGVyLCB0YWJsZS5wbHVnaW5OYW1lKSxcbiAgLy8gXCJXaGljaCBwaXBlbGluZXMgYXJlIGJlaGluZD9cIiDigJQgdGhlIG91dGRhdGVkIHNlY3Rpb24ncyBkcml2aW5nIHNjYW4uXG4gIGdhcElkeDogaW5kZXgoJ3BpcGVsaW5lX3BsdWdpbl9yZXNvbHV0aW9uX2dhcF9pZHgnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUudmVyc2lvbkdhcCksXG59KSk7XG5cbi8qKlxuICogT25lIHBpcGVsaW5lJ3MgZXhwb3N1cmUgdG8gb25lIHZ1bG5lcmFibGUgcGx1Z2luIHZlcnNpb24uXG4gKlxuICogT3BlbmVkIGJ5IHRoZSBuaWdodGx5IHJlc2NhbiB3aGVuIGEgdmVyc2lvbiBpbiB1c2UgaGFzIGZpeGFibGUgQ3JpdGljYWwvSGlnaFxuICogZmluZGluZ3MsIGFuZCBDTE9TRUQgYnkgYSBkZXBsb3kgdGhhdCBtb3ZlcyB0aGUgcGlwZWxpbmUgb2ZmIGl0LiBJdCBpcyBhXG4gKiBwZXItcGlwZWxpbmUgcm93IHJhdGhlciB0aGFuIGEgcGVyLXZlcnNpb24gb25lIGJlY2F1c2UgdGhlIHF1ZXN0aW9uIGEgbWFuYWdlclxuICogYXNrcyBpcyBcIndoaWNoIG9mIG91ciBwaXBlbGluZXMgaXMgZXhwb3NlZFwiLCBhbmQgYW5zd2VyaW5nIHRoYXQgZnJvbSBhXG4gKiB2ZXJzaW9uLWxldmVsIHRhYmxlIG1lYW5zIHJlLWRlcml2aW5nIHRoZSBwaXBlbGluZSBzZXQgb24gZXZlcnkgcmVhZC5cbiAqXG4gKiBLZXllZCBieSBJTUFHRSBESUdFU1QsIG5vdCB2ZXJzaW9uIHN0cmluZzogYSB2ZXJzaW9uIHJlYnVpbHQgb24gYSBwYXRjaGVkIGJhc2VcbiAqIGltYWdlIGlzIGEgZGlmZmVyZW50IGFydGlmYWN0IHdpdGggZGlmZmVyZW50IGZpbmRpbmdzLCBhbmQga2V5aW5nIG9uIHRoZSBzdHJpbmdcbiAqIHdvdWxkIHJlcG9ydCB0aGUgb2xkIG9uZSBmb3JldmVyLlxuICpcbiAqIEB0YWJsZSBwbHVnaW5fdnVsbl9leHBvc3VyZVxuICovXG5leHBvcnQgY29uc3QgcGx1Z2luVnVsbkV4cG9zdXJlID0gcGdUYWJsZSgncGx1Z2luX3Z1bG5fZXhwb3N1cmUnLCB7XG4gIGlkOiB2YXJjaGFyKCdpZCcsIHsgbGVuZ3RoOiAyNTUgfSkucHJpbWFyeUtleSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHBpcGVsaW5lSWQ6IHZhcmNoYXIoJ3BpcGVsaW5lX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHBsdWdpblB1Ymxpc2hlcjogdmFyY2hhcigncGx1Z2luX3B1Ymxpc2hlcicsIHsgbGVuZ3RoOiAzOSB9KSxcbiAgcGx1Z2luTmFtZTogdmFyY2hhcigncGx1Z2luX25hbWUnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcbiAgcGx1Z2luVmVyc2lvbjogdmFyY2hhcigncGx1Z2luX3ZlcnNpb24nLCB7IGxlbmd0aDogNTAgfSkubm90TnVsbCgpLFxuICBpbWFnZURpZ2VzdDogdmFyY2hhcignaW1hZ2VfZGlnZXN0JywgeyBsZW5ndGg6IDcxIH0pLFxuICBzb3VyY2U6IHZhcmNoYXIoJ3NvdXJjZScsIHsgbGVuZ3RoOiAxMCB9KS4kdHlwZTxFeHBvc3VyZVNvdXJjZT4oKS5ub3ROdWxsKCksXG4gIGNyaXRpY2FsQ291bnQ6IGludGVnZXIoJ2NyaXRpY2FsX2NvdW50JykuZGVmYXVsdCgwKS5ub3ROdWxsKCksXG4gIGhpZ2hDb3VudDogaW50ZWdlcignaGlnaF9jb3VudCcpLmRlZmF1bHQoMCkubm90TnVsbCgpLFxuICAvKiogVGhlIGZpbmRpbmdzIHRoZW1zZWx2ZXM6IENWRSBpZCwgcGFja2FnZSwgZml4ZWQtaW4gdmVyc2lvbi4gQ2FwcGVkIGJ5IHRoZSB3cml0ZXIuICovXG4gIHRvcEZpbmRpbmdzOiBqc29uYigndG9wX2ZpbmRpbmdzJykuJHR5cGU8QXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+PigpLmRlZmF1bHQoW10pLm5vdE51bGwoKSxcbiAgZmxhZ2dlZEF0OiB0aW1lc3RhbXAoJ2ZsYWdnZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICAvKiogU2V0IHdoZW4gYSBkZXBsb3kgbW92ZWQgdGhlIHBpcGVsaW5lIG9udG8gYSB2ZXJzaW9uIHdpdGhvdXQgdGhlIGZpbmRpbmdzLiAqL1xuICBmaXhlZEF0OiB0aW1lc3RhbXAoJ2ZpeGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIHRyaWFnZVN0YXRlOiB2YXJjaGFyKCd0cmlhZ2Vfc3RhdGUnLCB7IGxlbmd0aDogMjAgfSkuJHR5cGU8RXhwb3N1cmVUcmlhZ2VTdGF0ZT4oKS5kZWZhdWx0KCdvcGVuJykubm90TnVsbCgpLFxuICAvKiogQW4gYWNjZXB0YW5jZSBpcyB0aW1lLWJveGVkOiBhIHBlcm1hbmVudCBtdXRlIGlzIGhvdyBhIGZpbmRpbmcgaXMgZm9yZ290dGVuLiAqL1xuICBhY2NlcHRlZFVudGlsOiB0aW1lc3RhbXAoJ2FjY2VwdGVkX3VudGlsJywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIHRyaWFnZVJlYXNvbjogdGV4dCgndHJpYWdlX3JlYXNvbicpLFxuICB0cmlhZ2VkQnk6IHRleHQoJ3RyaWFnZWRfYnknKSxcbiAgdHJpYWdlZEF0OiB0aW1lc3RhbXAoJ3RyaWFnZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgdXBkYXRlZEF0OiB0aW1lc3RhbXAoJ3VwZGF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxufSwgKHRhYmxlKSA9PiAoe1xuICAvLyBPbmUgbGl2ZSBleHBvc3VyZSBwZXIgKHBpcGVsaW5lLCBwbHVnaW4gdmVyc2lvbiwgZGlnZXN0LCBzb3VyY2UpOiBhIG5pZ2h0bHlcbiAgLy8gcmVzY2FuIHJlZnJlc2hlcyBjb3VudHMgcmF0aGVyIHRoYW4gb3BlbmluZyBhIG5ldyByb3cgZXZlcnkgbmlnaHQuXG4gIGV4cG9zdXJlVW5pcXVlOiB1bmlxdWVJbmRleCgncGx1Z2luX3Z1bG5fZXhwb3N1cmVfdW5pcXVlJylcbiAgICAub24odGFibGUucGlwZWxpbmVJZCwgdGFibGUucGx1Z2luTmFtZSwgdGFibGUucGx1Z2luVmVyc2lvbiwgdGFibGUuc291cmNlKSxcbiAgb3JnT3BlbklkeDogaW5kZXgoJ3BsdWdpbl92dWxuX2V4cG9zdXJlX29yZ19vcGVuX2lkeCcpLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS50cmlhZ2VTdGF0ZSlcbiAgICAud2hlcmUoc3FsYGZpeGVkX2F0IElTIE5VTExgKSxcbiAgZGlnZXN0SWR4OiBpbmRleCgncGx1Z2luX3Z1bG5fZXhwb3N1cmVfZGlnZXN0X2lkeCcpLm9uKHRhYmxlLmltYWdlRGlnZXN0KSxcbn0pKTtcblxuZXhwb3J0IHR5cGUgRG9yYURlcGxveW1lbnQgPSB0eXBlb2YgZG9yYURlcGxveW1lbnQuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgRG9yYURlcGxveW1lbnRJbnNlcnQgPSB0eXBlb2YgZG9yYURlcGxveW1lbnQuJGluZmVySW5zZXJ0O1xuZXhwb3J0IHR5cGUgRXhlY3V0aW9uRGFpbHlSb2xsdXAgPSB0eXBlb2YgZXhlY3V0aW9uRGFpbHlSb2xsdXAuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgRXhlY3V0aW9uRGFpbHlSb2xsdXBJbnNlcnQgPSB0eXBlb2YgZXhlY3V0aW9uRGFpbHlSb2xsdXAuJGluZmVySW5zZXJ0O1xuZXhwb3J0IHR5cGUgUGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uID0gdHlwZW9mIHBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi4kaW5mZXJTZWxlY3Q7XG5leHBvcnQgdHlwZSBQaXBlbGluZVBsdWdpblJlc29sdXRpb25JbnNlcnQgPSB0eXBlb2YgcGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLiRpbmZlckluc2VydDtcbmV4cG9ydCB0eXBlIFBsdWdpblZ1bG5FeHBvc3VyZSA9IHR5cGVvZiBwbHVnaW5WdWxuRXhwb3N1cmUuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgUGx1Z2luVnVsbkV4cG9zdXJlSW5zZXJ0ID0gdHlwZW9mIHBsdWdpblZ1bG5FeHBvc3VyZS4kaW5mZXJJbnNlcnQ7XG4iXX0=