@pipeline-builder/pipeline-data 3.4.64 → 3.4.66

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/README.md CHANGED
@@ -2,33 +2,60 @@
2
2
 
3
3
  📖 **[View documentation](https://mwashburn160.github.io/pipeline-builder/)**
4
4
 
5
- Database layer for [Pipeline Builder](https://mwashburn160.github.io/pipeline-builder/): Drizzle ORM schemas, connection management, query builders, and the generic `CrudService` base class with built-in multi-tenant access control used by every backend service.
5
+ Database layer for [Pipeline Builder](https://mwashburn160.github.io/pipeline-builder/): Drizzle ORM schemas, connection management, query builders, and the generic `CrudService` base class with per-organization (and team) access control.
6
6
 
7
- ## Key Exports
7
+ > Internal workspace package — consumed by other packages via `workspace:*`.
8
8
 
9
- ### Connection
10
- - `getConnection`, `db`, `closeConnection` — Shared PostgreSQL pool, Drizzle client, and lifecycle management
11
- - `dbReplica` — Optional read-replica client for read-heavy queries (reporting, listings)
12
- - `ConnectionRetryStrategy` — Retry logic for transient connection failures
13
- - `runMigrations` — Drizzle migration runner
9
+ ## Responsibilities
14
10
 
15
- ### Schemas
16
- - `schema` — All Drizzle table definitions: core pipeline/plugin/message tables, the pipeline deployment registry and execution-event log, observability dashboards and per-org alerting, plus the full compliance suite (policies, rules, exemptions, audit log, scans, reports)
17
- - Entity types: `Pipeline`, `Plugin`, `Message`, `PipelineEvent`, `ComplianceRule`, and a matching `*Insert` / `*Update` type for each table
11
+ - Defines the Drizzle ORM schema for every backend table (pipelines, plugins, messages, pipeline events, and the compliance suite).
12
+ - Manages the PostgreSQL connection lifecycle with retry logic.
13
+ - Provides the generic `CrudService` base class with built-in multi-tenant (org/team) access control and pagination.
14
+ - Supplies filter-to-SQL query/condition builders and `AsyncLocalStorage`-backed tenant-context primitives for transactions.
15
+ - Hosts the `ReportingService` used to ingest pipeline events and serve org-scoped reporting.
18
16
 
19
- ### CrudService
20
- - `CrudService<TEntity, TFilter, TInsert, TUpdate>` — Abstract base providing `find`, `findById`, `findPaginated`, `count`, `create`, `update`, `delete` (soft delete), `setDefault`, and `updateMany`
21
- - Built-in multi-tenant access control and pagination; subclasses implement `buildConditions` and a few column accessors and inherit the rest
22
- - Optional per-entity lifecycle hooks fire after mutations (e.g. cache invalidation)
17
+ ## Key exports
23
18
 
24
- ### Query Builders & Access Control
25
- - `AccessControlQueryBuilder` Row-level, org-scoped condition builder enforcing tenant isolation and `accessModifier` visibility
26
- - `buildPipelineConditions`, `buildPluginConditions`, `buildMessageConditions`, and the compliance condition builders — filter-to-SQL translators used by the services
27
- - Tenancy helpers: `tenantContext`, `runWithTenantContext`, `withTenantTx` `AsyncLocalStorage`-backed tenant scoping for transactions
19
+ ### Database
20
+ | Export | Purpose |
21
+ |---|---|
22
+ | `db` | Shared Drizzle database instance |
23
+ | `getConnection`, `closeConnection` | PostgreSQL connection lifecycle (with retry strategy) |
24
+ | `schema` | All Drizzle table definitions and their `*Insert` / `*Update` types |
25
+ | `runMigrations` (`MigrateOptions`) | Drizzle migration runner |
26
+ | `tenantContext`, `runWithTenantContext`, `getTenantContext`, `withTenantTx` | Tenant-context primitives for scoped/RLS transactions |
28
27
 
29
- ### Reporting
30
- - `ReportingService` / `reportingService` — Aggregate-query base for pipeline event ingestion and org-scoped reporting
28
+ ### Services
29
+ | Export | Purpose |
30
+ |---|---|
31
+ | `CrudService<TEntity, TFilter, TInsert, TUpdate>` | Abstract base providing `find`, `findById`, `findPaginated`, `count`, `create`, `update`, `delete` (soft), `setDefault`, `updateMany` with multi-tenant access control |
32
+ | `ReportingService` / `reportingService` | Aggregate-query base for pipeline-event ingestion and org-scoped reporting |
33
+
34
+ ### Query builders & filters
35
+ | Export | Purpose |
36
+ |---|---|
37
+ | `AccessControlQueryBuilder` | Row-level, org-scoped condition builder enforcing tenant isolation and `accessModifier` visibility |
38
+ | `buildPipelineConditions`, `buildPluginConditions`, `buildMessageConditions`, and the compliance condition builders | Filter-to-SQL translators used by the services |
39
+ | `PipelineFilter`, `PluginFilter`, `MessageFilter`, the compliance filter types | Typed filter interfaces |
40
+ | `drizzleRows`, `drizzleCount` | Drizzle result type helpers |
41
+
42
+ ## Usage
43
+
44
+ ```typescript
45
+ import { CrudService, db, schema } from '@pipeline-builder/pipeline-data';
46
+
47
+ class PipelineService extends CrudService<Pipeline, PipelineFilter, PipelineInsert, PipelineUpdate> {
48
+ // implement buildConditions + a few column accessors; inherit the rest
49
+ }
50
+ ```
51
+
52
+ ## Development
53
+
54
+ ```bash
55
+ pnpm build # projen build (compile + lint + test + package)
56
+ pnpm test # run the Jest test suite
57
+ ```
31
58
 
32
59
  ## License
33
60
 
34
- Apache-2.0. See [LICENSE](./LICENSE).
61
+ Apache-2.0. See [LICENSE](./LICENSE).
@@ -1,34 +1,27 @@
1
- "use strict";
2
1
  // Copyright 2026 Pipeline Builder Contributors
3
2
  // SPDX-License-Identifier: Apache-2.0
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.AccessControlQueryBuilder = void 0;
6
- exports.escapeLikeWildcards = escapeLikeWildcards;
7
- exports.buildJsonbKeywordCondition = buildJsonbKeywordCondition;
8
- exports.parseBooleanFilter = parseBooleanFilter;
9
- exports.normalizeStringFilter = normalizeStringFilter;
10
- const api_core_1 = require("@pipeline-builder/api-core");
11
- const drizzle_orm_1 = require("drizzle-orm");
3
+ import { AccessModifier, SYSTEM_ORG_ID } from '@pipeline-builder/api-core';
4
+ import { eq, or, sql, SQL } from 'drizzle-orm';
12
5
  const FULL_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
13
6
  /**
14
7
  * Escape SQL LIKE wildcard characters to prevent wildcard injection.
15
8
  * Replaces `%` → `\\%`, `_` → `\\_`, and `\\` → `\\\\`.
16
9
  */
17
- function escapeLikeWildcards(str) {
10
+ export function escapeLikeWildcards(str) {
18
11
  return str.replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_');
19
12
  }
20
13
  /**
21
14
  * Build a condition that checks if a JSONB text array column contains a keyword (case-insensitive).
22
15
  * Used for keywords/tags filtering on pipelines, plugins, and compliance rules.
23
16
  */
24
- function buildJsonbKeywordCondition(column, keyword) {
17
+ export function buildJsonbKeywordCondition(column, keyword) {
25
18
  const escaped = escapeLikeWildcards(keyword.toLowerCase());
26
- return (0, drizzle_orm_1.sql) `EXISTS (SELECT 1 FROM jsonb_array_elements_text(${column}) AS el WHERE lower(el) LIKE ${'%' + escaped + '%'})`;
19
+ return sql `EXISTS (SELECT 1 FROM jsonb_array_elements_text(${column}) AS el WHERE lower(el) LIKE ${'%' + escaped + '%'})`;
27
20
  }
28
21
  /**
29
22
  * Parse boolean filter value from string or boolean
30
23
  */
31
- function parseBooleanFilter(value) {
24
+ export function parseBooleanFilter(value) {
32
25
  if (typeof value === 'boolean')
33
26
  return value;
34
27
  if (typeof value === 'string')
@@ -38,7 +31,7 @@ function parseBooleanFilter(value) {
38
31
  /**
39
32
  * Normalize string filter value to lowercase
40
33
  */
41
- function normalizeStringFilter(value) {
34
+ export function normalizeStringFilter(value) {
42
35
  return typeof value === 'string' ? value.toLowerCase() : String(value).toLowerCase();
43
36
  }
44
37
  /**
@@ -53,7 +46,7 @@ function normalizeStringFilter(value) {
53
46
  * @typeParam TSchema - Schema table type with access control fields
54
47
  * @typeParam TFilter - Filter type extending BaseAccessFilter
55
48
  */
56
- class AccessControlQueryBuilder {
49
+ export class AccessControlQueryBuilder {
57
50
  schema;
58
51
  constructor(schema) {
59
52
  this.schema = schema;
@@ -82,8 +75,8 @@ class AccessControlQueryBuilder {
82
75
  const conditions = [];
83
76
  if (!orgId) {
84
77
  // No org context — only system org's public records
85
- conditions.push((0, drizzle_orm_1.eq)(this.schema.orgId, api_core_1.SYSTEM_ORG_ID));
86
- conditions.push((0, drizzle_orm_1.eq)(this.schema.accessModifier, api_core_1.AccessModifier.PUBLIC));
78
+ conditions.push(eq(this.schema.orgId, SYSTEM_ORG_ID));
79
+ conditions.push(eq(this.schema.accessModifier, AccessModifier.PUBLIC));
87
80
  return conditions;
88
81
  }
89
82
  const normalizedOrgId = orgId.toLowerCase();
@@ -93,20 +86,20 @@ class AccessControlQueryBuilder {
93
86
  const normalized = typeof accessModifier === 'string'
94
87
  ? accessModifier.toLowerCase()
95
88
  : String(accessModifier).toLowerCase();
96
- conditions.push((0, drizzle_orm_1.eq)(this.schema.orgId, normalizedOrgId));
97
- conditions.push((0, drizzle_orm_1.eq)(this.schema.accessModifier, normalized));
89
+ conditions.push(eq(this.schema.orgId, normalizedOrgId));
90
+ conditions.push(eq(this.schema.accessModifier, normalized));
98
91
  }
99
92
  else {
100
93
  // Default catalog view: own org public + parent org public (team →
101
94
  // parent inheritance) + system org public.
102
- conditions.push((0, drizzle_orm_1.eq)(this.schema.accessModifier, api_core_1.AccessModifier.PUBLIC));
95
+ conditions.push(eq(this.schema.accessModifier, AccessModifier.PUBLIC));
103
96
  const orgScopes = [
104
- (0, drizzle_orm_1.eq)(this.schema.orgId, normalizedOrgId),
105
- (0, drizzle_orm_1.eq)(this.schema.orgId, api_core_1.SYSTEM_ORG_ID),
97
+ eq(this.schema.orgId, normalizedOrgId),
98
+ eq(this.schema.orgId, SYSTEM_ORG_ID),
106
99
  ];
107
100
  if (parentOrgId)
108
- orgScopes.push((0, drizzle_orm_1.eq)(this.schema.orgId, parentOrgId.toLowerCase()));
109
- conditions.push((0, drizzle_orm_1.or)(...orgScopes));
101
+ orgScopes.push(eq(this.schema.orgId, parentOrgId.toLowerCase()));
102
+ conditions.push(or(...orgScopes));
110
103
  }
111
104
  return conditions;
112
105
  }
@@ -124,12 +117,12 @@ class AccessControlQueryBuilder {
124
117
  return null;
125
118
  const idString = String(id).toLowerCase();
126
119
  if (FULL_UUID.test(idString)) {
127
- return (0, drizzle_orm_1.eq)(this.schema.id, idString);
120
+ return eq(this.schema.id, idString);
128
121
  }
129
122
  else {
130
123
  // Escape SQL LIKE wildcards to prevent wildcard injection
131
124
  const escaped = escapeLikeWildcards(idString);
132
- return (0, drizzle_orm_1.sql) `${this.schema.id}::text LIKE ${escaped + '%'} ESCAPE '\\'`;
125
+ return sql `${this.schema.id}::text LIKE ${escaped + '%'} ESCAPE '\\'`;
133
126
  }
134
127
  }
135
128
  /**
@@ -141,14 +134,14 @@ class AccessControlQueryBuilder {
141
134
  buildBooleanFilters(filter) {
142
135
  const conditions = [];
143
136
  if (filter.isDefault !== undefined) {
144
- conditions.push((0, drizzle_orm_1.eq)(this.schema.isDefault, parseBooleanFilter(filter.isDefault)));
137
+ conditions.push(eq(this.schema.isDefault, parseBooleanFilter(filter.isDefault)));
145
138
  }
146
139
  if (filter.isActive !== undefined) {
147
- conditions.push((0, drizzle_orm_1.eq)(this.schema.isActive, parseBooleanFilter(filter.isActive)));
140
+ conditions.push(eq(this.schema.isActive, parseBooleanFilter(filter.isActive)));
148
141
  }
149
142
  else {
150
143
  // Default to active records only to exclude soft-deleted entities
151
- conditions.push((0, drizzle_orm_1.eq)(this.schema.isActive, true));
144
+ conditions.push(eq(this.schema.isActive, true));
152
145
  }
153
146
  return conditions;
154
147
  }
@@ -164,7 +157,7 @@ class AccessControlQueryBuilder {
164
157
  buildAccessModifierFilter(accessModifier) {
165
158
  if (accessModifier === undefined)
166
159
  return null;
167
- return (0, drizzle_orm_1.sql) `${this.schema.accessModifier} = ${normalizeStringFilter(accessModifier)}`;
160
+ return sql `${this.schema.accessModifier} = ${normalizeStringFilter(accessModifier)}`;
168
161
  }
169
162
  /**
170
163
  * Build all common conditions (access control + ID + booleans)
@@ -189,5 +182,4 @@ class AccessControlQueryBuilder {
189
182
  return conditions;
190
183
  }
191
184
  }
192
- exports.AccessControlQueryBuilder = AccessControlQueryBuilder;
193
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYWNjZXNzLWNvbnRyb2wtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7O0FBWXRDLGtEQUVDO0FBTUQsZ0VBR0M7QUFLRCxnREFJQztBQUtELHNEQUVDO0FBckNELHlEQUEyRTtBQUMzRSw2Q0FBK0M7QUFHL0MsTUFBTSxTQUFTLEdBQUcsaUVBQWlFLENBQUM7QUFFcEY7OztHQUdHO0FBQ0gsU0FBZ0IsbUJBQW1CLENBQUMsR0FBVztJQUM3QyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM5RSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0IsMEJBQTBCLENBQUMsTUFBaUIsRUFBRSxPQUFlO0lBQzNFLE1BQU0sT0FBTyxHQUFHLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzNELE9BQU8sSUFBQSxpQkFBRyxFQUFBLG1EQUFtRCxNQUFNLGdDQUFnQyxHQUFHLEdBQUcsT0FBTyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQzVILENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGtCQUFrQixDQUFDLEtBQWM7SUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLEtBQUssTUFBTSxDQUFDO0lBQ3ZELE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3hCLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLHFCQUFxQixDQUFDLEtBQWM7SUFDbEQs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SyxTQUFTO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDOUMsT0FBTyxJQUFBLGlCQUFHLEVBQUEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsTUFBTSxxQkFBcUIsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO0lBQ3ZGLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxxQkFBcUIsQ0FBQyxNQUF3QixFQUFFLEtBQWMsRUFBRSxXQUFvQjtRQUN6RixNQUFNLFVBQVUsR0FBVSxFQUFFLENBQUM7UUFFN0Isb0VBQW9FO1FBQ3BFLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBRXhFLGlDQUFpQztRQUNqQyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNsRCxJQUFJLFdBQVc7WUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTlDLGtCQUFrQjtRQUNsQixVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFFckQsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztDQUNGO0FBbkpELDhEQW1KQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBBY2Nlc3NNb2RpZmllciwgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGVxLCBvciwgc3FsLCBTUUwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgdHlwZSB7IEFueUNvbHVtbiB9IGZyb20gJ2RyaXp6bGUtb3JtL2NvbHVtbic7XG5cbmNvbnN0IEZVTExfVVVJRCA9IC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17MTJ9JC9pO1xuXG4vKipcbiAqIEVzY2FwZSBTUUwgTElLRSB3aWxkY2FyZCBjaGFyYWN0ZXJzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uLlxuICogUmVwbGFjZXMgYCVgIOKGkiBgXFxcXCVgLCBgX2Ag4oaSIGBcXFxcX2AsIGFuZCBgXFxcXGAg4oaSIGBcXFxcXFxcXGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVMaWtlV2lsZGNhcmRzKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXFxcL2csICdcXFxcXFxcXCcpLnJlcGxhY2UoLyUvZywgJ1xcXFwlJykucmVwbGFjZSgvXy9nLCAnXFxcXF8nKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiBhIEpTT05CIHRleHQgYXJyYXkgY29sdW1uIGNvbnRhaW5zIGEga2V5d29yZCAoY2FzZS1pbnNlbnNpdGl2ZSkuXG4gKiBVc2VkIGZvciBrZXl3b3Jkcy90YWdzIGZpbHRlcmluZyBvbiBwaXBlbGluZXMsIHBsdWdpbnMsIGFuZCBjb21wbGlhbmNlIHJ1bGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRKc29uYktleXdvcmRDb25kaXRpb24oY29sdW1uOiBBbnlDb2x1bW4sIGtleXdvcmQ6IHN0cmluZyk6IFNRTCB7XG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGtleXdvcmQudG9Mb3dlckNhc2UoKSk7XG4gIHJldHVybiBzcWxgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIGpzb25iX2FycmF5X2VsZW1lbnRzX3RleHQoJHtjb2x1bW59KSBBUyBlbCBXSEVSRSBsb3dlcihlbCkgTElLRSAkeyclJyArIGVzY2FwZWQgKyAnJSd9KWA7XG59XG5cbi8qKlxuICogUGFyc2UgYm9vbGVhbiBmaWx0ZXIgdmFsdWUgZnJvbSBzdHJpbmcgb3IgYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCb29sZWFuRmlsdGVyKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbHVlID09PSAndHJ1ZSc7XG4gIHJldHVybiBCb29sZWFuKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgc3RyaW5nIGZpbHRlciB2YWx1ZSB0byBsb3dlcmNhc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZ0ZpbHRlcih2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6IFN0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBTY2hlbWEgdGFibGUgaW50ZXJmYWNlIGZvciBhY2Nlc3MgY29udHJvbCBxdWVyaWVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNjZXNzQ29udHJvbFNjaGVtYSB7XG4gIGlkOiBBbnlDb2x1bW47XG4gIG9yZ0lkOiBBbnlDb2x1bW47XG4gIGFjY2Vzc01vZGlmaWVyOiBBbnlDb2x1bW47XG4gIGlzRGVmYXVsdDogQW55Q29sdW1uO1xuICBpc0FjdGl2ZTogQW55Q29sdW1uO1xufVxuXG4vKipcbiAqIEJhc2UgZmlsdGVyIGludGVyZmFjZSB3aXRoIGNvbW1vbiBhY2Nlc3MgY29udHJvbCBmaWVsZHNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCYXNlQWNjZXNzRmlsdGVyIHtcbiAgaWQ/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgYWNjZXNzTW9kaWZpZXI/OiBzdHJpbmc7XG4gIGlzRGVmYXVsdD86IGJvb2xlYW4gfCBzdHJpbmc7XG4gIGlzQWN0aXZlPzogYm9vbGVhbiB8IHN0cmluZztcbn1cblxuLyoqXG4gKiBHZW5lcmljIGFjY2VzcyBjb250cm9sIHF1ZXJ5IGJ1aWxkZXIgZm9yIG11bHRpLXRlbmFudCBlbnRpdGllcy5cbiAqXG4gKiBDb25zb2xpZGF0ZXMgZHVwbGljYXRlIGFjY2VzcyBjb250cm9sIGxvZ2ljIHNoYXJlZCBhY3Jvc3MgcGlwZWxpbmUgYW5kIHBsdWdpbiBxdWVyaWVzLlxuICogSGFuZGxlczpcbiAqIC0gTXVsdGktdGVuYW50IGFjY2VzcyBjb250cm9sIChwdWJsaWMvcHJpdmF0ZS9vcmctYW5kLXB1YmxpYylcbiAqIC0gVVVJRCBwcmVmaXggbWF0Y2hpbmcgZm9yIElEIGZpbHRlcnNcbiAqIC0gQm9vbGVhbiBmaWVsZCBub3JtYWxpemF0aW9uXG4gKlxuICogQHR5cGVQYXJhbSBUU2NoZW1hIC0gU2NoZW1hIHRhYmxlIHR5cGUgd2l0aCBhY2Nlc3MgY29udHJvbCBmaWVsZHNcbiAqIEB0eXBlUGFyYW0gVEZpbHRlciAtIEZpbHRlciB0eXBlIGV4dGVuZGluZyBCYXNlQWNjZXNzRmlsdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBBY2Nlc3NDb250cm9sUXVlcnlCdWlsZGVyPFxuICBUU2NoZW1hIGV4dGVuZHMgQWNjZXNzQ29udHJvbFNjaGVtYSxcbiAgVEZpbHRlciBleHRlbmRzIEJhc2VBY2Nlc3NGaWx0ZXIsXG4+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzY2hlbWE6IFRTY2hlbWEsXG4gICkge31cblxuICAvKipcbiAgICogQnVpbGQgYWNjZXNzIGNvbnRyb2wgY29uZGl0aW9ucyBiYXNlZCBvbiBvcmdJZCBhbmQgYWNjZXNzTW9kaWZpZXIgZmlsdGVyLlxuICAgKlxuICAgKiBXaXRob3V0IG9yZ0lkIChhbm9ueW1vdXMpOlxuICAgKiAgIG9yZ0lkPSdzeXN0ZW0nIEFORCBhY2Nlc3NNb2RpZmllcj0ncHVibGljJ1xuICAgKlxuICAgKiBXaXRoIG9yZ0lkOlxuICAgKiAgIC0gYWNjZXNzTW9kaWZpZXI9J3ByaXZhdGUnOiBvcmdJZD0kb3JnIEFORCBhY2Nlc3NNb2RpZmllcj0ncHJpdmF0ZSdcbiAgICogICAtIGFjY2Vzc01vZGlmaWVyPSdwdWJsaWMnOiAgb3JnSWQ9JG9yZyBBTkQgYWNjZXNzTW9kaWZpZXI9J3B1YmxpYydcbiAgICogICAtIG5vIGFjY2Vzc01vZGlmaWVyOiAgICAgICAgYWNjZXNzTW9kaWZpZXI9J3B1YmxpYycgQU5EIChvcmdJZD0kb3JnIE9SIG9yZ0lkPSRwYXJlbnQgT1Igb3JnSWQ9J3N5c3RlbScpXG4gICAqXG4gICAqIGBwYXJlbnRPcmdJZGAgKG9yZyDihpIgdGVhbSBoaWVyYXJjaHkpIHdpZGVucyB0aGUgZGVmYXVsdCBjYXRhbG9nIHZpZXcgc28gYVxuICAgKiB0ZWFtIG9yZyBhbHNvIHNlZXMgaXRzIHBhcmVudCdzIHB1YmxpYyByZWNvcmRzLiBBYnNlbnQgZm9yIHJvb3Qgb3Jncywgc29cbiAgICogdGhlIGNvbmRpdGlvbiBpcyB1bmNoYW5nZWQgZm9yIG5vbi10ZWFtIGNhbGxlcnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwpXG4gICAqIEBwYXJhbSBwYXJlbnRPcmdJZCAtIFBhcmVudCBvcmcgSUQgd2hlbiB0aGUgY2FsbGVyIGlzIGEgdGVhbSAob3B0aW9uYWwpXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFNRTCBjb25kaXRpb25zIGZvciBhY2Nlc3MgY29udHJvbFxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgaWYgKCFvcmdJZCkge1xuICAgICAgLy8gTm8gb3JnIGNvbnRleHQg4oCUIG9ubHkgc3lzdGVtIG9yZydzIHB1YmxpYyByZWNvcmRzXG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIFNZU1RFTV9PUkdfSUQpKTtcbiAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5hY2Nlc3NNb2RpZmllciwgQWNjZXNzTW9kaWZpZXIuUFVCTElDKSk7XG4gICAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkT3JnSWQgPSBvcmdJZC50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGFjY2Vzc01vZGlmaWVyID0gZmlsdGVyLmFjY2Vzc01vZGlmaWVyIGFzIHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChhY2Nlc3NNb2RpZmllciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBFeHBsaWNpdCBmaWx0ZXI6IHNjb3BlIHRvIHVzZXIncyBvcmcgKyByZXF1ZXN0ZWQgYWNjZXNzIG1vZGlmaWVyXG4gICAgICBjb25zdCBub3JtYWxpemVkID0gdHlwZW9mIGFjY2Vzc01vZGlmaWVyID09PSAnc3RyaW5nJ1xuICAgICAgICA/IGFjY2Vzc01vZGlmaWVyLnRvTG93ZXJDYXNlKClcbiAgICAgICAgOiBTdHJpbmcoYWNjZXNzTW9kaWZpZXIpLnRvTG93ZXJDYXNlKCk7XG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIG5vcm1hbGl6ZWRPcmdJZCkpO1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmFjY2Vzc01vZGlmaWVyLCBub3JtYWxpemVkKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgY2F0YWxvZyB2aWV3OiBvd24gb3JnIHB1YmxpYyArIHBhcmVudCBvcmcgcHVibGljICh0ZWFtIOKGklxuICAgICAgLy8gcGFyZW50IGluaGVyaXRhbmNlKSArIHN5c3RlbSBvcmcgcHVibGljLlxuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmFjY2Vzc01vZGlmaWVyLCBBY2Nlc3NNb2RpZmllci5QVUJMSUMpKTtcbiAgICAgIGNvbnN0IG9yZ1Njb3BlcyA9IFtcbiAgICAgICAgZXEodGhpcy5zY2hlbWEub3JnSWQsIG5vcm1hbGl6ZWRPcmdJZCksXG4gICAgICAgIGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBTWVNURU1fT1JHX0lEKSxcbiAgICAgIF07XG4gICAgICBpZiAocGFyZW50T3JnSWQpIG9yZ1Njb3Blcy5wdXNoKGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBwYXJlbnRPcmdJZC50b0xvd2VyQ2FzZSgpKSk7XG4gICAgICBjb25kaXRpb25zLnB1c2gob3IoLi4ub3JnU2NvcGVzKSEpO1xuICAgIH1cblxuICAgIHJldHVybiBjb25kaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIElEIGZpbHRlciB3aXRoIFVVSUQgcHJlZml4IG1hdGNoaW5nIHN1cHBvcnRcbiAgICpcbiAgICogLSBGdWxsIFVVSUQ6IEV4YWN0IG1hdGNoXG4gICAqIC0gUGFydGlhbCBVVUlEOiBQcmVmaXggbWF0Y2ggdXNpbmcgU1FMIExJS0VcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gSUQgZmlsdGVyIHZhbHVlIChmdWxsIG9yIHBhcnRpYWwgVVVJRClcbiAgICogQHJldHVybnMgU1FMIGNvbmRpdGlvbiBvciBudWxsIGlmIG5vIElEIGZpbHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkSWRGaWx0ZXIoaWQ6IHVua25vd24pOiBTUUwgfCBudWxsIHtcbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCB8fCBpZCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBpZFN0cmluZyA9IFN0cmluZyhpZCkudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoRlVMTF9VVUlELnRlc3QoaWRTdHJpbmcpKSB7XG4gICAgICByZXR1cm4gZXEodGhpcy5zY2hlbWEuaWQsIGlkU3RyaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRXNjYXBlIFNRTCBMSUtFIHdpbGRjYXJkcyB0byBwcmV2ZW50IHdpbGRjYXJkIGluamVjdGlvblxuICAgICAgY29uc3QgZXNjYXBlZCA9IGVzY2FwZUxpa2VXaWxkY2FyZHMoaWRTdHJpbmcpO1xuICAgICAgcmV0dXJuIHNxbGAke3RoaXMuc2NoZW1hLmlkfTo6dGV4dCBMSUtFICR7ZXNjYXBlZCArICclJ30gRVNDQVBFICdcXFxcJ2A7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGJvb2xlYW4gZmllbGQgY29uZGl0aW9ucyAoaXNEZWZhdWx0LCBpc0FjdGl2ZSlcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9ucyBmb3IgYm9vbGVhbiBmaWVsZHNcbiAgICovXG4gIHByb3RlY3RlZCBidWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcjogUGFydGlhbDxURmlsdGVyPik6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgaWYgKGZpbHRlci5pc0RlZmF1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmlzRGVmYXVsdCwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0RlZmF1bHQpKSk7XG4gICAgfVxuXG4gICAgaWYgKGZpbHRlci5pc0FjdGl2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEuaXNBY3RpdmUsIHBhcnNlQm9vbGVhbkZpbHRlcihmaWx0ZXIuaXNBY3RpdmUpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgdG8gYWN0aXZlIHJlY29yZHMgb25seSB0byBleGNsdWRlIHNvZnQtZGVsZXRlZCBlbnRpdGllc1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmlzQWN0aXZlLCB0cnVlKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgZXhwbGljaXQgYWNjZXNzTW9kaWZpZXIgZmlsdGVyXG4gICAqXG4gICAqIE5vdGU6IFRoaXMgaXMgc2VwYXJhdGUgZnJvbSBhY2Nlc3MgY29udHJvbCBsb2dpYyAtIGl0IGZpbHRlcnMgYnkgdGhlIGV4YWN0XG4gICAqIGFjY2Vzc01vZGlmaWVyIHZhbHVlIHJhdGhlciB0aGFuIGFwcGx5aW5nIG11bHRpLXRlbmFudCBhY2Nlc3MgcnVsZXMuXG4gICAqXG4gICAqIEBwYXJhbSBhY2Nlc3NNb2RpZmllciAtIEFjY2VzcyBtb2RpZmllciBmaWx0ZXIgdmFsdWVcbiAgICogQHJldHVybnMgU1FMIGNvbmRpdGlvbiBvciBudWxsIGlmIG5vIGFjY2Vzc01vZGlmaWVyIGZpbHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQWNjZXNzTW9kaWZpZXJGaWx0ZXIoYWNjZXNzTW9kaWZpZXI6IHVua25vd24pOiBTUUwgfCBudWxsIHtcbiAgICBpZiAoYWNjZXNzTW9kaWZpZXIgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHNxbGAke3RoaXMuc2NoZW1hLmFjY2Vzc01vZGlmaWVyfSA9ICR7bm9ybWFsaXplU3RyaW5nRmlsdGVyKGFjY2Vzc01vZGlmaWVyKX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFsbCBjb21tb24gY29uZGl0aW9ucyAoYWNjZXNzIGNvbnRyb2wgKyBJRCArIGJvb2xlYW5zKVxuICAgKlxuICAgKiBUaGlzIGNvbWJpbmVzIGFsbCB0aGUgZ2VuZXJpYyBmaWx0ZXJzIHRoYXQgYXBwbHkgdG8gYW55IGFjY2Vzcy1jb250cm9sbGVkIGVudGl0eS5cbiAgICogU3ViY2xhc3NlcyBzaG91bGQgY2FsbCB0aGlzIGFuZCBhZGQgZW50aXR5LXNwZWNpZmljIGNvbmRpdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIGZhbGxzIGJhY2sgdG8gc3lzdGVtLXB1YmxpYy1vbmx5KVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9uc1xuICAgKi9cbiAgcHVibGljIGJ1aWxkQ29tbW9uQ29uZGl0aW9ucyhmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgLy8gQWNjZXNzIGNvbnRyb2wgKG11bHRpLXRlbmFudCkg4oCUIGhhbmRsZXMgYWNjZXNzTW9kaWZpZXIgaW50ZXJuYWxseVxuICAgIGNvbmRpdGlvbnMucHVzaCguLi50aGlzLmJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCkpO1xuXG4gICAgLy8gSUQgZmlsdGVyIHdpdGggcHJlZml4IG1hdGNoaW5nXG4gICAgY29uc3QgaWRDb25kaXRpb24gPSB0aGlzLmJ1aWxkSWRGaWx0ZXIoZmlsdGVyLmlkKTtcbiAgICBpZiAoaWRDb25kaXRpb24pIGNvbmRpdGlvbnMucHVzaChpZENvbmRpdGlvbik7XG5cbiAgICAvLyBCb29sZWFuIGZpbHRlcnNcbiAgICBjb25kaXRpb25zLnB1c2goLi4udGhpcy5idWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcikpO1xuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cbn1cbiJdfQ==
185
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYWNjZXNzLWNvbnRyb2wtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0UsT0FBTyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUcvQyxNQUFNLFNBQVMsR0FBRyxpRUFBaUUsQ0FBQztBQUVwRjs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsR0FBVztJQUM3QyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM5RSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUFDLE1BQWlCLEVBQUUsT0FBZTtJQUMzRSxNQUFNLE9BQU8sR0FBRyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUMzRCxPQUFPLEdBQUcsQ0FBQSxtREFBbUQsTUFBTSxnQ0FBZ0MsR0FBRyxHQUFHLE9BQU8sR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM1SCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsS0FBYztJQUMvQyxJQUFJLE9BQU8sS0FBSyxLQUFLLFNBQVM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUM3QyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFBRSxPQUFPLEtBQUssS0FBSyxNQUFNLENBQUM7SUFDdkQsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7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QUFDO1FBQzlDLE9BQU8sR0FBRyxDQUFBLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLE1BQU0scUJBQXFCLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztJQUN2RixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0kscUJBQXFCLENBQUMsTUFBd0IsRUFBRSxLQUFjLEVBQUUsV0FBb0I7UUFDekYsTUFBTSxVQUFVLEdBQVUsRUFBRSxDQUFDO1FBRTdCLG9FQUFvRTtRQUNwRSxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUV4RSxpQ0FBaUM7UUFDakMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbEQsSUFBSSxXQUFXO1lBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUU5QyxrQkFBa0I7UUFDbEIsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBRXJELE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBBY2Nlc3NNb2RpZmllciwgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGVxLCBvciwgc3FsLCBTUUwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgdHlwZSB7IEFueUNvbHVtbiB9IGZyb20gJ2RyaXp6bGUtb3JtL2NvbHVtbic7XG5cbmNvbnN0IEZVTExfVVVJRCA9IC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17MTJ9JC9pO1xuXG4vKipcbiAqIEVzY2FwZSBTUUwgTElLRSB3aWxkY2FyZCBjaGFyYWN0ZXJzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uLlxuICogUmVwbGFjZXMgYCVgIOKGkiBgXFxcXCVgLCBgX2Ag4oaSIGBcXFxcX2AsIGFuZCBgXFxcXGAg4oaSIGBcXFxcXFxcXGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVMaWtlV2lsZGNhcmRzKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXFxcL2csICdcXFxcXFxcXCcpLnJlcGxhY2UoLyUvZywgJ1xcXFwlJykucmVwbGFjZSgvXy9nLCAnXFxcXF8nKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiBhIEpTT05CIHRleHQgYXJyYXkgY29sdW1uIGNvbnRhaW5zIGEga2V5d29yZCAoY2FzZS1pbnNlbnNpdGl2ZSkuXG4gKiBVc2VkIGZvciBrZXl3b3Jkcy90YWdzIGZpbHRlcmluZyBvbiBwaXBlbGluZXMsIHBsdWdpbnMsIGFuZCBjb21wbGlhbmNlIHJ1bGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRKc29uYktleXdvcmRDb25kaXRpb24oY29sdW1uOiBBbnlDb2x1bW4sIGtleXdvcmQ6IHN0cmluZyk6IFNRTCB7XG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGtleXdvcmQudG9Mb3dlckNhc2UoKSk7XG4gIHJldHVybiBzcWxgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIGpzb25iX2FycmF5X2VsZW1lbnRzX3RleHQoJHtjb2x1bW59KSBBUyBlbCBXSEVSRSBsb3dlcihlbCkgTElLRSAkeyclJyArIGVzY2FwZWQgKyAnJSd9KWA7XG59XG5cbi8qKlxuICogUGFyc2UgYm9vbGVhbiBmaWx0ZXIgdmFsdWUgZnJvbSBzdHJpbmcgb3IgYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCb29sZWFuRmlsdGVyKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbHVlID09PSAndHJ1ZSc7XG4gIHJldHVybiBCb29sZWFuKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgc3RyaW5nIGZpbHRlciB2YWx1ZSB0byBsb3dlcmNhc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZ0ZpbHRlcih2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6IFN0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBTY2hlbWEgdGFibGUgaW50ZXJmYWNlIGZvciBhY2Nlc3MgY29udHJvbCBxdWVyaWVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNjZXNzQ29udHJvbFNjaGVtYSB7XG4gIGlkOiBBbnlDb2x1bW47XG4gIG9yZ0lkOiBBbnlDb2x1bW47XG4gIGFjY2Vzc01vZGlmaWVyOiBBbnlDb2x1bW47XG4gIGlzRGVmYXVsdDogQW55Q29sdW1uO1xuICBpc0FjdGl2ZTogQW55Q29sdW1uO1xufVxuXG4vKipcbiAqIEJhc2UgZmlsdGVyIGludGVyZmFjZSB3aXRoIGNvbW1vbiBhY2Nlc3MgY29udHJvbCBmaWVsZHNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCYXNlQWNjZXNzRmlsdGVyIHtcbiAgaWQ/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgYWNjZXNzTW9kaWZpZXI/OiBzdHJpbmc7XG4gIGlzRGVmYXVsdD86IGJvb2xlYW4gfCBzdHJpbmc7XG4gIGlzQWN0aXZlPzogYm9vbGVhbiB8IHN0cmluZztcbn1cblxuLyoqXG4gKiBHZW5lcmljIGFjY2VzcyBjb250cm9sIHF1ZXJ5IGJ1aWxkZXIgZm9yIG11bHRpLXRlbmFudCBlbnRpdGllcy5cbiAqXG4gKiBDb25zb2xpZGF0ZXMgZHVwbGljYXRlIGFjY2VzcyBjb250cm9sIGxvZ2ljIHNoYXJlZCBhY3Jvc3MgcGlwZWxpbmUgYW5kIHBsdWdpbiBxdWVyaWVzLlxuICogSGFuZGxlczpcbiAqIC0gTXVsdGktdGVuYW50IGFjY2VzcyBjb250cm9sIChwdWJsaWMvcHJpdmF0ZS9vcmctYW5kLXB1YmxpYylcbiAqIC0gVVVJRCBwcmVmaXggbWF0Y2hpbmcgZm9yIElEIGZpbHRlcnNcbiAqIC0gQm9vbGVhbiBmaWVsZCBub3JtYWxpemF0aW9uXG4gKlxuICogQHR5cGVQYXJhbSBUU2NoZW1hIC0gU2NoZW1hIHRhYmxlIHR5cGUgd2l0aCBhY2Nlc3MgY29udHJvbCBmaWVsZHNcbiAqIEB0eXBlUGFyYW0gVEZpbHRlciAtIEZpbHRlciB0eXBlIGV4dGVuZGluZyBCYXNlQWNjZXNzRmlsdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBBY2Nlc3NDb250cm9sUXVlcnlCdWlsZGVyPFxuICBUU2NoZW1hIGV4dGVuZHMgQWNjZXNzQ29udHJvbFNjaGVtYSxcbiAgVEZpbHRlciBleHRlbmRzIEJhc2VBY2Nlc3NGaWx0ZXIsXG4+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzY2hlbWE6IFRTY2hlbWEsXG4gICkge31cblxuICAvKipcbiAgICogQnVpbGQgYWNjZXNzIGNvbnRyb2wgY29uZGl0aW9ucyBiYXNlZCBvbiBvcmdJZCBhbmQgYWNjZXNzTW9kaWZpZXIgZmlsdGVyLlxuICAgKlxuICAgKiBXaXRob3V0IG9yZ0lkIChhbm9ueW1vdXMpOlxuICAgKiAgIG9yZ0lkPSdzeXN0ZW0nIEFORCBhY2Nlc3NNb2RpZmllcj0ncHVibGljJ1xuICAgKlxuICAgKiBXaXRoIG9yZ0lkOlxuICAgKiAgIC0gYWNjZXNzTW9kaWZpZXI9J3ByaXZhdGUnOiBvcmdJZD0kb3JnIEFORCBhY2Nlc3NNb2RpZmllcj0ncHJpdmF0ZSdcbiAgICogICAtIGFjY2Vzc01vZGlmaWVyPSdwdWJsaWMnOiAgb3JnSWQ9JG9yZyBBTkQgYWNjZXNzTW9kaWZpZXI9J3B1YmxpYydcbiAgICogICAtIG5vIGFjY2Vzc01vZGlmaWVyOiAgICAgICAgYWNjZXNzTW9kaWZpZXI9J3B1YmxpYycgQU5EIChvcmdJZD0kb3JnIE9SIG9yZ0lkPSRwYXJlbnQgT1Igb3JnSWQ9J3N5c3RlbScpXG4gICAqXG4gICAqIGBwYXJlbnRPcmdJZGAgKG9yZyDihpIgdGVhbSBoaWVyYXJjaHkpIHdpZGVucyB0aGUgZGVmYXVsdCBjYXRhbG9nIHZpZXcgc28gYVxuICAgKiB0ZWFtIG9yZyBhbHNvIHNlZXMgaXRzIHBhcmVudCdzIHB1YmxpYyByZWNvcmRzLiBBYnNlbnQgZm9yIHJvb3Qgb3Jncywgc29cbiAgICogdGhlIGNvbmRpdGlvbiBpcyB1bmNoYW5nZWQgZm9yIG5vbi10ZWFtIGNhbGxlcnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwpXG4gICAqIEBwYXJhbSBwYXJlbnRPcmdJZCAtIFBhcmVudCBvcmcgSUQgd2hlbiB0aGUgY2FsbGVyIGlzIGEgdGVhbSAob3B0aW9uYWwpXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFNRTCBjb25kaXRpb25zIGZvciBhY2Nlc3MgY29udHJvbFxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgaWYgKCFvcmdJZCkge1xuICAgICAgLy8gTm8gb3JnIGNvbnRleHQg4oCUIG9ubHkgc3lzdGVtIG9yZydzIHB1YmxpYyByZWNvcmRzXG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIFNZU1RFTV9PUkdfSUQpKTtcbiAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5hY2Nlc3NNb2RpZmllciwgQWNjZXNzTW9kaWZpZXIuUFVCTElDKSk7XG4gICAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkT3JnSWQgPSBvcmdJZC50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGFjY2Vzc01vZGlmaWVyID0gZmlsdGVyLmFjY2Vzc01vZGlmaWVyIGFzIHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChhY2Nlc3NNb2RpZmllciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBFeHBsaWNpdCBmaWx0ZXI6IHNjb3BlIHRvIHVzZXIncyBvcmcgKyByZXF1ZXN0ZWQgYWNjZXNzIG1vZGlmaWVyXG4gICAgICBjb25zdCBub3JtYWxpemVkID0gdHlwZW9mIGFjY2Vzc01vZGlmaWVyID09PSAnc3RyaW5nJ1xuICAgICAgICA/IGFjY2Vzc01vZGlmaWVyLnRvTG93ZXJDYXNlKClcbiAgICAgICAgOiBTdHJpbmcoYWNjZXNzTW9kaWZpZXIpLnRvTG93ZXJDYXNlKCk7XG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIG5vcm1hbGl6ZWRPcmdJZCkpO1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmFjY2Vzc01vZGlmaWVyLCBub3JtYWxpemVkKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgY2F0YWxvZyB2aWV3OiBvd24gb3JnIHB1YmxpYyArIHBhcmVudCBvcmcgcHVibGljICh0ZWFtIOKGklxuICAgICAgLy8gcGFyZW50IGluaGVyaXRhbmNlKSArIHN5c3RlbSBvcmcgcHVibGljLlxuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmFjY2Vzc01vZGlmaWVyLCBBY2Nlc3NNb2RpZmllci5QVUJMSUMpKTtcbiAgICAgIGNvbnN0IG9yZ1Njb3BlcyA9IFtcbiAgICAgICAgZXEodGhpcy5zY2hlbWEub3JnSWQsIG5vcm1hbGl6ZWRPcmdJZCksXG4gICAgICAgIGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBTWVNURU1fT1JHX0lEKSxcbiAgICAgIF07XG4gICAgICBpZiAocGFyZW50T3JnSWQpIG9yZ1Njb3Blcy5wdXNoKGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBwYXJlbnRPcmdJZC50b0xvd2VyQ2FzZSgpKSk7XG4gICAgICBjb25kaXRpb25zLnB1c2gob3IoLi4ub3JnU2NvcGVzKSEpO1xuICAgIH1cblxuICAgIHJldHVybiBjb25kaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIElEIGZpbHRlciB3aXRoIFVVSUQgcHJlZml4IG1hdGNoaW5nIHN1cHBvcnRcbiAgICpcbiAgICogLSBGdWxsIFVVSUQ6IEV4YWN0IG1hdGNoXG4gICAqIC0gUGFydGlhbCBVVUlEOiBQcmVmaXggbWF0Y2ggdXNpbmcgU1FMIExJS0VcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gSUQgZmlsdGVyIHZhbHVlIChmdWxsIG9yIHBhcnRpYWwgVVVJRClcbiAgICogQHJldHVybnMgU1FMIGNvbmRpdGlvbiBvciBudWxsIGlmIG5vIElEIGZpbHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkSWRGaWx0ZXIoaWQ6IHVua25vd24pOiBTUUwgfCBudWxsIHtcbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCB8fCBpZCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBpZFN0cmluZyA9IFN0cmluZyhpZCkudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoRlVMTF9VVUlELnRlc3QoaWRTdHJpbmcpKSB7XG4gICAgICByZXR1cm4gZXEodGhpcy5zY2hlbWEuaWQsIGlkU3RyaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRXNjYXBlIFNRTCBMSUtFIHdpbGRjYXJkcyB0byBwcmV2ZW50IHdpbGRjYXJkIGluamVjdGlvblxuICAgICAgY29uc3QgZXNjYXBlZCA9IGVzY2FwZUxpa2VXaWxkY2FyZHMoaWRTdHJpbmcpO1xuICAgICAgcmV0dXJuIHNxbGAke3RoaXMuc2NoZW1hLmlkfTo6dGV4dCBMSUtFICR7ZXNjYXBlZCArICclJ30gRVNDQVBFICdcXFxcJ2A7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGJvb2xlYW4gZmllbGQgY29uZGl0aW9ucyAoaXNEZWZhdWx0LCBpc0FjdGl2ZSlcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9ucyBmb3IgYm9vbGVhbiBmaWVsZHNcbiAgICovXG4gIHByb3RlY3RlZCBidWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcjogUGFydGlhbDxURmlsdGVyPik6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgaWYgKGZpbHRlci5pc0RlZmF1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmlzRGVmYXVsdCwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0RlZmF1bHQpKSk7XG4gICAgfVxuXG4gICAgaWYgKGZpbHRlci5pc0FjdGl2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEuaXNBY3RpdmUsIHBhcnNlQm9vbGVhbkZpbHRlcihmaWx0ZXIuaXNBY3RpdmUpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgdG8gYWN0aXZlIHJlY29yZHMgb25seSB0byBleGNsdWRlIHNvZnQtZGVsZXRlZCBlbnRpdGllc1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmlzQWN0aXZlLCB0cnVlKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgZXhwbGljaXQgYWNjZXNzTW9kaWZpZXIgZmlsdGVyXG4gICAqXG4gICAqIE5vdGU6IFRoaXMgaXMgc2VwYXJhdGUgZnJvbSBhY2Nlc3MgY29udHJvbCBsb2dpYyAtIGl0IGZpbHRlcnMgYnkgdGhlIGV4YWN0XG4gICAqIGFjY2Vzc01vZGlmaWVyIHZhbHVlIHJhdGhlciB0aGFuIGFwcGx5aW5nIG11bHRpLXRlbmFudCBhY2Nlc3MgcnVsZXMuXG4gICAqXG4gICAqIEBwYXJhbSBhY2Nlc3NNb2RpZmllciAtIEFjY2VzcyBtb2RpZmllciBmaWx0ZXIgdmFsdWVcbiAgICogQHJldHVybnMgU1FMIGNvbmRpdGlvbiBvciBudWxsIGlmIG5vIGFjY2Vzc01vZGlmaWVyIGZpbHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQWNjZXNzTW9kaWZpZXJGaWx0ZXIoYWNjZXNzTW9kaWZpZXI6IHVua25vd24pOiBTUUwgfCBudWxsIHtcbiAgICBpZiAoYWNjZXNzTW9kaWZpZXIgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHNxbGAke3RoaXMuc2NoZW1hLmFjY2Vzc01vZGlmaWVyfSA9ICR7bm9ybWFsaXplU3RyaW5nRmlsdGVyKGFjY2Vzc01vZGlmaWVyKX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFsbCBjb21tb24gY29uZGl0aW9ucyAoYWNjZXNzIGNvbnRyb2wgKyBJRCArIGJvb2xlYW5zKVxuICAgKlxuICAgKiBUaGlzIGNvbWJpbmVzIGFsbCB0aGUgZ2VuZXJpYyBmaWx0ZXJzIHRoYXQgYXBwbHkgdG8gYW55IGFjY2Vzcy1jb250cm9sbGVkIGVudGl0eS5cbiAgICogU3ViY2xhc3NlcyBzaG91bGQgY2FsbCB0aGlzIGFuZCBhZGQgZW50aXR5LXNwZWNpZmljIGNvbmRpdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIGZhbGxzIGJhY2sgdG8gc3lzdGVtLXB1YmxpYy1vbmx5KVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9uc1xuICAgKi9cbiAgcHVibGljIGJ1aWxkQ29tbW9uQ29uZGl0aW9ucyhmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgLy8gQWNjZXNzIGNvbnRyb2wgKG11bHRpLXRlbmFudCkg4oCUIGhhbmRsZXMgYWNjZXNzTW9kaWZpZXIgaW50ZXJuYWxseVxuICAgIGNvbmRpdGlvbnMucHVzaCguLi50aGlzLmJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCkpO1xuXG4gICAgLy8gSUQgZmlsdGVyIHdpdGggcHJlZml4IG1hdGNoaW5nXG4gICAgY29uc3QgaWRDb25kaXRpb24gPSB0aGlzLmJ1aWxkSWRGaWx0ZXIoZmlsdGVyLmlkKTtcbiAgICBpZiAoaWRDb25kaXRpb24pIGNvbmRpdGlvbnMucHVzaChpZENvbmRpdGlvbik7XG5cbiAgICAvLyBCb29sZWFuIGZpbHRlcnNcbiAgICBjb25kaXRpb25zLnB1c2goLi4udGhpcy5idWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcikpO1xuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cbn1cbiJdfQ==