@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.
- package/lib/api/alert-destinations.d.ts +17 -0
- package/lib/api/alert-destinations.js +36 -0
- package/lib/api/reporting/analytics-queries.d.ts +274 -0
- package/lib/api/reporting/analytics-queries.js +598 -0
- package/lib/api/reporting/daily-rollup.d.ts +41 -0
- package/lib/api/reporting/daily-rollup.js +173 -0
- package/lib/api/reporting/deploy-rollup.d.ts +78 -0
- package/lib/api/reporting/deploy-rollup.js +203 -0
- package/lib/api/reporting/dora-scoring.d.ts +14 -0
- package/lib/api/reporting/dora-scoring.js +25 -1
- package/lib/api/reporting/dora.js +30 -6
- package/lib/api/reporting/failure-classifier.d.ts +54 -0
- package/lib/api/reporting/failure-classifier.js +179 -0
- package/lib/api/reporting/ingest.d.ts +2 -2
- package/lib/api/reporting/ingest.js +129 -4
- package/lib/api/reporting/last-deploy.d.ts +31 -0
- package/lib/api/reporting/last-deploy.js +93 -0
- package/lib/api/reporting/needs-attention.d.ts +93 -0
- package/lib/api/reporting/needs-attention.js +152 -0
- package/lib/api/reporting/plugin-exposure.d.ts +129 -0
- package/lib/api/reporting/plugin-exposure.js +312 -0
- package/lib/api/reporting/retention-sweep.js +9 -1
- package/lib/api/reporting/sql-helpers.d.ts +35 -2
- package/lib/api/reporting/sql-helpers.js +39 -1
- package/lib/api/reporting/stakeholder/compose.d.ts +115 -0
- package/lib/api/reporting/stakeholder/compose.js +234 -0
- package/lib/api/reporting/stakeholder/index.d.ts +14 -0
- package/lib/api/reporting/stakeholder/index.js +17 -0
- package/lib/api/reporting/stakeholder/period.d.ts +102 -0
- package/lib/api/reporting/stakeholder/period.js +273 -0
- package/lib/api/reporting/stakeholder/report-html.d.ts +93 -0
- package/lib/api/reporting/stakeholder/report-html.js +208 -0
- package/lib/api/reporting/stakeholder/sections.d.ts +117 -0
- package/lib/api/reporting/stakeholder/sections.js +249 -0
- package/lib/api/reporting/stakeholder/store.d.ts +450 -0
- package/lib/api/reporting/stakeholder/store.js +981 -0
- package/lib/api/reporting/stakeholder/templates.d.ts +21 -0
- package/lib/api/reporting/stakeholder/templates.js +104 -0
- package/lib/api/reporting/types.d.ts +73 -0
- package/lib/api/reporting/types.js +1 -1
- package/lib/api/reporting-service.d.ts +94 -5
- package/lib/api/reporting-service.js +169 -10
- package/lib/api/soft-delete-sweep.d.ts +11 -2
- package/lib/api/soft-delete-sweep.js +17 -6
- package/lib/database/drizzle-schema.d.ts +2244 -385
- package/lib/database/drizzle-schema.js +18 -7
- package/lib/database/index.d.ts +1 -1
- package/lib/database/index.js +4 -2
- package/lib/database/schema/compliance.d.ts +0 -682
- package/lib/database/schema/compliance.js +6 -66
- package/lib/database/schema/ecosystem.d.ts +20 -157
- package/lib/database/schema/ecosystem.js +23 -16
- package/lib/database/schema/pipeline.d.ts +200 -0
- package/lib/database/schema/pipeline.js +100 -1
- package/lib/database/schema/plugin.d.ts +20 -1
- package/lib/database/schema/plugin.js +13 -1
- package/lib/database/schema/reporting-analytics.d.ts +1212 -0
- package/lib/database/schema/reporting-analytics.js +250 -0
- package/lib/database/schema/reporting-stakeholder.d.ts +1373 -0
- package/lib/database/schema/reporting-stakeholder.js +251 -0
- package/lib/index.d.ts +10 -1
- package/lib/index.js +15 -1
- package/lib/testing/exports.json +67 -4
- 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=
|