@pipeline-builder/pipeline-data 4.3.2 → 4.3.4
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/crud-service.d.ts +7 -0
- package/lib/api/crud-service.js +14 -3
- package/lib/api/ecosystem-privacy.d.ts +25 -0
- package/lib/api/ecosystem-privacy.js +58 -0
- package/lib/api/pipeline-step-resolution.d.ts +111 -0
- package/lib/api/pipeline-step-resolution.js +163 -0
- package/lib/api/plugin-consumption-policy.d.ts +8 -2
- package/lib/api/plugin-consumption-policy.js +20 -3
- package/lib/api/plugin-resolution.d.ts +26 -9
- package/lib/api/plugin-resolution.js +51 -33
- package/lib/api/public-directory.js +1 -1
- package/lib/api/reporting/analytics-queries.d.ts +6 -4
- package/lib/api/reporting/analytics-queries.js +15 -14
- package/lib/api/reporting/deploy-rollup.d.ts +2 -0
- package/lib/api/reporting/deploy-rollup.js +5 -1
- package/lib/api/reporting/failure-classifier.d.ts +2 -6
- package/lib/api/reporting/failure-classifier.js +22 -1
- package/lib/api/reporting/ingest.js +73 -16
- package/lib/api/reporting/plugin-exposure.d.ts +261 -15
- package/lib/api/reporting/plugin-exposure.js +423 -38
- package/lib/api/reporting/stakeholder/compose.d.ts +1 -1
- package/lib/api/reporting/stakeholder/compose.js +30 -1
- package/lib/api/reporting/stakeholder/store.d.ts +16 -2
- package/lib/api/reporting/stakeholder/store.js +17 -6
- package/lib/api/reporting/types.d.ts +80 -1
- package/lib/api/reporting/types.js +1 -1
- package/lib/api/reporting-service.d.ts +11 -4
- package/lib/api/reporting-service.js +106 -43
- package/lib/api/soft-delete-sweep.d.ts +8 -18
- package/lib/api/soft-delete-sweep.js +35 -5
- package/lib/api/support-cases.d.ts +380 -0
- package/lib/api/support-cases.js +671 -0
- package/lib/api/version-references.d.ts +80 -0
- package/lib/api/version-references.js +135 -0
- package/lib/core/query-filters.d.ts +3 -3
- package/lib/core/query-filters.js +1 -1
- package/lib/database/drizzle-schema.d.ts +4858 -2759
- package/lib/database/drizzle-schema.js +13 -3
- package/lib/database/index.d.ts +1 -1
- package/lib/database/index.js +2 -2
- package/lib/database/schema/ecosystem.d.ts +53 -0
- package/lib/database/schema/ecosystem.js +14 -3
- package/lib/database/schema/pipeline.d.ts +38 -0
- package/lib/database/schema/pipeline.js +20 -2
- package/lib/database/schema/plugin.d.ts +265 -0
- package/lib/database/schema/plugin.js +34 -3
- package/lib/database/schema/reporting-analytics.d.ts +786 -4
- package/lib/database/schema/reporting-analytics.js +111 -5
- package/lib/database/schema/support.d.ts +1093 -0
- package/lib/database/schema/support.js +323 -0
- package/lib/database/tenancy.d.ts +7 -5
- package/lib/database/tenancy.js +1 -1
- package/lib/index.d.ts +7 -3
- package/lib/index.js +11 -3
- package/lib/testing/exports.json +57 -0
- package/package.json +4 -3
|
@@ -0,0 +1,323 @@
|
|
|
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, index, uniqueIndex } from 'drizzle-orm/pg-core';
|
|
6
|
+
/**
|
|
7
|
+
* The WORKFLOW axis of a support case.
|
|
8
|
+
*
|
|
9
|
+
* `messages` already carries the conversation — identity, threading, priority,
|
|
10
|
+
* per-participant read state, attachments and soft-delete. What it has no column
|
|
11
|
+
* for is workflow: status, ownership, resolution and the response clock. That is
|
|
12
|
+
* this table, one row per case, joined to the conversation by `threadId`.
|
|
13
|
+
*
|
|
14
|
+
* Keeping them apart rather than widening `messages` is deliberate: `messages`
|
|
15
|
+
* also carries announcements and ordinary conversations, which have no status,
|
|
16
|
+
* no assignee and no response target. Six nullable columns on every announcement
|
|
17
|
+
* row to describe a state announcements cannot be in is how a table stops
|
|
18
|
+
* meaning one thing.
|
|
19
|
+
*
|
|
20
|
+
* @table support_cases
|
|
21
|
+
*/
|
|
22
|
+
export const supportCase = pgTable('support_cases', {
|
|
23
|
+
// Internal key. NOT the case identity — see `threadId`.
|
|
24
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
25
|
+
/**
|
|
26
|
+
* The root `messages.id` of the thread, and the CANONICAL case identity.
|
|
27
|
+
*
|
|
28
|
+
* The convention already exists: readers walk `threadId === root.id` and
|
|
29
|
+
* `update-message.ts` uses `updated.threadId ?? updated.id` for exactly this
|
|
30
|
+
* "the root is the identity" idea. So case identity falls out of threading the
|
|
31
|
+
* support path rather than being a new concept.
|
|
32
|
+
*/
|
|
33
|
+
threadId: uuid('thread_id').notNull(),
|
|
34
|
+
// The TENANT org. Never the system org — a case is always about one tenant,
|
|
35
|
+
// even though the system org is the other participant in the thread.
|
|
36
|
+
orgId: varchar('org_id', { length: 255 }).notNull(),
|
|
37
|
+
/**
|
|
38
|
+
* Per-org, customer-quotable case number (rendered `ACME-1042`).
|
|
39
|
+
*
|
|
40
|
+
* A bare UUID is not something anyone reads out on a call or puts in an email
|
|
41
|
+
* subject, and a GLOBAL sequence would disclose total case volume to every
|
|
42
|
+
* customer. Allocated from `support_case_counters` in the same transaction as
|
|
43
|
+
* the insert; `support_case_org_number_uq` is the backstop that turns a
|
|
44
|
+
* bypassed counter into a failed insert rather than two cases sharing the one
|
|
45
|
+
* identifier customers quote back.
|
|
46
|
+
*/
|
|
47
|
+
displayNumber: integer('display_number').notNull(),
|
|
48
|
+
// open | awaiting_support | awaiting_customer | resolved | closed
|
|
49
|
+
status: varchar('status', { length: 32 }).default('open').notNull(),
|
|
50
|
+
// Set by the opener; re-rankable by staff. Self-selected severity is why staff
|
|
51
|
+
// re-ranking is in v1: otherwise the tenant chooses the target they are owed.
|
|
52
|
+
severity: varchar('severity', { length: 16 }).default('normal').notNull(),
|
|
53
|
+
/**
|
|
54
|
+
* The support level held when the case was OPENED, frozen onto the case.
|
|
55
|
+
*
|
|
56
|
+
* Frozen deliberately: a customer who downgrades mid-case should still get the
|
|
57
|
+
* response they bought when they opened it. Resolving entitlement live would
|
|
58
|
+
* change an open case's promise underneath the person waiting on it.
|
|
59
|
+
*/
|
|
60
|
+
level: varchar('level', { length: 32 }).notNull(),
|
|
61
|
+
/** True when the case was opened by spending a one-time incident rather than
|
|
62
|
+
* against a contact seat. Recorded so "how many incidents were actually
|
|
63
|
+
* used" is answerable from the cases, not only from a balance delta. */
|
|
64
|
+
openedWithIncident: boolean('opened_with_incident').default(false).notNull(),
|
|
65
|
+
// --- the two owners, which move independently. NEITHER is `createdBy`.
|
|
66
|
+
/** STAFF owner — a system-org actor. `null` is legitimate: it is the unowned
|
|
67
|
+
* pool, and how "I cannot take this" is said without a pseudo-assignee. */
|
|
68
|
+
assignedTo: text('assigned_to'),
|
|
69
|
+
/** TENANT owner — the designated contact currently responsible. Distinct from
|
|
70
|
+
* `createdBy`, which is the immutable audit fact of who raised the case:
|
|
71
|
+
* mutating that to express "someone else owns this now" would destroy the
|
|
72
|
+
* only record of who actually opened it. */
|
|
73
|
+
tenantContact: text('tenant_contact'),
|
|
74
|
+
// --- the response clock
|
|
75
|
+
/**
|
|
76
|
+
* When the first response is DUE, computed once at open and never recomputed.
|
|
77
|
+
*
|
|
78
|
+
* Frozen for the same reason `level` is: a change to the working week or the
|
|
79
|
+
* holiday list must not move a promise already made to a customer. Three
|
|
80
|
+
* things follow from storing it rather than deriving it per read:
|
|
81
|
+
* - the staff queue orders by a real deadline with no calendar arithmetic
|
|
82
|
+
* per row;
|
|
83
|
+
* - the standard/priority breach check becomes CONTRACTUAL, where a
|
|
84
|
+
* wall-clock quantile cannot express a business-day target at all (a
|
|
85
|
+
* priority case raised at 17:01 on a Friday is not late until Monday
|
|
86
|
+
* evening, ~79 wall-clock hours later);
|
|
87
|
+
* - a level with no published target, and a case opened while the calendar
|
|
88
|
+
* was misconfigured, are both simply NULL — no deadline rather than a
|
|
89
|
+
* wrong one.
|
|
90
|
+
*/
|
|
91
|
+
responseDueAt: timestamp('response_due_at', { withTimezone: true }),
|
|
92
|
+
/** First staff reply. THE measured number — the response target is sold on it. */
|
|
93
|
+
firstResponseAt: timestamp('first_response_at', { withTimezone: true }),
|
|
94
|
+
/**
|
|
95
|
+
* CSAT, 1–5, set by the TENANT once the case is closed. Null = not rated,
|
|
96
|
+
* which is the usual state and must stay distinguishable from a bad rating.
|
|
97
|
+
*
|
|
98
|
+
* Lives here rather than in its own table because a case has exactly one
|
|
99
|
+
* rating — a table would buy a join and a uniqueness constraint to enforce
|
|
100
|
+
* what a column gets for free. First-response latency says whether we
|
|
101
|
+
* answered fast; this is the only thing that says whether the answer helped,
|
|
102
|
+
* and a desk can hit every target while being bad at support.
|
|
103
|
+
*/
|
|
104
|
+
satisfaction: integer('satisfaction'),
|
|
105
|
+
/** Optional free text with the rating. Capped at the route. */
|
|
106
|
+
satisfactionComment: text('satisfaction_comment'),
|
|
107
|
+
satisfactionAt: timestamp('satisfaction_at', { withTimezone: true }),
|
|
108
|
+
/** Set when status → `awaiting_customer`; the pause anchor. */
|
|
109
|
+
awaitingSince: timestamp('awaiting_since', { withTimezone: true }),
|
|
110
|
+
/**
|
|
111
|
+
* Accumulated seconds spent waiting on the customer.
|
|
112
|
+
*
|
|
113
|
+
* Ageing subtracts this. Without it a case we answered in an hour, where the
|
|
114
|
+
* tenant replied four days later, reads as a four-day case — and the metric
|
|
115
|
+
* Phase 2b exists to produce reports a number no customer will accept. An
|
|
116
|
+
* accumulator plus the current anchor survives a case bouncing between states
|
|
117
|
+
* repeatedly, which replaying status history would not.
|
|
118
|
+
*/
|
|
119
|
+
awaitingTotalSeconds: integer('awaiting_total_seconds').default(0).notNull(),
|
|
120
|
+
closedAt: timestamp('closed_at', { withTimezone: true }),
|
|
121
|
+
closedBy: text('closed_by'),
|
|
122
|
+
// Audit + soft-delete, same shape as `messages`.
|
|
123
|
+
createdBy: text('created_by').default(SYSTEM_ORG_ID).notNull(),
|
|
124
|
+
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
125
|
+
updatedBy: text('updated_by').default(SYSTEM_ORG_ID).notNull(),
|
|
126
|
+
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
|
127
|
+
isActive: boolean('is_active').default(true).notNull(),
|
|
128
|
+
deletedAt: timestamp('deleted_at', { withTimezone: true }),
|
|
129
|
+
deletedBy: text('deleted_by'),
|
|
130
|
+
purgeAfter: timestamp('purge_after', { withTimezone: true }),
|
|
131
|
+
}, (table) => ({
|
|
132
|
+
/**
|
|
133
|
+
* THE queue query: every open case across ALL tenants, oldest first.
|
|
134
|
+
*
|
|
135
|
+
* The one query shape with no org predicate to narrow it, so it is also the
|
|
136
|
+
* only one that scans. Partial because the queue never asks about closed
|
|
137
|
+
* cases — which are most of the table within a month. Mirrors
|
|
138
|
+
* `message_purge_idx`, which is partial for the same reason.
|
|
139
|
+
*/
|
|
140
|
+
queueIdx: index('support_case_queue_idx')
|
|
141
|
+
.on(table.createdAt)
|
|
142
|
+
.where(sql `status IN ('open', 'awaiting_support') AND deleted_at IS NULL`),
|
|
143
|
+
/**
|
|
144
|
+
* The on-call sweep's only query: premium cases whose first-response target is
|
|
145
|
+
* approaching with nothing stamped yet.
|
|
146
|
+
*
|
|
147
|
+
* PARTIAL because the tick runs every five minutes forever and the rows it
|
|
148
|
+
* wants are a tiny, shrinking fraction of the table — unanswered premium
|
|
149
|
+
* cases. Without it every tick is a scan, and it is the one query with no org
|
|
150
|
+
* predicate to narrow it.
|
|
151
|
+
*
|
|
152
|
+
* `level` and NOT `is_premium`: that column lives on support_CONTACTS and
|
|
153
|
+
* marks an upgraded contact, while a case freezes the opening contact's
|
|
154
|
+
* effective level at open. The case's own promise is its `level`, so
|
|
155
|
+
* upgrading a contact later must not move a deadline already published to a
|
|
156
|
+
* customer.
|
|
157
|
+
*/
|
|
158
|
+
responseDueIdx: index('support_case_response_due_idx')
|
|
159
|
+
.on(table.responseDueAt)
|
|
160
|
+
.where(sql `level = 'support_premium' AND first_response_at IS NULL AND deleted_at IS NULL`),
|
|
161
|
+
// A tenant listing its own cases.
|
|
162
|
+
orgStatusIdx: index('support_case_org_status_idx').on(table.orgId, table.status),
|
|
163
|
+
// The rolling-window case count behind the FAIR-USE allowance: how many cases
|
|
164
|
+
// this account raised in the last N days. Leading `org_id` because the count
|
|
165
|
+
// is always scoped to an account subtree, then `created_at` so the window is a
|
|
166
|
+
// range scan rather than a filter over every case the org ever raised.
|
|
167
|
+
orgCreatedIdx: index('support_case_org_created_idx').on(table.orgId, table.createdAt),
|
|
168
|
+
// "What am I on the hook for", one engineer.
|
|
169
|
+
assigneeIdx: index('support_case_assigned_idx')
|
|
170
|
+
.on(table.assignedTo, table.status)
|
|
171
|
+
.where(sql `assigned_to IS NOT NULL`),
|
|
172
|
+
// "My cases" for a contact, AND the lookup that finds a departing contact's
|
|
173
|
+
// open cases so they can be reassigned instead of orphaned.
|
|
174
|
+
tenantContactIdx: index('support_case_tenant_contact_idx')
|
|
175
|
+
.on(table.tenantContact, table.status)
|
|
176
|
+
.where(sql `tenant_contact IS NOT NULL`),
|
|
177
|
+
// Case identity, reached from any message in the thread.
|
|
178
|
+
threadUq: uniqueIndex('support_case_thread_uq').on(table.threadId),
|
|
179
|
+
// The customer-quotable number is unique per org, enforced not assumed.
|
|
180
|
+
displayUq: uniqueIndex('support_case_org_number_uq')
|
|
181
|
+
.on(table.orgId, table.displayNumber)
|
|
182
|
+
.where(sql `deleted_at IS NULL`),
|
|
183
|
+
}));
|
|
184
|
+
/**
|
|
185
|
+
* Per-org allocator for `support_cases.display_number`.
|
|
186
|
+
*
|
|
187
|
+
* Postgres sequences are global and cannot be per-org without one sequence per
|
|
188
|
+
* tenant, so the counter is a row: `UPDATE … SET next_number = next_number + 1
|
|
189
|
+
* RETURNING next_number` inside the case-insert transaction, where the row lock
|
|
190
|
+
* serialises concurrent opens within one org.
|
|
191
|
+
*
|
|
192
|
+
* @table support_case_counters
|
|
193
|
+
*/
|
|
194
|
+
export const supportCaseCounter = pgTable('support_case_counters', {
|
|
195
|
+
orgId: varchar('org_id', { length: 255 }).primaryKey(),
|
|
196
|
+
nextNumber: integer('next_number').default(1).notNull(),
|
|
197
|
+
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
|
198
|
+
});
|
|
199
|
+
/**
|
|
200
|
+
* The members authorised to open support cases — what the per-contact price
|
|
201
|
+
* bills for.
|
|
202
|
+
*
|
|
203
|
+
* The COUNT is capped against effective `supportContacts` at designation time,
|
|
204
|
+
* in the same shape seats are capped at invite time. `supportContacts` has a
|
|
205
|
+
* tier base of 0 everywhere, so an org with no support add-on has no contacts
|
|
206
|
+
* and cannot open a case: the paywall is a quota check, not a feature flag.
|
|
207
|
+
*
|
|
208
|
+
* @table support_contacts
|
|
209
|
+
*/
|
|
210
|
+
export const supportContact = pgTable('support_contacts', {
|
|
211
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
212
|
+
orgId: varchar('org_id', { length: 255 }).notNull(),
|
|
213
|
+
userId: text('user_id').notNull(),
|
|
214
|
+
// Who nominated them. Audit-worthy: a contact is a paid, privileged slot.
|
|
215
|
+
designatedBy: text('designated_by').notNull(),
|
|
216
|
+
designatedAt: timestamp('designated_at', { withTimezone: true }).defaultNow().notNull(),
|
|
217
|
+
/**
|
|
218
|
+
* Whether this contact is UPGRADED to premium — 24×7 coverage, the 8-hour
|
|
219
|
+
* any-day target, and the only contacts who may declare `urgent` severity.
|
|
220
|
+
*
|
|
221
|
+
* A column on the contact rather than a level on the org, because that is what
|
|
222
|
+
* the upgrade model means: an account holds one BASELINE level covering every
|
|
223
|
+
* contact and upgrades a subset. Without this the `supportPremiumContacts` cap
|
|
224
|
+
* would grant a quota over nothing — there would be no way for any contact to
|
|
225
|
+
* actually be premium, and the case-open path would have nothing to read.
|
|
226
|
+
*
|
|
227
|
+
* The case freezes the OPENING CONTACT's effective level at open
|
|
228
|
+
* (`support_case.level`), so flipping this later never changes the promise on
|
|
229
|
+
* a case already raised.
|
|
230
|
+
*/
|
|
231
|
+
isPremium: boolean('is_premium').default(false).notNull(),
|
|
232
|
+
isActive: boolean('is_active').default(true).notNull(),
|
|
233
|
+
revokedAt: timestamp('revoked_at', { withTimezone: true }),
|
|
234
|
+
revokedBy: text('revoked_by'),
|
|
235
|
+
}, (table) => ({
|
|
236
|
+
// One live designation per (org, user). Partial so a revoked row does not
|
|
237
|
+
// block re-designating the same person later.
|
|
238
|
+
orgUserUq: uniqueIndex('support_contact_org_user_uq')
|
|
239
|
+
.on(table.orgId, table.userId)
|
|
240
|
+
.where(sql `is_active = true`),
|
|
241
|
+
// Counting an org's live contacts against its cap, and listing them for the
|
|
242
|
+
// tenant-side owner picker.
|
|
243
|
+
orgActiveIdx: index('support_contact_org_active_idx').on(table.orgId, table.isActive),
|
|
244
|
+
// The premium SUBSET, counted against `supportPremiumContacts` on every
|
|
245
|
+
// upgrade. Partial on both flags because that is the only question asked of
|
|
246
|
+
// it: how many live contacts in this scope are upgraded.
|
|
247
|
+
orgPremiumIdx: index('support_contact_org_premium_idx')
|
|
248
|
+
.on(table.orgId, table.userId)
|
|
249
|
+
.where(sql `is_active = true AND is_premium = true`),
|
|
250
|
+
}));
|
|
251
|
+
/**
|
|
252
|
+
* Canned staff replies — a shared library of answers the desk reuses.
|
|
253
|
+
*
|
|
254
|
+
* SYSTEM-WIDE, not per-tenant, and deliberately so: these are the vendor's own
|
|
255
|
+
* wording for recurring questions, authored once and used across every
|
|
256
|
+
* customer. There is no `org_id` because scoping them per tenant would be the
|
|
257
|
+
* opposite of the point — the value is that the answer to "how do I rotate a
|
|
258
|
+
* service key" is written well once rather than retyped badly fifty times.
|
|
259
|
+
*
|
|
260
|
+
* That also means RLS does not apply: every row is visible to the staff who can
|
|
261
|
+
* reach the queue, and to nobody else. The routes are system-admin gated on
|
|
262
|
+
* both read and write for exactly that reason.
|
|
263
|
+
*
|
|
264
|
+
* Soft-deleted rather than removed, because a retired template is still the
|
|
265
|
+
* explanation of what a past reply said.
|
|
266
|
+
*
|
|
267
|
+
* @table support_canned_responses
|
|
268
|
+
*/
|
|
269
|
+
export const supportCannedResponse = pgTable('support_canned_responses', {
|
|
270
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
271
|
+
/** Short label the picker lists. */
|
|
272
|
+
title: varchar('title', { length: 200 }).notNull(),
|
|
273
|
+
body: text('body').notNull(),
|
|
274
|
+
createdBy: text('created_by').notNull(),
|
|
275
|
+
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
276
|
+
updatedBy: text('updated_by').notNull(),
|
|
277
|
+
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
|
278
|
+
isActive: boolean('is_active').default(true).notNull(),
|
|
279
|
+
}, (table) => ({
|
|
280
|
+
// The picker's only query: live templates, alphabetical.
|
|
281
|
+
activeTitleIdx: index('support_canned_active_idx').on(table.isActive, table.title),
|
|
282
|
+
}));
|
|
283
|
+
/**
|
|
284
|
+
* CSAT: the customer's verdict on a closed case.
|
|
285
|
+
*
|
|
286
|
+
* A COLUMN SET on the case rather than its own table, unlike notes. The reason
|
|
287
|
+
* is cardinality, not convenience: a case has many notes and exactly one
|
|
288
|
+
* satisfaction rating, so a table would buy an extra join and a uniqueness
|
|
289
|
+
* constraint to enforce what a column gets for free.
|
|
290
|
+
*
|
|
291
|
+
* Why it matters more here than in most products: the thing being SOLD is a
|
|
292
|
+
* response time, and first-response latency only measures whether we answered
|
|
293
|
+
* fast — not whether the answer was any good. A desk can hit every target and
|
|
294
|
+
* still be bad at support, and without this nothing in the system would notice.
|
|
295
|
+
*
|
|
296
|
+
* @table support_cases (columns)
|
|
297
|
+
*/
|
|
298
|
+
/**
|
|
299
|
+
* Staff-only notes on a case.
|
|
300
|
+
*
|
|
301
|
+
* A SEPARATE TABLE rather than a flag on `messages`, and the reason is the
|
|
302
|
+
* failure mode: `messages` is read through one shared visibility predicate
|
|
303
|
+
* (`buildMessageConditions`), so a flag means every read path that forgets the
|
|
304
|
+
* extra condition leaks an internal note to the tenant. A separate table cannot
|
|
305
|
+
* leak by omission — it has to be joined deliberately.
|
|
306
|
+
*
|
|
307
|
+
* @table support_case_notes
|
|
308
|
+
*/
|
|
309
|
+
export const supportCaseNote = pgTable('support_case_notes', {
|
|
310
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
311
|
+
caseId: uuid('case_id').notNull(),
|
|
312
|
+
// Denormalised so a note can never be served without its tenant scope.
|
|
313
|
+
orgId: varchar('org_id', { length: 255 }).notNull(),
|
|
314
|
+
content: text('content').notNull(),
|
|
315
|
+
createdBy: text('created_by').notNull(),
|
|
316
|
+
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
317
|
+
isActive: boolean('is_active').default(true).notNull(),
|
|
318
|
+
deletedAt: timestamp('deleted_at', { withTimezone: true }),
|
|
319
|
+
deletedBy: text('deleted_by'),
|
|
320
|
+
}, (table) => ({
|
|
321
|
+
caseIdx: index('support_case_note_case_idx').on(table.caseId, table.isActive),
|
|
322
|
+
}));
|
|
323
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VwcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kYXRhYmFzZS9zY2hlbWEvc3VwcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXBIOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsZUFBZSxFQUFFO0lBQ2xELHdEQUF3RDtJQUN4RCxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLGFBQWEsRUFBRTtJQUUzQzs7Ozs7OztPQU9HO0lBQ0gsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFFckMsNEVBQTRFO0lBQzVFLHFFQUFxRTtJQUNyRSxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUVuRDs7Ozs7Ozs7O09BU0c7SUFDSCxhQUFhLEVBQUUsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUMsT0FBTyxFQUFFO0lBRWxELGtFQUFrRTtJQUNsRSxNQUFNLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFFbkUsK0VBQStFO0lBQy9FLDhFQUE4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UUFBUSxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ25ELE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ2xDLFNBQVMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ3ZDLFNBQVMsRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxFQUFFO0lBQ2pGLFFBQVEsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN0RCxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUMxRCxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQztDQUM5QixFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2IsT0FBTyxFQUFFLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUM7Q0FDOUUsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGJvb2xlYW4sIGludGVnZXIsIHZhcmNoYXIsIHBnVGFibGUsIHRleHQsIHRpbWVzdGFtcCwgdXVpZCwgaW5kZXgsIHVuaXF1ZUluZGV4IH0gZnJvbSAnZHJpenpsZS1vcm0vcGctY29yZSc7XG5cbi8qKlxuICogVGhlIFdPUktGTE9XIGF4aXMgb2YgYSBzdXBwb3J0IGNhc2UuXG4gKlxuICogYG1lc3NhZ2VzYCBhbHJlYWR5IGNhcnJpZXMgdGhlIGNvbnZlcnNhdGlvbiDigJQgaWRlbnRpdHksIHRocmVhZGluZywgcHJpb3JpdHksXG4gKiBwZXItcGFydGljaXBhbnQgcmVhZCBzdGF0ZSwgYXR0YWNobWVudHMgYW5kIHNvZnQtZGVsZXRlLiBXaGF0IGl0IGhhcyBubyBjb2x1bW5cbiAqIGZvciBpcyB3b3JrZmxvdzogc3RhdHVzLCBvd25lcnNoaXAsIHJlc29sdXRpb24gYW5kIHRoZSByZXNwb25zZSBjbG9jay4gVGhhdCBpc1xuICogdGhpcyB0YWJsZSwgb25lIHJvdyBwZXIgY2FzZSwgam9pbmVkIHRvIHRoZSBjb252ZXJzYXRpb24gYnkgYHRocmVhZElkYC5cbiAqXG4gKiBLZWVwaW5nIHRoZW0gYXBhcnQgcmF0aGVyIHRoYW4gd2lkZW5pbmcgYG1lc3NhZ2VzYCBpcyBkZWxpYmVyYXRlOiBgbWVzc2FnZXNgXG4gKiBhbHNvIGNhcnJpZXMgYW5ub3VuY2VtZW50cyBhbmQgb3JkaW5hcnkgY29udmVyc2F0aW9ucywgd2hpY2ggaGF2ZSBubyBzdGF0dXMsXG4gKiBubyBhc3NpZ25lZSBhbmQgbm8gcmVzcG9uc2UgdGFyZ2V0LiBTaXggbnVsbGFibGUgY29sdW1ucyBvbiBldmVyeSBhbm5vdW5jZW1lbnRcbiAqIHJvdyB0byBkZXNjcmliZSBhIHN0YXRlIGFubm91bmNlbWVudHMgY2Fubm90IGJlIGluIGlzIGhvdyBhIHRhYmxlIHN0b3BzXG4gKiBtZWFuaW5nIG9uZSB0aGluZy5cbiAqXG4gKiBAdGFibGUgc3VwcG9ydF9jYXNlc1xuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydENhc2UgPSBwZ1RhYmxlKCdzdXBwb3J0X2Nhc2VzJywge1xuICAvLyBJbnRlcm5hbCBrZXkuIE5PVCB0aGUgY2FzZSBpZGVudGl0eSDigJQgc2VlIGB0aHJlYWRJZGAuXG4gIGlkOiB1dWlkKCdpZCcpLnByaW1hcnlLZXkoKS5kZWZhdWx0UmFuZG9tKCksXG5cbiAgLyoqXG4gICAqIFRoZSByb290IGBtZXNzYWdlcy5pZGAgb2YgdGhlIHRocmVhZCwgYW5kIHRoZSBDQU5PTklDQUwgY2FzZSBpZGVudGl0eS5cbiAgICpcbiAgICogVGhlIGNvbnZlbnRpb24gYWxyZWFkeSBleGlzdHM6IHJlYWRlcnMgd2FsayBgdGhyZWFkSWQgPT09IHJvb3QuaWRgIGFuZFxuICAgKiBgdXBkYXRlLW1lc3NhZ2UudHNgIHVzZXMgYHVwZGF0ZWQudGhyZWFkSWQgPz8gdXBkYXRlZC5pZGAgZm9yIGV4YWN0bHkgdGhpc1xuICAgKiBcInRoZSByb290IGlzIHRoZSBpZGVudGl0eVwiIGlkZWEuIFNvIGNhc2UgaWRlbnRpdHkgZmFsbHMgb3V0IG9mIHRocmVhZGluZyB0aGVcbiAgICogc3VwcG9ydCBwYXRoIHJhdGhlciB0aGFuIGJlaW5nIGEgbmV3IGNvbmNlcHQuXG4gICAqL1xuICB0aHJlYWRJZDogdXVpZCgndGhyZWFkX2lkJykubm90TnVsbCgpLFxuXG4gIC8vIFRoZSBURU5BTlQgb3JnLiBOZXZlciB0aGUgc3lzdGVtIG9yZyDigJQgYSBjYXNlIGlzIGFsd2F5cyBhYm91dCBvbmUgdGVuYW50LFxuICAvLyBldmVuIHRob3VnaCB0aGUgc3lzdGVtIG9yZyBpcyB0aGUgb3RoZXIgcGFydGljaXBhbnQgaW4gdGhlIHRocmVhZC5cbiAgb3JnSWQ6IHZhcmNoYXIoJ29yZ19pZCcsIHsgbGVuZ3RoOiAyNTUgfSkubm90TnVsbCgpLFxuXG4gIC8qKlxuICAgKiBQZXItb3JnLCBjdXN0b21lci1xdW90YWJsZSBjYXNlIG51bWJlciAocmVuZGVyZWQgYEFDTUUtMTA0MmApLlxuICAgKlxuICAgKiBBIGJhcmUgVVVJRCBpcyBub3Qgc29tZXRoaW5nIGFueW9uZSByZWFkcyBvdXQgb24gYSBjYWxsIG9yIHB1dHMgaW4gYW4gZW1haWxcbiAgICogc3ViamVjdCwgYW5kIGEgR0xPQkFMIHNlcXVlbmNlIHdvdWxkIGRpc2Nsb3NlIHRvdGFsIGNhc2Ugdm9sdW1lIHRvIGV2ZXJ5XG4gICAqIGN1c3RvbWVyLiBBbGxvY2F0ZWQgZnJvbSBgc3VwcG9ydF9jYXNlX2NvdW50ZXJzYCBpbiB0aGUgc2FtZSB0cmFuc2FjdGlvbiBhc1xuICAgKiB0aGUgaW5zZXJ0OyBgc3VwcG9ydF9jYXNlX29yZ19udW1iZXJfdXFgIGlzIHRoZSBiYWNrc3RvcCB0aGF0IHR1cm5zIGFcbiAgICogYnlwYXNzZWQgY291bnRlciBpbnRvIGEgZmFpbGVkIGluc2VydCByYXRoZXIgdGhhbiB0d28gY2FzZXMgc2hhcmluZyB0aGUgb25lXG4gICAqIGlkZW50aWZpZXIgY3VzdG9tZXJzIHF1b3RlIGJhY2suXG4gICAqL1xuICBkaXNwbGF5TnVtYmVyOiBpbnRlZ2VyKCdkaXNwbGF5X251bWJlcicpLm5vdE51bGwoKSxcblxuICAvLyBvcGVuIHwgYXdhaXRpbmdfc3VwcG9ydCB8IGF3YWl0aW5nX2N1c3RvbWVyIHwgcmVzb2x2ZWQgfCBjbG9zZWRcbiAgc3RhdHVzOiB2YXJjaGFyKCdzdGF0dXMnLCB7IGxlbmd0aDogMzIgfSkuZGVmYXVsdCgnb3BlbicpLm5vdE51bGwoKSxcblxuICAvLyBTZXQgYnkgdGhlIG9wZW5lcjsgcmUtcmFua2FibGUgYnkgc3RhZmYuIFNlbGYtc2VsZWN0ZWQgc2V2ZXJpdHkgaXMgd2h5IHN0YWZmXG4gIC8vIHJlLXJhbmtpbmcgaXMgaW4gdjE6IG90aGVyd2lzZSB0aGUgdGVuYW50IGNob29zZXMgdGhlIHRhcmdldCB0aGV5IGFyZSBvd2VkLlxuICBzZXZlcml0eTogdmFyY2hhcignc2V2ZXJpdHknLCB7IGxlbmd0aDogMTYgfSkuZGVmYXVsdCgnbm9ybWFsJykubm90TnVsbCgpLFxuXG4gIC8qKlxuICAgKiBUaGUgc3VwcG9ydCBsZXZlbCBoZWxkIHdoZW4gdGhlIGNhc2Ugd2FzIE9QRU5FRCwgZnJvemVuIG9udG8gdGhlIGNhc2UuXG4gICAqXG4gICAqIEZyb3plbiBkZWxpYmVyYXRlbHk6IGEgY3VzdG9tZXIgd2hvIGRvd25ncmFkZXMgbWlkLWNhc2Ugc2hvdWxkIHN0aWxsIGdldCB0aGVcbiAgICogcmVzcG9uc2UgdGhleSBib3VnaHQgd2hlbiB0aGV5IG9wZW5lZCBpdC4gUmVzb2x2aW5nIGVudGl0bGVtZW50IGxpdmUgd291bGRcbiAgICogY2hhbmdlIGFuIG9wZW4gY2FzZSdzIHByb21pc2UgdW5kZXJuZWF0aCB0aGUgcGVyc29uIHdhaXRpbmcgb24gaXQuXG4gICAqL1xuICBsZXZlbDogdmFyY2hhcignbGV2ZWwnLCB7IGxlbmd0aDogMzIgfSkubm90TnVsbCgpLFxuXG4gIC8qKiBUcnVlIHdoZW4gdGhlIGNhc2Ugd2FzIG9wZW5lZCBieSBzcGVuZGluZyBhIG9uZS10aW1lIGluY2lkZW50IHJhdGhlciB0aGFuXG4gICAqICBhZ2FpbnN0IGEgY29udGFjdCBzZWF0LiBSZWNvcmRlZCBzbyBcImhvdyBtYW55IGluY2lkZW50cyB3ZXJlIGFjdHVhbGx5XG4gICAqICB1c2VkXCIgaXMgYW5zd2VyYWJsZSBmcm9tIHRoZSBjYXNlcywgbm90IG9ubHkgZnJvbSBhIGJhbGFuY2UgZGVsdGEuICovXG4gIG9wZW5lZFdpdGhJbmNpZGVudDogYm9vbGVhbignb3BlbmVkX3dpdGhfaW5jaWRlbnQnKS5kZWZhdWx0KGZhbHNlKS5ub3ROdWxsKCksXG5cbiAgLy8gLS0tIHRoZSB0d28gb3duZXJzLCB3aGljaCBtb3ZlIGluZGVwZW5kZW50bHkuIE5FSVRIRVIgaXMgYGNyZWF0ZWRCeWAuXG4gIC8qKiBTVEFGRiBvd25lciDigJQgYSBzeXN0ZW0tb3JnIGFjdG9yLiBgbnVsbGAgaXMgbGVnaXRpbWF0ZTogaXQgaXMgdGhlIHVub3duZWRcbiAgICogIHBvb2wsIGFuZCBob3cgXCJJIGNhbm5vdCB0YWtlIHRoaXNcIiBpcyBzYWlkIHdpdGhvdXQgYSBwc2V1ZG8tYXNzaWduZWUuICovXG4gIGFzc2lnbmVkVG86IHRleHQoJ2Fzc2lnbmVkX3RvJyksXG4gIC8qKiBURU5BTlQgb3duZXIg4oCUIHRoZSBkZXNpZ25hdGVkIGNvbnRhY3QgY3VycmVudGx5IHJlc3BvbnNpYmxlLiBEaXN0aW5jdCBmcm9tXG4gICAqICBgY3JlYXRlZEJ5YCwgd2hpY2ggaXMgdGhlIGltbXV0YWJsZSBhdWRpdCBmYWN0IG9mIHdobyByYWlzZWQgdGhlIGNhc2U6XG4gICAqICBtdXRhdGluZyB0aGF0IHRvIGV4cHJlc3MgXCJzb21lb25lIGVsc2Ugb3ducyB0aGlzIG5vd1wiIHdvdWxkIGRlc3Ryb3kgdGhlXG4gICAqICBvbmx5IHJlY29yZCBvZiB3aG8gYWN0dWFsbHkgb3BlbmVkIGl0LiAqL1xuICB0ZW5hbnRDb250YWN0OiB0ZXh0KCd0ZW5hbnRfY29udGFjdCcpLFxuXG4gIC8vIC0tLSB0aGUgcmVzcG9uc2UgY2xvY2tcbiAgLyoqXG4gICAqIFdoZW4gdGhlIGZpcnN0IHJlc3BvbnNlIGlzIERVRSwgY29tcHV0ZWQgb25jZSBhdCBvcGVuIGFuZCBuZXZlciByZWNvbXB1dGVkLlxuICAgKlxuICAgKiBGcm96ZW4gZm9yIHRoZSBzYW1lIHJlYXNvbiBgbGV2ZWxgIGlzOiBhIGNoYW5nZSB0byB0aGUgd29ya2luZyB3ZWVrIG9yIHRoZVxuICAgKiBob2xpZGF5IGxpc3QgbXVzdCBub3QgbW92ZSBhIHByb21pc2UgYWxyZWFkeSBtYWRlIHRvIGEgY3VzdG9tZXIuIFRocmVlXG4gICAqIHRoaW5ncyBmb2xsb3cgZnJvbSBzdG9yaW5nIGl0IHJhdGhlciB0aGFuIGRlcml2aW5nIGl0IHBlciByZWFkOlxuICAgKiAgIC0gdGhlIHN0YWZmIHF1ZXVlIG9yZGVycyBieSBhIHJlYWwgZGVhZGxpbmUgd2l0aCBubyBjYWxlbmRhciBhcml0aG1ldGljXG4gICAqICAgICBwZXIgcm93O1xuICAgKiAgIC0gdGhlIHN0YW5kYXJkL3ByaW9yaXR5IGJyZWFjaCBjaGVjayBiZWNvbWVzIENPTlRSQUNUVUFMLCB3aGVyZSBhXG4gICAqICAgICB3YWxsLWNsb2NrIHF1YW50aWxlIGNhbm5vdCBleHByZXNzIGEgYnVzaW5lc3MtZGF5IHRhcmdldCBhdCBhbGwgKGFcbiAgICogICAgIHByaW9yaXR5IGNhc2UgcmFpc2VkIGF0IDE3OjAxIG9uIGEgRnJpZGF5IGlzIG5vdCBsYXRlIHVudGlsIE1vbmRheVxuICAgKiAgICAgZXZlbmluZywgfjc5IHdhbGwtY2xvY2sgaG91cnMgbGF0ZXIpO1xuICAgKiAgIC0gYSBsZXZlbCB3aXRoIG5vIHB1Ymxpc2hlZCB0YXJnZXQsIGFuZCBhIGNhc2Ugb3BlbmVkIHdoaWxlIHRoZSBjYWxlbmRhclxuICAgKiAgICAgd2FzIG1pc2NvbmZpZ3VyZWQsIGFyZSBib3RoIHNpbXBseSBOVUxMIOKAlCBubyBkZWFkbGluZSByYXRoZXIgdGhhbiBhXG4gICAqICAgICB3cm9uZyBvbmUuXG4gICAqL1xuICByZXNwb25zZUR1ZUF0OiB0aW1lc3RhbXAoJ3Jlc3BvbnNlX2R1ZV9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICAvKiogRmlyc3Qgc3RhZmYgcmVwbHkuIFRIRSBtZWFzdXJlZCBudW1iZXIg4oCUIHRoZSByZXNwb25zZSB0YXJnZXQgaXMgc29sZCBvbiBpdC4gKi9cbiAgZmlyc3RSZXNwb25zZUF0OiB0aW1lc3RhbXAoJ2ZpcnN0X3Jlc3BvbnNlX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIC8qKlxuICAgKiBDU0FULCAx4oCTNSwgc2V0IGJ5IHRoZSBURU5BTlQgb25jZSB0aGUgY2FzZSBpcyBjbG9zZWQuIE51bGwgPSBub3QgcmF0ZWQsXG4gICAqIHdoaWNoIGlzIHRoZSB1c3VhbCBzdGF0ZSBhbmQgbXVzdCBzdGF5IGRpc3Rpbmd1aXNoYWJsZSBmcm9tIGEgYmFkIHJhdGluZy5cbiAgICpcbiAgICogTGl2ZXMgaGVyZSByYXRoZXIgdGhhbiBpbiBpdHMgb3duIHRhYmxlIGJlY2F1c2UgYSBjYXNlIGhhcyBleGFjdGx5IG9uZVxuICAgKiByYXRpbmcg4oCUIGEgdGFibGUgd291bGQgYnV5IGEgam9pbiBhbmQgYSB1bmlxdWVuZXNzIGNvbnN0cmFpbnQgdG8gZW5mb3JjZVxuICAgKiB3aGF0IGEgY29sdW1uIGdldHMgZm9yIGZyZWUuIEZpcnN0LXJlc3BvbnNlIGxhdGVuY3kgc2F5cyB3aGV0aGVyIHdlXG4gICAqIGFuc3dlcmVkIGZhc3Q7IHRoaXMgaXMgdGhlIG9ubHkgdGhpbmcgdGhhdCBzYXlzIHdoZXRoZXIgdGhlIGFuc3dlciBoZWxwZWQsXG4gICAqIGFuZCBhIGRlc2sgY2FuIGhpdCBldmVyeSB0YXJnZXQgd2hpbGUgYmVpbmcgYmFkIGF0IHN1cHBvcnQuXG4gICAqL1xuICBzYXRpc2ZhY3Rpb246IGludGVnZXIoJ3NhdGlzZmFjdGlvbicpLFxuICAvKiogT3B0aW9uYWwgZnJlZSB0ZXh0IHdpdGggdGhlIHJhdGluZy4gQ2FwcGVkIGF0IHRoZSByb3V0ZS4gKi9cbiAgc2F0aXNmYWN0aW9uQ29tbWVudDogdGV4dCgnc2F0aXNmYWN0aW9uX2NvbW1lbnQnKSxcbiAgc2F0aXNmYWN0aW9uQXQ6IHRpbWVzdGFtcCgnc2F0aXNmYWN0aW9uX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIC8qKiBTZXQgd2hlbiBzdGF0dXMg4oaSIGBhd2FpdGluZ19jdXN0b21lcmA7IHRoZSBwYXVzZSBhbmNob3IuICovXG4gIGF3YWl0aW5nU2luY2U6IHRpbWVzdGFtcCgnYXdhaXRpbmdfc2luY2UnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgLyoqXG4gICAqIEFjY3VtdWxhdGVkIHNlY29uZHMgc3BlbnQgd2FpdGluZyBvbiB0aGUgY3VzdG9tZXIuXG4gICAqXG4gICAqIEFnZWluZyBzdWJ0cmFjdHMgdGhpcy4gV2l0aG91dCBpdCBhIGNhc2Ugd2UgYW5zd2VyZWQgaW4gYW4gaG91ciwgd2hlcmUgdGhlXG4gICAqIHRlbmFudCByZXBsaWVkIGZvdXIgZGF5cyBsYXRlciwgcmVhZHMgYXMgYSBmb3VyLWRheSBjYXNlIOKAlCBhbmQgdGhlIG1ldHJpY1xuICAgKiBQaGFzZSAyYiBleGlzdHMgdG8gcHJvZHVjZSByZXBvcnRzIGEgbnVtYmVyIG5vIGN1c3RvbWVyIHdpbGwgYWNjZXB0LiBBblxuICAgKiBhY2N1bXVsYXRvciBwbHVzIHRoZSBjdXJyZW50IGFuY2hvciBzdXJ2aXZlcyBhIGNhc2UgYm91bmNpbmcgYmV0d2VlbiBzdGF0ZXNcbiAgICogcmVwZWF0ZWRseSwgd2hpY2ggcmVwbGF5aW5nIHN0YXR1cyBoaXN0b3J5IHdvdWxkIG5vdC5cbiAgICovXG4gIGF3YWl0aW5nVG90YWxTZWNvbmRzOiBpbnRlZ2VyKCdhd2FpdGluZ190b3RhbF9zZWNvbmRzJykuZGVmYXVsdCgwKS5ub3ROdWxsKCksXG5cbiAgY2xvc2VkQXQ6IHRpbWVzdGFtcCgnY2xvc2VkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIGNsb3NlZEJ5OiB0ZXh0KCdjbG9zZWRfYnknKSxcblxuICAvLyBBdWRpdCArIHNvZnQtZGVsZXRlLCBzYW1lIHNoYXBlIGFzIGBtZXNzYWdlc2AuXG4gIGNyZWF0ZWRCeTogdGV4dCgnY3JlYXRlZF9ieScpLmRlZmF1bHQoU1lTVEVNX09SR19JRCkubm90TnVsbCgpLFxuICBjcmVhdGVkQXQ6IHRpbWVzdGFtcCgnY3JlYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRCeTogdGV4dCgndXBkYXRlZF9ieScpLmRlZmF1bHQoU1lTVEVNX09SR19JRCkubm90TnVsbCgpLFxuICB1cGRhdGVkQXQ6IHRpbWVzdGFtcCgndXBkYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIGlzQWN0aXZlOiBib29sZWFuKCdpc19hY3RpdmUnKS5kZWZhdWx0KHRydWUpLm5vdE51bGwoKSxcbiAgZGVsZXRlZEF0OiB0aW1lc3RhbXAoJ2RlbGV0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgZGVsZXRlZEJ5OiB0ZXh0KCdkZWxldGVkX2J5JyksXG4gIHB1cmdlQWZ0ZXI6IHRpbWVzdGFtcCgncHVyZ2VfYWZ0ZXInLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbn0sICh0YWJsZSkgPT4gKHtcbiAgLyoqXG4gICAqIFRIRSBxdWV1ZSBxdWVyeTogZXZlcnkgb3BlbiBjYXNlIGFjcm9zcyBBTEwgdGVuYW50cywgb2xkZXN0IGZpcnN0LlxuICAgKlxuICAgKiBUaGUgb25lIHF1ZXJ5IHNoYXBlIHdpdGggbm8gb3JnIHByZWRpY2F0ZSB0byBuYXJyb3cgaXQsIHNvIGl0IGlzIGFsc28gdGhlXG4gICAqIG9ubHkgb25lIHRoYXQgc2NhbnMuIFBhcnRpYWwgYmVjYXVzZSB0aGUgcXVldWUgbmV2ZXIgYXNrcyBhYm91dCBjbG9zZWRcbiAgICogY2FzZXMg4oCUIHdoaWNoIGFyZSBtb3N0IG9mIHRoZSB0YWJsZSB3aXRoaW4gYSBtb250aC4gTWlycm9yc1xuICAgKiBgbWVzc2FnZV9wdXJnZV9pZHhgLCB3aGljaCBpcyBwYXJ0aWFsIGZvciB0aGUgc2FtZSByZWFzb24uXG4gICAqL1xuICBxdWV1ZUlkeDogaW5kZXgoJ3N1cHBvcnRfY2FzZV9xdWV1ZV9pZHgnKVxuICAgIC5vbih0YWJsZS5jcmVhdGVkQXQpXG4gICAgLndoZXJlKHNxbGBzdGF0dXMgSU4gKCdvcGVuJywgJ2F3YWl0aW5nX3N1cHBvcnQnKSBBTkQgZGVsZXRlZF9hdCBJUyBOVUxMYCksXG5cbiAgLyoqXG4gICAqIFRoZSBvbi1jYWxsIHN3ZWVwJ3Mgb25seSBxdWVyeTogcHJlbWl1bSBjYXNlcyB3aG9zZSBmaXJzdC1yZXNwb25zZSB0YXJnZXQgaXNcbiAgICogYXBwcm9hY2hpbmcgd2l0aCBub3RoaW5nIHN0YW1wZWQgeWV0LlxuICAgKlxuICAgKiBQQVJUSUFMIGJlY2F1c2UgdGhlIHRpY2sgcnVucyBldmVyeSBmaXZlIG1pbnV0ZXMgZm9yZXZlciBhbmQgdGhlIHJvd3MgaXRcbiAgICogd2FudHMgYXJlIGEgdGlueSwgc2hyaW5raW5nIGZyYWN0aW9uIG9mIHRoZSB0YWJsZSDigJQgdW5hbnN3ZXJlZCBwcmVtaXVtXG4gICAqIGNhc2VzLiBXaXRob3V0IGl0IGV2ZXJ5IHRpY2sgaXMgYSBzY2FuLCBhbmQgaXQgaXMgdGhlIG9uZSBxdWVyeSB3aXRoIG5vIG9yZ1xuICAgKiBwcmVkaWNhdGUgdG8gbmFycm93IGl0LlxuICAgKlxuICAgKiBgbGV2ZWxgIGFuZCBOT1QgYGlzX3ByZW1pdW1gOiB0aGF0IGNvbHVtbiBsaXZlcyBvbiBzdXBwb3J0X0NPTlRBQ1RTIGFuZFxuICAgKiBtYXJrcyBhbiB1cGdyYWRlZCBjb250YWN0LCB3aGlsZSBhIGNhc2UgZnJlZXplcyB0aGUgb3BlbmluZyBjb250YWN0J3NcbiAgICogZWZmZWN0aXZlIGxldmVsIGF0IG9wZW4uIFRoZSBjYXNlJ3Mgb3duIHByb21pc2UgaXMgaXRzIGBsZXZlbGAsIHNvXG4gICAqIHVwZ3JhZGluZyBhIGNvbnRhY3QgbGF0ZXIgbXVzdCBub3QgbW92ZSBhIGRlYWRsaW5lIGFscmVhZHkgcHVibGlzaGVkIHRvIGFcbiAgICogY3VzdG9tZXIuXG4gICAqL1xuICByZXNwb25zZUR1ZUlkeDogaW5kZXgoJ3N1cHBvcnRfY2FzZV9yZXNwb25zZV9kdWVfaWR4JylcbiAgICAub24odGFibGUucmVzcG9uc2VEdWVBdClcbiAgICAud2hlcmUoc3FsYGxldmVsID0gJ3N1cHBvcnRfcHJlbWl1bScgQU5EIGZpcnN0X3Jlc3BvbnNlX2F0IElTIE5VTEwgQU5EIGRlbGV0ZWRfYXQgSVMgTlVMTGApLFxuXG4gIC8vIEEgdGVuYW50IGxpc3RpbmcgaXRzIG93biBjYXNlcy5cbiAgb3JnU3RhdHVzSWR4OiBpbmRleCgnc3VwcG9ydF9jYXNlX29yZ19zdGF0dXNfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLnN0YXR1cyksXG4gIC8vIFRoZSByb2xsaW5nLXdpbmRvdyBjYXNlIGNvdW50IGJlaGluZCB0aGUgRkFJUi1VU0UgYWxsb3dhbmNlOiBob3cgbWFueSBjYXNlc1xuICAvLyB0aGlzIGFjY291bnQgcmFpc2VkIGluIHRoZSBsYXN0IE4gZGF5cy4gTGVhZGluZyBgb3JnX2lkYCBiZWNhdXNlIHRoZSBjb3VudFxuICAvLyBpcyBhbHdheXMgc2NvcGVkIHRvIGFuIGFjY291bnQgc3VidHJlZSwgdGhlbiBgY3JlYXRlZF9hdGAgc28gdGhlIHdpbmRvdyBpcyBhXG4gIC8vIHJhbmdlIHNjYW4gcmF0aGVyIHRoYW4gYSBmaWx0ZXIgb3ZlciBldmVyeSBjYXNlIHRoZSBvcmcgZXZlciByYWlzZWQuXG4gIG9yZ0NyZWF0ZWRJZHg6IGluZGV4KCdzdXBwb3J0X2Nhc2Vfb3JnX2NyZWF0ZWRfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLmNyZWF0ZWRBdCksXG5cbiAgLy8gXCJXaGF0IGFtIEkgb24gdGhlIGhvb2sgZm9yXCIsIG9uZSBlbmdpbmVlci5cbiAgYXNzaWduZWVJZHg6IGluZGV4KCdzdXBwb3J0X2Nhc2VfYXNzaWduZWRfaWR4JylcbiAgICAub24odGFibGUuYXNzaWduZWRUbywgdGFibGUuc3RhdHVzKVxuICAgIC53aGVyZShzcWxgYXNzaWduZWRfdG8gSVMgTk9UIE5VTExgKSxcblxuICAvLyBcIk15IGNhc2VzXCIgZm9yIGEgY29udGFjdCwgQU5EIHRoZSBsb29rdXAgdGhhdCBmaW5kcyBhIGRlcGFydGluZyBjb250YWN0J3NcbiAgLy8gb3BlbiBjYXNlcyBzbyB0aGV5IGNhbiBiZSByZWFzc2lnbmVkIGluc3RlYWQgb2Ygb3JwaGFuZWQuXG4gIHRlbmFudENvbnRhY3RJZHg6IGluZGV4KCdzdXBwb3J0X2Nhc2VfdGVuYW50X2NvbnRhY3RfaWR4JylcbiAgICAub24odGFibGUudGVuYW50Q29udGFjdCwgdGFibGUuc3RhdHVzKVxuICAgIC53aGVyZShzcWxgdGVuYW50X2NvbnRhY3QgSVMgTk9UIE5VTExgKSxcblxuICAvLyBDYXNlIGlkZW50aXR5LCByZWFjaGVkIGZyb20gYW55IG1lc3NhZ2UgaW4gdGhlIHRocmVhZC5cbiAgdGhyZWFkVXE6IHVuaXF1ZUluZGV4KCdzdXBwb3J0X2Nhc2VfdGhyZWFkX3VxJykub24odGFibGUudGhyZWFkSWQpLFxuXG4gIC8vIFRoZSBjdXN0b21lci1xdW90YWJsZSBudW1iZXIgaXMgdW5pcXVlIHBlciBvcmcsIGVuZm9yY2VkIG5vdCBhc3N1bWVkLlxuICBkaXNwbGF5VXE6IHVuaXF1ZUluZGV4KCdzdXBwb3J0X2Nhc2Vfb3JnX251bWJlcl91cScpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS5kaXNwbGF5TnVtYmVyKVxuICAgIC53aGVyZShzcWxgZGVsZXRlZF9hdCBJUyBOVUxMYCksXG59KSk7XG5cbi8qKlxuICogUGVyLW9yZyBhbGxvY2F0b3IgZm9yIGBzdXBwb3J0X2Nhc2VzLmRpc3BsYXlfbnVtYmVyYC5cbiAqXG4gKiBQb3N0Z3JlcyBzZXF1ZW5jZXMgYXJlIGdsb2JhbCBhbmQgY2Fubm90IGJlIHBlci1vcmcgd2l0aG91dCBvbmUgc2VxdWVuY2UgcGVyXG4gKiB0ZW5hbnQsIHNvIHRoZSBjb3VudGVyIGlzIGEgcm93OiBgVVBEQVRFIOKApiBTRVQgbmV4dF9udW1iZXIgPSBuZXh0X251bWJlciArIDFcbiAqIFJFVFVSTklORyBuZXh0X251bWJlcmAgaW5zaWRlIHRoZSBjYXNlLWluc2VydCB0cmFuc2FjdGlvbiwgd2hlcmUgdGhlIHJvdyBsb2NrXG4gKiBzZXJpYWxpc2VzIGNvbmN1cnJlbnQgb3BlbnMgd2l0aGluIG9uZSBvcmcuXG4gKlxuICogQHRhYmxlIHN1cHBvcnRfY2FzZV9jb3VudGVyc1xuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydENhc2VDb3VudGVyID0gcGdUYWJsZSgnc3VwcG9ydF9jYXNlX2NvdW50ZXJzJywge1xuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5wcmltYXJ5S2V5KCksXG4gIG5leHROdW1iZXI6IGludGVnZXIoJ25leHRfbnVtYmVyJykuZGVmYXVsdCgxKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRBdDogdGltZXN0YW1wKCd1cGRhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbn0pO1xuXG4vKipcbiAqIFRoZSBtZW1iZXJzIGF1dGhvcmlzZWQgdG8gb3BlbiBzdXBwb3J0IGNhc2VzIOKAlCB3aGF0IHRoZSBwZXItY29udGFjdCBwcmljZVxuICogYmlsbHMgZm9yLlxuICpcbiAqIFRoZSBDT1VOVCBpcyBjYXBwZWQgYWdhaW5zdCBlZmZlY3RpdmUgYHN1cHBvcnRDb250YWN0c2AgYXQgZGVzaWduYXRpb24gdGltZSxcbiAqIGluIHRoZSBzYW1lIHNoYXBlIHNlYXRzIGFyZSBjYXBwZWQgYXQgaW52aXRlIHRpbWUuIGBzdXBwb3J0Q29udGFjdHNgIGhhcyBhXG4gKiB0aWVyIGJhc2Ugb2YgMCBldmVyeXdoZXJlLCBzbyBhbiBvcmcgd2l0aCBubyBzdXBwb3J0IGFkZC1vbiBoYXMgbm8gY29udGFjdHNcbiAqIGFuZCBjYW5ub3Qgb3BlbiBhIGNhc2U6IHRoZSBwYXl3YWxsIGlzIGEgcXVvdGEgY2hlY2ssIG5vdCBhIGZlYXR1cmUgZmxhZy5cbiAqXG4gKiBAdGFibGUgc3VwcG9ydF9jb250YWN0c1xuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydENvbnRhY3QgPSBwZ1RhYmxlKCdzdXBwb3J0X2NvbnRhY3RzJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHVzZXJJZDogdGV4dCgndXNlcl9pZCcpLm5vdE51bGwoKSxcbiAgLy8gV2hvIG5vbWluYXRlZCB0aGVtLiBBdWRpdC13b3J0aHk6IGEgY29udGFjdCBpcyBhIHBhaWQsIHByaXZpbGVnZWQgc2xvdC5cbiAgZGVzaWduYXRlZEJ5OiB0ZXh0KCdkZXNpZ25hdGVkX2J5Jykubm90TnVsbCgpLFxuICBkZXNpZ25hdGVkQXQ6IHRpbWVzdGFtcCgnZGVzaWduYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgY29udGFjdCBpcyBVUEdSQURFRCB0byBwcmVtaXVtIOKAlCAyNMOXNyBjb3ZlcmFnZSwgdGhlIDgtaG91clxuICAgKiBhbnktZGF5IHRhcmdldCwgYW5kIHRoZSBvbmx5IGNvbnRhY3RzIHdobyBtYXkgZGVjbGFyZSBgdXJnZW50YCBzZXZlcml0eS5cbiAgICpcbiAgICogQSBjb2x1bW4gb24gdGhlIGNvbnRhY3QgcmF0aGVyIHRoYW4gYSBsZXZlbCBvbiB0aGUgb3JnLCBiZWNhdXNlIHRoYXQgaXMgd2hhdFxuICAgKiB0aGUgdXBncmFkZSBtb2RlbCBtZWFuczogYW4gYWNjb3VudCBob2xkcyBvbmUgQkFTRUxJTkUgbGV2ZWwgY292ZXJpbmcgZXZlcnlcbiAgICogY29udGFjdCBhbmQgdXBncmFkZXMgYSBzdWJzZXQuIFdpdGhvdXQgdGhpcyB0aGUgYHN1cHBvcnRQcmVtaXVtQ29udGFjdHNgIGNhcFxuICAgKiB3b3VsZCBncmFudCBhIHF1b3RhIG92ZXIgbm90aGluZyDigJQgdGhlcmUgd291bGQgYmUgbm8gd2F5IGZvciBhbnkgY29udGFjdCB0b1xuICAgKiBhY3R1YWxseSBiZSBwcmVtaXVtLCBhbmQgdGhlIGNhc2Utb3BlbiBwYXRoIHdvdWxkIGhhdmUgbm90aGluZyB0byByZWFkLlxuICAgKlxuICAgKiBUaGUgY2FzZSBmcmVlemVzIHRoZSBPUEVOSU5HIENPTlRBQ1QncyBlZmZlY3RpdmUgbGV2ZWwgYXQgb3BlblxuICAgKiAoYHN1cHBvcnRfY2FzZS5sZXZlbGApLCBzbyBmbGlwcGluZyB0aGlzIGxhdGVyIG5ldmVyIGNoYW5nZXMgdGhlIHByb21pc2Ugb25cbiAgICogYSBjYXNlIGFscmVhZHkgcmFpc2VkLlxuICAgKi9cbiAgaXNQcmVtaXVtOiBib29sZWFuKCdpc19wcmVtaXVtJykuZGVmYXVsdChmYWxzZSkubm90TnVsbCgpLFxuICBpc0FjdGl2ZTogYm9vbGVhbignaXNfYWN0aXZlJykuZGVmYXVsdCh0cnVlKS5ub3ROdWxsKCksXG4gIHJldm9rZWRBdDogdGltZXN0YW1wKCdyZXZva2VkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIHJldm9rZWRCeTogdGV4dCgncmV2b2tlZF9ieScpLFxufSwgKHRhYmxlKSA9PiAoe1xuICAvLyBPbmUgbGl2ZSBkZXNpZ25hdGlvbiBwZXIgKG9yZywgdXNlcikuIFBhcnRpYWwgc28gYSByZXZva2VkIHJvdyBkb2VzIG5vdFxuICAvLyBibG9jayByZS1kZXNpZ25hdGluZyB0aGUgc2FtZSBwZXJzb24gbGF0ZXIuXG4gIG9yZ1VzZXJVcTogdW5pcXVlSW5kZXgoJ3N1cHBvcnRfY29udGFjdF9vcmdfdXNlcl91cScpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS51c2VySWQpXG4gICAgLndoZXJlKHNxbGBpc19hY3RpdmUgPSB0cnVlYCksXG4gIC8vIENvdW50aW5nIGFuIG9yZydzIGxpdmUgY29udGFjdHMgYWdhaW5zdCBpdHMgY2FwLCBhbmQgbGlzdGluZyB0aGVtIGZvciB0aGVcbiAgLy8gdGVuYW50LXNpZGUgb3duZXIgcGlja2VyLlxuICBvcmdBY3RpdmVJZHg6IGluZGV4KCdzdXBwb3J0X2NvbnRhY3Rfb3JnX2FjdGl2ZV9pZHgnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUuaXNBY3RpdmUpLFxuICAvLyBUaGUgcHJlbWl1bSBTVUJTRVQsIGNvdW50ZWQgYWdhaW5zdCBgc3VwcG9ydFByZW1pdW1Db250YWN0c2Agb24gZXZlcnlcbiAgLy8gdXBncmFkZS4gUGFydGlhbCBvbiBib3RoIGZsYWdzIGJlY2F1c2UgdGhhdCBpcyB0aGUgb25seSBxdWVzdGlvbiBhc2tlZCBvZlxuICAvLyBpdDogaG93IG1hbnkgbGl2ZSBjb250YWN0cyBpbiB0aGlzIHNjb3BlIGFyZSB1cGdyYWRlZC5cbiAgb3JnUHJlbWl1bUlkeDogaW5kZXgoJ3N1cHBvcnRfY29udGFjdF9vcmdfcHJlbWl1bV9pZHgnKVxuICAgIC5vbih0YWJsZS5vcmdJZCwgdGFibGUudXNlcklkKVxuICAgIC53aGVyZShzcWxgaXNfYWN0aXZlID0gdHJ1ZSBBTkQgaXNfcHJlbWl1bSA9IHRydWVgKSxcbn0pKTtcblxuLyoqXG4gKiBDYW5uZWQgc3RhZmYgcmVwbGllcyDigJQgYSBzaGFyZWQgbGlicmFyeSBvZiBhbnN3ZXJzIHRoZSBkZXNrIHJldXNlcy5cbiAqXG4gKiBTWVNURU0tV0lERSwgbm90IHBlci10ZW5hbnQsIGFuZCBkZWxpYmVyYXRlbHkgc286IHRoZXNlIGFyZSB0aGUgdmVuZG9yJ3Mgb3duXG4gKiB3b3JkaW5nIGZvciByZWN1cnJpbmcgcXVlc3Rpb25zLCBhdXRob3JlZCBvbmNlIGFuZCB1c2VkIGFjcm9zcyBldmVyeVxuICogY3VzdG9tZXIuIFRoZXJlIGlzIG5vIGBvcmdfaWRgIGJlY2F1c2Ugc2NvcGluZyB0aGVtIHBlciB0ZW5hbnQgd291bGQgYmUgdGhlXG4gKiBvcHBvc2l0ZSBvZiB0aGUgcG9pbnQg4oCUIHRoZSB2YWx1ZSBpcyB0aGF0IHRoZSBhbnN3ZXIgdG8gXCJob3cgZG8gSSByb3RhdGUgYVxuICogc2VydmljZSBrZXlcIiBpcyB3cml0dGVuIHdlbGwgb25jZSByYXRoZXIgdGhhbiByZXR5cGVkIGJhZGx5IGZpZnR5IHRpbWVzLlxuICpcbiAqIFRoYXQgYWxzbyBtZWFucyBSTFMgZG9lcyBub3QgYXBwbHk6IGV2ZXJ5IHJvdyBpcyB2aXNpYmxlIHRvIHRoZSBzdGFmZiB3aG8gY2FuXG4gKiByZWFjaCB0aGUgcXVldWUsIGFuZCB0byBub2JvZHkgZWxzZS4gVGhlIHJvdXRlcyBhcmUgc3lzdGVtLWFkbWluIGdhdGVkIG9uXG4gKiBib3RoIHJlYWQgYW5kIHdyaXRlIGZvciBleGFjdGx5IHRoYXQgcmVhc29uLlxuICpcbiAqIFNvZnQtZGVsZXRlZCByYXRoZXIgdGhhbiByZW1vdmVkLCBiZWNhdXNlIGEgcmV0aXJlZCB0ZW1wbGF0ZSBpcyBzdGlsbCB0aGVcbiAqIGV4cGxhbmF0aW9uIG9mIHdoYXQgYSBwYXN0IHJlcGx5IHNhaWQuXG4gKlxuICogQHRhYmxlIHN1cHBvcnRfY2FubmVkX3Jlc3BvbnNlc1xuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydENhbm5lZFJlc3BvbnNlID0gcGdUYWJsZSgnc3VwcG9ydF9jYW5uZWRfcmVzcG9uc2VzJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICAvKiogU2hvcnQgbGFiZWwgdGhlIHBpY2tlciBsaXN0cy4gKi9cbiAgdGl0bGU6IHZhcmNoYXIoJ3RpdGxlJywgeyBsZW5ndGg6IDIwMCB9KS5ub3ROdWxsKCksXG4gIGJvZHk6IHRleHQoJ2JvZHknKS5ub3ROdWxsKCksXG4gIGNyZWF0ZWRCeTogdGV4dCgnY3JlYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXAoJ2NyZWF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICB1cGRhdGVkQnk6IHRleHQoJ3VwZGF0ZWRfYnknKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRBdDogdGltZXN0YW1wKCd1cGRhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbiAgaXNBY3RpdmU6IGJvb2xlYW4oJ2lzX2FjdGl2ZScpLmRlZmF1bHQodHJ1ZSkubm90TnVsbCgpLFxufSwgKHRhYmxlKSA9PiAoe1xuICAvLyBUaGUgcGlja2VyJ3Mgb25seSBxdWVyeTogbGl2ZSB0ZW1wbGF0ZXMsIGFscGhhYmV0aWNhbC5cbiAgYWN0aXZlVGl0bGVJZHg6IGluZGV4KCdzdXBwb3J0X2Nhbm5lZF9hY3RpdmVfaWR4Jykub24odGFibGUuaXNBY3RpdmUsIHRhYmxlLnRpdGxlKSxcbn0pKTtcblxuLyoqXG4gKiBDU0FUOiB0aGUgY3VzdG9tZXIncyB2ZXJkaWN0IG9uIGEgY2xvc2VkIGNhc2UuXG4gKlxuICogQSBDT0xVTU4gU0VUIG9uIHRoZSBjYXNlIHJhdGhlciB0aGFuIGl0cyBvd24gdGFibGUsIHVubGlrZSBub3Rlcy4gVGhlIHJlYXNvblxuICogaXMgY2FyZGluYWxpdHksIG5vdCBjb252ZW5pZW5jZTogYSBjYXNlIGhhcyBtYW55IG5vdGVzIGFuZCBleGFjdGx5IG9uZVxuICogc2F0aXNmYWN0aW9uIHJhdGluZywgc28gYSB0YWJsZSB3b3VsZCBidXkgYW4gZXh0cmEgam9pbiBhbmQgYSB1bmlxdWVuZXNzXG4gKiBjb25zdHJhaW50IHRvIGVuZm9yY2Ugd2hhdCBhIGNvbHVtbiBnZXRzIGZvciBmcmVlLlxuICpcbiAqIFdoeSBpdCBtYXR0ZXJzIG1vcmUgaGVyZSB0aGFuIGluIG1vc3QgcHJvZHVjdHM6IHRoZSB0aGluZyBiZWluZyBTT0xEIGlzIGFcbiAqIHJlc3BvbnNlIHRpbWUsIGFuZCBmaXJzdC1yZXNwb25zZSBsYXRlbmN5IG9ubHkgbWVhc3VyZXMgd2hldGhlciB3ZSBhbnN3ZXJlZFxuICogZmFzdCDigJQgbm90IHdoZXRoZXIgdGhlIGFuc3dlciB3YXMgYW55IGdvb2QuIEEgZGVzayBjYW4gaGl0IGV2ZXJ5IHRhcmdldCBhbmRcbiAqIHN0aWxsIGJlIGJhZCBhdCBzdXBwb3J0LCBhbmQgd2l0aG91dCB0aGlzIG5vdGhpbmcgaW4gdGhlIHN5c3RlbSB3b3VsZCBub3RpY2UuXG4gKlxuICogQHRhYmxlIHN1cHBvcnRfY2FzZXMgKGNvbHVtbnMpXG4gKi9cblxuLyoqXG4gKiBTdGFmZi1vbmx5IG5vdGVzIG9uIGEgY2FzZS5cbiAqXG4gKiBBIFNFUEFSQVRFIFRBQkxFIHJhdGhlciB0aGFuIGEgZmxhZyBvbiBgbWVzc2FnZXNgLCBhbmQgdGhlIHJlYXNvbiBpcyB0aGVcbiAqIGZhaWx1cmUgbW9kZTogYG1lc3NhZ2VzYCBpcyByZWFkIHRocm91Z2ggb25lIHNoYXJlZCB2aXNpYmlsaXR5IHByZWRpY2F0ZVxuICogKGBidWlsZE1lc3NhZ2VDb25kaXRpb25zYCksIHNvIGEgZmxhZyBtZWFucyBldmVyeSByZWFkIHBhdGggdGhhdCBmb3JnZXRzIHRoZVxuICogZXh0cmEgY29uZGl0aW9uIGxlYWtzIGFuIGludGVybmFsIG5vdGUgdG8gdGhlIHRlbmFudC4gQSBzZXBhcmF0ZSB0YWJsZSBjYW5ub3RcbiAqIGxlYWsgYnkgb21pc3Npb24g4oCUIGl0IGhhcyB0byBiZSBqb2luZWQgZGVsaWJlcmF0ZWx5LlxuICpcbiAqIEB0YWJsZSBzdXBwb3J0X2Nhc2Vfbm90ZXNcbiAqL1xuZXhwb3J0IGNvbnN0IHN1cHBvcnRDYXNlTm90ZSA9IHBnVGFibGUoJ3N1cHBvcnRfY2FzZV9ub3RlcycsIHtcbiAgaWQ6IHV1aWQoJ2lkJykucHJpbWFyeUtleSgpLmRlZmF1bHRSYW5kb20oKSxcbiAgY2FzZUlkOiB1dWlkKCdjYXNlX2lkJykubm90TnVsbCgpLFxuICAvLyBEZW5vcm1hbGlzZWQgc28gYSBub3RlIGNhbiBuZXZlciBiZSBzZXJ2ZWQgd2l0aG91dCBpdHMgdGVuYW50IHNjb3BlLlxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIGNvbnRlbnQ6IHRleHQoJ2NvbnRlbnQnKS5ub3ROdWxsKCksXG4gIGNyZWF0ZWRCeTogdGV4dCgnY3JlYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXAoJ2NyZWF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICBpc0FjdGl2ZTogYm9vbGVhbignaXNfYWN0aXZlJykuZGVmYXVsdCh0cnVlKS5ub3ROdWxsKCksXG4gIGRlbGV0ZWRBdDogdGltZXN0YW1wKCdkZWxldGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIGRlbGV0ZWRCeTogdGV4dCgnZGVsZXRlZF9ieScpLFxufSwgKHRhYmxlKSA9PiAoe1xuICBjYXNlSWR4OiBpbmRleCgnc3VwcG9ydF9jYXNlX25vdGVfY2FzZV9pZHgnKS5vbih0YWJsZS5jYXNlSWQsIHRhYmxlLmlzQWN0aXZlKSxcbn0pKTtcblxuLyoqIFR5cGVTY3JpcHQgdHlwZXMgcmVwcmVzZW50aW5nIGRhdGFiYXNlIHJvd3MgKi9cbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlID0gdHlwZW9mIHN1cHBvcnRDYXNlLiRpbmZlclNlbGVjdDtcbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlSW5zZXJ0ID0gdHlwZW9mIHN1cHBvcnRDYXNlLiRpbmZlckluc2VydDtcbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlVXBkYXRlID0gUGFydGlhbDxPbWl0PFN1cHBvcnRDYXNlSW5zZXJ0LCAnaWQnIHwgJ2NyZWF0ZWRBdCcgfCAnY3JlYXRlZEJ5JyB8ICdvcmdJZCcgfCAndGhyZWFkSWQnIHwgJ2Rpc3BsYXlOdW1iZXInPj47XG5cbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlQ291bnRlciA9IHR5cGVvZiBzdXBwb3J0Q2FzZUNvdW50ZXIuJGluZmVyU2VsZWN0O1xuXG5leHBvcnQgdHlwZSBTdXBwb3J0Q29udGFjdCA9IHR5cGVvZiBzdXBwb3J0Q29udGFjdC4kaW5mZXJTZWxlY3Q7XG5leHBvcnQgdHlwZSBTdXBwb3J0Q29udGFjdEluc2VydCA9IHR5cGVvZiBzdXBwb3J0Q29udGFjdC4kaW5mZXJJbnNlcnQ7XG5cbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlTm90ZSA9IHR5cGVvZiBzdXBwb3J0Q2FzZU5vdGUuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgU3VwcG9ydENhc2VOb3RlSW5zZXJ0ID0gdHlwZW9mIHN1cHBvcnRDYXNlTm90ZS4kaW5mZXJJbnNlcnQ7XG4iXX0=
|
|
@@ -64,11 +64,13 @@ export interface TenantContext {
|
|
|
64
64
|
* the AsyncLocalStorage store — the store is per-request, so this cannot leak
|
|
65
65
|
* between requests.
|
|
66
66
|
*
|
|
67
|
-
* SCOPE: this covers reads AFTER a write IN THE SAME REQUEST.
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
67
|
+
* SCOPE: this flag covers reads AFTER a write IN THE SAME REQUEST. The
|
|
68
|
+
* next-request case (POST, then a page reload issuing GET) needs shared state
|
|
69
|
+
* and is handled by api-server's `write-pin.ts`, which remembers in Redis
|
|
70
|
+
* that an org wrote recently and PRE-SETS this same flag on the next
|
|
71
|
+
* request's context — one mechanism and one code path rather than two. It
|
|
72
|
+
* fails closed (no Redis, or an unreachable one, routes reads to the primary)
|
|
73
|
+
* and short-circuits entirely when no read replica is configured.
|
|
72
74
|
*/
|
|
73
75
|
mayHaveWritten?: boolean;
|
|
74
76
|
}
|
package/lib/database/tenancy.js
CHANGED
|
@@ -247,4 +247,4 @@ export async function withTenantTxRead(fn) {
|
|
|
247
247
|
return fn(tx);
|
|
248
248
|
});
|
|
249
249
|
}
|
|
250
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW5jeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhYmFzZS90ZW5hbmN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBRUgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDL0UsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFFNUUsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFlOUMsU0FBUyxjQUFjO0lBQ3JCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDeEQsSUFBSSxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxNQUFNLElBQUksR0FBRyxLQUFLLFFBQVE7UUFBRSxPQUFPLEdBQUcsQ0FBQztJQUN2RSx1RUFBdUU7SUFDdkUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0FBQ25FLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMscUJBQXFCO0lBQzVCLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSxNQUFNLENBQUMs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QUNkLEdBQUcsQ0FBQSxtQ0FBbUMsS0FBSywwQ0FBMEMsWUFBWSw0Q0FBNEMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FDakwsQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxFQUFFLENBQUMsT0FBTyxDQUNkLEdBQUcsQ0FBQSxtQ0FBbUMsS0FBSywwQ0FBMEMsWUFBWSxTQUFTLENBQzNHLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDaEIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogVGVuYW50LWNvbnRleHQgcGx1bWJpbmcgZm9yIFBvc3RncmVzIHJvdy1sZXZlbCBzZWN1cml0eS5cbiAqXG4gKiBCYWNrZ3JvdW5kOiBwb3N0Z3Jlcy1pbml0LnNxbCBpbnN0YWxscyBSTFMgcG9saWNpZXMgb24gZXZlcnkgdXNlci1kYXRhXG4gKiB0YWJsZSB0aGF0IGNvbnN1bHQgdHdvIHNlc3Npb24gR1VDcyDigJQgYGFwcC5vcmdfaWRgIGFuZCBgYXBwLmlzX3N5c2FkbWluYC5cbiAqIEV2ZXJ5IHRlbmFudCB0YWJsZSBpcyBgRk9SQ0UgUk9XIExFVkVMIFNFQ1VSSVRZYCwgc28gdGhlIHBvbGljaWVzIGVuZm9yY2VcbiAqIGV2ZW4gZm9yIHRoZSAob3duaW5nKSBjb25uZWN0aW9uIHVzZXIg4oCUIGEgcXVlcnkgYWdhaW5zdCBvbmUgbXVzdCBydW4gaW5zaWRlIGFcbiAqIHRyYW5zYWN0aW9uIHRoYXQgaGFzIFNFVCBMT0NBTCdkIGJvdGggR1VDcyBvciBpdCByZXR1cm5zIHplcm8gcm93cyBmb3JcbiAqIG5vbi1zeXNhZG1pbnMgKGFuZCBtYXkgZmFpbCB0byB3cml0ZSBmb3IgYW55IGNhbGxlcikuIFRoZSBjcm9zcy1vcmcgcGx1Z2luXG4gKiBlY29zeXN0ZW0gY2F0YWxvZyB0YWJsZXMgY2FycnkgYSBwZXJtaXNzaXZlIGFwcC1yb2xlIHBvbGljeSBpbnN0ZWFkLlxuICpcbiAqIFRoaXMgbW9kdWxlIGlzIHRoZSBzZWFtLlxuICpcbiAqICAgMS4gYHRlbmFudENvbnRleHRgIChBc3luY0xvY2FsU3RvcmFnZSkgY2FycmllcyBge29yZ0lkLCBpc1N1cGVyQWRtaW59YFxuICogICAgICBkb3duIHRoZSBjYWxsIGNoYWluIHdpdGhvdXQgcHJvcC1kcmlsbGluZy4gU2V0IG9uY2UgYXQgdGhlIHJlcXVlc3RcbiAqICAgICAgYm91bmRhcnk7IHJlYWRhYmxlIGZyb20gYW55d2hlcmUuXG4gKlxuICogICAyLiBgd2l0aFRlbmFudFR4KGZuKWAgb3BlbnMgYSB0cmFuc2FjdGlvbiwgU0VUIExPQ0FMJ3MgYm90aCBHVUNzIGZyb21cbiAqICAgICAgdGhlIHN1cnJvdW5kaW5nIGNvbnRleHQsIHRoZW4gaW52b2tlcyBgZm4odHgpYC4gU2VydmljZXMgbWlncmF0ZSBvbmVcbiAqICAgICAgYXQgYSB0aW1lIGJ5IHdyYXBwaW5nIHRoZWlyIGV4aXN0aW5nIGRyaXp6bGUgY2FsbHMgaW4gdGhpcyBoZWxwZXIg4oCUXG4gKiAgICAgIGBkYi5zZWxlY3QoKS5mcm9tKC4uLilgIGJlY29tZXMgYHdpdGhUZW5hbnRUeCh0eCA9PiB0eC5zZWxlY3QoKS5mcm9tKC4uLikpYC5cbiAqXG4gKiAgIDMuIGBydW5XaXRoVGVuYW50Q29udGV4dChjdHgsIGZuKWAgaXMgdGhlIEV4cHJlc3MtbWlkZGxld2FyZS1zaWRlXG4gKiAgICAgIGJvb2tlbmQgdGhhdCBlc3RhYmxpc2hlcyB0aGUgQXN5bmNMb2NhbFN0b3JhZ2Ugc2NvcGUgZm9yIHRoZSByZXF1ZXN0LlxuICpcbiAqIE1pZ3JhdGlvbiBvcmRlcjpcbiAqICAgLSBGaXJzdCBhZG9wdGVyczogbmV3bHktd3JpdHRlbiBzZXJ2aWNlcyAoZGFzaGJvYXJkLCBhbGVydC1kZXN0aW5hdGlvbilcbiAqICAgICB3aGVyZSB0aGUgY2hhbmdlIGlzIG1lY2hhbmljYWwuXG4gKiAgIC0gVGhlbiBoaWdoLXdyaXRlIHNlcnZpY2VzIChwbHVnaW4sIHBpcGVsaW5lKS4gU29hayBlYWNoIG9uZSBiZWZvcmVcbiAqICAgICBmbGlwcGluZyB0aGUgdW5kZXJseWluZyB0YWJsZSB0byBGT1JDRS5cbiAqICAgLSBhZG1pbl9hdWRpdF9sb2cgdXNlcyBhIHN5c2FkbWluLW9ubHkgcG9saWN5IOKAlCBzeXNhZG1pbiBwYXRocyBtdXN0XG4gKiAgICAgYWxzbyBzZXQgYGFwcC5pc19zeXNhZG1pbiA9ICd0cnVlJ2Agb3IgdGhleSdsbCBsb3NlIGFjY2VzcyB0byBpdC5cbiAqL1xuXG5pbXBvcnQgeyBBc3luY0xvY2FsU3RvcmFnZSB9IGZyb20gJ25vZGU6YXN5bmNfaG9va3MnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBlbWl0Q291bnRlciwgZW52SW50IH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgc3FsIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgZGIgfSBmcm9tICcuL3Bvc3RncmVzLWNvbm5lY3Rpb24uanMnO1xuaW1wb3J0IHsgZ2V0UmVhZERiLCBnZXRSZWFkUG9vbCB9IGZyb20gJy4vcmVhZC1jb25uZWN0aW9uLmpzJztcbmltcG9ydCB7IGxhZ1ZlcmRpY3QsIG1heWJlU2FtcGxlTGFnLCB0eXBlIExhZ1ZlcmRpY3QgfSBmcm9tICcuL3JlYWQtbGFnLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCd0ZW5hbnQtY29udGV4dCcpO1xuXG4vKipcbiAqIEJlaGF2aW9yIHdoZW4gYHdpdGhUZW5hbnRUeGAgaXMgaW52b2tlZCBvdXRzaWRlIGFueSBgcnVuV2l0aFRlbmFudENvbnRleHRgXG4gKiBzY29wZS4gVGhlIGVmZmVjdGl2ZSBkZWZhdWx0IGlzIGZhaWwtZmFzdCAoJ3N0cmljdCcpIGluIHByb2R1Y3Rpb24gc28gYVxuICogbWlzc2luZyB0ZW5hbnQgc2NvcGUgc3VyZmFjZXMgYXQgdGhlIGJhZCBjYWxsIHNpdGUgaW5zdGVhZCBvZiBzaWxlbnRseVxuICogcnVubmluZyB3aXRoIGVtcHR5IFJMUyBHVUNzOyBvdXRzaWRlIHByb2R1Y3Rpb24gaXQgZGVmYXVsdHMgdG8gJ3dhcm4nIHNvXG4gKiB1bi1hdWRpdGVkIGRldi90ZXN0IHBhdGhzIGtlZXAgd29ya2luZyBidXQgbG9nIGFuIGFjdGlvbmFibGUgdHJhY2UuIEFuXG4gKiBleHBsaWNpdCBSTFNfQ09OVEVYVF9NT0RFIGVudiBvdmVycmlkZSBhbHdheXMgd2lucy5cbiAqXG4gKiAnc2lsZW50JyBpcyBrZXB0IGZvciB0ZXN0cyBhbmQgc2NyaXB0cyB0aGF0IGludGVudGlvbmFsbHkgZW50ZXIgdGhlIERCXG4gKiB3aXRob3V0IGNvbnRleHQgKGUuZy4gaW50ZWdyYXRpb24gdGVzdCBzZXR1cCB0aGF0IHJ1bnMgYXMgdGhlIGNvbm5lY3Rpb25cbiAqIG93bmVyIGJlZm9yZSBhbnkgdGVuYW50IGlzIHByb3Zpc2lvbmVkKS5cbiAqL1xudHlwZSBDb250ZXh0TW9kZSA9ICdzaWxlbnQnIHwgJ3dhcm4nIHwgJ3N0cmljdCc7XG5mdW5jdGlvbiBnZXRDb250ZXh0TW9kZSgpOiBDb250ZXh0TW9kZSB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LlJMU19DT05URVhUX01PREU/LnRvTG93ZXJDYXNlKCk7XG4gIGlmIChyYXcgPT09ICdzaWxlbnQnIHx8IHJhdyA9PT0gJ3dhcm4nIHx8IHJhdyA9PT0gJ3N0cmljdCcpIHJldHVybiByYXc7XG4gIC8vIE5vIGV4cGxpY2l0IG92ZXJyaWRlOiBmYWlsLWZhc3QgaW4gcHJvZHVjdGlvbiwgd2FybiBldmVyeXdoZXJlIGVsc2UuXG4gIHJldHVybiBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nID8gJ3N0cmljdCcgOiAnd2Fybic7XG59XG5cbi8qKlxuICogUGVyLXN0YXRlbWVudCBzZXJ2ZXItc2lkZSB0aW1lb3V0IChtcykgYXBwbGllZCBJTlNJREUgZXZlcnkgYHdpdGhUZW5hbnRUeGBcbiAqIHRyYW5zYWN0aW9uLCBuZXh0IHRvIHRoZSBSTFMgR1VDcy4gYHdpdGhUZW5hbnRUeGAgaXMgdGhlIHJlYWwgcXVlcnkgcGF0aCBmb3JcbiAqIGFsbCBSTFMvQ1JVRCByZWFkcyBhbmQgd3JpdGVzLCBzbyB0aGlzIGlzIHdoZXJlIHRoZSBEQi1zaWRlIGd1YXJkIGJlbG9uZ3MgKHRoZVxuICogb2xkIGBDb25uZWN0aW9uLnRyYW5zYWN0aW9uYCB3cmFwcGVyIHRoYXQgc2V0IGl0IGlzIGRlYWQg4oCUIHNlZVxuICogcG9zdGdyZXMtY29ubmVjdGlvbi50cykuIEJvdW5kcyBhIHJ1bmF3YXkgcXVlcnkgc28gaXQgY2FuJ3QgaG9sZCBhIHBvb2xlZFxuICogY29ubmVjdGlvbiBvcGVuIGluZGVmaW5pdGVseS4gRW52LWNvbmZpZ3VyYWJsZSB2aWEgYERCX1NUQVRFTUVOVF9USU1FT1VUX01TYFxuICogKGRlZmF1bHQgMzBzKTsgc2V0IHRvIGAwYCB0byBkaXNhYmxlIHRoZSB0aW1lb3V0LlxuICovXG5mdW5jdGlvbiBnZXRTdGF0ZW1lbnRUaW1lb3V0TXMoKTogbnVtYmVyIHtcbiAgY29uc3QgbXMgPSBlbnZJbnQoJ0RCX1NUQVRFTUVOVF9USU1FT1VUX01TJywgMzBfMDAwKTtcbiAgcmV0dXJuIG1zID49IDAgPyBtcyA6IDMwXzAwMDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5hbnRDb250ZXh0IHtcbiAgLyoqIENhbGxlcidzIG9yZy4gVW5kZWZpbmVkIGZvciB1bi1hdXRoZW50aWNhdGVkIC8gc3lzdGVtIGpvYnMuICovXG4gIG9yZ0lkPzogc3RyaW5nO1xuICAvKiogQ2FsbGVyJ3MgdXNlciBpZC4gTm90IHVzZWQgZm9yIFJMUyDigJQgUG9zdGdyZXMgcG9saWNpZXMgYXJlIG9yZy1ncmFpbmVkLFxuICAgKiAgd2l0aCBubyBwZXItdXNlciBzZXNzaW9uIEdVQyDigJQgYnV0IGNhcnJpZWQgc28gYXBwLWxheWVyIHByZWRpY2F0ZXMgd2l0aCBhXG4gICAqICBQRVItVVNFUiBydW5nIChwaXBlbGluZSB0ZW1wbGF0ZXMnIGBwcml2YXRlYCB2aXNpYmlsaXR5KSBjYW4gcmVzb2x2ZSBcIndob1xuICAgKiAgaXMgYXNraW5nXCIgb24gcGF0aHMgdGhhdCBoYXZlIG5vd2hlcmUgdG8gcGFzcyBpdCwgbm90YWJseSBDcnVkU2VydmljZSdzXG4gICAqICBgd3JpdGVDb25kaXRpb25zYC4gQWJzZW50IGZvciBzeXN0ZW0gam9icywgd2hpY2ggaXMgdGhlIGZhaWwtY2xvc2VkIGNhc2U6XG4gICAqICBubyB2aWV3ZXIg4oeSIG5vIHByaXZhdGUgcm93cy4gKi9cbiAgdXNlcklkPzogc3RyaW5nO1xuICAvKiogVHJ1ZSB3aGVuIHRoZSBjYWxsZXIgaXMgYSBzeXNhZG1pbiAoc3lzdGVtLW9yZyBhZG1pbikuIEJ5cGFzc2VzIFJMU1xuICAgKiAgcG9saWNpZXMgdmlhIHRoZSBzeXNhZG1pbi1ieXBhc3MgYnJhbmNoIGluIGBjdXJyZW50X2lzX3N5c2FkbWluKClgLiAqL1xuICBpc1N1cGVyQWRtaW46IGJvb2xlYW47XG4gIC8qKiBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB0aGUgY2FsbGVyJ3MgYWN0aXZlLW9yZyBwYXJlbnQgKHByZXNlbnQgb25seSB3aGVuIHRoZVxuICAgKiAgYWN0aXZlIG9yZyBpcyBhIHRlYW0pLiBOb3QgdXNlZCBmb3IgUkxTOyBjYXJyaWVkIHNvIGRvd25zdHJlYW0gc2lkZS1lZmZlY3RzXG4gICAqICAoZS5nLiBlbnRpdHktZXZlbnQgY29tcGxpYW5jZSBldmFsKSBjYW4gaG9ub3IgcGFyZW50IGBwcm9wYWdhdGVUb0NoaWxkcmVuYFxuICAgKiAgcnVsZXMgd2l0aG91dCBhIHJlcXVlc3QgaW4gc2NvcGUuICovXG4gIHBhcmVudE9yZ0lkPzogc3RyaW5nO1xuICAvKipcbiAgICogU2V0IG9uY2UgdGhpcyByZXF1ZXN0IGhhcyBvcGVuZWQgYSBQUklNQVJZIHRyYW5zYWN0aW9uLCBpLmUuIG1heSBoYXZlXG4gICAqIHdyaXR0ZW4uIFN1YnNlcXVlbnQgYHdpdGhUZW5hbnRUeFJlYWRgIGNhbGxzIGluIHRoZSBzYW1lIHJlcXVlc3QgdGhlbiBnbyB0b1xuICAgKiB0aGUgcHJpbWFyeSB0b28sIHNvIGEgaGFuZGxlciBjYW5ub3QgcmVhZCBpdHMgb3duIHdyaXRlIG9mZiBhIHJlcGxpY2EgdGhhdFxuICAgKiBoYXMgbm90IHJlcGxheWVkIGl0IHlldC5cbiAgICpcbiAgICogRGVsaWJlcmF0ZWx5IHNldCBieSBgd2l0aFRlbmFudFR4YCByYXRoZXIgdGhhbiBieSB3cml0ZSBjYWxsIHNpdGVzOiB0aGF0XG4gICAqIHBhdGggaXMgdGhlIG9uZSB0aGF0IGNhbiB3cml0ZSwgaXQgbmVlZHMgbm8gcGVyLWNhbGwtc2l0ZSBkaXNjaXBsaW5lLCBhbmRcbiAgICogYmVpbmcgd3JvbmcgaW4gdGhpcyBkaXJlY3Rpb24gb25seSBjb3N0cyBhIHJlcGxpY2EgaGl0LiBNdXRhdGVkIGluIHBsYWNlIG9uXG4gICAqIHRoZSBBc3luY0xvY2FsU3RvcmFnZSBzdG9yZSDigJQgdGhlIHN0b3JlIGlzIHBlci1yZXF1ZXN0LCBzbyB0aGlzIGNhbm5vdCBsZWFrXG4gICAqIGJldHdlZW4gcmVxdWVzdHMuXG4gICAqXG4gICAqIFNDT1BFOiB0aGlzIGNvdmVycyByZWFkcyBBRlRFUiBhIHdyaXRlIElOIFRIRSBTQU1FIFJFUVVFU1QuIEl0IGRvZXMgTk9UXG4gICAqIGNvdmVyIHRoZSBuZXh0IHJlcXVlc3QgKFBPU1QgdGhlbiBhIHBhZ2UgcmVsb2FkIGlzc3VpbmcgR0VUKS4gVGhhdCBuZWVkc1xuICAgKiBzaGFyZWQgc3RhdGUg4oCUIHNlZSB0aGUgY3Jvc3MtcmVxdWVzdCBzZWN0aW9uIG9mXG4gICAqIGRvY3MvcGxhbnMvcG9zdGdyZXMtcmVhZC13cml0ZS1zcGxpdC5tZCDigJQgYW5kIG11c3QgYmUgc2V0dGxlZCBiZWZvcmUgY2FsbFxuICAgKiBzaXRlcyBhcmUgbWlncmF0ZWQgaW4gYnVsay5cbiAgICovXG4gIG1heUhhdmVXcml0dGVuPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQZXItcmVxdWVzdCB0ZW5hbnQgY29udGV4dC4gUG9wdWxhdGVkIGJ5IEV4cHJlc3MgbWlkZGxld2FyZSBvbmNlIHRoZSBKV1RcbiAqIGlzIHZhbGlkYXRlZDsgY29uc3VtZWQgYnkgYHdpdGhUZW5hbnRUeGAgYW5kIGFueSBoZWxwZXIgdGhhdCBuZWVkcyB0b1xuICoga25vdyBcIndobyBpcyB0aGUgY2FsbGVyXCIgd2l0aG91dCByZS1kZXJpdmluZyBmcm9tIHRoZSByZXF1ZXN0IG9iamVjdC5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbmFudENvbnRleHQgPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2U8VGVuYW50Q29udGV4dD4oKTtcblxuLyoqXG4gKiBSdW4gYGZuYCBpbnNpZGUgdGhlIGdpdmVuIHRlbmFudCBzY29wZS4gVGhlIEFzeW5jTG9jYWxTdG9yYWdlIHNjb3BlXG4gKiBzdXJ2aXZlcyBhY3Jvc3MgYXN5bmMgYm91bmRhcmllcyAoUHJvbWlzZXMsIHNldFRpbWVvdXQsIGV0Yy4pLCBzbyBhbnlcbiAqIGB3aXRoVGVuYW50VHhgIGNhbGwgaW5zaWRlIGBmbmAg4oCUIGRpcmVjdGx5IG9yIHRocm91Z2ggYW55IGRlcHRoIG9mXG4gKiBhc3luYyBoZWxwZXJzIOKAlCBwaWNrcyB1cCBgY3R4YC5cbiAqXG4gKiBXcmFwIGBuZXh0KClgIGZyb20gYW4gRXhwcmVzcyBtaWRkbGV3YXJlIHRvIGVzdGFibGlzaCBwZXItcmVxdWVzdCBzY29wZTpcbiAqXG4gKiAgICAgYXBwLnVzZSgocmVxLCByZXMsIG5leHQpID0+IHtcbiAqICAgICAgIHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbiB9LCAoKSA9PiBuZXh0KCkpO1xuICogICAgIH0pO1xuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuV2l0aFRlbmFudENvbnRleHQ8VD4oY3R4OiBUZW5hbnRDb250ZXh0LCBmbjogKCkgPT4gVCk6IFQge1xuICByZXR1cm4gdGVuYW50Q29udGV4dC5ydW4oY3R4LCBmbik7XG59XG5cbi8qKiBSZWFkIHRoZSBjdXJyZW50IHRlbmFudCBjb250ZXh0LiBSZXR1cm5zIHVuZGVmaW5lZCBvdXRzaWRlIGFuXG4gKiAgYHJ1bldpdGhUZW5hbnRDb250ZXh0YCBzY29wZSAoZS5nLiBiYWNrZ3JvdW5kIHdvcmtlcnMsIG1pZ3JhdGlvbnMpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRlbmFudENvbnRleHQoKTogVGVuYW50Q29udGV4dCB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB0ZW5hbnRDb250ZXh0LmdldFN0b3JlKCk7XG59XG5cbi8qKlxuICogT3BlbiBhIHRyYW5zYWN0aW9uIHdpdGggUkxTIEdVQ3MgU0VUIExPQ0FMIGZyb20gdGhlIGN1cnJlbnRcbiAqIEFzeW5jTG9jYWxTdG9yYWdlIHRlbmFudCBjb250ZXh0LCB0aGVuIGludm9rZSBgZm4odHgpYC5cbiAqXG4gKiAtIFdoZW4gY2FsbGVkIG91dHNpZGUgYSB0ZW5hbnQgc2NvcGUgKGUuZy4gZnJvbSBhIGJhY2tncm91bmQgam9iIHRoYXRcbiAqICAgZG9lc24ndCBoYXZlIGEgY2FsbGVyIGlkZW50aXR5KSwgdGhlIHRyYW5zYWN0aW9uIGlzIG9wZW5lZCB3aXRoIGJvdGhcbiAqICAgR1VDcyBjbGVhcmVkIOKAlCBSTFMgcG9saWNpZXMgd2lsbCByZXR1cm4gemVybyByb3dzIG9uIEZPUkNFJ2QgdGFibGVzLlxuICogICBDYWxsZXJzIHRoYXQgbmVlZCBhIHN5c2FkbWluLWVxdWl2YWxlbnQgc2NvcGUgc2hvdWxkIHdyYXAgdGhlbXNlbHZlcyBpblxuICogICBgcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwg4oCmKWAgZXhwbGljaXRseS5cbiAqXG4gKiAtIFVzZXMgYHNldF9jb25maWcoa2V5LCB2YWx1ZSwgdHJ1ZSlgICh0aGUgYm9vbGVhbiA9IGBpc19sb2NhbGAsIGkuZS5cbiAqICAgdHJhbnNhY3Rpb24tc2NvcGVkKS4gRXF1aXZhbGVudCB0byBgU0VUIExPQ0FMYCBidXQgdGFrZXMgdGhlIHZhbHVlIGFzXG4gKiAgIGEgcGFyYW1ldGVyLCB3aGljaCBpcyB3aGF0IHdlIHdhbnQg4oCUIERyaXp6bGUncyBgc3FsYCB0ZW1wbGF0ZSBiaW5kcyB0aGVcbiAqICAgdmFsdWUgc2FmZWx5IHNvIGFuIGF0dGFja2VyLWNvbnRyb2xsZWQgYG9yZ0lkYCBjYW4ndCBlc2NhcGUgdGhlIHF1b3RpbmcuXG4gKlxuICogLSBSZXR1cm5zIHdoYXRldmVyIGBmbmAgcmV0dXJuczsgdGhyb3dzIHdoYXRldmVyIGBmbmAgdGhyb3dzIChEcml6emxlXG4gKiAgIGhhbmRsZXMgdGhlIENPTU1JVC9ST0xMQkFDSyBmb3IgdXMpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2l0aFRlbmFudFR4PFQ+KFxuICBmbjogKHR4OiBQYXJhbWV0ZXJzPFBhcmFtZXRlcnM8dHlwZW9mIGRiLnRyYW5zYWN0aW9uPlswXT5bMF0pID0+IFByb21pc2U8VD4sXG4gIC8qKlxuICAgKiBJTlRFUk5BTC4gV2hldGhlciB0aGlzIHRyYW5zYWN0aW9uIHNob3VsZCBtYXJrIHRoZSByZXF1ZXN0IGFzIHBvc3NpYmx5XG4gICAqIGhhdmluZyB3cml0dGVuLiBBbHdheXMgdHJ1ZSBmb3IgYSByZWFsIGNhbGxlcjsgb25seSB3aXRoVGVuYW50VHhSZWFkJ3NcbiAgICogcHJpbWFyeS1mYWxsYmFjayBwYXRoIHBhc3NlcyBmYWxzZSwgYmVjYXVzZSBhIHJlYWQgdGhhdCBsYW5kcyBvbiB0aGVcbiAgICogcHJpbWFyeSBoYXMgbm90IHdyaXR0ZW4uIFNlZSB0aGUgY29tbWVudCBhdCB0aGUgYXNzaWdubWVudCBiZWxvdy5cbiAgICovXG4gIG1hcmtXcml0dGVuID0gdHJ1ZSxcbik6IFByb21pc2U8VD4ge1xuICBjb25zdCBjdHggPSB0ZW5hbnRDb250ZXh0LmdldFN0b3JlKCk7XG5cbiAgaWYgKCFjdHgpIHtcbiAgICAvLyBTdXJmYWNlIHRoZSBidWcgaW5zdGVhZCBvZiBzaWxlbnRseSBTRVQnaW5nIGVtcHR5IEdVQ3MuIFRoZSBkZWZhdWx0XG4gICAgLy8gbW9kZSAoJ3dhcm4nKSBsb2dzIGFuIGFjdGlvbmFibGUgdHJhY2Ugc28gdGhlIGJhZCBjYWxsIHNpdGUgaXMgZWFzeVxuICAgIC8vIHRvIGZpbmQ7IHByb2R1Y3Rpb24gZGVwbG95bWVudHMgdGhhdCBoYXZlIGZpbmlzaGVkIHRoZSBhdWRpdCBjYW4gc2V0XG4gICAgLy8gUkxTX0NPTlRFWFRfTU9ERT1zdHJpY3QgdG8gZmFpbC1mYXN0IGF0IHRoZSBjYWxsIHNpdGUgKGJldHRlciBzdGFja1xuICAgIC8vIHRyYWNlIHRoYW4gdGhlIFBvc3RncmVzIFwicGVybWlzc2lvbiBkZW5pZWRcIiB0aGF0IHdvdWxkIG90aGVyd2lzZVxuICAgIC8vIHN1cmZhY2UgZnJvbSBGT1JDRSdkIFJMUykuXG4gICAgY29uc3QgbW9kZSA9IGdldENvbnRleHRNb2RlKCk7XG4gICAgaWYgKG1vZGUgPT09ICdzdHJpY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICd3aXRoVGVuYW50VHggY2FsbGVkIG91dHNpZGUgYSB0ZW5hbnQgc2NvcGUuIFdyYXAgeW91ciBoYW5kbGVyL3dvcmtlciAnXG4gICAgICAgICsgJ2luIHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbiB9LCAuLi4pIGJlZm9yZSBpbnZva2luZyAnXG4gICAgICAgICsgJ2FueSBzZXJ2aWNlIHRoYXQgdG91Y2hlcyBSTFMtZW5mb3JjZWQgdGFibGVzLicsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAobW9kZSA9PT0gJ3dhcm4nKSB7XG4gICAgICAvLyBJbmNsdWRlIGEgc3ludGhldGljIHN0YWNrIHNvIHRoZSBvZmZlbmRpbmcgY2FsbCBzaXRlIGlzIGluIHRoZSBsb2cuXG4gICAgICBsb2dnZXIud2Fybignd2l0aFRlbmFudFR4IGNhbGxlZCBvdXRzaWRlIGEgdGVuYW50IHNjb3BlOyBSTFMgR1VDcyB3aWxsIGJlIGVtcHR5Jywge1xuICAgICAgICBzdGFjazogbmV3IEVycm9yKCd0ZW5hbnQtY29udGV4dCBtaXNzaW5nJykuc3RhY2ssXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvcmdJZCA9IGN0eD8ub3JnSWQgPz8gJyc7XG4gIGNvbnN0IGlzU3VwZXJBZG1pbiA9IGN0eD8uaXNTdXBlckFkbWluID8gJ3RydWUnIDogJ2ZhbHNlJztcblxuICBjb25zdCBzdGF0ZW1lbnRUaW1lb3V0TXMgPSBnZXRTdGF0ZW1lbnRUaW1lb3V0TXMoKTtcblxuICAvLyBUaGlzIHRyYW5zYWN0aW9uIHJ1bnMgb24gdGhlIFBSSU1BUlkgYW5kIG1heSB3cml0ZSwgc28gYW55IGxhdGVyIHJlYWQgaW5cbiAgLy8gdGhpcyByZXF1ZXN0IG11c3Qgc3RheSBvbiB0aGUgcHJpbWFyeSB0b28uIFNldCBiZWZvcmUgdGhlIHRyYW5zYWN0aW9uIG9wZW5zXG4gIC8vIHJhdGhlciB0aGFuIGFmdGVyIGl0IGNvbW1pdHM6IGEgcmVhZCBpc3N1ZWQgY29uY3VycmVudGx5IGZyb20gdGhlIHNhbWVcbiAgLy8gaGFuZGxlciB3b3VsZCBvdGhlcndpc2UgcmFjZSB0aGUgZmxhZy5cbiAgLy9cbiAgLy8gYG1hcmtXcml0dGVuOiBmYWxzZWAgaXMgcGFzc2VkIE9OTFkgYnkgd2l0aFRlbmFudFR4UmVhZCdzIGZhbGxiYWNrIHBhdGgsXG4gIC8vIGFuZCBpdCBpcyBub3QgYW4gb3B0aW1pc2F0aW9uIOKAlCB3aXRob3V0IGl0IHRoZSBmZWF0dXJlIGRlZmVhdHMgaXRzZWxmLiBUaGF0XG4gIC8vIHBhdGggcnVucyBvbiB0aGUgcHJpbWFyeSwgc28gaXQgd291bGQgc2V0IHRoaXMgZmxhZywgd2hpY2ggYXBpLXNlcnZlcidzXG4gIC8vIG1pZGRsZXdhcmUgcmVhZHMgYWZ0ZXIgdGhlIHJlc3BvbnNlIHRvIHNldCB0aGUgUmVkaXMgd3JpdGUgcGluLiBBIHB1cmVseVxuICAvLyBSRUFELU9OTFkgcmVxdWVzdCB3b3VsZCB0aGVyZWZvcmUgcGluIGl0cyB3aG9sZSBvcmcgdG8gdGhlIHByaW1hcnkgZm9yIHRoZVxuICAvLyBwaW4gVFRMLCBldmVyeSB0aW1lLCBhbmQgc2luY2UgcmVhZHMgZmFsbCBiYWNrIHdoZW5ldmVyIG5vIHJlcGxpY2EgaXNcbiAgLy8gY29uZmlndXJlZCAodGhlIHNoaXBwaW5nIGRlZmF1bHQpIGV2ZXJ5IG9yZyB3b3VsZCBiZSBwZXJtYW5lbnRseSBwaW5uZWQuXG4gIC8vIFRoZSBmbGFnIG1lYW5zIFwidGhpcyByZXF1ZXN0IG1heSBoYXZlIFdSSVRURU5cIiwgbm90IFwidGhpcyByZXF1ZXN0IHRvdWNoZWRcbiAgLy8gdGhlIHByaW1hcnlcIiwgYW5kIHRoZSBkaWZmZXJlbmNlIGlzIHRoZSB3aG9sZSByZWFkLW9mZmxvYWQgYmVuZWZpdC5cbiAgaWYgKGN0eCAmJiBtYXJrV3JpdHRlbikgY3R4Lm1heUhhdmVXcml0dGVuID0gdHJ1ZTtcblxuICByZXR1cm4gZGIudHJhbnNhY3Rpb24oYXN5bmMgKHR4KSA9PiB7XG4gICAgLy8gU2V0IGV2ZXJ5IHRyYW5zYWN0aW9uLXNjb3BlZCBHVUMgaW4gYSBTSU5HTEUgcm91bmQtdHJpcC4gYHNldF9jb25maWcoKWBcbiAgICAvLyByZXR1cm5zIGl0cyB2YWx1ZSwgc28gbXVsdGlwbGUgY2FsbHMgY29tcG9zZSBpbiBvbmUgU0VMRUNUIHJhdGhlciB0aGFuIGFcbiAgICAvLyByb3VuZC10cmlwIHBlciBHVUMg4oCUIGVhY2ggYSBuZXR3b3JrIGhvcCB0aGF0IHRheGVzIHRoZSBzaGFyZWQgUGdCb3VuY2VyXG4gICAgLy8gcG9vbCBvbiB0aGUgaG90IHBhdGguIGB0cnVlYFxuICAgIC8vID0gaXNfbG9jYWwgKFNFVCBMT0NBTCBzZW1hbnRpY3M6IGF1dG8tcmVsZWFzZWQgb24gQ09NTUlUL1JPTExCQUNLKS4gVGhlXG4gICAgLy8gZHJpdmVyIGJpbmRzIHRoZSB2YWx1ZXMgYXMgcGFyYW1ldGVycywgc28gYSBob3N0aWxlIG9yZ19pZCBjYW4ndCBicmVhayBvdXRcbiAgICAvLyBvZiB0aGUgR1VDIHN5bnRheC5cbiAgICAvL1xuICAgIC8vIFRoZSBzdGF0ZW1lbnRfdGltZW91dCBHVUMgYm91bmRzIGEgcnVuYXdheSBxdWVyeSBzbyBpdCBjYW4ndCBob2xkIGEgcG9vbGVkXG4gICAgLy8gY29ubmVjdGlvbiBvcGVuIGluZGVmaW5pdGVseSAoYFNFVCBMT0NBTCBzdGF0ZW1lbnRfdGltZW91dCA9ICQxYCBpcyByZWplY3RlZFxuICAgIC8vIGJ5IFBvc3RncmVzLCBoZW5jZSBzZXRfY29uZmlnIHdpdGggYSBib3VuZCBtcyB2YWx1ZSkuIEluY2x1ZGVkIGluIHRoZSBzYW1lXG4gICAgLy8gc3RhdGVtZW50IHdoZW4gZW5hYmxlZCAoPjApLCBkcm9wcGVkIGVudGlyZWx5IHdoZW4gZGlzYWJsZWQgKDApLlxuICAgIGlmIChzdGF0ZW1lbnRUaW1lb3V0TXMgPiAwKSB7XG4gICAgICBhd2FpdCB0eC5leGVjdXRlKFxuICAgICAgICBzcWxgU0VMRUNUIHNldF9jb25maWcoJ2FwcC5vcmdfaWQnLCAke29yZ0lkfSwgdHJ1ZSksIHNldF9jb25maWcoJ2FwcC5pc19zeXNhZG1pbicsICR7aXNTdXBlckFkbWlufSwgdHJ1ZSksIHNldF9jb25maWcoJ3N0YXRlbWVudF90aW1lb3V0JywgJHtTdHJpbmcoc3RhdGVtZW50VGltZW91dE1zKX0sIHRydWUpYCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHR4LmV4ZWN1dGUoXG4gICAgICAgIHNxbGBTRUxFQ1Qgc2V0X2NvbmZpZygnYXBwLm9yZ19pZCcsICR7b3JnSWR9LCB0cnVlKSwgc2V0X2NvbmZpZygnYXBwLmlzX3N5c2FkbWluJywgJHtpc1N1cGVyQWRtaW59LCB0cnVlKWAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZm4odHgpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBXaHkgYSByZWFkIHdhcyBvciB3YXMgbm90IHNlbnQgdG8gdGhlIHJlcGxpY2EuIFJldHVybmVkIGJ5XG4gKiB7QGxpbmsgY2hvb3NlUmVhZFRhcmdldH0gc28gdGhlIGRlY2lzaW9uIGlzIGluc3BlY3RhYmxlIOKAlCBhbmQgdGVzdGFibGVcbiAqIHdpdGhvdXQgYSByZXBsaWNhLCB3aGljaCBtYXR0ZXJzIGJlY2F1c2UgdGhlIHRlc3Qgc3Vic3RyYXRlIChQR2xpdGUpIGhhcyBub1xuICogcmVwbGljYXRpb24gYXQgYWxsLlxuICovXG5leHBvcnQgdHlwZSBSZWFkVGFyZ2V0UmVhc29uID1cbiAgLyoqIE5vIHJlcGxpY2EgY29uZmlndXJlZCwgb3IgREJfUkVBRF9FTkFCTEVEPWZhbHNlLiAqL1xuICB8ICduby1yZXBsaWNhJ1xuICAvKiogVGhpcyByZXF1ZXN0IGFscmVhZHkgb3BlbmVkIGEgcHJpbWFyeSB0cmFuc2FjdGlvbiBhbmQgbWF5IGhhdmUgd3JpdHRlbi4gKi9cbiAgfCAnbWF5LWhhdmUtd3JpdHRlbidcbiAgLyoqXG4gICAqIE5vIHRlbmFudCBjb250ZXh0LiBBIGNhbGxlciBvdXRzaWRlIGBydW5XaXRoVGVuYW50Q29udGV4dGAgaGFzIG5vIG9yZyB0b1xuICAgKiBzY29wZSBSTFMgYnkgYW5kIG5vIHdhdGVybWFyayB0byBjb21wYXJlLCBzbyBpdCBnb2VzIHRvIHRoZSBwcmltYXJ5IOKAlCB3aGVyZVxuICAgKiBgd2l0aFRlbmFudFR4YCdzIFJMU19DT05URVhUX01PREUgZ3VhcmQgbG9ncyBvciB0aHJvd3MuIFJvdXRlZCB0byBhIHJlcGxpY2FcbiAgICogaW5zdGVhZCwgdGhlIHNhbWUgY2FsbCB3b3VsZCBzZXQgYGFwcC5vcmdfaWQgPSAnJ2Agd2l0aCBubyBkaWFnbm9zdGljIGF0IGFsbC5cbiAgICovXG4gIHwgJ25vLWNvbnRleHQnXG4gIC8qKlxuICAgKiBBIHJlcGxpY2EgZXhpc3RzIGJ1dCBpdHMgcmVwbGF5IGxhZyBpcyBiZXlvbmQgYERCX1JFQURfTUFYX0xBR19TRUNPTkRTYCxcbiAgICogb3IgaXMgVU5LTk9XTiAobm8gc2FtcGxlIHlldCwgdGhlIHNhbXBsZSBmYWlsZWQsIG9yIHRoZSBjYWNoZWQgc2FtcGxlIGhhc1xuICAgKiBnb25lIHN0YWxlKS4gVW5rbm93biBhbmQgbGFnZ2luZyBhcmUgdGhlIHNhbWUgZGVjaXNpb24gb24gcHVycG9zZTogdGhlXG4gICAqIGNpcmN1aXQgZmFpbHMgY2xvc2VkLlxuICAgKi9cbiAgfCAncmVwbGljYS1sYWdnaW5nJ1xuICAvKiogUm91dGVkIHRvIHRoZSByZXBsaWNhLiAqL1xuICB8ICdyZXBsaWNhJztcblxuZXhwb3J0IGludGVyZmFjZSBSZWFkVGFyZ2V0IHtcbiAgdXNlUmVwbGljYTogYm9vbGVhbjtcbiAgcmVhc29uOiBSZWFkVGFyZ2V0UmVhc29uO1xufVxuXG4vKipcbiAqIERlY2lkZSB3aGVyZSBhIHJlYWQtb25seSB0cmFuc2FjdGlvbiBzaG91bGQgcnVuLlxuICpcbiAqIFB1cmUgYW5kIHNpZGUtZWZmZWN0IGZyZWUgb24gcHVycG9zZTogdGhpcyBpcyB0aGUgd2hvbGUgb2YgdGhlIHJvdXRpbmdcbiAqIHBvbGljeSwgYW5kIGl0IGlzIHRoZSBwYXJ0IHdvcnRoIHRlc3RpbmcuIFJlcGxpY2F0aW9uIGl0c2VsZiBjYW5ub3QgYmVcbiAqIHJlcHJvZHVjZWQgbG9jYWxseSwgc28gdGhlIHRlc3RhYmxlIHVuaXQgaXMgdGhlIERFQ0lTSU9OLCBub3QgdGhlIGxhZy5cbiAqXG4gKiBUaGUgYmlhcyBpcyBkZWxpYmVyYXRlOiBhbnl0aGluZyB1bmNlcnRhaW4gcmVzb2x2ZXMgdG8gdGhlIHByaW1hcnkuIEEgcmVhZFxuICogc2VydmVkIGJ5IHRoZSBwcmltYXJ5IGlzIG1lcmVseSBsZXNzIGVmZmljaWVudDsgYSByZWFkIHNlcnZlZCBieSBhIHN0YWxlXG4gKiByZXBsaWNhIGlzIGEgdXNlci12aXNpYmxlIGJ1ZyBub2JvZHkgY2FuIHJlcHJvZHVjZS5cbiAqL1xuLyoqIEV2ZXJ5dGhpbmcgYWJvdXQgdGhlIHJlcGxpY2EgdGhhdCBpcyBub3QgcmVxdWVzdC1zcGVjaWZpYy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVhZFJlcGxpY2FIZWFsdGgge1xuICAvKiogQSByZXBsaWNhIHBvb2wgZXhpc3RzIEFORCBgREJfUkVBRF9FTkFCTEVEYCBpcyBub3QgZmFsc2UuICovXG4gIGF2YWlsYWJsZTogYm9vbGVhbjtcbiAgLyoqIFRoZSBsYWcgY2lyY3VpdCdzIHZlcmRpY3QuIGB1bmtub3duYCBpcyB0cmVhdGVkIGV4YWN0bHkgbGlrZSBgbGFnZ2luZ2AuICovXG4gIGxhZzogTGFnVmVyZGljdDtcbn1cblxuLyoqXG4gKiBXaGVyZSBhIHJlYWQgZ29lcywgYW5kIHdoeS5cbiAqXG4gKiBTWVNURU0gZ2F0ZXMgYXJlIGNoZWNrZWQgYmVmb3JlIFJFUVVFU1QgZ2F0ZXMsIHdoaWNoIG1hdHRlcnMgb25seSBmb3IgdGhlXG4gKiBleHBsYW5hdGlvbiDigJQgYnV0IHRoZSBleHBsYW5hdGlvbiBpcyB3aGF0IGFuIG9wZXJhdG9yIHJlYWRzIHdoZW4gYXNraW5nIHdoeVxuICogdGhlIHJlcGxpY2EgaXMgaWRsZSwgYW5kIFwibXkgcmVxdWVzdCB3cm90ZVwiIGlzIGEgZmFyIGxlc3MgdXNlZnVsIGFuc3dlciB0aGFuXG4gKiBcInRoZSBzdGFuZGJ5IGlzIDQwIHNlY29uZHMgYmVoaW5kXCIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaG9vc2VSZWFkVGFyZ2V0KGN0eDogVGVuYW50Q29udGV4dCB8IHVuZGVmaW5lZCwgaGVhbHRoOiBSZWFkUmVwbGljYUhlYWx0aCk6IFJlYWRUYXJnZXQge1xuICBpZiAoIWhlYWx0aC5hdmFpbGFibGUpIHJldHVybiB7IHVzZVJlcGxpY2E6IGZhbHNlLCByZWFzb246ICduby1yZXBsaWNhJyB9O1xuICBpZiAoaGVhbHRoLmxhZyAhPT0gJ29rJykgcmV0dXJuIHsgdXNlUmVwbGljYTogZmFsc2UsIHJlYXNvbjogJ3JlcGxpY2EtbGFnZ2luZycgfTtcbiAgaWYgKCFjdHgpIHJldHVybiB7IHVzZVJlcGxpY2E6IGZhbHNlLCByZWFzb246ICduby1jb250ZXh0JyB9O1xuICBpZiAoY3R4Lm1heUhhdmVXcml0dGVuKSByZXR1cm4geyB1c2VSZXBsaWNhOiBmYWxzZSwgcmVhc29uOiAnbWF5LWhhdmUtd3JpdHRlbicgfTtcbiAgcmV0dXJuIHsgdXNlUmVwbGljYTogdHJ1ZSwgcmVhc29uOiAncmVwbGljYScgfTtcbn1cblxuLyoqXG4gKiBPcGVuIGEgUkVBRC1PTkxZIHRyYW5zYWN0aW9uIHdpdGggdGhlIHNhbWUgUkxTIEdVQ3MgYHdpdGhUZW5hbnRUeGAgc2V0cyxcbiAqIHJvdXRlZCB0byB0aGUgcmVwbGljYSB3aGVuIHtAbGluayBjaG9vc2VSZWFkVGFyZ2V0fSBhbGxvd3MgaXQuXG4gKlxuICogYFNFVCBUUkFOU0FDVElPTiBSRUFEIE9OTFlgIGlzIHRoZSBndWFyZHJhaWwsIG5vdCBkZWNvcmF0aW9uLiBTZXZlcmFsIHF1ZXJpZXNcbiAqIGluIHRoaXMgY29kZWJhc2UgbG9vayBsaWtlIHJlYWRzIGF0IHRoZSBjYWxsIHNpdGUgYW5kIGFyZSBub3Qg4oCUXG4gKiBgU0VMRUNUIOKApiBGT1IgVVBEQVRFYCBpbiBjcnVkLXNlcnZpY2UncyBzZXREZWZhdWx0LCBgcGdfYWR2aXNvcnlfeGFjdF9sb2NrYFxuICogaW4gcGlwZWxpbmUtc2VydmljZSBhbmQgY29tcGxpYW5jZSdzIHN1YnNjcmlwdGlvbi1zZXJ2aWNlLiBSb3V0ZWQgdG8gYVxuICogc3RhbmRieSB0aG9zZSBmYWlsIGFueXdheTsgZGVjbGFyaW5nIHRoZSB0cmFuc2FjdGlvbiByZWFkLW9ubHkgbWFrZXMgdGhlbVxuICogZmFpbCBIRVJFLCB3aXRoIGEgY2xlYXIgbWVzc2FnZSwgaW5jbHVkaW5nIG9uIHRoZSBwcmltYXJ5IHdoZXJlIHRoZXkgd291bGRcbiAqIG90aGVyd2lzZSBzdWNjZWVkIGFuZCBxdWlldGx5IGFjcXVpcmUgYSBsb2NrIHRoZSBjYWxsZXIgZGlkIG5vdCBpbnRlbmQuXG4gKlxuICogRmFsbHMgYmFjayB0byB0aGUgcHJpbWFyeSB0cmFuc3BhcmVudGx5LCBzbyBhIGNhbGxlciBuZXZlciBoYXMgdG8gYXNrXG4gKiB3aGV0aGVyIGEgcmVwbGljYSBleGlzdHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3aXRoVGVuYW50VHhSZWFkPFQ+KFxuICBmbjogKHR4OiBQYXJhbWV0ZXJzPFBhcmFtZXRlcnM8dHlwZW9mIGRiLnRyYW5zYWN0aW9uPlswXT5bMF0pID0+IFByb21pc2U8VD4sXG4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgY3R4ID0gdGVuYW50Q29udGV4dC5nZXRTdG9yZSgpO1xuICBjb25zdCByZWFkRGIgPSBnZXRSZWFkRGIoKTtcbiAgY29uc3QgcmVhZFBvb2wgPSBnZXRSZWFkUG9vbCgpO1xuXG4gIC8vIEtlZXAgdGhlIGxhZyBzYW1wbGUgd2FybS4gRmlyZS1hbmQtZm9yZ2V0IGJ5IGRlc2lnbjogaXQgaXMgZGVib3VuY2VkIHRvXG4gIC8vIERCX1JFQURfTEFHX1NBTVBMRV9NUywgbmV2ZXIgdGhyb3dzLCBhbmQgbXVzdCBub3QgYWRkIGEgcm91bmQtdHJpcCB0byB0aGlzXG4gIC8vIHJlYWQuIFRoZSBmaXJzdCByZWFkIG9mIGEgcHJvY2VzcyB0aGVyZWZvcmUgcm91dGVzIHRvIHRoZSBwcmltYXJ5IChub1xuICAvLyBzYW1wbGUgeWV0KSBhbmQgd2FybXMgdGhlIGNpcmN1aXQgZm9yIHRoZSBvbmVzIGFmdGVyIGl0LlxuICBpZiAocmVhZFBvb2wpIHZvaWQgbWF5YmVTYW1wbGVMYWcocmVhZFBvb2wpO1xuXG4gIGNvbnN0IHRhcmdldCA9IGNob29zZVJlYWRUYXJnZXQoY3R4LCB7IGF2YWlsYWJsZTogcmVhZERiICE9PSBudWxsLCBsYWc6IGxhZ1ZlcmRpY3QoKSB9KTtcbiAgZW1pdENvdW50ZXIoJ3Bvc3RncmVzX3JlYWRfcm91dGVkX3RvdGFsJywgeyB0YXJnZXQ6IHRhcmdldC51c2VSZXBsaWNhID8gJ3JlcGxpY2EnIDogJ3ByaW1hcnknLCByZWFzb246IHRhcmdldC5yZWFzb24gfSk7XG5cbiAgaWYgKCF0YXJnZXQudXNlUmVwbGljYSkge1xuICAgIC8vIFByaW1hcnkgcGF0aDogaWRlbnRpY2FsIHNlbWFudGljcyB0byB3aXRoVGVuYW50VHgsIHBsdXMgdGhlIHJlYWQtb25seVxuICAgIC8vIGRlY2xhcmF0aW9uIHNvIGFuIGFjY2lkZW50YWwgd3JpdGUgaXMgY2F1Z2h0IG9uIGV2ZXJ5IHRhcmdldCDigJQgaW5jbHVkaW5nXG4gICAgLy8gdGhlIG9uZXMgdGhhdCB3aWxsIG5ldmVyIGhhdmUgYSByZXBsaWNhLlxuICAgIHJldHVybiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB7XG4gICAgICBhd2FpdCB0eC5leGVjdXRlKHNxbGBTRVQgVFJBTlNBQ1RJT04gUkVBRCBPTkxZYCk7XG4gICAgICByZXR1cm4gZm4odHgpO1xuICAgIH0sIC8qIG1hcmtXcml0dGVuICovIGZhbHNlKTtcbiAgfVxuXG4gIC8vIE5vbi1udWxsIGJ5IGNvbnN0cnVjdGlvbjogY2hvb3NlUmVhZFRhcmdldCBvbmx5IHJldHVybnMgdXNlUmVwbGljYSBmb3IgYVxuICAvLyBjdHggdGhhdCBleGlzdHMuIFJlYWQgdGhlIEdVQ3Mgb2ZmIGl0IGRpcmVjdGx5IHJhdGhlciB0aGFuIGRlZmF1bHRpbmcgdG9cbiAgLy8gJycg4oCUIGEgZGVmYXVsdCBoZXJlIHdvdWxkIHNpbGVudGx5IHJlLW9wZW4gdGhlIGhvbGUgdGhhdCAnbm8tY29udGV4dCdcbiAgLy8gY2xvc2VzLCBiZWNhdXNlIGFuIGVtcHR5IGFwcC5vcmdfaWQgaXMgYSBWQUxJRC1sb29raW5nIFJMUyBzY29wZS5cbiAgY29uc3QgeyBvcmdJZCB9ID0gY3R4ITtcbiAgY29uc3QgaXNTdXBlckFkbWluID0gY3R4IS5pc1N1cGVyQWRtaW4gPyAndHJ1ZScgOiAnZmFsc2UnO1xuICBjb25zdCBzdGF0ZW1lbnRUaW1lb3V0TXMgPSBnZXRTdGF0ZW1lbnRUaW1lb3V0TXMoKTtcblxuICByZXR1cm4gcmVhZERiIS50cmFuc2FjdGlvbihhc3luYyAodHgpID0+IHtcbiAgICBhd2FpdCB0eC5leGVjdXRlKHNxbGBTRVQgVFJBTlNBQ1RJT04gUkVBRCBPTkxZYCk7XG4gICAgaWYgKHN0YXRlbWVudFRpbWVvdXRNcyA+IDApIHtcbiAgICAgIGF3YWl0IHR4LmV4ZWN1dGUoXG4gICAgICAgIHNxbGBTRUxFQ1Qgc2V0X2NvbmZpZygnYXBwLm9yZ19pZCcsICR7b3JnSWR9LCB0cnVlKSwgc2V0X2NvbmZpZygnYXBwLmlzX3N5c2FkbWluJywgJHtpc1N1cGVyQWRtaW59LCB0cnVlKSwgc2V0X2NvbmZpZygnc3RhdGVtZW50X3RpbWVvdXQnLCAke1N0cmluZyhzdGF0ZW1lbnRUaW1lb3V0TXMpfSwgdHJ1ZSlgLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdHguZXhlY3V0ZShcbiAgICAgICAgc3FsYFNFTEVDVCBzZXRfY29uZmlnKCdhcHAub3JnX2lkJywgJHtvcmdJZH0sIHRydWUpLCBzZXRfY29uZmlnKCdhcHAuaXNfc3lzYWRtaW4nLCAke2lzU3VwZXJBZG1pbn0sIHRydWUpYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBmbih0eCk7XG4gIH0pO1xufVxuIl19
|
|
250
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW5jeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhYmFzZS90ZW5hbmN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBRUgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDL0UsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFFNUUsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFlOUMsU0FBUyxjQUFjO0lBQ3JCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDeEQsSUFBSSxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxNQUFNLElBQUksR0FBRyxLQUFLLFFBQVE7UUFBRSxPQUFPLEdBQUcsQ0FBQztJQUN2RSx1RUFBdUU7SUFDdkUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0FBQ25FLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMscUJBQXFCO0lBQzVCLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSxNQUFNLENBQUMs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QUNkLEdBQUcsQ0FBQSxtQ0FBbUMsS0FBSywwQ0FBMEMsWUFBWSw0Q0FBNEMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FDakwsQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxFQUFFLENBQUMsT0FBTyxDQUNkLEdBQUcsQ0FBQSxtQ0FBbUMsS0FBSywwQ0FBMEMsWUFBWSxTQUFTLENBQzNHLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDaEIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogVGVuYW50LWNvbnRleHQgcGx1bWJpbmcgZm9yIFBvc3RncmVzIHJvdy1sZXZlbCBzZWN1cml0eS5cbiAqXG4gKiBCYWNrZ3JvdW5kOiBwb3N0Z3Jlcy1pbml0LnNxbCBpbnN0YWxscyBSTFMgcG9saWNpZXMgb24gZXZlcnkgdXNlci1kYXRhXG4gKiB0YWJsZSB0aGF0IGNvbnN1bHQgdHdvIHNlc3Npb24gR1VDcyDigJQgYGFwcC5vcmdfaWRgIGFuZCBgYXBwLmlzX3N5c2FkbWluYC5cbiAqIEV2ZXJ5IHRlbmFudCB0YWJsZSBpcyBgRk9SQ0UgUk9XIExFVkVMIFNFQ1VSSVRZYCwgc28gdGhlIHBvbGljaWVzIGVuZm9yY2VcbiAqIGV2ZW4gZm9yIHRoZSAob3duaW5nKSBjb25uZWN0aW9uIHVzZXIg4oCUIGEgcXVlcnkgYWdhaW5zdCBvbmUgbXVzdCBydW4gaW5zaWRlIGFcbiAqIHRyYW5zYWN0aW9uIHRoYXQgaGFzIFNFVCBMT0NBTCdkIGJvdGggR1VDcyBvciBpdCByZXR1cm5zIHplcm8gcm93cyBmb3JcbiAqIG5vbi1zeXNhZG1pbnMgKGFuZCBtYXkgZmFpbCB0byB3cml0ZSBmb3IgYW55IGNhbGxlcikuIFRoZSBjcm9zcy1vcmcgcGx1Z2luXG4gKiBlY29zeXN0ZW0gY2F0YWxvZyB0YWJsZXMgY2FycnkgYSBwZXJtaXNzaXZlIGFwcC1yb2xlIHBvbGljeSBpbnN0ZWFkLlxuICpcbiAqIFRoaXMgbW9kdWxlIGlzIHRoZSBzZWFtLlxuICpcbiAqICAgMS4gYHRlbmFudENvbnRleHRgIChBc3luY0xvY2FsU3RvcmFnZSkgY2FycmllcyBge29yZ0lkLCBpc1N1cGVyQWRtaW59YFxuICogICAgICBkb3duIHRoZSBjYWxsIGNoYWluIHdpdGhvdXQgcHJvcC1kcmlsbGluZy4gU2V0IG9uY2UgYXQgdGhlIHJlcXVlc3RcbiAqICAgICAgYm91bmRhcnk7IHJlYWRhYmxlIGZyb20gYW55d2hlcmUuXG4gKlxuICogICAyLiBgd2l0aFRlbmFudFR4KGZuKWAgb3BlbnMgYSB0cmFuc2FjdGlvbiwgU0VUIExPQ0FMJ3MgYm90aCBHVUNzIGZyb21cbiAqICAgICAgdGhlIHN1cnJvdW5kaW5nIGNvbnRleHQsIHRoZW4gaW52b2tlcyBgZm4odHgpYC4gU2VydmljZXMgbWlncmF0ZSBvbmVcbiAqICAgICAgYXQgYSB0aW1lIGJ5IHdyYXBwaW5nIHRoZWlyIGV4aXN0aW5nIGRyaXp6bGUgY2FsbHMgaW4gdGhpcyBoZWxwZXIg4oCUXG4gKiAgICAgIGBkYi5zZWxlY3QoKS5mcm9tKC4uLilgIGJlY29tZXMgYHdpdGhUZW5hbnRUeCh0eCA9PiB0eC5zZWxlY3QoKS5mcm9tKC4uLikpYC5cbiAqXG4gKiAgIDMuIGBydW5XaXRoVGVuYW50Q29udGV4dChjdHgsIGZuKWAgaXMgdGhlIEV4cHJlc3MtbWlkZGxld2FyZS1zaWRlXG4gKiAgICAgIGJvb2tlbmQgdGhhdCBlc3RhYmxpc2hlcyB0aGUgQXN5bmNMb2NhbFN0b3JhZ2Ugc2NvcGUgZm9yIHRoZSByZXF1ZXN0LlxuICpcbiAqIE1pZ3JhdGlvbiBvcmRlcjpcbiAqICAgLSBGaXJzdCBhZG9wdGVyczogbmV3bHktd3JpdHRlbiBzZXJ2aWNlcyAoZGFzaGJvYXJkLCBhbGVydC1kZXN0aW5hdGlvbilcbiAqICAgICB3aGVyZSB0aGUgY2hhbmdlIGlzIG1lY2hhbmljYWwuXG4gKiAgIC0gVGhlbiBoaWdoLXdyaXRlIHNlcnZpY2VzIChwbHVnaW4sIHBpcGVsaW5lKS4gU29hayBlYWNoIG9uZSBiZWZvcmVcbiAqICAgICBmbGlwcGluZyB0aGUgdW5kZXJseWluZyB0YWJsZSB0byBGT1JDRS5cbiAqICAgLSBhZG1pbl9hdWRpdF9sb2cgdXNlcyBhIHN5c2FkbWluLW9ubHkgcG9saWN5IOKAlCBzeXNhZG1pbiBwYXRocyBtdXN0XG4gKiAgICAgYWxzbyBzZXQgYGFwcC5pc19zeXNhZG1pbiA9ICd0cnVlJ2Agb3IgdGhleSdsbCBsb3NlIGFjY2VzcyB0byBpdC5cbiAqL1xuXG5pbXBvcnQgeyBBc3luY0xvY2FsU3RvcmFnZSB9IGZyb20gJ25vZGU6YXN5bmNfaG9va3MnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBlbWl0Q291bnRlciwgZW52SW50IH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgc3FsIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgZGIgfSBmcm9tICcuL3Bvc3RncmVzLWNvbm5lY3Rpb24uanMnO1xuaW1wb3J0IHsgZ2V0UmVhZERiLCBnZXRSZWFkUG9vbCB9IGZyb20gJy4vcmVhZC1jb25uZWN0aW9uLmpzJztcbmltcG9ydCB7IGxhZ1ZlcmRpY3QsIG1heWJlU2FtcGxlTGFnLCB0eXBlIExhZ1ZlcmRpY3QgfSBmcm9tICcuL3JlYWQtbGFnLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCd0ZW5hbnQtY29udGV4dCcpO1xuXG4vKipcbiAqIEJlaGF2aW9yIHdoZW4gYHdpdGhUZW5hbnRUeGAgaXMgaW52b2tlZCBvdXRzaWRlIGFueSBgcnVuV2l0aFRlbmFudENvbnRleHRgXG4gKiBzY29wZS4gVGhlIGVmZmVjdGl2ZSBkZWZhdWx0IGlzIGZhaWwtZmFzdCAoJ3N0cmljdCcpIGluIHByb2R1Y3Rpb24gc28gYVxuICogbWlzc2luZyB0ZW5hbnQgc2NvcGUgc3VyZmFjZXMgYXQgdGhlIGJhZCBjYWxsIHNpdGUgaW5zdGVhZCBvZiBzaWxlbnRseVxuICogcnVubmluZyB3aXRoIGVtcHR5IFJMUyBHVUNzOyBvdXRzaWRlIHByb2R1Y3Rpb24gaXQgZGVmYXVsdHMgdG8gJ3dhcm4nIHNvXG4gKiB1bi1hdWRpdGVkIGRldi90ZXN0IHBhdGhzIGtlZXAgd29ya2luZyBidXQgbG9nIGFuIGFjdGlvbmFibGUgdHJhY2UuIEFuXG4gKiBleHBsaWNpdCBSTFNfQ09OVEVYVF9NT0RFIGVudiBvdmVycmlkZSBhbHdheXMgd2lucy5cbiAqXG4gKiAnc2lsZW50JyBpcyBrZXB0IGZvciB0ZXN0cyBhbmQgc2NyaXB0cyB0aGF0IGludGVudGlvbmFsbHkgZW50ZXIgdGhlIERCXG4gKiB3aXRob3V0IGNvbnRleHQgKGUuZy4gaW50ZWdyYXRpb24gdGVzdCBzZXR1cCB0aGF0IHJ1bnMgYXMgdGhlIGNvbm5lY3Rpb25cbiAqIG93bmVyIGJlZm9yZSBhbnkgdGVuYW50IGlzIHByb3Zpc2lvbmVkKS5cbiAqL1xudHlwZSBDb250ZXh0TW9kZSA9ICdzaWxlbnQnIHwgJ3dhcm4nIHwgJ3N0cmljdCc7XG5mdW5jdGlvbiBnZXRDb250ZXh0TW9kZSgpOiBDb250ZXh0TW9kZSB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LlJMU19DT05URVhUX01PREU/LnRvTG93ZXJDYXNlKCk7XG4gIGlmIChyYXcgPT09ICdzaWxlbnQnIHx8IHJhdyA9PT0gJ3dhcm4nIHx8IHJhdyA9PT0gJ3N0cmljdCcpIHJldHVybiByYXc7XG4gIC8vIE5vIGV4cGxpY2l0IG92ZXJyaWRlOiBmYWlsLWZhc3QgaW4gcHJvZHVjdGlvbiwgd2FybiBldmVyeXdoZXJlIGVsc2UuXG4gIHJldHVybiBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nID8gJ3N0cmljdCcgOiAnd2Fybic7XG59XG5cbi8qKlxuICogUGVyLXN0YXRlbWVudCBzZXJ2ZXItc2lkZSB0aW1lb3V0IChtcykgYXBwbGllZCBJTlNJREUgZXZlcnkgYHdpdGhUZW5hbnRUeGBcbiAqIHRyYW5zYWN0aW9uLCBuZXh0IHRvIHRoZSBSTFMgR1VDcy4gYHdpdGhUZW5hbnRUeGAgaXMgdGhlIHJlYWwgcXVlcnkgcGF0aCBmb3JcbiAqIGFsbCBSTFMvQ1JVRCByZWFkcyBhbmQgd3JpdGVzLCBzbyB0aGlzIGlzIHdoZXJlIHRoZSBEQi1zaWRlIGd1YXJkIGJlbG9uZ3MgKHRoZVxuICogb2xkIGBDb25uZWN0aW9uLnRyYW5zYWN0aW9uYCB3cmFwcGVyIHRoYXQgc2V0IGl0IGlzIGRlYWQg4oCUIHNlZVxuICogcG9zdGdyZXMtY29ubmVjdGlvbi50cykuIEJvdW5kcyBhIHJ1bmF3YXkgcXVlcnkgc28gaXQgY2FuJ3QgaG9sZCBhIHBvb2xlZFxuICogY29ubmVjdGlvbiBvcGVuIGluZGVmaW5pdGVseS4gRW52LWNvbmZpZ3VyYWJsZSB2aWEgYERCX1NUQVRFTUVOVF9USU1FT1VUX01TYFxuICogKGRlZmF1bHQgMzBzKTsgc2V0IHRvIGAwYCB0byBkaXNhYmxlIHRoZSB0aW1lb3V0LlxuICovXG5mdW5jdGlvbiBnZXRTdGF0ZW1lbnRUaW1lb3V0TXMoKTogbnVtYmVyIHtcbiAgY29uc3QgbXMgPSBlbnZJbnQoJ0RCX1NUQVRFTUVOVF9USU1FT1VUX01TJywgMzBfMDAwKTtcbiAgcmV0dXJuIG1zID49IDAgPyBtcyA6IDMwXzAwMDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5hbnRDb250ZXh0IHtcbiAgLyoqIENhbGxlcidzIG9yZy4gVW5kZWZpbmVkIGZvciB1bi1hdXRoZW50aWNhdGVkIC8gc3lzdGVtIGpvYnMuICovXG4gIG9yZ0lkPzogc3RyaW5nO1xuICAvKiogQ2FsbGVyJ3MgdXNlciBpZC4gTm90IHVzZWQgZm9yIFJMUyDigJQgUG9zdGdyZXMgcG9saWNpZXMgYXJlIG9yZy1ncmFpbmVkLFxuICAgKiAgd2l0aCBubyBwZXItdXNlciBzZXNzaW9uIEdVQyDigJQgYnV0IGNhcnJpZWQgc28gYXBwLWxheWVyIHByZWRpY2F0ZXMgd2l0aCBhXG4gICAqICBQRVItVVNFUiBydW5nIChwaXBlbGluZSB0ZW1wbGF0ZXMnIGBwcml2YXRlYCB2aXNpYmlsaXR5KSBjYW4gcmVzb2x2ZSBcIndob1xuICAgKiAgaXMgYXNraW5nXCIgb24gcGF0aHMgdGhhdCBoYXZlIG5vd2hlcmUgdG8gcGFzcyBpdCwgbm90YWJseSBDcnVkU2VydmljZSdzXG4gICAqICBgd3JpdGVDb25kaXRpb25zYC4gQWJzZW50IGZvciBzeXN0ZW0gam9icywgd2hpY2ggaXMgdGhlIGZhaWwtY2xvc2VkIGNhc2U6XG4gICAqICBubyB2aWV3ZXIg4oeSIG5vIHByaXZhdGUgcm93cy4gKi9cbiAgdXNlcklkPzogc3RyaW5nO1xuICAvKiogVHJ1ZSB3aGVuIHRoZSBjYWxsZXIgaXMgYSBzeXNhZG1pbiAoc3lzdGVtLW9yZyBhZG1pbikuIEJ5cGFzc2VzIFJMU1xuICAgKiAgcG9saWNpZXMgdmlhIHRoZSBzeXNhZG1pbi1ieXBhc3MgYnJhbmNoIGluIGBjdXJyZW50X2lzX3N5c2FkbWluKClgLiAqL1xuICBpc1N1cGVyQWRtaW46IGJvb2xlYW47XG4gIC8qKiBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB0aGUgY2FsbGVyJ3MgYWN0aXZlLW9yZyBwYXJlbnQgKHByZXNlbnQgb25seSB3aGVuIHRoZVxuICAgKiAgYWN0aXZlIG9yZyBpcyBhIHRlYW0pLiBOb3QgdXNlZCBmb3IgUkxTOyBjYXJyaWVkIHNvIGRvd25zdHJlYW0gc2lkZS1lZmZlY3RzXG4gICAqICAoZS5nLiBlbnRpdHktZXZlbnQgY29tcGxpYW5jZSBldmFsKSBjYW4gaG9ub3IgcGFyZW50IGBwcm9wYWdhdGVUb0NoaWxkcmVuYFxuICAgKiAgcnVsZXMgd2l0aG91dCBhIHJlcXVlc3QgaW4gc2NvcGUuICovXG4gIHBhcmVudE9yZ0lkPzogc3RyaW5nO1xuICAvKipcbiAgICogU2V0IG9uY2UgdGhpcyByZXF1ZXN0IGhhcyBvcGVuZWQgYSBQUklNQVJZIHRyYW5zYWN0aW9uLCBpLmUuIG1heSBoYXZlXG4gICAqIHdyaXR0ZW4uIFN1YnNlcXVlbnQgYHdpdGhUZW5hbnRUeFJlYWRgIGNhbGxzIGluIHRoZSBzYW1lIHJlcXVlc3QgdGhlbiBnbyB0b1xuICAgKiB0aGUgcHJpbWFyeSB0b28sIHNvIGEgaGFuZGxlciBjYW5ub3QgcmVhZCBpdHMgb3duIHdyaXRlIG9mZiBhIHJlcGxpY2EgdGhhdFxuICAgKiBoYXMgbm90IHJlcGxheWVkIGl0IHlldC5cbiAgICpcbiAgICogRGVsaWJlcmF0ZWx5IHNldCBieSBgd2l0aFRlbmFudFR4YCByYXRoZXIgdGhhbiBieSB3cml0ZSBjYWxsIHNpdGVzOiB0aGF0XG4gICAqIHBhdGggaXMgdGhlIG9uZSB0aGF0IGNhbiB3cml0ZSwgaXQgbmVlZHMgbm8gcGVyLWNhbGwtc2l0ZSBkaXNjaXBsaW5lLCBhbmRcbiAgICogYmVpbmcgd3JvbmcgaW4gdGhpcyBkaXJlY3Rpb24gb25seSBjb3N0cyBhIHJlcGxpY2EgaGl0LiBNdXRhdGVkIGluIHBsYWNlIG9uXG4gICAqIHRoZSBBc3luY0xvY2FsU3RvcmFnZSBzdG9yZSDigJQgdGhlIHN0b3JlIGlzIHBlci1yZXF1ZXN0LCBzbyB0aGlzIGNhbm5vdCBsZWFrXG4gICAqIGJldHdlZW4gcmVxdWVzdHMuXG4gICAqXG4gICAqIFNDT1BFOiB0aGlzIGZsYWcgY292ZXJzIHJlYWRzIEFGVEVSIGEgd3JpdGUgSU4gVEhFIFNBTUUgUkVRVUVTVC4gVGhlXG4gICAqIG5leHQtcmVxdWVzdCBjYXNlIChQT1NULCB0aGVuIGEgcGFnZSByZWxvYWQgaXNzdWluZyBHRVQpIG5lZWRzIHNoYXJlZCBzdGF0ZVxuICAgKiBhbmQgaXMgaGFuZGxlZCBieSBhcGktc2VydmVyJ3MgYHdyaXRlLXBpbi50c2AsIHdoaWNoIHJlbWVtYmVycyBpbiBSZWRpc1xuICAgKiB0aGF0IGFuIG9yZyB3cm90ZSByZWNlbnRseSBhbmQgUFJFLVNFVFMgdGhpcyBzYW1lIGZsYWcgb24gdGhlIG5leHRcbiAgICogcmVxdWVzdCdzIGNvbnRleHQg4oCUIG9uZSBtZWNoYW5pc20gYW5kIG9uZSBjb2RlIHBhdGggcmF0aGVyIHRoYW4gdHdvLiBJdFxuICAgKiBmYWlscyBjbG9zZWQgKG5vIFJlZGlzLCBvciBhbiB1bnJlYWNoYWJsZSBvbmUsIHJvdXRlcyByZWFkcyB0byB0aGUgcHJpbWFyeSlcbiAgICogYW5kIHNob3J0LWNpcmN1aXRzIGVudGlyZWx5IHdoZW4gbm8gcmVhZCByZXBsaWNhIGlzIGNvbmZpZ3VyZWQuXG4gICAqL1xuICBtYXlIYXZlV3JpdHRlbj86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUGVyLXJlcXVlc3QgdGVuYW50IGNvbnRleHQuIFBvcHVsYXRlZCBieSBFeHByZXNzIG1pZGRsZXdhcmUgb25jZSB0aGUgSldUXG4gKiBpcyB2YWxpZGF0ZWQ7IGNvbnN1bWVkIGJ5IGB3aXRoVGVuYW50VHhgIGFuZCBhbnkgaGVscGVyIHRoYXQgbmVlZHMgdG9cbiAqIGtub3cgXCJ3aG8gaXMgdGhlIGNhbGxlclwiIHdpdGhvdXQgcmUtZGVyaXZpbmcgZnJvbSB0aGUgcmVxdWVzdCBvYmplY3QuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5hbnRDb250ZXh0ID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlPFRlbmFudENvbnRleHQ+KCk7XG5cbi8qKlxuICogUnVuIGBmbmAgaW5zaWRlIHRoZSBnaXZlbiB0ZW5hbnQgc2NvcGUuIFRoZSBBc3luY0xvY2FsU3RvcmFnZSBzY29wZVxuICogc3Vydml2ZXMgYWNyb3NzIGFzeW5jIGJvdW5kYXJpZXMgKFByb21pc2VzLCBzZXRUaW1lb3V0LCBldGMuKSwgc28gYW55XG4gKiBgd2l0aFRlbmFudFR4YCBjYWxsIGluc2lkZSBgZm5gIOKAlCBkaXJlY3RseSBvciB0aHJvdWdoIGFueSBkZXB0aCBvZlxuICogYXN5bmMgaGVscGVycyDigJQgcGlja3MgdXAgYGN0eGAuXG4gKlxuICogV3JhcCBgbmV4dCgpYCBmcm9tIGFuIEV4cHJlc3MgbWlkZGxld2FyZSB0byBlc3RhYmxpc2ggcGVyLXJlcXVlc3Qgc2NvcGU6XG4gKlxuICogICAgIGFwcC51c2UoKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gKiAgICAgICBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW4gfSwgKCkgPT4gbmV4dCgpKTtcbiAqICAgICB9KTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ1bldpdGhUZW5hbnRDb250ZXh0PFQ+KGN0eDogVGVuYW50Q29udGV4dCwgZm46ICgpID0+IFQpOiBUIHtcbiAgcmV0dXJuIHRlbmFudENvbnRleHQucnVuKGN0eCwgZm4pO1xufVxuXG4vKiogUmVhZCB0aGUgY3VycmVudCB0ZW5hbnQgY29udGV4dC4gUmV0dXJucyB1bmRlZmluZWQgb3V0c2lkZSBhblxuICogIGBydW5XaXRoVGVuYW50Q29udGV4dGAgc2NvcGUgKGUuZy4gYmFja2dyb3VuZCB3b3JrZXJzLCBtaWdyYXRpb25zKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUZW5hbnRDb250ZXh0KCk6IFRlbmFudENvbnRleHQgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdGVuYW50Q29udGV4dC5nZXRTdG9yZSgpO1xufVxuXG4vKipcbiAqIE9wZW4gYSB0cmFuc2FjdGlvbiB3aXRoIFJMUyBHVUNzIFNFVCBMT0NBTCBmcm9tIHRoZSBjdXJyZW50XG4gKiBBc3luY0xvY2FsU3RvcmFnZSB0ZW5hbnQgY29udGV4dCwgdGhlbiBpbnZva2UgYGZuKHR4KWAuXG4gKlxuICogLSBXaGVuIGNhbGxlZCBvdXRzaWRlIGEgdGVuYW50IHNjb3BlIChlLmcuIGZyb20gYSBiYWNrZ3JvdW5kIGpvYiB0aGF0XG4gKiAgIGRvZXNuJ3QgaGF2ZSBhIGNhbGxlciBpZGVudGl0eSksIHRoZSB0cmFuc2FjdGlvbiBpcyBvcGVuZWQgd2l0aCBib3RoXG4gKiAgIEdVQ3MgY2xlYXJlZCDigJQgUkxTIHBvbGljaWVzIHdpbGwgcmV0dXJuIHplcm8gcm93cyBvbiBGT1JDRSdkIHRhYmxlcy5cbiAqICAgQ2FsbGVycyB0aGF0IG5lZWQgYSBzeXNhZG1pbi1lcXVpdmFsZW50IHNjb3BlIHNob3VsZCB3cmFwIHRoZW1zZWx2ZXMgaW5cbiAqICAgYHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIOKApilgIGV4cGxpY2l0bHkuXG4gKlxuICogLSBVc2VzIGBzZXRfY29uZmlnKGtleSwgdmFsdWUsIHRydWUpYCAodGhlIGJvb2xlYW4gPSBgaXNfbG9jYWxgLCBpLmUuXG4gKiAgIHRyYW5zYWN0aW9uLXNjb3BlZCkuIEVxdWl2YWxlbnQgdG8gYFNFVCBMT0NBTGAgYnV0IHRha2VzIHRoZSB2YWx1ZSBhc1xuICogICBhIHBhcmFtZXRlciwgd2hpY2ggaXMgd2hhdCB3ZSB3YW50IOKAlCBEcml6emxlJ3MgYHNxbGAgdGVtcGxhdGUgYmluZHMgdGhlXG4gKiAgIHZhbHVlIHNhZmVseSBzbyBhbiBhdHRhY2tlci1jb250cm9sbGVkIGBvcmdJZGAgY2FuJ3QgZXNjYXBlIHRoZSBxdW90aW5nLlxuICpcbiAqIC0gUmV0dXJucyB3aGF0ZXZlciBgZm5gIHJldHVybnM7IHRocm93cyB3aGF0ZXZlciBgZm5gIHRocm93cyAoRHJpenpsZVxuICogICBoYW5kbGVzIHRoZSBDT01NSVQvUk9MTEJBQ0sgZm9yIHVzKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhUZW5hbnRUeDxUPihcbiAgZm46ICh0eDogUGFyYW1ldGVyczxQYXJhbWV0ZXJzPHR5cGVvZiBkYi50cmFuc2FjdGlvbj5bMF0+WzBdKSA9PiBQcm9taXNlPFQ+LFxuICAvKipcbiAgICogSU5URVJOQUwuIFdoZXRoZXIgdGhpcyB0cmFuc2FjdGlvbiBzaG91bGQgbWFyayB0aGUgcmVxdWVzdCBhcyBwb3NzaWJseVxuICAgKiBoYXZpbmcgd3JpdHRlbi4gQWx3YXlzIHRydWUgZm9yIGEgcmVhbCBjYWxsZXI7IG9ubHkgd2l0aFRlbmFudFR4UmVhZCdzXG4gICAqIHByaW1hcnktZmFsbGJhY2sgcGF0aCBwYXNzZXMgZmFsc2UsIGJlY2F1c2UgYSByZWFkIHRoYXQgbGFuZHMgb24gdGhlXG4gICAqIHByaW1hcnkgaGFzIG5vdCB3cml0dGVuLiBTZWUgdGhlIGNvbW1lbnQgYXQgdGhlIGFzc2lnbm1lbnQgYmVsb3cuXG4gICAqL1xuICBtYXJrV3JpdHRlbiA9IHRydWUsXG4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgY3R4ID0gdGVuYW50Q29udGV4dC5nZXRTdG9yZSgpO1xuXG4gIGlmICghY3R4KSB7XG4gICAgLy8gU3VyZmFjZSB0aGUgYnVnIGluc3RlYWQgb2Ygc2lsZW50bHkgU0VUJ2luZyBlbXB0eSBHVUNzLiBUaGUgZGVmYXVsdFxuICAgIC8vIG1vZGUgKCd3YXJuJykgbG9ncyBhbiBhY3Rpb25hYmxlIHRyYWNlIHNvIHRoZSBiYWQgY2FsbCBzaXRlIGlzIGVhc3lcbiAgICAvLyB0byBmaW5kOyBwcm9kdWN0aW9uIGRlcGxveW1lbnRzIHRoYXQgaGF2ZSBmaW5pc2hlZCB0aGUgYXVkaXQgY2FuIHNldFxuICAgIC8vIFJMU19DT05URVhUX01PREU9c3RyaWN0IHRvIGZhaWwtZmFzdCBhdCB0aGUgY2FsbCBzaXRlIChiZXR0ZXIgc3RhY2tcbiAgICAvLyB0cmFjZSB0aGFuIHRoZSBQb3N0Z3JlcyBcInBlcm1pc3Npb24gZGVuaWVkXCIgdGhhdCB3b3VsZCBvdGhlcndpc2VcbiAgICAvLyBzdXJmYWNlIGZyb20gRk9SQ0UnZCBSTFMpLlxuICAgIGNvbnN0IG1vZGUgPSBnZXRDb250ZXh0TW9kZSgpO1xuICAgIGlmIChtb2RlID09PSAnc3RyaWN0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnd2l0aFRlbmFudFR4IGNhbGxlZCBvdXRzaWRlIGEgdGVuYW50IHNjb3BlLiBXcmFwIHlvdXIgaGFuZGxlci93b3JrZXIgJ1xuICAgICAgICArICdpbiBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW4gfSwgLi4uKSBiZWZvcmUgaW52b2tpbmcgJ1xuICAgICAgICArICdhbnkgc2VydmljZSB0aGF0IHRvdWNoZXMgUkxTLWVuZm9yY2VkIHRhYmxlcy4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKG1vZGUgPT09ICd3YXJuJykge1xuICAgICAgLy8gSW5jbHVkZSBhIHN5bnRoZXRpYyBzdGFjayBzbyB0aGUgb2ZmZW5kaW5nIGNhbGwgc2l0ZSBpcyBpbiB0aGUgbG9nLlxuICAgICAgbG9nZ2VyLndhcm4oJ3dpdGhUZW5hbnRUeCBjYWxsZWQgb3V0c2lkZSBhIHRlbmFudCBzY29wZTsgUkxTIEdVQ3Mgd2lsbCBiZSBlbXB0eScsIHtcbiAgICAgICAgc3RhY2s6IG5ldyBFcnJvcigndGVuYW50LWNvbnRleHQgbWlzc2luZycpLnN0YWNrLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb3JnSWQgPSBjdHg/Lm9yZ0lkID8/ICcnO1xuICBjb25zdCBpc1N1cGVyQWRtaW4gPSBjdHg/LmlzU3VwZXJBZG1pbiA/ICd0cnVlJyA6ICdmYWxzZSc7XG5cbiAgY29uc3Qgc3RhdGVtZW50VGltZW91dE1zID0gZ2V0U3RhdGVtZW50VGltZW91dE1zKCk7XG5cbiAgLy8gVGhpcyB0cmFuc2FjdGlvbiBydW5zIG9uIHRoZSBQUklNQVJZIGFuZCBtYXkgd3JpdGUsIHNvIGFueSBsYXRlciByZWFkIGluXG4gIC8vIHRoaXMgcmVxdWVzdCBtdXN0IHN0YXkgb24gdGhlIHByaW1hcnkgdG9vLiBTZXQgYmVmb3JlIHRoZSB0cmFuc2FjdGlvbiBvcGVuc1xuICAvLyByYXRoZXIgdGhhbiBhZnRlciBpdCBjb21taXRzOiBhIHJlYWQgaXNzdWVkIGNvbmN1cnJlbnRseSBmcm9tIHRoZSBzYW1lXG4gIC8vIGhhbmRsZXIgd291bGQgb3RoZXJ3aXNlIHJhY2UgdGhlIGZsYWcuXG4gIC8vXG4gIC8vIGBtYXJrV3JpdHRlbjogZmFsc2VgIGlzIHBhc3NlZCBPTkxZIGJ5IHdpdGhUZW5hbnRUeFJlYWQncyBmYWxsYmFjayBwYXRoLFxuICAvLyBhbmQgaXQgaXMgbm90IGFuIG9wdGltaXNhdGlvbiDigJQgd2l0aG91dCBpdCB0aGUgZmVhdHVyZSBkZWZlYXRzIGl0c2VsZi4gVGhhdFxuICAvLyBwYXRoIHJ1bnMgb24gdGhlIHByaW1hcnksIHNvIGl0IHdvdWxkIHNldCB0aGlzIGZsYWcsIHdoaWNoIGFwaS1zZXJ2ZXInc1xuICAvLyBtaWRkbGV3YXJlIHJlYWRzIGFmdGVyIHRoZSByZXNwb25zZSB0byBzZXQgdGhlIFJlZGlzIHdyaXRlIHBpbi4gQSBwdXJlbHlcbiAgLy8gUkVBRC1PTkxZIHJlcXVlc3Qgd291bGQgdGhlcmVmb3JlIHBpbiBpdHMgd2hvbGUgb3JnIHRvIHRoZSBwcmltYXJ5IGZvciB0aGVcbiAgLy8gcGluIFRUTCwgZXZlcnkgdGltZSwgYW5kIHNpbmNlIHJlYWRzIGZhbGwgYmFjayB3aGVuZXZlciBubyByZXBsaWNhIGlzXG4gIC8vIGNvbmZpZ3VyZWQgKHRoZSBzaGlwcGluZyBkZWZhdWx0KSBldmVyeSBvcmcgd291bGQgYmUgcGVybWFuZW50bHkgcGlubmVkLlxuICAvLyBUaGUgZmxhZyBtZWFucyBcInRoaXMgcmVxdWVzdCBtYXkgaGF2ZSBXUklUVEVOXCIsIG5vdCBcInRoaXMgcmVxdWVzdCB0b3VjaGVkXG4gIC8vIHRoZSBwcmltYXJ5XCIsIGFuZCB0aGUgZGlmZmVyZW5jZSBpcyB0aGUgd2hvbGUgcmVhZC1vZmZsb2FkIGJlbmVmaXQuXG4gIGlmIChjdHggJiYgbWFya1dyaXR0ZW4pIGN0eC5tYXlIYXZlV3JpdHRlbiA9IHRydWU7XG5cbiAgcmV0dXJuIGRiLnRyYW5zYWN0aW9uKGFzeW5jICh0eCkgPT4ge1xuICAgIC8vIFNldCBldmVyeSB0cmFuc2FjdGlvbi1zY29wZWQgR1VDIGluIGEgU0lOR0xFIHJvdW5kLXRyaXAuIGBzZXRfY29uZmlnKClgXG4gICAgLy8gcmV0dXJucyBpdHMgdmFsdWUsIHNvIG11bHRpcGxlIGNhbGxzIGNvbXBvc2UgaW4gb25lIFNFTEVDVCByYXRoZXIgdGhhbiBhXG4gICAgLy8gcm91bmQtdHJpcCBwZXIgR1VDIOKAlCBlYWNoIGEgbmV0d29yayBob3AgdGhhdCB0YXhlcyB0aGUgc2hhcmVkIFBnQm91bmNlclxuICAgIC8vIHBvb2wgb24gdGhlIGhvdCBwYXRoLiBgdHJ1ZWBcbiAgICAvLyA9IGlzX2xvY2FsIChTRVQgTE9DQUwgc2VtYW50aWNzOiBhdXRvLXJlbGVhc2VkIG9uIENPTU1JVC9ST0xMQkFDSykuIFRoZVxuICAgIC8vIGRyaXZlciBiaW5kcyB0aGUgdmFsdWVzIGFzIHBhcmFtZXRlcnMsIHNvIGEgaG9zdGlsZSBvcmdfaWQgY2FuJ3QgYnJlYWsgb3V0XG4gICAgLy8gb2YgdGhlIEdVQyBzeW50YXguXG4gICAgLy9cbiAgICAvLyBUaGUgc3RhdGVtZW50X3RpbWVvdXQgR1VDIGJvdW5kcyBhIHJ1bmF3YXkgcXVlcnkgc28gaXQgY2FuJ3QgaG9sZCBhIHBvb2xlZFxuICAgIC8vIGNvbm5lY3Rpb24gb3BlbiBpbmRlZmluaXRlbHkgKGBTRVQgTE9DQUwgc3RhdGVtZW50X3RpbWVvdXQgPSAkMWAgaXMgcmVqZWN0ZWRcbiAgICAvLyBieSBQb3N0Z3JlcywgaGVuY2Ugc2V0X2NvbmZpZyB3aXRoIGEgYm91bmQgbXMgdmFsdWUpLiBJbmNsdWRlZCBpbiB0aGUgc2FtZVxuICAgIC8vIHN0YXRlbWVudCB3aGVuIGVuYWJsZWQgKD4wKSwgZHJvcHBlZCBlbnRpcmVseSB3aGVuIGRpc2FibGVkICgwKS5cbiAgICBpZiAoc3RhdGVtZW50VGltZW91dE1zID4gMCkge1xuICAgICAgYXdhaXQgdHguZXhlY3V0ZShcbiAgICAgICAgc3FsYFNFTEVDVCBzZXRfY29uZmlnKCdhcHAub3JnX2lkJywgJHtvcmdJZH0sIHRydWUpLCBzZXRfY29uZmlnKCdhcHAuaXNfc3lzYWRtaW4nLCAke2lzU3VwZXJBZG1pbn0sIHRydWUpLCBzZXRfY29uZmlnKCdzdGF0ZW1lbnRfdGltZW91dCcsICR7U3RyaW5nKHN0YXRlbWVudFRpbWVvdXRNcyl9LCB0cnVlKWAsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCB0eC5leGVjdXRlKFxuICAgICAgICBzcWxgU0VMRUNUIHNldF9jb25maWcoJ2FwcC5vcmdfaWQnLCAke29yZ0lkfSwgdHJ1ZSksIHNldF9jb25maWcoJ2FwcC5pc19zeXNhZG1pbicsICR7aXNTdXBlckFkbWlufSwgdHJ1ZSlgLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGZuKHR4KTtcbiAgfSk7XG59XG5cbi8qKlxuICogV2h5IGEgcmVhZCB3YXMgb3Igd2FzIG5vdCBzZW50IHRvIHRoZSByZXBsaWNhLiBSZXR1cm5lZCBieVxuICoge0BsaW5rIGNob29zZVJlYWRUYXJnZXR9IHNvIHRoZSBkZWNpc2lvbiBpcyBpbnNwZWN0YWJsZSDigJQgYW5kIHRlc3RhYmxlXG4gKiB3aXRob3V0IGEgcmVwbGljYSwgd2hpY2ggbWF0dGVycyBiZWNhdXNlIHRoZSB0ZXN0IHN1YnN0cmF0ZSAoUEdsaXRlKSBoYXMgbm9cbiAqIHJlcGxpY2F0aW9uIGF0IGFsbC5cbiAqL1xuZXhwb3J0IHR5cGUgUmVhZFRhcmdldFJlYXNvbiA9XG4gIC8qKiBObyByZXBsaWNhIGNvbmZpZ3VyZWQsIG9yIERCX1JFQURfRU5BQkxFRD1mYWxzZS4gKi9cbiAgfCAnbm8tcmVwbGljYSdcbiAgLyoqIFRoaXMgcmVxdWVzdCBhbHJlYWR5IG9wZW5lZCBhIHByaW1hcnkgdHJhbnNhY3Rpb24gYW5kIG1heSBoYXZlIHdyaXR0ZW4uICovXG4gIHwgJ21heS1oYXZlLXdyaXR0ZW4nXG4gIC8qKlxuICAgKiBObyB0ZW5hbnQgY29udGV4dC4gQSBjYWxsZXIgb3V0c2lkZSBgcnVuV2l0aFRlbmFudENvbnRleHRgIGhhcyBubyBvcmcgdG9cbiAgICogc2NvcGUgUkxTIGJ5IGFuZCBubyB3YXRlcm1hcmsgdG8gY29tcGFyZSwgc28gaXQgZ29lcyB0byB0aGUgcHJpbWFyeSDigJQgd2hlcmVcbiAgICogYHdpdGhUZW5hbnRUeGAncyBSTFNfQ09OVEVYVF9NT0RFIGd1YXJkIGxvZ3Mgb3IgdGhyb3dzLiBSb3V0ZWQgdG8gYSByZXBsaWNhXG4gICAqIGluc3RlYWQsIHRoZSBzYW1lIGNhbGwgd291bGQgc2V0IGBhcHAub3JnX2lkID0gJydgIHdpdGggbm8gZGlhZ25vc3RpYyBhdCBhbGwuXG4gICAqL1xuICB8ICduby1jb250ZXh0J1xuICAvKipcbiAgICogQSByZXBsaWNhIGV4aXN0cyBidXQgaXRzIHJlcGxheSBsYWcgaXMgYmV5b25kIGBEQl9SRUFEX01BWF9MQUdfU0VDT05EU2AsXG4gICAqIG9yIGlzIFVOS05PV04gKG5vIHNhbXBsZSB5ZXQsIHRoZSBzYW1wbGUgZmFpbGVkLCBvciB0aGUgY2FjaGVkIHNhbXBsZSBoYXNcbiAgICogZ29uZSBzdGFsZSkuIFVua25vd24gYW5kIGxhZ2dpbmcgYXJlIHRoZSBzYW1lIGRlY2lzaW9uIG9uIHB1cnBvc2U6IHRoZVxuICAgKiBjaXJjdWl0IGZhaWxzIGNsb3NlZC5cbiAgICovXG4gIHwgJ3JlcGxpY2EtbGFnZ2luZydcbiAgLyoqIFJvdXRlZCB0byB0aGUgcmVwbGljYS4gKi9cbiAgfCAncmVwbGljYSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVhZFRhcmdldCB7XG4gIHVzZVJlcGxpY2E6IGJvb2xlYW47XG4gIHJlYXNvbjogUmVhZFRhcmdldFJlYXNvbjtcbn1cblxuLyoqXG4gKiBEZWNpZGUgd2hlcmUgYSByZWFkLW9ubHkgdHJhbnNhY3Rpb24gc2hvdWxkIHJ1bi5cbiAqXG4gKiBQdXJlIGFuZCBzaWRlLWVmZmVjdCBmcmVlIG9uIHB1cnBvc2U6IHRoaXMgaXMgdGhlIHdob2xlIG9mIHRoZSByb3V0aW5nXG4gKiBwb2xpY3ksIGFuZCBpdCBpcyB0aGUgcGFydCB3b3J0aCB0ZXN0aW5nLiBSZXBsaWNhdGlvbiBpdHNlbGYgY2Fubm90IGJlXG4gKiByZXByb2R1Y2VkIGxvY2FsbHksIHNvIHRoZSB0ZXN0YWJsZSB1bml0IGlzIHRoZSBERUNJU0lPTiwgbm90IHRoZSBsYWcuXG4gKlxuICogVGhlIGJpYXMgaXMgZGVsaWJlcmF0ZTogYW55dGhpbmcgdW5jZXJ0YWluIHJlc29sdmVzIHRvIHRoZSBwcmltYXJ5LiBBIHJlYWRcbiAqIHNlcnZlZCBieSB0aGUgcHJpbWFyeSBpcyBtZXJlbHkgbGVzcyBlZmZpY2llbnQ7IGEgcmVhZCBzZXJ2ZWQgYnkgYSBzdGFsZVxuICogcmVwbGljYSBpcyBhIHVzZXItdmlzaWJsZSBidWcgbm9ib2R5IGNhbiByZXByb2R1Y2UuXG4gKi9cbi8qKiBFdmVyeXRoaW5nIGFib3V0IHRoZSByZXBsaWNhIHRoYXQgaXMgbm90IHJlcXVlc3Qtc3BlY2lmaWMuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlYWRSZXBsaWNhSGVhbHRoIHtcbiAgLyoqIEEgcmVwbGljYSBwb29sIGV4aXN0cyBBTkQgYERCX1JFQURfRU5BQkxFRGAgaXMgbm90IGZhbHNlLiAqL1xuICBhdmFpbGFibGU6IGJvb2xlYW47XG4gIC8qKiBUaGUgbGFnIGNpcmN1aXQncyB2ZXJkaWN0LiBgdW5rbm93bmAgaXMgdHJlYXRlZCBleGFjdGx5IGxpa2UgYGxhZ2dpbmdgLiAqL1xuICBsYWc6IExhZ1ZlcmRpY3Q7XG59XG5cbi8qKlxuICogV2hlcmUgYSByZWFkIGdvZXMsIGFuZCB3aHkuXG4gKlxuICogU1lTVEVNIGdhdGVzIGFyZSBjaGVja2VkIGJlZm9yZSBSRVFVRVNUIGdhdGVzLCB3aGljaCBtYXR0ZXJzIG9ubHkgZm9yIHRoZVxuICogZXhwbGFuYXRpb24g4oCUIGJ1dCB0aGUgZXhwbGFuYXRpb24gaXMgd2hhdCBhbiBvcGVyYXRvciByZWFkcyB3aGVuIGFza2luZyB3aHlcbiAqIHRoZSByZXBsaWNhIGlzIGlkbGUsIGFuZCBcIm15IHJlcXVlc3Qgd3JvdGVcIiBpcyBhIGZhciBsZXNzIHVzZWZ1bCBhbnN3ZXIgdGhhblxuICogXCJ0aGUgc3RhbmRieSBpcyA0MCBzZWNvbmRzIGJlaGluZFwiLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hvb3NlUmVhZFRhcmdldChjdHg6IFRlbmFudENvbnRleHQgfCB1bmRlZmluZWQsIGhlYWx0aDogUmVhZFJlcGxpY2FIZWFsdGgpOiBSZWFkVGFyZ2V0IHtcbiAgaWYgKCFoZWFsdGguYXZhaWxhYmxlKSByZXR1cm4geyB1c2VSZXBsaWNhOiBmYWxzZSwgcmVhc29uOiAnbm8tcmVwbGljYScgfTtcbiAgaWYgKGhlYWx0aC5sYWcgIT09ICdvaycpIHJldHVybiB7IHVzZVJlcGxpY2E6IGZhbHNlLCByZWFzb246ICdyZXBsaWNhLWxhZ2dpbmcnIH07XG4gIGlmICghY3R4KSByZXR1cm4geyB1c2VSZXBsaWNhOiBmYWxzZSwgcmVhc29uOiAnbm8tY29udGV4dCcgfTtcbiAgaWYgKGN0eC5tYXlIYXZlV3JpdHRlbikgcmV0dXJuIHsgdXNlUmVwbGljYTogZmFsc2UsIHJlYXNvbjogJ21heS1oYXZlLXdyaXR0ZW4nIH07XG4gIHJldHVybiB7IHVzZVJlcGxpY2E6IHRydWUsIHJlYXNvbjogJ3JlcGxpY2EnIH07XG59XG5cbi8qKlxuICogT3BlbiBhIFJFQUQtT05MWSB0cmFuc2FjdGlvbiB3aXRoIHRoZSBzYW1lIFJMUyBHVUNzIGB3aXRoVGVuYW50VHhgIHNldHMsXG4gKiByb3V0ZWQgdG8gdGhlIHJlcGxpY2Egd2hlbiB7QGxpbmsgY2hvb3NlUmVhZFRhcmdldH0gYWxsb3dzIGl0LlxuICpcbiAqIGBTRVQgVFJBTlNBQ1RJT04gUkVBRCBPTkxZYCBpcyB0aGUgZ3VhcmRyYWlsLCBub3QgZGVjb3JhdGlvbi4gU2V2ZXJhbCBxdWVyaWVzXG4gKiBpbiB0aGlzIGNvZGViYXNlIGxvb2sgbGlrZSByZWFkcyBhdCB0aGUgY2FsbCBzaXRlIGFuZCBhcmUgbm90IOKAlFxuICogYFNFTEVDVCDigKYgRk9SIFVQREFURWAgaW4gY3J1ZC1zZXJ2aWNlJ3Mgc2V0RGVmYXVsdCwgYHBnX2Fkdmlzb3J5X3hhY3RfbG9ja2BcbiAqIGluIHBpcGVsaW5lLXNlcnZpY2UgYW5kIGNvbXBsaWFuY2UncyBzdWJzY3JpcHRpb24tc2VydmljZS4gUm91dGVkIHRvIGFcbiAqIHN0YW5kYnkgdGhvc2UgZmFpbCBhbnl3YXk7IGRlY2xhcmluZyB0aGUgdHJhbnNhY3Rpb24gcmVhZC1vbmx5IG1ha2VzIHRoZW1cbiAqIGZhaWwgSEVSRSwgd2l0aCBhIGNsZWFyIG1lc3NhZ2UsIGluY2x1ZGluZyBvbiB0aGUgcHJpbWFyeSB3aGVyZSB0aGV5IHdvdWxkXG4gKiBvdGhlcndpc2Ugc3VjY2VlZCBhbmQgcXVpZXRseSBhY3F1aXJlIGEgbG9jayB0aGUgY2FsbGVyIGRpZCBub3QgaW50ZW5kLlxuICpcbiAqIEZhbGxzIGJhY2sgdG8gdGhlIHByaW1hcnkgdHJhbnNwYXJlbnRseSwgc28gYSBjYWxsZXIgbmV2ZXIgaGFzIHRvIGFza1xuICogd2hldGhlciBhIHJlcGxpY2EgZXhpc3RzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2l0aFRlbmFudFR4UmVhZDxUPihcbiAgZm46ICh0eDogUGFyYW1ldGVyczxQYXJhbWV0ZXJzPHR5cGVvZiBkYi50cmFuc2FjdGlvbj5bMF0+WzBdKSA9PiBQcm9taXNlPFQ+LFxuKTogUHJvbWlzZTxUPiB7XG4gIGNvbnN0IGN0eCA9IHRlbmFudENvbnRleHQuZ2V0U3RvcmUoKTtcbiAgY29uc3QgcmVhZERiID0gZ2V0UmVhZERiKCk7XG4gIGNvbnN0IHJlYWRQb29sID0gZ2V0UmVhZFBvb2woKTtcblxuICAvLyBLZWVwIHRoZSBsYWcgc2FtcGxlIHdhcm0uIEZpcmUtYW5kLWZvcmdldCBieSBkZXNpZ246IGl0IGlzIGRlYm91bmNlZCB0b1xuICAvLyBEQl9SRUFEX0xBR19TQU1QTEVfTVMsIG5ldmVyIHRocm93cywgYW5kIG11c3Qgbm90IGFkZCBhIHJvdW5kLXRyaXAgdG8gdGhpc1xuICAvLyByZWFkLiBUaGUgZmlyc3QgcmVhZCBvZiBhIHByb2Nlc3MgdGhlcmVmb3JlIHJvdXRlcyB0byB0aGUgcHJpbWFyeSAobm9cbiAgLy8gc2FtcGxlIHlldCkgYW5kIHdhcm1zIHRoZSBjaXJjdWl0IGZvciB0aGUgb25lcyBhZnRlciBpdC5cbiAgaWYgKHJlYWRQb29sKSB2b2lkIG1heWJlU2FtcGxlTGFnKHJlYWRQb29sKTtcblxuICBjb25zdCB0YXJnZXQgPSBjaG9vc2VSZWFkVGFyZ2V0KGN0eCwgeyBhdmFpbGFibGU6IHJlYWREYiAhPT0gbnVsbCwgbGFnOiBsYWdWZXJkaWN0KCkgfSk7XG4gIGVtaXRDb3VudGVyKCdwb3N0Z3Jlc19yZWFkX3JvdXRlZF90b3RhbCcsIHsgdGFyZ2V0OiB0YXJnZXQudXNlUmVwbGljYSA/ICdyZXBsaWNhJyA6ICdwcmltYXJ5JywgcmVhc29uOiB0YXJnZXQucmVhc29uIH0pO1xuXG4gIGlmICghdGFyZ2V0LnVzZVJlcGxpY2EpIHtcbiAgICAvLyBQcmltYXJ5IHBhdGg6IGlkZW50aWNhbCBzZW1hbnRpY3MgdG8gd2l0aFRlbmFudFR4LCBwbHVzIHRoZSByZWFkLW9ubHlcbiAgICAvLyBkZWNsYXJhdGlvbiBzbyBhbiBhY2NpZGVudGFsIHdyaXRlIGlzIGNhdWdodCBvbiBldmVyeSB0YXJnZXQg4oCUIGluY2x1ZGluZ1xuICAgIC8vIHRoZSBvbmVzIHRoYXQgd2lsbCBuZXZlciBoYXZlIGEgcmVwbGljYS5cbiAgICByZXR1cm4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgYXdhaXQgdHguZXhlY3V0ZShzcWxgU0VUIFRSQU5TQUNUSU9OIFJFQUQgT05MWWApO1xuICAgICAgcmV0dXJuIGZuKHR4KTtcbiAgICB9LCAvKiBtYXJrV3JpdHRlbiAqLyBmYWxzZSk7XG4gIH1cblxuICAvLyBOb24tbnVsbCBieSBjb25zdHJ1Y3Rpb246IGNob29zZVJlYWRUYXJnZXQgb25seSByZXR1cm5zIHVzZVJlcGxpY2EgZm9yIGFcbiAgLy8gY3R4IHRoYXQgZXhpc3RzLiBSZWFkIHRoZSBHVUNzIG9mZiBpdCBkaXJlY3RseSByYXRoZXIgdGhhbiBkZWZhdWx0aW5nIHRvXG4gIC8vICcnIOKAlCBhIGRlZmF1bHQgaGVyZSB3b3VsZCBzaWxlbnRseSByZS1vcGVuIHRoZSBob2xlIHRoYXQgJ25vLWNvbnRleHQnXG4gIC8vIGNsb3NlcywgYmVjYXVzZSBhbiBlbXB0eSBhcHAub3JnX2lkIGlzIGEgVkFMSUQtbG9va2luZyBSTFMgc2NvcGUuXG4gIGNvbnN0IHsgb3JnSWQgfSA9IGN0eCE7XG4gIGNvbnN0IGlzU3VwZXJBZG1pbiA9IGN0eCEuaXNTdXBlckFkbWluID8gJ3RydWUnIDogJ2ZhbHNlJztcbiAgY29uc3Qgc3RhdGVtZW50VGltZW91dE1zID0gZ2V0U3RhdGVtZW50VGltZW91dE1zKCk7XG5cbiAgcmV0dXJuIHJlYWREYiEudHJhbnNhY3Rpb24oYXN5bmMgKHR4KSA9PiB7XG4gICAgYXdhaXQgdHguZXhlY3V0ZShzcWxgU0VUIFRSQU5TQUNUSU9OIFJFQUQgT05MWWApO1xuICAgIGlmIChzdGF0ZW1lbnRUaW1lb3V0TXMgPiAwKSB7XG4gICAgICBhd2FpdCB0eC5leGVjdXRlKFxuICAgICAgICBzcWxgU0VMRUNUIHNldF9jb25maWcoJ2FwcC5vcmdfaWQnLCAke29yZ0lkfSwgdHJ1ZSksIHNldF9jb25maWcoJ2FwcC5pc19zeXNhZG1pbicsICR7aXNTdXBlckFkbWlufSwgdHJ1ZSksIHNldF9jb25maWcoJ3N0YXRlbWVudF90aW1lb3V0JywgJHtTdHJpbmcoc3RhdGVtZW50VGltZW91dE1zKX0sIHRydWUpYCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHR4LmV4ZWN1dGUoXG4gICAgICAgIHNxbGBTRUxFQ1Qgc2V0X2NvbmZpZygnYXBwLm9yZ19pZCcsICR7b3JnSWR9LCB0cnVlKSwgc2V0X2NvbmZpZygnYXBwLmlzX3N5c2FkbWluJywgJHtpc1N1cGVyQWRtaW59LCB0cnVlKWAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZm4odHgpO1xuICB9KTtcbn1cbiJdfQ==
|
package/lib/index.d.ts
CHANGED
|
@@ -30,17 +30,21 @@ export * from './api/crud-service.js';
|
|
|
30
30
|
export { parseSemver, compareSemverParts, compareSemver, isVersionRange, satisfiesVersionSpec, semverOrderBy, } from './api/semver-range.js';
|
|
31
31
|
export { normalizeQuery, searchPublicListings, listPublicCategories, getPublicListing, getPublicListedVersion, listPublicReviews, listPublicListingsForSitemap, type DirectoryTrustTier, type DirectorySort, DIRECTORY_SORTS, DIRECTORY_TIERS, type DirectorySearchParams, type ReviewSort, REVIEW_SORTS, type PublicListingRow, } from './api/public-directory.js';
|
|
32
32
|
export { listEnabledAlertDestinations, type NotificationDestination, } from './api/alert-destinations.js';
|
|
33
|
+
export { anonymizeReviewsByAuthor } from './api/ecosystem-privacy.js';
|
|
34
|
+
export { openSupportCase, findCaseByThread, listQueue, listOrgCases, stampFirstResponse, setCaseStatus, setCaseSeverity, assignCase, assignCases, closeCases, transferCaseToContact, openCasesForContact, SUPPORT_CASE_STATUSES, QUEUE_STATUSES, type SupportCaseStatus, type OpenCaseInput, countActiveSupportContacts, listActiveSupportContacts, isSupportContact, designateSupportContact, revokeSupportContact, countPremiumSupportContacts, isPremiumSupportContact, setSupportContactPremium, countCasesInWindow, rateCase, addCaseNote, listCaseNotes, deleteCaseNote, type SupportCaseNote, listCannedResponses, createCannedResponse, updateCannedResponse, deleteCannedResponse, type CannedResponse, listCasesDueForPage, } from './api/support-cases.js';
|
|
33
35
|
export { policyOf, effectiveConsumptionPolicy, applyPolicyUpdate, type ConsumptionPolicy, DEFAULT_CONSUMPTION_POLICY, } from './api/plugin-consumption-policy.js';
|
|
34
36
|
export { advisoryRangeCovers, advisoryRangeProblem, advisoriesCovering, blockingAdvisories, } from './api/plugin-advisories.js';
|
|
35
|
-
export { listingBlock, implicitInstallRange, installAdmits, scopeOrgIds, installModeFor, drizzleListingSource, resolveListingReference, listedVersionWarnings, listedPluginRecord, loadOrgInstallContext, orgListingStates, resolvableListings, type ResolutionRefusal, type ResolutionScope, type ListingDataSource, type ListingResolved, type OrgListingState, } from './api/plugin-resolution.js';
|
|
37
|
+
export { listingBlock, implicitInstallRange, installAdmits, scopeOrgIds, installModeFor, drizzleListingSource, resolveListingReference, listedVersionWarnings, listedPluginRecord, loadOrgInstallContext, orgListingStates, resolvableListings, type ResolutionRefusal, type ResolutionScope, type ListingDataSource, type ListingResolved, type OrgListingState, vulnUpgradeAvailableWarning, type VulnUpgradeAvailableWarning, } from './api/plugin-resolution.js';
|
|
38
|
+
export { findVersionReferences, distinctPipelines, versionReferencedPredicate, orgImageDigestsInUse, type VersionReferenceTarget, type VersionReference, } from './api/version-references.js';
|
|
39
|
+
export { declaredResolution, recordStepLookup, pipelineStepLookups, declaredPipelinesForPlugin, stageAndStep, stepLabelOf, type DeclaredStepInput, type DeclaredStepPlugin, type DeclaredStepResolution, type StepLookupRecord, type DeclaredPipelineRef, } from './api/pipeline-step-resolution.js';
|
|
36
40
|
export { runSoftDeletePurge, createSoftDeletePurgeScheduler, type PurgeableEntity, } from './api/soft-delete-sweep.js';
|
|
37
|
-
export { type BuildHealth, type DoraLevel, type DoraMetrics, type DoraOptions, type DoraTrendPoint, type IncidentListItem, type ReportingSettings, type IncidentTestResult, type IngestCaller, type IngestMetric, type LastDeployedCommit, } from './api/reporting-service.js';
|
|
41
|
+
export { type BuildHealth, type DoraLevel, type DoraMetrics, type DoraOptions, type DoraTrendPoint, type DeploymentOutcomeWrite, type IncidentListItem, type IncidentState, type IncidentWrite, type ReportingSettings, type IncidentTestResult, type IngestCaller, type IngestMetric, type LastDeployedCommit, } from './api/reporting-service.js';
|
|
38
42
|
export { upsertDeployments, applyDeployOutcome, correlateIncident, isDeployEvent, leadTimeGapOf, type DeployCandidate, } from './api/reporting/deploy-rollup.js';
|
|
39
43
|
export { rebuildDay, runRollupPass, rollupSettleHours, rollupBatchDays, utcDayStart, } from './api/reporting/daily-rollup.js';
|
|
40
44
|
export { classifyFailure, isTeamActionable, FAILURE_CATEGORY_LABELS, } from './api/reporting/failure-classifier.js';
|
|
41
45
|
export { getPipelineBreakdown, getFailureAnalysis, getStagePerformance, getResourceConsumption, getPromotionView, getOutdatedPlugins, getPluginVulnerabilities, getAdoption, type AnalyticsScope, type PipelineBreakdownRow, type FailureCategoryRow, type StagePerformanceRow, type ResourceRow, type PromotionRow, type OutdatedPluginRow, type VulnerabilityRow, type AdoptionSummary, } from './api/reporting/analytics-queries.js';
|
|
42
46
|
export { evaluateNeedsAttention, thresholdsFrom, DEFAULT_THRESHOLDS, type NeedsAttentionThresholds, type AttentionFinding, type AttentionItem, type AttentionInput, type AttentionRuleId, } from './api/reporting/needs-attention.js';
|
|
43
|
-
export { replacePipelineResolution, refreshLatestForPlugin, upsertExposures, closeFixedExposures, openExposures, triageExposure, lapsedAcceptances, versionGap, type ResolvedStep, type ExposureInput, type VersionGap, } from './api/reporting/plugin-exposure.js';
|
|
47
|
+
export { replacePipelineResolution, refreshLatestForPlugin, upsertExposures, closeFixedExposures, closePipelineExposures, closeVersionExposures, reconcilePipelineExposures, syncVersionExposures, pipelinesOnVersion, exposureFromScan, liveExposurePredicate, openExposures, triageExposure, lapsedAcceptances, pipelineExposures, exposureById, activeAcceptances, acceptanceKey, reopenLapsedAcceptances, versionGap, type PipelineExposure, type TriageDecision, type PipelineAcceptances, type LapsedAcceptance, type ResolvedStep, type ExposureInput, type ExposureStep, type ExposureCounts, type LiveVersion, type PipelineOnVersion, type PluginVersionRef, type ScanState, type VersionGap, } from './api/reporting/plugin-exposure.js';
|
|
44
48
|
export { resolvePeriod, resolvePeriodByLabel, rejectUnreportablePeriod, nextPeriodBoundary, completePeriodsSince, registerSection, getSection, allSections, sectionIds, REPORT_TEMPLATE_SPECS, getTemplate, composeSnapshot, LOW_SAMPLE_THRESHOLD, REPORT_FEATURE_SUBSTITUTES, renderReportHtml, reportFileName, trendSentence, type ReportHtmlInput, type ResolvedPeriod, type PeriodRejection, type SectionSpec, type SectionContext, type SectionDataSource, type TemplateSpec, type ReportSnapshot, type ComposedSection, type DataQualityNote, type ComposeOptions, type TrendDirection, StakeholderReportStore, stakeholderReportStore, hashToken, mintToken, DEFAULT_SHARE_LINK_TTL_DAYS, MAX_SHARE_LINK_TTL_DAYS, MAX_BOUNCES, VERIFICATION_TTL_MS, type CreateDefinitionInput, type UpdateDefinitionInput, type MintedShareLink, type ResolvedShareLink, } from './api/reporting/stakeholder/index.js';
|
|
45
49
|
export { type PluginRuntimeFilter, type PluginRuntimeStats, ReportingService, reportingService, } from './api/reporting-service.js';
|
|
46
50
|
export { type PluginFilter, type PipelineFilter, type PipelineTemplateFilter, type MessageFilter, type CompliancePolicyFilter, type ComplianceRuleFilter, type ComplianceExemptionFilter, type ComplianceAuditFilter, type ComplianceScanFilter, } from './core/query-filters.js';
|