velocious 1.0.480 → 1.0.482

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.
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Single owner of the `schema_migrations` ledger shape and the only place that reads
3
+ * or writes applied migration versions for a database connection. The migrator uses
4
+ * it to record versions as it runs migrations; provisioning / schema-clone paths use
5
+ * `markApplied` / `baselineFromDatabase` to record versions as applied WITHOUT
6
+ * re-running them (the Rails `schema:load` / Flyway `baseline` idea). That keeps the
7
+ * ledger honest when a database's schema was advanced out of band — e.g. by cloning
8
+ * table structure between databases — so the migrator does not later re-run a
9
+ * migration whose schema object already exists.
10
+ */
11
+ export default class MigrationsLedger {
12
+ /**
13
+ * The ledger table name.
14
+ * @returns {string}
15
+ */
16
+ static tableName(): string;
17
+ /**
18
+ * Whether the ledger table exists on the given database.
19
+ * @param {import("./drivers/base.js").default} db
20
+ * @returns {Promise<boolean>}
21
+ */
22
+ static tableExists(db: import("./drivers/base.js").default): Promise<boolean>;
23
+ /**
24
+ * Creates the ledger table if it does not exist. This is the single definition of
25
+ * the `schema_migrations` table shape.
26
+ * @param {import("./drivers/base.js").default} db
27
+ * @returns {Promise<void>}
28
+ */
29
+ static ensureTable(db: import("./drivers/base.js").default): Promise<void>;
30
+ /**
31
+ * Every applied migration version recorded in the ledger.
32
+ * @param {import("./drivers/base.js").default} db
33
+ * @returns {Promise<string[]>}
34
+ */
35
+ static appliedVersions(db: import("./drivers/base.js").default): Promise<string[]>;
36
+ /**
37
+ * Whether the given version is recorded as applied.
38
+ * @param {import("./drivers/base.js").default} db
39
+ * @param {string} version
40
+ * @returns {Promise<boolean>}
41
+ */
42
+ static hasVersion(db: import("./drivers/base.js").default, version: string): Promise<boolean>;
43
+ /**
44
+ * Records a single version as applied. The targeted existence check keeps the
45
+ * migrator's per-migration hot path cheap (no full-table load per migration).
46
+ * @param {import("./drivers/base.js").default} db
47
+ * @param {string} version
48
+ * @returns {Promise<void>}
49
+ */
50
+ static recordVersion(db: import("./drivers/base.js").default, version: string): Promise<void>;
51
+ /**
52
+ * Removes a version from the ledger (used when migrating down).
53
+ * @param {import("./drivers/base.js").default} db
54
+ * @param {string} version
55
+ * @returns {Promise<void>}
56
+ */
57
+ static removeVersion(db: import("./drivers/base.js").default, version: string): Promise<void>;
58
+ /**
59
+ * Baselines a database's ledger: records each version as applied without running
60
+ * its migration. Idempotent — already-recorded versions are skipped. Ensures the
61
+ * ledger table exists first, then loads the existing set once for the whole batch.
62
+ * @param {import("./drivers/base.js").default} db
63
+ * @param {string[]} versions
64
+ * @returns {Promise<string[]>} The versions that were newly recorded.
65
+ */
66
+ static markApplied(db: import("./drivers/base.js").default, versions: string[]): Promise<string[]>;
67
+ /**
68
+ * Baselines `targetDb` to match the applied versions of `sourceDb`. Use when a
69
+ * provisioning path advanced `targetDb`'s schema to match `sourceDb` out of band
70
+ * (e.g. cloning table structure between databases): the migrations are, by
71
+ * construction, already applied on the target, so record them without re-running.
72
+ * @param {{sourceDb: import("./drivers/base.js").default, targetDb: import("./drivers/base.js").default}} args
73
+ * @returns {Promise<string[]>} The versions that were newly recorded on the target.
74
+ */
75
+ static baselineFromDatabase({ sourceDb, targetDb }: {
76
+ sourceDb: import("./drivers/base.js").default;
77
+ targetDb: import("./drivers/base.js").default;
78
+ }): Promise<string[]>;
79
+ }
80
+ //# sourceMappingURL=migrations-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations-ledger.d.ts","sourceRoot":"","sources":["../../../src/database/migrations-ledger.js"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH;IACE;;;OAGG;IACH,oBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,uBAHW,OAAO,mBAAmB,EAAE,OAAO,GACjC,OAAO,CAAC,OAAO,CAAC,CAM5B;IAED;;;;;OAKG;IACH,uBAHW,OAAO,mBAAmB,EAAE,OAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAczB;IAED;;;;OAIG;IACH,2BAHW,OAAO,mBAAmB,EAAE,OAAO,GACjC,OAAO,CAAC,MAAM,EAAE,CAAC,CAM7B;IAED;;;;;OAKG;IACH,sBAJW,OAAO,mBAAmB,EAAE,OAAO,WACnC,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAS5B;IAED;;;;;;OAMG;IACH,yBAJW,OAAO,mBAAmB,EAAE,OAAO,WACnC,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAMzB;IAED;;;;;OAKG;IACH,yBAJW,OAAO,mBAAmB,EAAE,OAAO,WACnC,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAIzB;IAED;;;;;;;OAOG;IACH,uBAJW,OAAO,mBAAmB,EAAE,OAAO,YACnC,MAAM,EAAE,GACN,OAAO,CAAC,MAAM,EAAE,CAAC,CAmB7B;IAED;;;;;;;OAOG;IACH,oDAHW;QAAC,QAAQ,EAAE,OAAO,mBAAmB,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,mBAAmB,EAAE,OAAO,CAAA;KAAC,GAC5F,OAAO,CAAC,MAAM,EAAE,CAAC,CAM7B;CACF"}
@@ -0,0 +1,126 @@
1
+ // @ts-check
2
+ import { digg } from "diggerize";
3
+ import TableData from "./table-data/index.js";
4
+ const TABLE_NAME = "schema_migrations";
5
+ /**
6
+ * Single owner of the `schema_migrations` ledger shape and the only place that reads
7
+ * or writes applied migration versions for a database connection. The migrator uses
8
+ * it to record versions as it runs migrations; provisioning / schema-clone paths use
9
+ * `markApplied` / `baselineFromDatabase` to record versions as applied WITHOUT
10
+ * re-running them (the Rails `schema:load` / Flyway `baseline` idea). That keeps the
11
+ * ledger honest when a database's schema was advanced out of band — e.g. by cloning
12
+ * table structure between databases — so the migrator does not later re-run a
13
+ * migration whose schema object already exists.
14
+ */
15
+ export default class MigrationsLedger {
16
+ /**
17
+ * The ledger table name.
18
+ * @returns {string}
19
+ */
20
+ static tableName() {
21
+ return TABLE_NAME;
22
+ }
23
+ /**
24
+ * Whether the ledger table exists on the given database.
25
+ * @param {import("./drivers/base.js").default} db
26
+ * @returns {Promise<boolean>}
27
+ */
28
+ static async tableExists(db) {
29
+ const table = await db.getTableByName(TABLE_NAME, { throwError: false });
30
+ return Boolean(table);
31
+ }
32
+ /**
33
+ * Creates the ledger table if it does not exist. This is the single definition of
34
+ * the `schema_migrations` table shape.
35
+ * @param {import("./drivers/base.js").default} db
36
+ * @returns {Promise<void>}
37
+ */
38
+ static async ensureTable(db) {
39
+ if (await MigrationsLedger.tableExists(db))
40
+ return;
41
+ const tableData = new TableData(TABLE_NAME, { ifNotExists: true });
42
+ tableData.string("version", { null: false, primaryKey: true });
43
+ for (const sql of await db.createTableSql(tableData)) {
44
+ await db.query(sql);
45
+ }
46
+ db.clearSchemaCache();
47
+ }
48
+ /**
49
+ * Every applied migration version recorded in the ledger.
50
+ * @param {import("./drivers/base.js").default} db
51
+ * @returns {Promise<string[]>}
52
+ */
53
+ static async appliedVersions(db) {
54
+ const rows = await db.select(TABLE_NAME);
55
+ return rows.map((row) => `${digg(row, "version")}`);
56
+ }
57
+ /**
58
+ * Whether the given version is recorded as applied.
59
+ * @param {import("./drivers/base.js").default} db
60
+ * @param {string} version
61
+ * @returns {Promise<boolean>}
62
+ */
63
+ static async hasVersion(db, version) {
64
+ const rows = await db.newQuery()
65
+ .from(TABLE_NAME)
66
+ .where({ version })
67
+ .results();
68
+ return rows.length > 0;
69
+ }
70
+ /**
71
+ * Records a single version as applied. The targeted existence check keeps the
72
+ * migrator's per-migration hot path cheap (no full-table load per migration).
73
+ * @param {import("./drivers/base.js").default} db
74
+ * @param {string} version
75
+ * @returns {Promise<void>}
76
+ */
77
+ static async recordVersion(db, version) {
78
+ if (await MigrationsLedger.hasVersion(db, version))
79
+ return;
80
+ await db.insert({ tableName: TABLE_NAME, data: { version } });
81
+ }
82
+ /**
83
+ * Removes a version from the ledger (used when migrating down).
84
+ * @param {import("./drivers/base.js").default} db
85
+ * @param {string} version
86
+ * @returns {Promise<void>}
87
+ */
88
+ static async removeVersion(db, version) {
89
+ await db.delete({ tableName: TABLE_NAME, conditions: { version } });
90
+ }
91
+ /**
92
+ * Baselines a database's ledger: records each version as applied without running
93
+ * its migration. Idempotent — already-recorded versions are skipped. Ensures the
94
+ * ledger table exists first, then loads the existing set once for the whole batch.
95
+ * @param {import("./drivers/base.js").default} db
96
+ * @param {string[]} versions
97
+ * @returns {Promise<string[]>} The versions that were newly recorded.
98
+ */
99
+ static async markApplied(db, versions) {
100
+ await MigrationsLedger.ensureTable(db);
101
+ const existing = new Set(await MigrationsLedger.appliedVersions(db));
102
+ const recorded = [];
103
+ for (const version of versions) {
104
+ const normalizedVersion = `${version}`;
105
+ if (existing.has(normalizedVersion))
106
+ continue;
107
+ await db.insert({ tableName: TABLE_NAME, data: { version: normalizedVersion } });
108
+ existing.add(normalizedVersion);
109
+ recorded.push(normalizedVersion);
110
+ }
111
+ return recorded;
112
+ }
113
+ /**
114
+ * Baselines `targetDb` to match the applied versions of `sourceDb`. Use when a
115
+ * provisioning path advanced `targetDb`'s schema to match `sourceDb` out of band
116
+ * (e.g. cloning table structure between databases): the migrations are, by
117
+ * construction, already applied on the target, so record them without re-running.
118
+ * @param {{sourceDb: import("./drivers/base.js").default, targetDb: import("./drivers/base.js").default}} args
119
+ * @returns {Promise<string[]>} The versions that were newly recorded on the target.
120
+ */
121
+ static async baselineFromDatabase({ sourceDb, targetDb }) {
122
+ const sourceVersions = await MigrationsLedger.appliedVersions(sourceDb);
123
+ return await MigrationsLedger.markApplied(targetDb, sourceVersions);
124
+ }
125
+ }
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0aW9ucy1sZWRnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvbWlncmF0aW9ucy1sZWRnZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxTQUFTLE1BQU0sdUJBQXVCLENBQUE7QUFFN0MsTUFBTSxVQUFVLEdBQUcsbUJBQW1CLENBQUE7QUFFdEM7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyxnQkFBZ0I7SUFDbkM7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLFNBQVM7UUFDZCxPQUFPLFVBQVUsQ0FBQTtJQUNuQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEVBQUU7UUFDekIsTUFBTSxLQUFLLEdBQUcsTUFBTSxFQUFFLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxFQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFBO1FBRXRFLE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEVBQUU7UUFDekIsSUFBSSxNQUFNLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFBRSxPQUFNO1FBRWxELE1BQU0sU0FBUyxHQUFHLElBQUksU0FBUyxDQUFDLFVBQVUsRUFBRSxFQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO1FBRWhFLFNBQVMsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQTtRQUU1RCxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFDLGNBQWMsQ0FBQyxTQUFT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QUMsQ0FBQTtJQUNyRSxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtkaWdnfSBmcm9tIFwiZGlnZ2VyaXplXCJcbmltcG9ydCBUYWJsZURhdGEgZnJvbSBcIi4vdGFibGUtZGF0YS9pbmRleC5qc1wiXG5cbmNvbnN0IFRBQkxFX05BTUUgPSBcInNjaGVtYV9taWdyYXRpb25zXCJcblxuLyoqXG4gKiBTaW5nbGUgb3duZXIgb2YgdGhlIGBzY2hlbWFfbWlncmF0aW9uc2AgbGVkZ2VyIHNoYXBlIGFuZCB0aGUgb25seSBwbGFjZSB0aGF0IHJlYWRzXG4gKiBvciB3cml0ZXMgYXBwbGllZCBtaWdyYXRpb24gdmVyc2lvbnMgZm9yIGEgZGF0YWJhc2UgY29ubmVjdGlvbi4gVGhlIG1pZ3JhdG9yIHVzZXNcbiAqIGl0IHRvIHJlY29yZCB2ZXJzaW9ucyBhcyBpdCBydW5zIG1pZ3JhdGlvbnM7IHByb3Zpc2lvbmluZyAvIHNjaGVtYS1jbG9uZSBwYXRocyB1c2VcbiAqIGBtYXJrQXBwbGllZGAgLyBgYmFzZWxpbmVGcm9tRGF0YWJhc2VgIHRvIHJlY29yZCB2ZXJzaW9ucyBhcyBhcHBsaWVkIFdJVEhPVVRcbiAqIHJlLXJ1bm5pbmcgdGhlbSAodGhlIFJhaWxzIGBzY2hlbWE6bG9hZGAgLyBGbHl3YXkgYGJhc2VsaW5lYCBpZGVhKS4gVGhhdCBrZWVwcyB0aGVcbiAqIGxlZGdlciBob25lc3Qgd2hlbiBhIGRhdGFiYXNlJ3Mgc2NoZW1hIHdhcyBhZHZhbmNlZCBvdXQgb2YgYmFuZCDigJQgZS5nLiBieSBjbG9uaW5nXG4gKiB0YWJsZSBzdHJ1Y3R1cmUgYmV0d2VlbiBkYXRhYmFzZXMg4oCUIHNvIHRoZSBtaWdyYXRvciBkb2VzIG5vdCBsYXRlciByZS1ydW4gYVxuICogbWlncmF0aW9uIHdob3NlIHNjaGVtYSBvYmplY3QgYWxyZWFkeSBleGlzdHMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1pZ3JhdGlvbnNMZWRnZXIge1xuICAvKipcbiAgICogVGhlIGxlZGdlciB0YWJsZSBuYW1lLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgc3RhdGljIHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gVEFCTEVfTkFNRVxuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGxlZGdlciB0YWJsZSBleGlzdHMgb24gdGhlIGdpdmVuIGRhdGFiYXNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGRiXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHRhYmxlRXhpc3RzKGRiKSB7XG4gICAgY29uc3QgdGFibGUgPSBhd2FpdCBkYi5nZXRUYWJsZUJ5TmFtZShUQUJMRV9OQU1FLCB7dGhyb3dFcnJvcjogZmFsc2V9KVxuXG4gICAgcmV0dXJuIEJvb2xlYW4odGFibGUpXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgbGVkZ2VyIHRhYmxlIGlmIGl0IGRvZXMgbm90IGV4aXN0LiBUaGlzIGlzIHRoZSBzaW5nbGUgZGVmaW5pdGlvbiBvZlxuICAgKiB0aGUgYHNjaGVtYV9taWdyYXRpb25zYCB0YWJsZSBzaGFwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIHN0YXRpYyBhc3luYyBlbnN1cmVUYWJsZShkYikge1xuICAgIGlmIChhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLnRhYmxlRXhpc3RzKGRiKSkgcmV0dXJuXG5cbiAgICBjb25zdCB0YWJsZURhdGEgPSBuZXcgVGFibGVEYXRhKFRBQkxFX05BTUUsIHtpZk5vdEV4aXN0czogdHJ1ZX0pXG5cbiAgICB0YWJsZURhdGEuc3RyaW5nKFwidmVyc2lvblwiLCB7bnVsbDogZmFsc2UsIHByaW1hcnlLZXk6IHRydWV9KVxuXG4gICAgZm9yIChjb25zdCBzcWwgb2YgYXdhaXQgZGIuY3JlYXRlVGFibGVTcWwodGFibGVEYXRhKSkge1xuICAgICAgYXdhaXQgZGIucXVlcnkoc3FsKVxuICAgIH1cblxuICAgIGRiLmNsZWFyU2NoZW1hQ2FjaGUoKVxuICB9XG5cbiAgLyoqXG4gICAqIEV2ZXJ5IGFwcGxpZWQgbWlncmF0aW9uIHZlcnNpb24gcmVjb3JkZWQgaW4gdGhlIGxlZGdlci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59XG4gICAqL1xuICBzdGF0aWMgYXN5bmMgYXBwbGllZFZlcnNpb25zKGRiKSB7XG4gICAgY29uc3Qgcm93cyA9IGF3YWl0IGRiLnNlbGVjdChUQUJMRV9OQU1FKVxuXG4gICAgcmV0dXJuIHJvd3MubWFwKChyb3cpID0+IGAke2RpZ2cocm93LCBcInZlcnNpb25cIil9YClcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBnaXZlbiB2ZXJzaW9uIGlzIHJlY29yZGVkIGFzIGFwcGxpZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZlcnNpb25cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59XG4gICAqL1xuICBzdGF0aWMgYXN5bmMgaGFzVmVyc2lvbihkYiwgdmVyc2lvbikge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBkYi5uZXdRdWVyeSgpXG4gICAgICAuZnJvbShUQUJMRV9OQU1FKVxuICAgICAgLndoZXJlKHt2ZXJzaW9ufSlcbiAgICAgIC5yZXN1bHRzKClcblxuICAgIHJldHVybiByb3dzLmxlbmd0aCA+IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIGEgc2luZ2xlIHZlcnNpb24gYXMgYXBwbGllZC4gVGhlIHRhcmdldGVkIGV4aXN0ZW5jZSBjaGVjayBrZWVwcyB0aGVcbiAgICogbWlncmF0b3IncyBwZXItbWlncmF0aW9uIGhvdCBwYXRoIGNoZWFwIChubyBmdWxsLXRhYmxlIGxvYWQgcGVyIG1pZ3JhdGlvbikuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZlcnNpb25cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcmVjb3JkVmVyc2lvbihkYiwgdmVyc2lvbikge1xuICAgIGlmIChhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLmhhc1ZlcnNpb24oZGIsIHZlcnNpb24pKSByZXR1cm5cblxuICAgIGF3YWl0IGRiLmluc2VydCh7dGFibGVOYW1lOiBUQUJMRV9OQU1FLCBkYXRhOiB7dmVyc2lvbn19KVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSB2ZXJzaW9uIGZyb20gdGhlIGxlZGdlciAodXNlZCB3aGVuIG1pZ3JhdGluZyBkb3duKS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmVyc2lvblxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIHN0YXRpYyBhc3luYyByZW1vdmVWZXJzaW9uKGRiLCB2ZXJzaW9uKSB7XG4gICAgYXdhaXQgZGIuZGVsZXRlKHt0YWJsZU5hbWU6IFRBQkxFX05BTUUsIGNvbmRpdGlvbnM6IHt2ZXJzaW9ufX0pXG4gIH1cblxuICAvKipcbiAgICogQmFzZWxpbmVzIGEgZGF0YWJhc2UncyBsZWRnZXI6IHJlY29yZHMgZWFjaCB2ZXJzaW9uIGFzIGFwcGxpZWQgd2l0aG91dCBydW5uaW5nXG4gICAqIGl0cyBtaWdyYXRpb24uIElkZW1wb3RlbnQg4oCUIGFscmVhZHktcmVjb3JkZWQgdmVyc2lvbnMgYXJlIHNraXBwZWQuIEVuc3VyZXMgdGhlXG4gICAqIGxlZGdlciB0YWJsZSBleGlzdHMgZmlyc3QsIHRoZW4gbG9hZHMgdGhlIGV4aXN0aW5nIHNldCBvbmNlIGZvciB0aGUgd2hvbGUgYmF0Y2guXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGJcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gdmVyc2lvbnNcbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fSBUaGUgdmVyc2lvbnMgdGhhdCB3ZXJlIG5ld2x5IHJlY29yZGVkLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIG1hcmtBcHBsaWVkKGRiLCB2ZXJzaW9ucykge1xuICAgIGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIuZW5zdXJlVGFibGUoZGIpXG5cbiAgICBjb25zdCBleGlzdGluZyA9IG5ldyBTZXQoYXdhaXQgTWlncmF0aW9uc0xlZGdlci5hcHBsaWVkVmVyc2lvbnMoZGIpKVxuICAgIGNvbnN0IHJlY29yZGVkID0gW11cblxuICAgIGZvciAoY29uc3QgdmVyc2lvbiBvZiB2ZXJzaW9ucykge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFZlcnNpb24gPSBgJHt2ZXJzaW9ufWBcblxuICAgICAgaWYgKGV4aXN0aW5nLmhhcyhub3JtYWxpemVkVmVyc2lvbikpIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IGRiLmluc2VydCh7dGFibGVOYW1lOiBUQUJMRV9OQU1FLCBkYXRhOiB7dmVyc2lvbjogbm9ybWFsaXplZFZlcnNpb259fSlcbiAgICAgIGV4aXN0aW5nLmFkZChub3JtYWxpemVkVmVyc2lvbilcbiAgICAgIHJlY29yZGVkLnB1c2gobm9ybWFsaXplZFZlcnNpb24pXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlY29yZGVkXG4gIH1cblxuICAvKipcbiAgICogQmFzZWxpbmVzIGB0YXJnZXREYmAgdG8gbWF0Y2ggdGhlIGFwcGxpZWQgdmVyc2lvbnMgb2YgYHNvdXJjZURiYC4gVXNlIHdoZW4gYVxuICAgKiBwcm92aXNpb25pbmcgcGF0aCBhZHZhbmNlZCBgdGFyZ2V0RGJgJ3Mgc2NoZW1hIHRvIG1hdGNoIGBzb3VyY2VEYmAgb3V0IG9mIGJhbmRcbiAgICogKGUuZy4gY2xvbmluZyB0YWJsZSBzdHJ1Y3R1cmUgYmV0d2VlbiBkYXRhYmFzZXMpOiB0aGUgbWlncmF0aW9ucyBhcmUsIGJ5XG4gICAqIGNvbnN0cnVjdGlvbiwgYWxyZWFkeSBhcHBsaWVkIG9uIHRoZSB0YXJnZXQsIHNvIHJlY29yZCB0aGVtIHdpdGhvdXQgcmUtcnVubmluZy5cbiAgICogQHBhcmFtIHt7c291cmNlRGI6IGltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIHRhcmdldERiOiBpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fX0gYXJnc1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IFRoZSB2ZXJzaW9ucyB0aGF0IHdlcmUgbmV3bHkgcmVjb3JkZWQgb24gdGhlIHRhcmdldC5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBiYXNlbGluZUZyb21EYXRhYmFzZSh7c291cmNlRGIsIHRhcmdldERifSkge1xuICAgIGNvbnN0IHNvdXJjZVZlcnNpb25zID0gYXdhaXQgTWlncmF0aW9uc0xlZGdlci5hcHBsaWVkVmVyc2lvbnMoc291cmNlRGIpXG5cbiAgICByZXR1cm4gYXdhaXQgTWlncmF0aW9uc0xlZGdlci5tYXJrQXBwbGllZCh0YXJnZXREYiwgc291cmNlVmVyc2lvbnMpXG4gIH1cbn1cbiJdfQ==
@@ -1 +1 @@
1
- {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../../../src/database/migrator.js"],"names":[],"mappings":"AASA;IAME;;;;;OAKG;IACH,iEAHG;QAAoD,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;QACrB,mBAAmB;KAC7C,EASA;IAnBD;;yDAEqD;IACrD,oBADU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAC1B;IAarB,qDAAkC;IAClC,0CAA8C;IAC9C,eAA8B;IAGhC;;;;OAIG;IACH,wCAHW,MAAM,GACJ,OAAO,CAMnB;IAGD;;;OAGG;IACH,WAFa,OAAO,CAAC,IAAI,CAAC,CAKzB;IAED;;;OAGG;IACH,yBAFa,OAAO,CAAC,IAAI,CAAC,CAUzB;IAED;;;;;;OAMG;IACH,uDAJG;QAAqB,YAAY,EAAzB,MAAM;QACoC,EAAE,EAA5C,OAAO,mBAAmB,EAAE,OAAO;KAC3C,GAAU,OAAO,CAAC,IAAI,CAAC,CA2BzB;IAED;;;;;OAKG;IACH,qCAJW,MAAM,WACN,MAAM,GACJ,OAAO,CAWnB;IAED;;;;;OAKG;IACH,oBAJW,OAAO,qBAAqB,EAAE,mBAAmB,EAAE,kBACnD,OAAO,qBAAqB,EAAE,0BAA0B,GACtD,OAAO,CAAC,MAAM,CAAC,CA6B3B;IAED;;;;OAIG;IACH,+CAHW,OAAO,qBAAqB,EAAE,2BAA2B,GACvD,OAAO,CAAC,IAAI,CAAC,CA+CzB;IAED;;;OAGG;IACH,oBAFa,OAAO,CAAC,IAAI,CAAC,CAYzB;IAED;;;OAGG;IACH,0BAFa,OAAO,CAAC,IAAI,CAAC,CAYzB;IAED;;;;;;OAMG;IACH,wDAJG;QAAqB,YAAY,EAAzB,MAAM;QACoC,EAAE,EAA5C,OAAO,mBAAmB,EAAE,OAAO;KAC3C,GAAU,OAAO,CAAC,IAAI,CAAC,CAyBzB;IAED;;;;OAIG;IACH,yBAHW,OAAO,mBAAmB,EAAE,OAAO,GACjC,OAAO,CAAC,OAAO,CAAC,CAQ5B;IAED;;;;OAIG;IACH,sCAHW,OAAO,qBAAqB,EAAE,2BAA2B,GACvD,OAAO,CAAC,IAAI,CAAC,CAoCzB;IAED;;;OAGG;IACH,SAFa,OAAO,CAAC,IAAI,CAAC,CAsCzB;IAED;;;;;OAKG;IACH,gBAJW,OAAO,qBAAqB,EAAE,mBAAmB,EAAE,kBACnD,OAAO,qBAAqB,EAAE,0BAA0B,GACtD,OAAO,CAAC,IAAI,CAAC,CAyBzB;IAED;;;OAGG;IACH,2BAFa,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmBvC;IAED;;;;;;;OAOG;IACH,6DALG;QAAgE,SAAS,EAAjE,OAAO,qBAAqB,EAAE,mBAAmB;QACQ,gBAAgB,EAAzE,OAAO,qBAAqB,EAAE,oBAAoB;QACpC,SAAS;KAC/B,GAAU,OAAO,CAAC,OAAO,CAAC,CAiI5B;CACF;mBAtiBkB,cAAc"}
1
+ {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../../../src/database/migrator.js"],"names":[],"mappings":"AASA;IAME;;;;;OAKG;IACH,iEAHG;QAAoD,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;QACrB,mBAAmB;KAC7C,EASA;IAnBD;;yDAEqD;IACrD,oBADU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAC1B;IAarB,qDAAkC;IAClC,0CAA8C;IAC9C,eAA8B;IAGhC;;;;OAIG;IACH,wCAHW,MAAM,GACJ,OAAO,CAMnB;IAGD;;;OAGG;IACH,WAFa,OAAO,CAAC,IAAI,CAAC,CAKzB;IAED;;;OAGG;IACH,yBAFa,OAAO,CAAC,IAAI,CAAC,CAUzB;IAED;;;;;;OAMG;IACH,uDAJG;QAAqB,YAAY,EAAzB,MAAM;QACoC,EAAE,EAA5C,OAAO,mBAAmB,EAAE,OAAO;KAC3C,GAAU,OAAO,CAAC,IAAI,CAAC,CAgBzB;IAED;;;;;OAKG;IACH,qCAJW,MAAM,WACN,MAAM,GACJ,OAAO,CAWnB;IAED;;;;;OAKG;IACH,oBAJW,OAAO,qBAAqB,EAAE,mBAAmB,EAAE,kBACnD,OAAO,qBAAqB,EAAE,0BAA0B,GACtD,OAAO,CAAC,MAAM,CAAC,CA6B3B;IAED;;;;OAIG;IACH,+CAHW,OAAO,qBAAqB,EAAE,2BAA2B,GACvD,OAAO,CAAC,IAAI,CAAC,CA+CzB;IAED;;;OAGG;IACH,oBAFa,OAAO,CAAC,IAAI,CAAC,CAYzB;IAED;;;OAGG;IACH,0BAFa,OAAO,CAAC,IAAI,CAAC,CAYzB;IAED;;;;;;OAMG;IACH,wDAJG;QAAqB,YAAY,EAAzB,MAAM;QACoC,EAAE,EAA5C,OAAO,mBAAmB,EAAE,OAAO;KAC3C,GAAU,OAAO,CAAC,IAAI,CAAC,CAuBzB;IAED;;;;OAIG;IACH,yBAHW,OAAO,mBAAmB,EAAE,OAAO,GACjC,OAAO,CAAC,OAAO,CAAC,CAI5B;IAED;;;;OAIG;IACH,sCAHW,OAAO,qBAAqB,EAAE,2BAA2B,GACvD,OAAO,CAAC,IAAI,CAAC,CAoCzB;IAED;;;OAGG;IACH,SAFa,OAAO,CAAC,IAAI,CAAC,CAsCzB;IAED;;;;;OAKG;IACH,gBAJW,OAAO,qBAAqB,EAAE,mBAAmB,EAAE,kBACnD,OAAO,qBAAqB,EAAE,0BAA0B,GACtD,OAAO,CAAC,IAAI,CAAC,CAyBzB;IAED;;;OAGG;IACH,2BAFa,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmBvC;IAED;;;;;;;OAOG;IACH,6DALG;QAAgE,SAAS,EAAjE,OAAO,qBAAqB,EAAE,mBAAmB;QACQ,gBAAgB,EAAzE,OAAO,qBAAqB,EAAE,oBAAoB;QACpC,SAAS;KAC/B,GAAU,OAAO,CAAC,OAAO,CAAC,CA0H5B;CACF;mBA9gBkB,cAAc"}
@@ -2,9 +2,9 @@
2
2
  import { digg } from "diggerize";
3
3
  import * as inflection from "inflection";
4
4
  import Logger from "../logger.js";
5
+ import MigrationsLedger from "./migrations-ledger.js";
5
6
  import { NotImplementedError } from "./migration/index.js";
6
7
  import restArgsError from "../utils/rest-args-error.js";
7
- import TableData from "./table-data/index.js";
8
8
  export default class VelociousDatabaseMigrator {
9
9
  /**
10
10
  * Migrations versions.
@@ -67,19 +67,12 @@ export default class VelociousDatabaseMigrator {
67
67
  this.logger.debug(`${dbIdentifier} isn't configured for migrations - skipping creating migrations table for it`);
68
68
  return;
69
69
  }
70
- const exists = await this.migrationsTableExist(db);
71
- if (exists) {
70
+ if (await this.migrationsTableExist(db)) {
72
71
  this.logger.debug(`${dbIdentifier} migrations table already exists - skipping`);
73
72
  }
74
73
  else {
75
- this.logger.debug("New TableData for schema_migrations");
76
- const schemaMigrationsTable = new TableData("schema_migrations", { ifNotExists: true });
77
- schemaMigrationsTable.string("version", { null: false, primaryKey: true });
78
- const createSchemaMigrationsTableSqls = await db.createTableSql(schemaMigrationsTable);
79
- for (const createSchemaMigrationsTableSql of createSchemaMigrationsTableSqls) {
80
- this.logger.debug(`Creating migrations table with SQL`, createSchemaMigrationsTableSql);
81
- await db.query(createSchemaMigrationsTableSql);
82
- }
74
+ this.logger.debug("Creating schema_migrations table via MigrationsLedger");
75
+ await MigrationsLedger.ensureTable(db);
83
76
  }
84
77
  }
85
78
  /**
@@ -213,10 +206,9 @@ export default class VelociousDatabaseMigrator {
213
206
  delete this.migrationsVersions[dbIdentifier];
214
207
  return;
215
208
  }
216
- const rows = await db.select("schema_migrations");
209
+ const versions = await MigrationsLedger.appliedVersions(db);
217
210
  this.migrationsVersions[dbIdentifier] = {};
218
- for (const row of rows) {
219
- const version = digg(row, "version");
211
+ for (const version of versions) {
220
212
  this.migrationsVersions[dbIdentifier][version] = true;
221
213
  }
222
214
  }
@@ -226,10 +218,7 @@ export default class VelociousDatabaseMigrator {
226
218
  * @returns {Promise<boolean>} - Resolves with Whether migrations table exist.
227
219
  */
228
220
  async migrationsTableExist(db) {
229
- const schemaTable = await db.getTableByName("schema_migrations", { throwError: false });
230
- if (!schemaTable)
231
- return false;
232
- return true;
221
+ return await MigrationsLedger.tableExists(db);
233
222
  }
234
223
  /**
235
224
  * Runs execute require context.
@@ -451,13 +440,7 @@ export default class VelociousDatabaseMigrator {
451
440
  throw changeError;
452
441
  }
453
442
  }
454
- const existingSchemaMigrations = await db.newQuery()
455
- .from("schema_migrations")
456
- .where({ version: dateString })
457
- .results();
458
- if (existingSchemaMigrations.length == 0) {
459
- await db.insert({ tableName: "schema_migrations", data: { version: dateString } });
460
- }
443
+ await MigrationsLedger.recordVersion(db, dateString);
461
444
  }
462
445
  else if (direction == "down") {
463
446
  try {
@@ -471,7 +454,7 @@ export default class VelociousDatabaseMigrator {
471
454
  throw downError;
472
455
  }
473
456
  }
474
- await db.delete({ tableName: "schema_migrations", conditions: { version: dateString } });
457
+ await MigrationsLedger.removeVersion(db, dateString);
475
458
  }
476
459
  else {
477
460
  throw new Error(`Unknown direction: ${direction}`);
@@ -480,4 +463,4 @@ export default class VelociousDatabaseMigrator {
480
463
  return applied;
481
464
  }
482
465
  }
483
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvbWlncmF0b3IuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDeEMsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ2pDLE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLHNCQUFzQixDQUFBO0FBQ3hELE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sU0FBUyxNQUFNLHVCQUF1QixDQUFBO0FBRTdDLE1BQU0sQ0FBQyxPQUFPLE9BQU8seUJBQXlCO0lBQzVDOzt5REFFcUQ7SUFDckQsa0JBQWtCLEdBQUcsRUFBRSxDQUFBO0lBRXZCOzs7OztPQUtHO0lBQ0gsWUFBWSxFQUFDLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxHQUFHLFFBQVEsRUFBQztRQUMzRCxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUE7UUFFdkIsSUFBSSxDQUFDLGFBQWE7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUE7UUFFekUsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFDbEMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLG1CQUFtQixDQUFBO1FBQzlDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDaEMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCx5QkFBeUIsQ0FBQyxZQUFZO1FBQ3BDLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CO1lBQUUsT0FBTyxJQUFJLENBQUE7UUFFMUMsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBQ3hELENBQUM7SUFHRDs7O09BR0c7SUFD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RSxVQUFVLEVBQUUsRUFBQyxPQUFPLEVBQUUsVUFBVSxFQUFDLEVBQUMsQ0FBQyxDQUFBO1lBQ3RGLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixTQUFTLEVBQUUsQ0FBQyxDQUFBO1lBQ3BELENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUE7SUFDaEIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7ZGlnZ30gZnJvbSBcImRpZ2dlcml6ZVwiXG5pbXBvcnQgKiBhcyBpbmZsZWN0aW9uIGZyb20gXCJpbmZsZWN0aW9uXCJcbmltcG9ydCBMb2dnZXIgZnJvbSBcIi4uL2xvZ2dlci5qc1wiXG5pbXBvcnQge05vdEltcGxlbWVudGVkRXJyb3J9IGZyb20gXCIuL21pZ3JhdGlvbi9pbmRleC5qc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCBUYWJsZURhdGEgZnJvbSBcIi4vdGFibGUtZGF0YS9pbmRleC5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlTWlncmF0b3Ige1xuICAvKipcbiAgICogTWlncmF0aW9ucyB2ZXJzaW9ucy5cbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+Pn0gKi9cbiAgbWlncmF0aW9uc1ZlcnNpb25zID0ge31cblxuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IFthcmdzLmRhdGFiYXNlSWRlbnRpZmllcnNdIC0gT3B0aW9uYWwgZGF0YWJhc2UgaWRlbnRpZmllcnMgdG8gbWlncmF0ZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBkYXRhYmFzZUlkZW50aWZpZXJzLCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuXG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJjb25maWd1cmF0aW9uIGFyZ3VtZW50IGlzIHJlcXVpcmVkXCIpXG5cbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uXG4gICAgdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJzID0gZGF0YWJhc2VJZGVudGlmaWVyc1xuICAgIHRoaXMubG9nZ2VyID0gbmV3IExvZ2dlcih0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlcyBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGJJZGVudGlmaWVyIC0gRGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGlzIG1pZ3JhdG9yIHNob3VsZCB0b3VjaCB0aGUgZGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICovXG4gIGhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSB7XG4gICAgaWYgKCF0aGlzLmRhdGFiYXNlSWRlbnRpZmllcnMpIHJldHVybiB0cnVlXG5cbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJzLmluY2x1ZGVzKGRiSWRlbnRpZmllcilcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJ1bnMgcHJlcGFyZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHByZXBhcmUoKSB7XG4gICAgYXdhaXQgdGhpcy5jcmVhdGVNaWdyYXRpb25zVGFibGUoKVxuICAgIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjcmVhdGUgbWlncmF0aW9ucyB0YWJsZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZU1pZ3JhdGlvbnNUYWJsZSgpIHtcbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIGluIGRicykge1xuICAgICAgaWYgKCF0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSkgY29udGludWVcblxuICAgICAgYXdhaXQgdGhpcy5jcmVhdGVNaWdyYXRpb25zVGFibGVGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYjogZGJzW2RiSWRlbnRpZmllcl19KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNyZWF0ZSBtaWdyYXRpb25zIHRhYmxlIGZvciBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuZGJJZGVudGlmaWVyIC0gRGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBhcmdzLmRiIC0gRGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZU1pZ3JhdGlvbnNUYWJsZUZvckRhdGFiYXNlKHtkYklkZW50aWZpZXIsIGRifSkge1xuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKVxuXG4gICAgaWYgKCFkYXRhYmFzZUNvbmZpZ3VyYXRpb24ubWlncmF0aW9ucykge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBpc24ndCBjb25maWd1cmVkIGZvciBtaWdyYXRpb25zIC0gc2tpcHBpbmcgY3JlYXRpbmcgbWlncmF0aW9ucyB0YWJsZSBmb3IgaXRgKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RzID0gYXdhaXQgdGhpcy5taWdyYXRpb25zVGFibGVFeGlzdChkYilcblxuICAgIGlmIChleGlzdHMpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gbWlncmF0aW9ucyB0YWJsZSBhbHJlYWR5IGV4aXN0cyAtIHNraXBwaW5nYClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXCJOZXcgVGFibGVEYXRhIGZvciBzY2hlbWFfbWlncmF0aW9uc1wiKVxuICAgICAgY29uc3Qgc2NoZW1hTWlncmF0aW9uc1RhYmxlID0gbmV3IFRhYmxlRGF0YShcInNjaGVtYV9taWdyYXRpb25zXCIsIHtpZk5vdEV4aXN0czogdHJ1ZX0pXG5cbiAgICAgIHNjaGVtYU1pZ3JhdGlvbnNUYWJsZS5zdHJpbmcoXCJ2ZXJzaW9uXCIsIHtudWxsOiBmYWxzZSwgcHJpbWFyeUtleTogdHJ1ZX0pXG5cbiAgICAgIGNvbnN0IGNyZWF0ZVNjaGVtYU1pZ3JhdGlvbnNUYWJsZVNxbHMgPSBhd2FpdCBkYi5jcmVhdGVUYWJsZVNxbChzY2hlbWFNaWdyYXRpb25zVGFibGUpXG5cbiAgICAgIGZvciAoY29uc3QgY3JlYXRlU2NoZW1hTWlncmF0aW9uc1RhYmxlU3FsIG9mIGNyZWF0ZVNjaGVtYU1pZ3JhdGlvbnNUYWJsZVNxbHMpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYENyZWF0aW5nIG1pZ3JhdGlvbnMgdGFibGUgd2l0aCBTUUxgLCBjcmVhdGVTY2hlbWFNaWdyYXRpb25zVGFibGVTcWwpXG4gICAgICAgIGF3YWl0IGRiLnF1ZXJ5KGNyZWF0ZVNjaGVtYU1pZ3JhdGlvbnNUYWJsZVNxbClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYXMgcnVuIG1pZ3JhdGlvbiB2ZXJzaW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGJJZGVudGlmaWVyIC0gRGIgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHZlcnNpb24gLSBWZXJzaW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGl0IGhhcyBydW4gbWlncmF0aW9uIHZlcnNpb24uXG4gICAqL1xuICBoYXNSdW5NaWdyYXRpb25WZXJzaW9uKGRiSWRlbnRpZmllciwgdmVyc2lvbikge1xuICAgIGlmICghdGhpcy5taWdyYXRpb25zVmVyc2lvbnMpIHRocm93IG5ldyBFcnJvcihcIk1pZ3JhdGlvbnMgdmVyc2lvbnMgaGFzbid0IGJlZW4gbG9hZGVkIHlldFwiKVxuICAgIGlmICghdGhpcy5taWdyYXRpb25zVmVyc2lvbnNbZGJJZGVudGlmaWVyXSkgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb25zIHZlcnNpb25zIGhhc24ndCBiZWVuIGxvYWRlZCB5ZXQgZm9yIGRiOiAke2RiSWRlbnRpZmllcn1gKVxuXG4gICAgaWYgKHZlcnNpb24gaW4gdGhpcy5taWdyYXRpb25zVmVyc2lvbnNbZGJJZGVudGlmaWVyXSkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1pZ3JhdGUgZmlsZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5NaWdyYXRpb25PYmplY3RUeXBlW119IGZpbGVzIC0gRmlsZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5JbXBvcnRGdWxscGF0aENhbGxiYWNrVHlwZX0gaW1wb3J0Q2FsbGJhY2sgLSBJbXBvcnQgY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59IC0gTnVtYmVyIG9mIG1pZ3JhdGlvbnMgYWN0dWFsbHkgYXBwbGllZCAobm90IHNraXBwZWQgYXMgYWxyZWFkeS1ydW4pLlxuICAgKi9cbiAgYXN5bmMgbWlncmF0ZUZpbGVzKGZpbGVzLCBpbXBvcnRDYWxsYmFjaykge1xuICAgIGxldCBhcHBsaWVkQ291bnQgPSAwXG5cbiAgICBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZW5zdXJlQ29ubmVjdGlvbnMoe25hbWU6IFwiRGF0YWJhc2UgbWlncmF0b3I6IG1pZ3JhdGUgZmlsZXNcIn0sIGFzeW5jICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgbWlncmF0aW9uIG9mIGZpbGVzKSB7XG4gICAgICAgIGNvbnN0IGFwcGxpZWQgPSBhd2FpdCB0aGlzLnJ1bk1pZ3JhdGlvbkZpbGUoe1xuICAgICAgICAgIG1pZ3JhdGlvbixcbiAgICAgICAgICByZXF1aXJlTWlncmF0aW9uOiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIW1pZ3JhdGlvbi5mdWxsUGF0aCkgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb24gZGlkbid0IGhhdmUgYSBmdWxsUGF0aCBrZXk6ICR7T2JqZWN0LmtleXMobWlncmF0aW9uKS5qb2luKFwiLCBcIil9YClcblxuICAgICAgICAgICAgY29uc3QgbWlncmF0aW9uSW1wb3J0ID0gYXdhaXQgaW1wb3J0Q2FsbGJhY2sobWlncmF0aW9uLmZ1bGxQYXRoKVxuXG4gICAgICAgICAgICBpZiAoIW1pZ3JhdGlvbkltcG9ydCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbiBmaWxlIG11c3QgZXhwb3J0IG1pZ3JhdGlvbiBjbGFzczogJHttaWdyYXRpb24uZnVsbFBhdGh9YClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG1pZ3JhdGlvbkltcG9ydFxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICBpZiAoYXBwbGllZCkgYXBwbGllZENvdW50KytcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdGhpcy5fYWZ0ZXJNaWdyYXRpb25zKClcbiAgICB9KVxuXG4gICAgcmV0dXJuIGFwcGxpZWRDb3VudFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbWlncmF0ZSBmaWxlcyBmcm9tIHJlcXVpcmUgY29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLlJlcXVpcmVNaWdyYXRpb25Db250ZXh0VHlwZX0gcmVxdWlyZUNvbnRleHQgLSBSZXF1aXJlIGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBtaWdyYXRlRmlsZXNGcm9tUmVxdWlyZUNvbnRleHQocmVxdWlyZUNvbnRleHQpIHtcbiAgICAvKipcbiAgICAgKiBGaWxlcy5cbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5NaWdyYXRpb25PYmplY3RUeXBlW119ICovXG4gICAgbGV0IGZpbGVzID0gW11cblxuICAgIGZvciAoY29uc3QgZmlsZSBvZiByZXF1aXJlQ29udGV4dC5rZXlzKCkpIHtcbiAgICAgIC8vIFwiMTMsMTRcIiBiZWNhdXNlIHNvbWVzIFwicmVxdWlyZS1jb250ZXh0XCItbnBtLW1vZHVsZSBkZWxldGVzIGZpcnN0IGNoYXJhY3RlciE/XG4gICAgICBjb25zdCBtYXRjaCA9IGZpbGUubWF0Y2goLyhcXGR7MTMsMTR9KS0oLispXFwuanMkLylcblxuICAgICAgaWYgKCFtYXRjaCkgY29udGludWVcblxuICAgICAgLy8gRml4IHJlcXVpcmUtY29udGV4dC1ucG0tbW9kdWxlIGRlbGV0ZXMgZmlyc3QgY2hhcmFjdGVyXG4gICAgICBsZXQgZmlsZU5hbWUgPSBmaWxlXG4gICAgICBsZXQgZGF0ZU51bWJlciA9IG1hdGNoWzFdXG5cbiAgICAgIGlmIChkYXRlTnVtYmVyLmxlbmd0aCA9PSAxMykge1xuICAgICAgICBkYXRlTnVtYmVyID0gYDIke2RhdGVOdW1iZXJ9YFxuICAgICAgICBmaWxlTmFtZSA9IGAyJHtmaWxlTmFtZX1gXG4gICAgICB9XG5cbiAgICAgIC8vIFBhcnNlIHJlZ2V4XG4gICAgICBjb25zdCBkYXRlID0gcGFyc2VJbnQoZGF0ZU51bWJlcilcbiAgICAgIGNvbnN0IG1pZ3JhdGlvbk5hbWUgPSBtYXRjaFsyXVxuICAgICAgY29uc3QgbWlncmF0aW9uQ2xhc3NOYW1lID0gaW5mbGVjdGlvbi5jYW1lbGl6ZShtaWdyYXRpb25OYW1lLnJlcGxhY2VBbGwoXCItXCIsIFwiX1wiKSlcblxuICAgICAgZmlsZXMucHVzaCh7XG4gICAgICAgIGZpbGU6IGZpbGVOYW1lLFxuICAgICAgICBkYXRlLFxuICAgICAgICBtaWdyYXRpb25DbGFzc05hbWVcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgZmlsZXMgPSBmaWxlcy5zb3J0KChtaWdyYXRpb24xLCBtaWdyYXRpb24yKSA9PiBtaWdyYXRpb24xLmRhdGUgLSBtaWdyYXRpb24yLmRhdGUpXG5cbiAgICBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZW5zdXJlQ29ubmVjdGlvbnMoe25hbWU6IFwiRGF0YWJhc2UgbWlncmF0b3I6IG1pZ3JhdGUgcmVxdWlyZS1jb250ZXh0IGZpbGVzXCJ9LCBhc3luYyAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IG1pZ3JhdGlvbiBvZiBmaWxlcykge1xuICAgICAgICBhd2FpdCB0aGlzLnJ1bk1pZ3JhdGlvbkZpbGUoe1xuICAgICAgICAgIG1pZ3JhdGlvbixcbiAgICAgICAgICByZXF1aXJlTWlncmF0aW9uOiBhc3luYyAoKSA9PiByZXF1aXJlQ29udGV4dChtaWdyYXRpb24uZmlsZSkuZGVmYXVsdFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLl9hZnRlck1pZ3JhdGlvbnMoKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhZnRlciBtaWdyYXRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgX2FmdGVyTWlncmF0aW9ucygpIHtcbiAgICBjb25zdCBlbnZpcm9ubWVudEhhbmRsZXIgPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RW52aXJvbm1lbnRIYW5kbGVyKClcbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcbiAgICBjb25zdCBmaWx0ZXJlZERicyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKGRicykuZmlsdGVyKChbZGJJZGVudGlmaWVyXSkgPT4gdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpXG4gICAgKVxuXG4gICAgaWYgKCFlbnZpcm9ubWVudEhhbmRsZXIgfHwgT2JqZWN0LmtleXMoZmlsdGVyZWREYnMpLmxlbmd0aCA9PSAwKSByZXR1cm5cblxuICAgIGF3YWl0IGVudmlyb25tZW50SGFuZGxlci5hZnRlck1pZ3JhdGlvbnMoe2RiczogZmlsdGVyZWREYnN9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbG9hZCBtaWdyYXRpb25zIHZlcnNpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgbG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpIHtcbiAgICB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9ucyA9IHt9XG5cbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIGluIGRicykge1xuICAgICAgaWYgKCF0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSkgY29udGludWVcblxuICAgICAgYXdhaXQgdGhpcy5sb2FkTWlncmF0aW9uc1ZlcnNpb25zRm9yRGF0YWJhc2Uoe2RiSWRlbnRpZmllciwgZGI6IGRic1tkYklkZW50aWZpZXJdfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBsb2FkIG1pZ3JhdGlvbnMgdmVyc2lvbnMgZm9yIGRhdGFiYXNlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5kYklkZW50aWZpZXIgLSBEYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MuZGIgLSBEYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgbG9hZE1pZ3JhdGlvbnNWZXJzaW9uc0ZvckRhdGFiYXNlKHtkYklkZW50aWZpZXIsIGRifSkge1xuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKVxuXG4gICAgaWYgKCFkYXRhYmFzZUNvbmZpZ3VyYXRpb24ubWlncmF0aW9ucykge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBpc24ndCBjb25maWd1cmVkIGZvciBtaWdyYXRpb25zIC0gc2tpcHBpbmcgbG9hZGluZyBtaWdyYXRpb25zIHZlcnNpb25zIGZvciBpdGApXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWF3YWl0IHRoaXMubWlncmF0aW9uc1RhYmxlRXhpc3QoZGIpKSB7XG4gICAgICB0aGlzLmxvZ2dlci5pbmZvKGBNaWdyYXRpb24gdGFibGUgZG9lcyBub3QgZXhpc3QgZm9yICR7ZGJJZGVudGlmaWVyfSAtIHNraXBwaW5nIGxvYWRpbmcgbWlncmF0aW9ucyB2ZXJzaW9ucyBmb3IgaXRgKVxuICAgICAgZGVsZXRlIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl1cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBkYi5zZWxlY3QoXCJzY2hlbWFfbWlncmF0aW9uc1wiKVxuXG4gICAgdGhpcy5taWdyYXRpb25zVmVyc2lvbnNbZGJJZGVudGlmaWVyXSA9IHt9XG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgICBjb25zdCB2ZXJzaW9uID0gZGlnZyhyb3csIFwidmVyc2lvblwiKVxuXG4gICAgICB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdW3ZlcnNpb25dID0gdHJ1ZVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1pZ3JhdGlvbnMgdGFibGUgZXhpc3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGIgLSBEYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBSZXNvbHZlcyB3aXRoIFdoZXRoZXIgbWlncmF0aW9ucyB0YWJsZSBleGlzdC5cbiAgICovXG4gIGFzeW5jIG1pZ3JhdGlvbnNUYWJsZUV4aXN0KGRiKSB7XG4gICAgY29uc3Qgc2NoZW1hVGFibGUgPSBhd2FpdCBkYi5nZXRUYWJsZUJ5TmFtZShcInNjaGVtYV9taWdyYXRpb25zXCIsIHt0aHJvd0Vycm9yOiBmYWxzZX0pXG5cbiAgICBpZiAoIXNjaGVtYVRhYmxlKSByZXR1cm4gZmFsc2VcblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBleGVjdXRlIHJlcXVpcmUgY29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLlJlcXVpcmVNaWdyYXRpb25Db250ZXh0VHlwZX0gcmVxdWlyZUNvbnRleHQgLSBSZXF1aXJlIGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBleGVjdXRlUmVxdWlyZUNvbnRleHQocmVxdWlyZUNvbnRleHQpIHtcbiAgICBjb25zdCBtaWdyYXRpb25GaWxlcyA9IHJlcXVpcmVDb250ZXh0LmtleXMoKVxuXG4gICAgLyoqXG4gICAgICogRmlsZXMuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZVtdfSAqL1xuICAgIGxldCBmaWxlcyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgbWlncmF0aW9uRmlsZXMpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gZmlsZS5tYXRjaCgvXihcXGR7MTR9KS0oLispXFwuanMkLylcblxuICAgICAgaWYgKCFtYXRjaCkgY29udGludWVcblxuICAgICAgY29uc3QgZGF0ZSA9IHBhcnNlSW50KG1hdGNoWzFdKVxuICAgICAgY29uc3QgbWlncmF0aW9uTmFtZSA9IG1hdGNoWzJdXG4gICAgICBjb25zdCBtaWdyYXRpb25DbGFzc05hbWUgPSBpbmZsZWN0aW9uLmNhbWVsaXplKG1pZ3JhdGlvbk5hbWUpXG5cbiAgICAgIGNvbnN0IG1pZ3JhdGlvbk9iamVjdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5NaWdyYXRpb25PYmplY3RUeXBlfSAqLyAoe1xuICAgICAgICBmaWxlLFxuICAgICAgICBkYXRlLFxuICAgICAgICBtaWdyYXRpb25DbGFzc05hbWVcbiAgICAgIH0pXG5cbiAgICAgIGZpbGVzLnB1c2gobWlncmF0aW9uT2JqZWN0KVxuICAgIH1cblxuICAgIGZpbGVzID0gZmlsZXMuc29ydCgobWlncmF0aW9uMSwgbWlncmF0aW9uMikgPT4gbWlncmF0aW9uMS5kYXRlIC0gbWlncmF0aW9uMi5kYXRlKVxuXG4gICAgZm9yIChjb25zdCBtaWdyYXRpb24gb2YgZmlsZXMpIHtcbiAgICAgIGF3YWl0IHRoaXMucnVuTWlncmF0aW9uRmlsZSh7XG4gICAgICAgIG1pZ3JhdGlvbixcbiAgICAgICAgcmVxdWlyZU1pZ3JhdGlvbjogYXN5bmMgKCkgPT4gcmVxdWlyZUNvbnRleHQobWlncmF0aW9uLmZpbGUpLmRlZmF1bHRcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVzZXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyByZXNldCgpIHtcbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIGluIGRicykge1xuICAgICAgaWYgKCF0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSkgY29udGludWVcblxuICAgICAgY29uc3QgZGIgPSBkYnNbZGJJZGVudGlmaWVyXVxuXG4gICAgICBhd2FpdCBkYi53aXRoRGlzYWJsZWRGb3JlaWduS2V5cyhhc3luYyAoKSA9PiB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JzID0gW11cbiAgICAgICAgICBsZXQgYW55VGFibGVEcm9wcGVkID0gZmFsc2VcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRhYmxlIG9mIGF3YWl0IGRiLmdldFRhYmxlcygpKSB7XG4gICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmluZm8oYERyb3BwaW5nIHRhYmxlICR7dGFibGUuZ2V0TmFtZSgpfWApXG5cbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBkYi5kcm9wVGFibGUodGFibGUuZ2V0TmFtZSgpLCB7Y2FzY2FkZTogdHJ1ZX0pXG4gICAgICAgICAgICAgICAgYW55VGFibGVEcm9wcGVkID0gdHJ1ZVxuICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKGVycm9yKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGggPiAwICYmIGFueVRhYmxlRHJvcHBlZCkge1xuICAgICAgICAgICAgICAvLyBSZXRyeVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3JzWzBdXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJvbGxiYWNrLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZVtdfSBmaWxlcyAtIEZpbGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuSW1wb3J0RnVsbHBhdGhDYWxsYmFja1R5cGV9IGltcG9ydENhbGxiYWNrIEZ1bmN0aW9uIHRvIGltcG9ydCBhIGZpbGVcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrKGZpbGVzLCBpbXBvcnRDYWxsYmFjaykge1xuICAgIGNvbnN0IGxhdGVzdE1pZ3JhdGlvblZlcnNpb24gPSBhd2FpdCB0aGlzLl9sYXRlc3RNaWdyYXRpb25WZXJzaW9uKClcblxuICAgIGlmICghbGF0ZXN0TWlncmF0aW9uVmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWlncmF0aW9ucyBoYXZlIGJlZW4gcnVuIHlldFwiKVxuICAgIH1cblxuICAgIGNvbnN0IGxhdGVzdE1pZ3JhdGlvblZlcnNpb25OdW1iZXIgPSBwYXJzZUludChsYXRlc3RNaWdyYXRpb25WZXJzaW9uKVxuICAgIGNvbnN0IG1pZ3JhdGlvbiA9IGZpbGVzLmZpbmQoKGZpbGUpID0+IGZpbGUuZGF0ZSA9PSBsYXRlc3RNaWdyYXRpb25WZXJzaW9uTnVtYmVyKVxuXG4gICAgaWYgKCFtaWdyYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uIGZpbGUgZm9yIHZlcnNpb24gJHtsYXRlc3RNaWdyYXRpb25WZXJzaW9uTnVtYmVyfSBub3QgZm91bmRgKVxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMucnVuTWlncmF0aW9uRmlsZSh7XG4gICAgICBtaWdyYXRpb24sXG4gICAgICByZXF1aXJlTWlncmF0aW9uOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghbWlncmF0aW9uLmZ1bGxQYXRoKSB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbiBkaWRuJ3QgaGF2ZSBhIGZ1bGxQYXRoIGtleTogJHtPYmplY3Qua2V5cyhtaWdyYXRpb24pLmpvaW4oXCIsIFwiKX1gKVxuXG4gICAgICAgIHJldHVybiBhd2FpdCBpbXBvcnRDYWxsYmFjayhtaWdyYXRpb24uZnVsbFBhdGgpXG4gICAgICB9LFxuICAgICAgZGlyZWN0aW9uOiBcImRvd25cIlxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBsYXRlc3QgbWlncmF0aW9uIHZlcnNpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD59IFRoZSBsYXRlc3QgbWlncmF0aW9uIHZlcnNpb25cbiAgICovXG4gIGFzeW5jIF9sYXRlc3RNaWdyYXRpb25WZXJzaW9uKCkge1xuICAgIGlmICghdGhpcy5taWdyYXRpb25zVmVyc2lvbnMpIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpXG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGhpZ2hlc3RWZXJzaW9uLlxuICAgICAqIEB0eXBlIHtzdHJpbmcgfCB1bmRlZmluZWR9ICovXG4gICAgbGV0IGhpZ2hlc3RWZXJzaW9uXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9ucykge1xuICAgICAgZm9yIChjb25zdCBtaWdyYXRpb25WZXJzaW9uIGluIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl0pIHtcbiAgICAgICAgaWYgKCFoaWdoZXN0VmVyc2lvbiB8fCBtaWdyYXRpb25WZXJzaW9uID4gaGlnaGVzdFZlcnNpb24pIHtcbiAgICAgICAgICBoaWdoZXN0VmVyc2lvbiA9IG1pZ3JhdGlvblZlcnNpb25cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBoaWdoZXN0VmVyc2lvblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuIG1pZ3JhdGlvbiBmaWxlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZX0gYXJncy5taWdyYXRpb24gLSBNaWdyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5SZXF1aXJlTWlncmF0aW9uVHlwZX0gYXJncy5yZXF1aXJlTWlncmF0aW9uIC0gUmVxdWlyZSBtaWdyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5kaXJlY3Rpb25dIC0gRGlyZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIHRoZSBtaWdyYXRpb24gcmFuIG9uIGF0IGxlYXN0IG9uZSBkYXRhYmFzZSAoZmFsc2UgaWYgc2tpcHBlZCBhcyBhbHJlYWR5LXJ1biBldmVyeXdoZXJlKS5cbiAgICovXG4gIGFzeW5jIHJ1bk1pZ3JhdGlvbkZpbGUoe21pZ3JhdGlvbiwgcmVxdWlyZU1pZ3JhdGlvbiwgZGlyZWN0aW9uID0gXCJ1cFwifSkge1xuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJObyBjb25maWd1cmF0aW9uIHNldFwiKVxuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uLmlzRGF0YWJhc2VQb29sSW5pdGlhbGl6ZWQoKSkgYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmluaXRpYWxpemVEYXRhYmFzZVBvb2woKVxuICAgIGlmICghdGhpcy5taWdyYXRpb25zVmVyc2lvbnMpIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpXG5cbiAgICBsZXQgYXBwbGllZCA9IGZhbHNlXG4gICAgY29uc3QgZGJzID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG5cbiAgICAvKipcbiAgICAgKiBEYiBpZGVudGlmaWVycyBuZWVkaW5nIG1pZ3JhdGlvbiB2ZXJzaW9ucy5cbiAgICAgKiBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3QgZGJJZGVudGlmaWVyc05lZWRpbmdNaWdyYXRpb25WZXJzaW9ucyA9IFtdXG5cbiAgICAvLyBtaWdyYXRlRmlsZXMoKSB3cmFwcyBleGVjdXRpb24gaW4gZW5zdXJlQ29ubmVjdGlvbnMoKSwgc28gdGhlIGN1cnJlbnRcbiAgICAvLyBhc3luYyBjb250ZXh0IGNhbiBleHBvc2UgREIgaWRlbnRpZmllcnMgbm90IGxvYWRlZCBieSBwcmVwYXJlKCkuXG4gICAgZm9yIChjb25zdCBkYklkZW50aWZpZXIgaW4gZGJzKSB7XG4gICAgICBpZiAoIXRoaXMuaGFuZGxlc0RhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBkYXRhYmFzZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcilcblxuICAgICAgaWYgKCFkYXRhYmFzZUNvbmZpZ3VyYXRpb24ubWlncmF0aW9ucykgY29udGludWVcbiAgICAgIGlmICh0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdKSBjb250aW51ZVxuXG4gICAgICBkYklkZW50aWZpZXJzTmVlZGluZ01pZ3JhdGlvblZlcnNpb25zLnB1c2goZGJJZGVudGlmaWVyKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIG9mIGRiSWRlbnRpZmllcnNOZWVkaW5nTWlncmF0aW9uVmVyc2lvbnMpIHtcbiAgICAgIGNvbnN0IGRiID0gZGJzW2RiSWRlbnRpZmllcl1cblxuICAgICAgYXdhaXQgdGhpcy5jcmVhdGVNaWdyYXRpb25zVGFibGVGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pXG4gICAgICBhd2FpdCB0aGlzLmxvYWRNaWdyYXRpb25zVmVyc2lvbnNGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pXG4gICAgfVxuXG4gICAgY29uc3QgbWlncmF0aW9uQ2xhc3MgPSBhd2FpdCByZXF1aXJlTWlncmF0aW9uKClcblxuICAgIGlmICghbWlncmF0aW9uQ2xhc3MgfHwgdHlwZW9mIG1pZ3JhdGlvbkNsYXNzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9IG11c3QgZXhwb3J0IGEgZGVmYXVsdCBtaWdyYXRpb24gY2xhc3MuIFR5cGU6ICR7dHlwZW9mIG1pZ3JhdGlvbkNsYXNzfWApXG4gICAgfVxuXG4gICAgY29uc3QgbWlncmF0aW9uRGF0YWJhc2VJZGVudGlmaWVycyA9IG1pZ3JhdGlvbkNsYXNzLmdldERhdGFiYXNlSWRlbnRpZmllcnMoKSB8fCBbXCJkZWZhdWx0XCJdXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiBkYnMpIHtcbiAgICAgIGlmICghdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKVxuXG4gICAgICBpZiAoIWRhdGFiYXNlQ29uZmlndXJhdGlvbi5taWdyYXRpb25zKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaXNuJ3QgY29uZmlndXJlZCBmb3IgbWlncmF0aW9ucyAtIHNraXBwaW5nIG1pZ3JhdGlvbiAke2RpZ2cobWlncmF0aW9uLCBcImRhdGVcIil9YClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKCFtaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzLmluY2x1ZGVzKGRiSWRlbnRpZmllcikpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBzaG91bGRuJ3QgcnVuIG1pZ3JhdGlvbiAke21pZ3JhdGlvbi5maWxlfWAsIHttaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzfSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PSBcInVwXCIpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzUnVuTWlncmF0aW9uVmVyc2lvbihkYklkZW50aWZpZXIsIG1pZ3JhdGlvbi5kYXRlKSkge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaGFzIGFscmVhZHkgcnVuIG1pZ3JhdGlvbiAke21pZ3JhdGlvbi5maWxlfWApXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gXCJkb3duXCIpIHtcbiAgICAgICAgaWYgKCF0aGlzLmhhc1J1bk1pZ3JhdGlvblZlcnNpb24oZGJJZGVudGlmaWVyLCBtaWdyYXRpb24uZGF0ZSkpIHtcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHtkYklkZW50aWZpZXJ9IGhhc24ndCBydW4gbWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9YClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGlyZWN0aW9uOiAke2RpcmVjdGlvbn1gKVxuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUnVubmluZyBtaWdyYXRpb24gb24gJHtkYklkZW50aWZpZXJ9OiAke21pZ3JhdGlvbi5maWxlfWAsIHttaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzfSlcblxuICAgICAgYXBwbGllZCA9IHRydWVcbiAgICAgIGNvbnN0IGRiID0gZGJzW2RiSWRlbnRpZmllcl1cbiAgICAgIGNvbnN0IE1pZ3JhdGlvbkNsYXNzID0gbWlncmF0aW9uQ2xhc3NcbiAgICAgIGNvbnN0IG1pZ3JhdGlvbkluc3RhbmNlID0gbmV3IE1pZ3JhdGlvbkNsYXNzKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLFxuICAgICAgICBkYXRhYmFzZUlkZW50aWZpZXI6IGRiSWRlbnRpZmllcixcbiAgICAgICAgZGJcbiAgICAgIH0pXG4gICAgICBjb25zdCBkYXRlU3RyaW5nID0gYCR7ZGlnZyhtaWdyYXRpb24sIFwiZGF0ZVwiKX1gXG5cbiAgICAgIGlmIChkaXJlY3Rpb24gPT0gXCJ1cFwiKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgbWlncmF0aW9uSW5zdGFuY2UuY2hhbmdlKClcbiAgICAgICAgfSBjYXRjaCAoY2hhbmdlRXJyb3IpIHtcbiAgICAgICAgICBpZiAoY2hhbmdlRXJyb3IgaW5zdGFuY2VvZiBOb3RJbXBsZW1lbnRlZEVycm9yKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS51cCgpXG4gICAgICAgICAgICB9IGNhdGNoICh1cEVycm9yKSB7XG4gICAgICAgICAgICAgIGlmICh1cEVycm9yIGluc3RhbmNlb2YgTm90SW1wbGVtZW50ZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2NoYW5nZScgb3IgJ3VwJyBkaWRuJ3QgZXhpc3Qgb24gbWlncmF0aW9uOiAke21pZ3JhdGlvbi5maWxlfWAsIHtjYXVzZTogdXBFcnJvcn0pXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgdXBFcnJvclxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGNoYW5nZUVycm9yXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZXhpc3RpbmdTY2hlbWFNaWdyYXRpb25zID0gYXdhaXQgZGIubmV3UXVlcnkoKVxuICAgICAgICAgIC5mcm9tKFwic2NoZW1hX21pZ3JhdGlvbnNcIilcbiAgICAgICAgICAud2hlcmUoe3ZlcnNpb246IGRhdGVTdHJpbmd9KVxuICAgICAgICAgIC5yZXN1bHRzKClcblxuICAgICAgICBpZiAoZXhpc3RpbmdTY2hlbWFNaWdyYXRpb25zLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgYXdhaXQgZGIuaW5zZXJ0KHt0YWJsZU5hbWU6IFwic2NoZW1hX21pZ3JhdGlvbnNcIiwgZGF0YToge3ZlcnNpb246IGRhdGVTdHJpbmd9fSlcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gXCJkb3duXCIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS5kb3duKClcbiAgICAgICAgfSBjYXRjaCAoZG93bkVycm9yKSB7XG4gICAgICAgICAgaWYgKGRvd25FcnJvciBpbnN0YW5jZW9mIE5vdEltcGxlbWVudGVkRXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2Rvd24nIGRpZG4ndCBleGlzdCBvbiBtaWdyYXRpb246ICR7bWlncmF0aW9uLmZpbGV9IG9yIG1pZ3JhdGluZyBkb3duIHdpdGggYSBjaGFuZ2UgbWV0aG9kIGlzbid0IGN1cnJlbnRseSBzdXBwb3J0ZWRgLCB7Y2F1c2U6IGRvd25FcnJvcn0pXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGRvd25FcnJvclxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IGRiLmRlbGV0ZSh7dGFibGVOYW1lOiBcInNjaGVtYV9taWdyYXRpb25zXCIsIGNvbmRpdGlvbnM6IHt2ZXJzaW9uOiBkYXRlU3RyaW5nfX0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGlyZWN0aW9uOiAke2RpcmVjdGlvbn1gKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhcHBsaWVkXG4gIH1cbn1cbiJdfQ==
466
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvbWlncmF0b3IuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDeEMsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ2pDLE9BQU8sZ0JBQWdCLE1BQU0sd0JBQXdCLENBQUE7QUFDckQsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sc0JBQXNCLENBQUE7QUFDeEQsT0FBTyxhQUFhLE1BQU0sNkJBQTZCLENBQUE7QUFFdkQsTUFBTSxDQUFDLE9BQU8sT0FBTyx5QkFBeUI7SUFDNUM7O3lEQUVxRDtJQUNyRCxrQkFBa0IsR0FBRyxFQUFFLENBQUE7SUFFdkI7Ozs7O09BS0c7SUFDSCxZQUFZLEVBQUMsYUFBYSxFQUFFLG1CQUFtQixFQUFFLEdBQUcsUUFBUSxFQUFDO1FBQzNELGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUV2QixJQUFJLENBQUMsYUFBYTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQTtRQUV6RSxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQTtRQUNsQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsbUJBQW1CLENBQUE7UUFDOUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNoQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILHlCQUF5QixDQUFDLFlBQVk7UUFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUI7WUFBRSxPQUFPLElBQUksQ0FBQTtRQUUxQyxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDeEQsQ0FBQztJQUdEOzs7T0FHRztJ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TUFBTSxTQUFTLENBQUE7b0JBQ2pCLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxNQUFNLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUE7WUFDdEQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLFNBQVMsRUFBRSxDQUFDLENBQUE7WUFDcEQsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQTtJQUNoQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtkaWdnfSBmcm9tIFwiZGlnZ2VyaXplXCJcbmltcG9ydCAqIGFzIGluZmxlY3Rpb24gZnJvbSBcImluZmxlY3Rpb25cIlxuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi4vbG9nZ2VyLmpzXCJcbmltcG9ydCBNaWdyYXRpb25zTGVkZ2VyIGZyb20gXCIuL21pZ3JhdGlvbnMtbGVkZ2VyLmpzXCJcbmltcG9ydCB7Tm90SW1wbGVtZW50ZWRFcnJvcn0gZnJvbSBcIi4vbWlncmF0aW9uL2luZGV4LmpzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNEYXRhYmFzZU1pZ3JhdG9yIHtcbiAgLyoqXG4gICAqIE1pZ3JhdGlvbnMgdmVyc2lvbnMuXG4gICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPj59ICovXG4gIG1pZ3JhdGlvbnNWZXJzaW9ucyA9IHt9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbYXJncy5kYXRhYmFzZUlkZW50aWZpZXJzXSAtIE9wdGlvbmFsIGRhdGFiYXNlIGlkZW50aWZpZXJzIHRvIG1pZ3JhdGUuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgZGF0YWJhc2VJZGVudGlmaWVycywgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICAgIGlmICghY29uZmlndXJhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiY29uZmlndXJhdGlvbiBhcmd1bWVudCBpcyByZXF1aXJlZFwiKVxuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuZGF0YWJhc2VJZGVudGlmaWVycyA9IGRhdGFiYXNlSWRlbnRpZmllcnNcbiAgICB0aGlzLmxvZ2dlciA9IG5ldyBMb2dnZXIodGhpcylcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhbmRsZXMgZGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRiSWRlbnRpZmllciAtIERhdGFiYXNlIGlkZW50aWZpZXIuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhpcyBtaWdyYXRvciBzaG91bGQgdG91Y2ggdGhlIGRhdGFiYXNlIGlkZW50aWZpZXIuXG4gICAqL1xuICBoYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikge1xuICAgIGlmICghdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJzKSByZXR1cm4gdHJ1ZVxuXG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2VJZGVudGlmaWVycy5pbmNsdWRlcyhkYklkZW50aWZpZXIpXG4gIH1cblxuXG4gIC8qKlxuICAgKiBSdW5zIHByZXBhcmUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBwcmVwYXJlKCkge1xuICAgIGF3YWl0IHRoaXMuY3JlYXRlTWlncmF0aW9uc1RhYmxlKClcbiAgICBhd2FpdCB0aGlzLmxvYWRNaWdyYXRpb25zVmVyc2lvbnMoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3JlYXRlIG1pZ3JhdGlvbnMgdGFibGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjcmVhdGVNaWdyYXRpb25zVGFibGUoKSB7XG4gICAgY29uc3QgZGJzID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiBkYnMpIHtcbiAgICAgIGlmICghdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlTWlncmF0aW9uc1RhYmxlRm9yRGF0YWJhc2Uoe2RiSWRlbnRpZmllciwgZGI6IGRic1tkYklkZW50aWZpZXJdfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBjcmVhdGUgbWlncmF0aW9ucyB0YWJsZSBmb3IgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmRiSWRlbnRpZmllciAtIERhdGFiYXNlIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gYXJncy5kYiAtIERhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjcmVhdGVNaWdyYXRpb25zVGFibGVGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pIHtcbiAgICBjb25zdCBkYXRhYmFzZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcilcblxuICAgIGlmICghZGF0YWJhc2VDb25maWd1cmF0aW9uLm1pZ3JhdGlvbnMpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaXNuJ3QgY29uZmlndXJlZCBmb3IgbWlncmF0aW9ucyAtIHNraXBwaW5nIGNyZWF0aW5nIG1pZ3JhdGlvbnMgdGFibGUgZm9yIGl0YClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChhd2FpdCB0aGlzLm1pZ3JhdGlvbnNUYWJsZUV4aXN0KGRiKSkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBtaWdyYXRpb25zIHRhYmxlIGFscmVhZHkgZXhpc3RzIC0gc2tpcHBpbmdgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcIkNyZWF0aW5nIHNjaGVtYV9taWdyYXRpb25zIHRhYmxlIHZpYSBNaWdyYXRpb25zTGVkZ2VyXCIpXG4gICAgICBhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLmVuc3VyZVRhYmxlKGRiKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhcyBydW4gbWlncmF0aW9uIHZlcnNpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkYklkZW50aWZpZXIgLSBEYiBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdmVyc2lvbiAtIFZlcnNpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgaXQgaGFzIHJ1biBtaWdyYXRpb24gdmVyc2lvbi5cbiAgICovXG4gIGhhc1J1bk1pZ3JhdGlvblZlcnNpb24oZGJJZGVudGlmaWVyLCB2ZXJzaW9uKSB7XG4gICAgaWYgKCF0aGlzLm1pZ3JhdGlvbnNWZXJzaW9ucykgdGhyb3cgbmV3IEVycm9yKFwiTWlncmF0aW9ucyB2ZXJzaW9ucyBoYXNuJ3QgYmVlbiBsb2FkZWQgeWV0XCIpXG4gICAgaWYgKCF0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdKSB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbnMgdmVyc2lvbnMgaGFzbid0IGJlZW4gbG9hZGVkIHlldCBmb3IgZGI6ICR7ZGJJZGVudGlmaWVyfWApXG5cbiAgICBpZiAodmVyc2lvbiBpbiB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbWlncmF0ZSBmaWxlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGVbXX0gZmlsZXMgLSBGaWxlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLkltcG9ydEZ1bGxwYXRoQ2FsbGJhY2tUeXBlfSBpbXBvcnRDYWxsYmFjayAtIEltcG9ydCBjYWxsYmFjay5cbiAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn0gLSBOdW1iZXIgb2YgbWlncmF0aW9ucyBhY3R1YWxseSBhcHBsaWVkIChub3Qgc2tpcHBlZCBhcyBhbHJlYWR5LXJ1bikuXG4gICAqL1xuICBhc3luYyBtaWdyYXRlRmlsZXMoZmlsZXMsIGltcG9ydENhbGxiYWNrKSB7XG4gICAgbGV0IGFwcGxpZWRDb3VudCA9IDBcblxuICAgIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyh7bmFtZTogXCJEYXRhYmFzZSBtaWdyYXRvcjogbWlncmF0ZSBmaWxlc1wifSwgYXN5bmMgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBtaWdyYXRpb24gb2YgZmlsZXMpIHtcbiAgICAgICAgY29uc3QgYXBwbGllZCA9IGF3YWl0IHRoaXMucnVuTWlncmF0aW9uRmlsZSh7XG4gICAgICAgICAgbWlncmF0aW9uLFxuICAgICAgICAgIHJlcXVpcmVNaWdyYXRpb246IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGlmICghbWlncmF0aW9uLmZ1bGxQYXRoKSB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbiBkaWRuJ3QgaGF2ZSBhIGZ1bGxQYXRoIGtleTogJHtPYmplY3Qua2V5cyhtaWdyYXRpb24pLmpvaW4oXCIsIFwiKX1gKVxuXG4gICAgICAgICAgICBjb25zdCBtaWdyYXRpb25JbXBvcnQgPSBhd2FpdCBpbXBvcnRDYWxsYmFjayhtaWdyYXRpb24uZnVsbFBhdGgpXG5cbiAgICAgICAgICAgIGlmICghbWlncmF0aW9uSW1wb3J0KSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uIGZpbGUgbXVzdCBleHBvcnQgbWlncmF0aW9uIGNsYXNzOiAke21pZ3JhdGlvbi5mdWxsUGF0aH1gKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbWlncmF0aW9uSW1wb3J0XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChhcHBsaWVkKSBhcHBsaWVkQ291bnQrK1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLl9hZnRlck1pZ3JhdGlvbnMoKVxuICAgIH0pXG5cbiAgICByZXR1cm4gYXBwbGllZENvdW50XG4gIH1cblxuICAvKipcbiAgICogUnVucyBtaWdyYXRlIGZpbGVzIGZyb20gcmVxdWlyZSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuUmVxdWlyZU1pZ3JhdGlvbkNvbnRleHRUeXBlfSByZXF1aXJlQ29udGV4dCAtIFJlcXVpcmUgY29udGV4dC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIG1pZ3JhdGVGaWxlc0Zyb21SZXF1aXJlQ29udGV4dChyZXF1aXJlQ29udGV4dCkge1xuICAgIC8qKlxuICAgICAqIEZpbGVzLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGVbXX0gKi9cbiAgICBsZXQgZmlsZXMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIHJlcXVpcmVDb250ZXh0LmtleXMoKSkge1xuICAgICAgLy8gXCIxMywxNFwiIGJlY2F1c2Ugc29tZXMgXCJyZXF1aXJlLWNvbnRleHRcIi1ucG0tbW9kdWxlIGRlbGV0ZXMgZmlyc3QgY2hhcmFjdGVyIT9cbiAgICAgIGNvbnN0IG1hdGNoID0gZmlsZS5tYXRjaCgvKFxcZHsxMywxNH0pLSguKylcXC5qcyQvKVxuXG4gICAgICBpZiAoIW1hdGNoKSBjb250aW51ZVxuXG4gICAgICAvLyBGaXggcmVxdWlyZS1jb250ZXh0LW5wbS1tb2R1bGUgZGVsZXRlcyBmaXJzdCBjaGFyYWN0ZXJcbiAgICAgIGxldCBmaWxlTmFtZSA9IGZpbGVcbiAgICAgIGxldCBkYXRlTnVtYmVyID0gbWF0Y2hbMV1cblxuICAgICAgaWYgKGRhdGVOdW1iZXIubGVuZ3RoID09IDEzKSB7XG4gICAgICAgIGRhdGVOdW1iZXIgPSBgMiR7ZGF0ZU51bWJlcn1gXG4gICAgICAgIGZpbGVOYW1lID0gYDIke2ZpbGVOYW1lfWBcbiAgICAgIH1cblxuICAgICAgLy8gUGFyc2UgcmVnZXhcbiAgICAgIGNvbnN0IGRhdGUgPSBwYXJzZUludChkYXRlTnVtYmVyKVxuICAgICAgY29uc3QgbWlncmF0aW9uTmFtZSA9IG1hdGNoWzJdXG4gICAgICBjb25zdCBtaWdyYXRpb25DbGFzc05hbWUgPSBpbmZsZWN0aW9uLmNhbWVsaXplKG1pZ3JhdGlvbk5hbWUucmVwbGFjZUFsbChcIi1cIiwgXCJfXCIpKVxuXG4gICAgICBmaWxlcy5wdXNoKHtcbiAgICAgICAgZmlsZTogZmlsZU5hbWUsXG4gICAgICAgIGRhdGUsXG4gICAgICAgIG1pZ3JhdGlvbkNsYXNzTmFtZVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBmaWxlcyA9IGZpbGVzLnNvcnQoKG1pZ3JhdGlvbjEsIG1pZ3JhdGlvbjIpID0+IG1pZ3JhdGlvbjEuZGF0ZSAtIG1pZ3JhdGlvbjIuZGF0ZSlcblxuICAgIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyh7bmFtZTogXCJEYXRhYmFzZSBtaWdyYXRvcjogbWlncmF0ZSByZXF1aXJlLWNvbnRleHQgZmlsZXNcIn0sIGFzeW5jICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgbWlncmF0aW9uIG9mIGZpbGVzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucnVuTWlncmF0aW9uRmlsZSh7XG4gICAgICAgICAgbWlncmF0aW9uLFxuICAgICAgICAgIHJlcXVpcmVNaWdyYXRpb246IGFzeW5jICgpID0+IHJlcXVpcmVDb250ZXh0KG1pZ3JhdGlvbi5maWxlKS5kZWZhdWx0XG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuX2FmdGVyTWlncmF0aW9ucygpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFmdGVyIG1pZ3JhdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBfYWZ0ZXJNaWdyYXRpb25zKCkge1xuICAgIGNvbnN0IGVudmlyb25tZW50SGFuZGxlciA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXRFbnZpcm9ubWVudEhhbmRsZXIoKVxuICAgIGNvbnN0IGRicyA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5nZXRDdXJyZW50Q29ubmVjdGlvbnMoKVxuICAgIGNvbnN0IGZpbHRlcmVkRGJzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMoZGJzKS5maWx0ZXIoKFtkYklkZW50aWZpZXJdKSA9PiB0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSlcbiAgICApXG5cbiAgICBpZiAoIWVudmlyb25tZW50SGFuZGxlciB8fCBPYmplY3Qua2V5cyhmaWx0ZXJlZERicykubGVuZ3RoID09IDApIHJldHVyblxuXG4gICAgYXdhaXQgZW52aXJvbm1lbnRIYW5kbGVyLmFmdGVyTWlncmF0aW9ucyh7ZGJzOiBmaWx0ZXJlZERic30pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBsb2FkIG1pZ3JhdGlvbnMgdmVyc2lvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBsb2FkTWlncmF0aW9uc1ZlcnNpb25zKCkge1xuICAgIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zID0ge31cblxuICAgIGNvbnN0IGRicyA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5nZXRDdXJyZW50Q29ubmVjdGlvbnMoKVxuXG4gICAgZm9yIChjb25zdCBkYklkZW50aWZpZXIgaW4gZGJzKSB7XG4gICAgICBpZiAoIXRoaXMuaGFuZGxlc0RhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpKSBjb250aW51ZVxuXG4gICAgICBhd2FpdCB0aGlzLmxvYWRNaWdyYXRpb25zVmVyc2lvbnNGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYjogZGJzW2RiSWRlbnRpZmllcl19KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGxvYWQgbWlncmF0aW9ucyB2ZXJzaW9ucyBmb3IgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmRiSWRlbnRpZmllciAtIERhdGFiYXNlIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gYXJncy5kYiAtIERhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBsb2FkTWlncmF0aW9uc1ZlcnNpb25zRm9yRGF0YWJhc2Uoe2RiSWRlbnRpZmllciwgZGJ9KSB7XG4gICAgY29uc3QgZGF0YWJhc2VDb25maWd1cmF0aW9uID0gdGhpcy5jb25maWd1cmF0aW9uLmdldERhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpXG5cbiAgICBpZiAoIWRhdGFiYXNlQ29uZmlndXJhdGlvbi5taWdyYXRpb25zKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHtkYklkZW50aWZpZXJ9IGlzbid0IGNvbmZpZ3VyZWQgZm9yIG1pZ3JhdGlvbnMgLSBza2lwcGluZyBsb2FkaW5nIG1pZ3JhdGlvbnMgdmVyc2lvbnMgZm9yIGl0YClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICghYXdhaXQgdGhpcy5taWdyYXRpb25zVGFibGVFeGlzdChkYikpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmluZm8oYE1pZ3JhdGlvbiB0YWJsZSBkb2VzIG5vdCBleGlzdCBmb3IgJHtkYklkZW50aWZpZXJ9IC0gc2tpcHBpbmcgbG9hZGluZyBtaWdyYXRpb25zIHZlcnNpb25zIGZvciBpdGApXG4gICAgICBkZWxldGUgdGhpcy5taWdyYXRpb25zVmVyc2lvbnNbZGJJZGVudGlmaWVyXVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgdmVyc2lvbnMgPSBhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLmFwcGxpZWRWZXJzaW9ucyhkYilcblxuICAgIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl0gPSB7fVxuXG4gICAgZm9yIChjb25zdCB2ZXJzaW9uIG9mIHZlcnNpb25zKSB7XG4gICAgICB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdW3ZlcnNpb25dID0gdHJ1ZVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1pZ3JhdGlvbnMgdGFibGUgZXhpc3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGIgLSBEYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBSZXNvbHZlcyB3aXRoIFdoZXRoZXIgbWlncmF0aW9ucyB0YWJsZSBleGlzdC5cbiAgICovXG4gIGFzeW5jIG1pZ3JhdGlvbnNUYWJsZUV4aXN0KGRiKSB7XG4gICAgcmV0dXJuIGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIudGFibGVFeGlzdHMoZGIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBleGVjdXRlIHJlcXVpcmUgY29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLlJlcXVpcmVNaWdyYXRpb25Db250ZXh0VHlwZX0gcmVxdWlyZUNvbnRleHQgLSBSZXF1aXJlIGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBleGVjdXRlUmVxdWlyZUNvbnRleHQocmVxdWlyZUNvbnRleHQpIHtcbiAgICBjb25zdCBtaWdyYXRpb25GaWxlcyA9IHJlcXVpcmVDb250ZXh0LmtleXMoKVxuXG4gICAgLyoqXG4gICAgICogRmlsZXMuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZVtdfSAqL1xuICAgIGxldCBmaWxlcyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgbWlncmF0aW9uRmlsZXMpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gZmlsZS5tYXRjaCgvXihcXGR7MTR9KS0oLispXFwuanMkLylcblxuICAgICAgaWYgKCFtYXRjaCkgY29udGludWVcblxuICAgICAgY29uc3QgZGF0ZSA9IHBhcnNlSW50KG1hdGNoWzFdKVxuICAgICAgY29uc3QgbWlncmF0aW9uTmFtZSA9IG1hdGNoWzJdXG4gICAgICBjb25zdCBtaWdyYXRpb25DbGFzc05hbWUgPSBpbmZsZWN0aW9uLmNhbWVsaXplKG1pZ3JhdGlvbk5hbWUpXG5cbiAgICAgIGNvbnN0IG1pZ3JhdGlvbk9iamVjdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5NaWdyYXRpb25PYmplY3RUeXBlfSAqLyAoe1xuICAgICAgICBmaWxlLFxuICAgICAgICBkYXRlLFxuICAgICAgICBtaWdyYXRpb25DbGFzc05hbWVcbiAgICAgIH0pXG5cbiAgICAgIGZpbGVzLnB1c2gobWlncmF0aW9uT2JqZWN0KVxuICAgIH1cblxuICAgIGZpbGVzID0gZmlsZXMuc29ydCgobWlncmF0aW9uMSwgbWlncmF0aW9uMikgPT4gbWlncmF0aW9uMS5kYXRlIC0gbWlncmF0aW9uMi5kYXRlKVxuXG4gICAgZm9yIChjb25zdCBtaWdyYXRpb24gb2YgZmlsZXMpIHtcbiAgICAgIGF3YWl0IHRoaXMucnVuTWlncmF0aW9uRmlsZSh7XG4gICAgICAgIG1pZ3JhdGlvbixcbiAgICAgICAgcmVxdWlyZU1pZ3JhdGlvbjogYXN5bmMgKCkgPT4gcmVxdWlyZUNvbnRleHQobWlncmF0aW9uLmZpbGUpLmRlZmF1bHRcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVzZXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyByZXNldCgpIHtcbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIGluIGRicykge1xuICAgICAgaWYgKCF0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSkgY29udGludWVcblxuICAgICAgY29uc3QgZGIgPSBkYnNbZGJJZGVudGlmaWVyXVxuXG4gICAgICBhd2FpdCBkYi53aXRoRGlzYWJsZWRGb3JlaWduS2V5cyhhc3luYyAoKSA9PiB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JzID0gW11cbiAgICAgICAgICBsZXQgYW55VGFibGVEcm9wcGVkID0gZmFsc2VcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRhYmxlIG9mIGF3YWl0IGRiLmdldFRhYmxlcygpKSB7XG4gICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmluZm8oYERyb3BwaW5nIHRhYmxlICR7dGFibGUuZ2V0TmFtZSgpfWApXG5cbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBkYi5kcm9wVGFibGUodGFibGUuZ2V0TmFtZSgpLCB7Y2FzY2FkZTogdHJ1ZX0pXG4gICAgICAgICAgICAgICAgYW55VGFibGVEcm9wcGVkID0gdHJ1ZVxuICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKGVycm9yKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGggPiAwICYmIGFueVRhYmxlRHJvcHBlZCkge1xuICAgICAgICAgICAgICAvLyBSZXRyeVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3JzWzBdXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJvbGxiYWNrLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZVtdfSBmaWxlcyAtIEZpbGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuSW1wb3J0RnVsbHBhdGhDYWxsYmFja1R5cGV9IGltcG9ydENhbGxiYWNrIEZ1bmN0aW9uIHRvIGltcG9ydCBhIGZpbGVcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrKGZpbGVzLCBpbXBvcnRDYWxsYmFjaykge1xuICAgIGNvbnN0IGxhdGVzdE1pZ3JhdGlvblZlcnNpb24gPSBhd2FpdCB0aGlzLl9sYXRlc3RNaWdyYXRpb25WZXJzaW9uKClcblxuICAgIGlmICghbGF0ZXN0TWlncmF0aW9uVmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWlncmF0aW9ucyBoYXZlIGJlZW4gcnVuIHlldFwiKVxuICAgIH1cblxuICAgIGNvbnN0IGxhdGVzdE1pZ3JhdGlvblZlcnNpb25OdW1iZXIgPSBwYXJzZUludChsYXRlc3RNaWdyYXRpb25WZXJzaW9uKVxuICAgIGNvbnN0IG1pZ3JhdGlvbiA9IGZpbGVzLmZpbmQoKGZpbGUpID0+IGZpbGUuZGF0ZSA9PSBsYXRlc3RNaWdyYXRpb25WZXJzaW9uTnVtYmVyKVxuXG4gICAgaWYgKCFtaWdyYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uIGZpbGUgZm9yIHZlcnNpb24gJHtsYXRlc3RNaWdyYXRpb25WZXJzaW9uTnVtYmVyfSBub3QgZm91bmRgKVxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMucnVuTWlncmF0aW9uRmlsZSh7XG4gICAgICBtaWdyYXRpb24sXG4gICAgICByZXF1aXJlTWlncmF0aW9uOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghbWlncmF0aW9uLmZ1bGxQYXRoKSB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbiBkaWRuJ3QgaGF2ZSBhIGZ1bGxQYXRoIGtleTogJHtPYmplY3Qua2V5cyhtaWdyYXRpb24pLmpvaW4oXCIsIFwiKX1gKVxuXG4gICAgICAgIHJldHVybiBhd2FpdCBpbXBvcnRDYWxsYmFjayhtaWdyYXRpb24uZnVsbFBhdGgpXG4gICAgICB9LFxuICAgICAgZGlyZWN0aW9uOiBcImRvd25cIlxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBsYXRlc3QgbWlncmF0aW9uIHZlcnNpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD59IFRoZSBsYXRlc3QgbWlncmF0aW9uIHZlcnNpb25cbiAgICovXG4gIGFzeW5jIF9sYXRlc3RNaWdyYXRpb25WZXJzaW9uKCkge1xuICAgIGlmICghdGhpcy5taWdyYXRpb25zVmVyc2lvbnMpIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpXG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGhpZ2hlc3RWZXJzaW9uLlxuICAgICAqIEB0eXBlIHtzdHJpbmcgfCB1bmRlZmluZWR9ICovXG4gICAgbGV0IGhpZ2hlc3RWZXJzaW9uXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9ucykge1xuICAgICAgZm9yIChjb25zdCBtaWdyYXRpb25WZXJzaW9uIGluIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl0pIHtcbiAgICAgICAgaWYgKCFoaWdoZXN0VmVyc2lvbiB8fCBtaWdyYXRpb25WZXJzaW9uID4gaGlnaGVzdFZlcnNpb24pIHtcbiAgICAgICAgICBoaWdoZXN0VmVyc2lvbiA9IG1pZ3JhdGlvblZlcnNpb25cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBoaWdoZXN0VmVyc2lvblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuIG1pZ3JhdGlvbiBmaWxlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZX0gYXJncy5taWdyYXRpb24gLSBNaWdyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5SZXF1aXJlTWlncmF0aW9uVHlwZX0gYXJncy5yZXF1aXJlTWlncmF0aW9uIC0gUmVxdWlyZSBtaWdyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5kaXJlY3Rpb25dIC0gRGlyZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIHRoZSBtaWdyYXRpb24gcmFuIG9uIGF0IGxlYXN0IG9uZSBkYXRhYmFzZSAoZmFsc2UgaWYgc2tpcHBlZCBhcyBhbHJlYWR5LXJ1biBldmVyeXdoZXJlKS5cbiAgICovXG4gIGFzeW5jIHJ1bk1pZ3JhdGlvbkZpbGUoe21pZ3JhdGlvbiwgcmVxdWlyZU1pZ3JhdGlvbiwgZGlyZWN0aW9uID0gXCJ1cFwifSkge1xuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJObyBjb25maWd1cmF0aW9uIHNldFwiKVxuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uLmlzRGF0YWJhc2VQb29sSW5pdGlhbGl6ZWQoKSkgYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmluaXRpYWxpemVEYXRhYmFzZVBvb2woKVxuICAgIGlmICghdGhpcy5taWdyYXRpb25zVmVyc2lvbnMpIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpXG5cbiAgICBsZXQgYXBwbGllZCA9IGZhbHNlXG4gICAgY29uc3QgZGJzID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG5cbiAgICAvKipcbiAgICAgKiBEYiBpZGVudGlmaWVycyBuZWVkaW5nIG1pZ3JhdGlvbiB2ZXJzaW9ucy5cbiAgICAgKiBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3QgZGJJZGVudGlmaWVyc05lZWRpbmdNaWdyYXRpb25WZXJzaW9ucyA9IFtdXG5cbiAgICAvLyBtaWdyYXRlRmlsZXMoKSB3cmFwcyBleGVjdXRpb24gaW4gZW5zdXJlQ29ubmVjdGlvbnMoKSwgc28gdGhlIGN1cnJlbnRcbiAgICAvLyBhc3luYyBjb250ZXh0IGNhbiBleHBvc2UgREIgaWRlbnRpZmllcnMgbm90IGxvYWRlZCBieSBwcmVwYXJlKCkuXG4gICAgZm9yIChjb25zdCBkYklkZW50aWZpZXIgaW4gZGJzKSB7XG4gICAgICBpZiAoIXRoaXMuaGFuZGxlc0RhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBkYXRhYmFzZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcilcblxuICAgICAgaWYgKCFkYXRhYmFzZUNvbmZpZ3VyYXRpb24ubWlncmF0aW9ucykgY29udGludWVcbiAgICAgIGlmICh0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdKSBjb250aW51ZVxuXG4gICAgICBkYklkZW50aWZpZXJzTmVlZGluZ01pZ3JhdGlvblZlcnNpb25zLnB1c2goZGJJZGVudGlmaWVyKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIG9mIGRiSWRlbnRpZmllcnNOZWVkaW5nTWlncmF0aW9uVmVyc2lvbnMpIHtcbiAgICAgIGNvbnN0IGRiID0gZGJzW2RiSWRlbnRpZmllcl1cblxuICAgICAgYXdhaXQgdGhpcy5jcmVhdGVNaWdyYXRpb25zVGFibGVGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pXG4gICAgICBhd2FpdCB0aGlzLmxvYWRNaWdyYXRpb25zVmVyc2lvbnNGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pXG4gICAgfVxuXG4gICAgY29uc3QgbWlncmF0aW9uQ2xhc3MgPSBhd2FpdCByZXF1aXJlTWlncmF0aW9uKClcblxuICAgIGlmICghbWlncmF0aW9uQ2xhc3MgfHwgdHlwZW9mIG1pZ3JhdGlvbkNsYXNzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9IG11c3QgZXhwb3J0IGEgZGVmYXVsdCBtaWdyYXRpb24gY2xhc3MuIFR5cGU6ICR7dHlwZW9mIG1pZ3JhdGlvbkNsYXNzfWApXG4gICAgfVxuXG4gICAgY29uc3QgbWlncmF0aW9uRGF0YWJhc2VJZGVudGlmaWVycyA9IG1pZ3JhdGlvbkNsYXNzLmdldERhdGFiYXNlSWRlbnRpZmllcnMoKSB8fCBbXCJkZWZhdWx0XCJdXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiBkYnMpIHtcbiAgICAgIGlmICghdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKVxuXG4gICAgICBpZiAoIWRhdGFiYXNlQ29uZmlndXJhdGlvbi5taWdyYXRpb25zKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaXNuJ3QgY29uZmlndXJlZCBmb3IgbWlncmF0aW9ucyAtIHNraXBwaW5nIG1pZ3JhdGlvbiAke2RpZ2cobWlncmF0aW9uLCBcImRhdGVcIil9YClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKCFtaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzLmluY2x1ZGVzKGRiSWRlbnRpZmllcikpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBzaG91bGRuJ3QgcnVuIG1pZ3JhdGlvbiAke21pZ3JhdGlvbi5maWxlfWAsIHttaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzfSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PSBcInVwXCIpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzUnVuTWlncmF0aW9uVmVyc2lvbihkYklkZW50aWZpZXIsIG1pZ3JhdGlvbi5kYXRlKSkge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaGFzIGFscmVhZHkgcnVuIG1pZ3JhdGlvbiAke21pZ3JhdGlvbi5maWxlfWApXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gXCJkb3duXCIpIHtcbiAgICAgICAgaWYgKCF0aGlzLmhhc1J1bk1pZ3JhdGlvblZlcnNpb24oZGJJZGVudGlmaWVyLCBtaWdyYXRpb24uZGF0ZSkpIHtcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHtkYklkZW50aWZpZXJ9IGhhc24ndCBydW4gbWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9YClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGlyZWN0aW9uOiAke2RpcmVjdGlvbn1gKVxuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUnVubmluZyBtaWdyYXRpb24gb24gJHtkYklkZW50aWZpZXJ9OiAke21pZ3JhdGlvbi5maWxlfWAsIHttaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzfSlcblxuICAgICAgYXBwbGllZCA9IHRydWVcbiAgICAgIGNvbnN0IGRiID0gZGJzW2RiSWRlbnRpZmllcl1cbiAgICAgIGNvbnN0IE1pZ3JhdGlvbkNsYXNzID0gbWlncmF0aW9uQ2xhc3NcbiAgICAgIGNvbnN0IG1pZ3JhdGlvbkluc3RhbmNlID0gbmV3IE1pZ3JhdGlvbkNsYXNzKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLFxuICAgICAgICBkYXRhYmFzZUlkZW50aWZpZXI6IGRiSWRlbnRpZmllcixcbiAgICAgICAgZGJcbiAgICAgIH0pXG4gICAgICBjb25zdCBkYXRlU3RyaW5nID0gYCR7ZGlnZyhtaWdyYXRpb24sIFwiZGF0ZVwiKX1gXG5cbiAgICAgIGlmIChkaXJlY3Rpb24gPT0gXCJ1cFwiKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgbWlncmF0aW9uSW5zdGFuY2UuY2hhbmdlKClcbiAgICAgICAgfSBjYXRjaCAoY2hhbmdlRXJyb3IpIHtcbiAgICAgICAgICBpZiAoY2hhbmdlRXJyb3IgaW5zdGFuY2VvZiBOb3RJbXBsZW1lbnRlZEVycm9yKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS51cCgpXG4gICAgICAgICAgICB9IGNhdGNoICh1cEVycm9yKSB7XG4gICAgICAgICAgICAgIGlmICh1cEVycm9yIGluc3RhbmNlb2YgTm90SW1wbGVtZW50ZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2NoYW5nZScgb3IgJ3VwJyBkaWRuJ3QgZXhpc3Qgb24gbWlncmF0aW9uOiAke21pZ3JhdGlvbi5maWxlfWAsIHtjYXVzZTogdXBFcnJvcn0pXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgdXBFcnJvclxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGNoYW5nZUVycm9yXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgTWlncmF0aW9uc0xlZGdlci5yZWNvcmRWZXJzaW9uKGRiLCBkYXRlU3RyaW5nKVxuICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gXCJkb3duXCIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS5kb3duKClcbiAgICAgICAgfSBjYXRjaCAoZG93bkVycm9yKSB7XG4gICAgICAgICAgaWYgKGRvd25FcnJvciBpbnN0YW5jZW9mIE5vdEltcGxlbWVudGVkRXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2Rvd24nIGRpZG4ndCBleGlzdCBvbiBtaWdyYXRpb246ICR7bWlncmF0aW9uLmZpbGV9IG9yIG1pZ3JhdGluZyBkb3duIHdpdGggYSBjaGFuZ2UgbWV0aG9kIGlzbid0IGN1cnJlbnRseSBzdXBwb3J0ZWRgLCB7Y2F1c2U6IGRvd25FcnJvcn0pXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGRvd25FcnJvclxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIucmVtb3ZlVmVyc2lvbihkYiwgZGF0ZVN0cmluZylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkaXJlY3Rpb246ICR7ZGlyZWN0aW9ufWApXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGFwcGxpZWRcbiAgfVxufVxuIl19