@tricoteuses/assemblee 1.0.0-next.2 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +2 -0
  2. package/lib/api.js +23 -7
  3. package/lib/api.mjs +41 -0
  4. package/lib/bugs/acteur-00010/plugin.test.js +139 -33
  5. package/lib/bugs/acteur-00010/plugin.test.mjs +33 -0
  6. package/lib/bugs/acteur-00010.js +166 -24
  7. package/lib/bugs/acteur-00010.mjs +31 -0
  8. package/lib/bugs/agenda-00002/plugin.test.js +178 -52
  9. package/lib/bugs/agenda-00002/plugin.test.mjs +52 -0
  10. package/lib/bugs/agenda-00002.js +507 -143
  11. package/lib/bugs/agenda-00002.mjs +197 -0
  12. package/lib/bugs/agenda-00008/plugin.test.js +143 -31
  13. package/lib/bugs/agenda-00008/plugin.test.mjs +31 -0
  14. package/lib/bugs/agenda-00008.js +180 -25
  15. package/lib/bugs/agenda-00008.mjs +30 -0
  16. package/lib/bugs/agenda-00011/plugin.test.js +371 -156
  17. package/lib/bugs/agenda-00011/plugin.test.mjs +156 -0
  18. package/lib/bugs/agenda-00011.js +416 -117
  19. package/lib/bugs/agenda-00011.mjs +150 -0
  20. package/lib/bugs.js +591 -54
  21. package/lib/bugs.mjs +93 -0
  22. package/lib/cleaners/actes_legislatifs.js +149 -61
  23. package/lib/cleaners/actes_legislatifs.mjs +311 -0
  24. package/lib/cleaners/acteurs.js +255 -123
  25. package/lib/cleaners/acteurs.mjs +211 -0
  26. package/lib/cleaners/amendements.js +242 -117
  27. package/lib/cleaners/amendements.mjs +292 -0
  28. package/lib/cleaners/documents.js +147 -62
  29. package/lib/cleaners/documents.mjs +162 -0
  30. package/lib/cleaners/dossiers_legislatifs.js +132 -45
  31. package/lib/cleaners/dossiers_legislatifs.mjs +123 -0
  32. package/lib/cleaners/index.js +64 -8
  33. package/lib/cleaners/index.mjs +8 -0
  34. package/lib/cleaners/organes.js +54 -21
  35. package/lib/cleaners/organes.mjs +64 -0
  36. package/lib/cleaners/reunions.js +237 -127
  37. package/lib/cleaners/reunions.mjs +318 -0
  38. package/lib/cleaners/scrutins.js +261 -99
  39. package/lib/cleaners/scrutins.mjs +254 -0
  40. package/lib/cleaners/xml.js +81 -16
  41. package/lib/cleaners/xml.mjs +42 -0
  42. package/lib/datasets.js +284 -153
  43. package/lib/datasets.mjs +596 -0
  44. package/lib/dates.js +93 -34
  45. package/lib/dates.mjs +98 -0
  46. package/lib/dossiers_legislatifs.js +107 -33
  47. package/lib/dossiers_legislatifs.mjs +215 -0
  48. package/lib/file_systems.js +203 -35
  49. package/lib/file_systems.mjs +64 -0
  50. package/lib/git.js +139 -41
  51. package/lib/git.mjs +114 -0
  52. package/lib/index.js +310 -16
  53. package/lib/index.mjs +16 -0
  54. package/lib/inserters.js +355 -131
  55. package/lib/inserters.mjs +413 -0
  56. package/lib/loaders.js +900 -440
  57. package/lib/loaders.mjs +678 -0
  58. package/lib/organes.js +15 -5
  59. package/lib/organes.mjs +18 -0
  60. package/lib/parsers/documents.js +241 -89
  61. package/lib/parsers/documents.mjs +433 -0
  62. package/lib/parsers/index.js +36 -3
  63. package/lib/parsers/index.mjs +3 -0
  64. package/lib/parsers/recherche_amendements.js +616 -173
  65. package/lib/parsers/recherche_amendements.mjs +189 -0
  66. package/lib/raw_types/acteurs_et_organes.d.ts +36 -148
  67. package/lib/raw_types/acteurs_et_organes.js +228 -506
  68. package/lib/raw_types/acteurs_et_organes.mjs +1240 -0
  69. package/lib/raw_types/agendas.js +165 -75
  70. package/lib/raw_types/agendas.mjs +944 -0
  71. package/lib/raw_types/amendements.js +165 -77
  72. package/lib/raw_types/amendements.mjs +1040 -0
  73. package/lib/raw_types/dossiers_legislatifs.d.ts +1 -43
  74. package/lib/raw_types/dossiers_legislatifs.js +181 -143
  75. package/lib/raw_types/dossiers_legislatifs.mjs +1792 -0
  76. package/lib/raw_types/scrutins.js +144 -61
  77. package/lib/raw_types/scrutins.mjs +645 -0
  78. package/lib/scripts/bugs_helper.js +657 -155
  79. package/lib/scripts/bugs_helper.mjs +286 -0
  80. package/lib/scripts/clean_data.js +380 -145
  81. package/lib/scripts/clean_data.mjs +190 -0
  82. package/lib/scripts/clean_reorganized_data.js +627 -331
  83. package/lib/scripts/clean_reorganized_data.mjs +520 -0
  84. package/lib/scripts/diff_amendements.js +159 -73
  85. package/lib/scripts/diff_amendements.mjs +234 -0
  86. package/lib/scripts/document_dossiers_legislatifs.js +570 -288
  87. package/lib/scripts/document_dossiers_legislatifs.mjs +494 -0
  88. package/lib/scripts/get_today_reunions.js +37 -20
  89. package/lib/scripts/get_today_reunions.mjs +41 -0
  90. package/lib/scripts/merge_scrutins.js +121 -39
  91. package/lib/scripts/merge_scrutins.mjs +69 -0
  92. package/lib/scripts/parse_textes_lois.js +179 -125
  93. package/lib/scripts/parse_textes_lois.mjs +215 -0
  94. package/lib/scripts/raw_types_from_amendements.js +276 -77
  95. package/lib/scripts/raw_types_from_amendements.mjs +118 -0
  96. package/lib/scripts/reorganize_data.js +867 -446
  97. package/lib/scripts/reorganize_data.mjs +712 -0
  98. package/lib/scripts/retrieve_deputes_photos.js +378 -157
  99. package/lib/scripts/retrieve_deputes_photos.mjs +230 -0
  100. package/lib/scripts/retrieve_documents.js +648 -172
  101. package/lib/scripts/retrieve_documents.mjs +292 -0
  102. package/lib/scripts/retrieve_open_data.js +286 -85
  103. package/lib/scripts/retrieve_open_data.mjs +125 -0
  104. package/lib/scripts/retrieve_pending_amendments.js +302 -69
  105. package/lib/scripts/retrieve_pending_amendments.mjs +130 -0
  106. package/lib/scripts/retrieve_senateurs_photos.js +374 -198
  107. package/lib/scripts/retrieve_senateurs_photos.mjs +277 -0
  108. package/lib/scripts/retrieve_textes_lois.js +343 -89
  109. package/lib/scripts/retrieve_textes_lois.mjs +168 -0
  110. package/lib/scripts/test_load.js +30 -11
  111. package/lib/scripts/test_load.mjs +26 -0
  112. package/lib/scripts/test_load_big_files.js +30 -11
  113. package/lib/scripts/test_load_big_files.mjs +26 -0
  114. package/lib/scripts/validate_json.js +370 -120
  115. package/lib/scripts/validate_json.mjs +216 -0
  116. package/lib/shared_types/codes_actes.js +50 -15
  117. package/lib/shared_types/codes_actes.mjs +228 -0
  118. package/lib/strings.js +16 -3
  119. package/lib/strings.mjs +7 -0
  120. package/lib/types/acteurs_et_organes.js +156 -71
  121. package/lib/types/acteurs_et_organes.mjs +918 -0
  122. package/lib/types/agendas.js +154 -67
  123. package/lib/types/agendas.mjs +623 -0
  124. package/lib/types/amendements.js +166 -77
  125. package/lib/types/amendements.mjs +885 -0
  126. package/lib/types/dossiers_legislatifs.d.ts +1 -42
  127. package/lib/types/dossiers_legislatifs.js +182 -143
  128. package/lib/types/dossiers_legislatifs.mjs +1120 -0
  129. package/lib/types/legislatures.js +12 -3
  130. package/lib/types/legislatures.mjs +9 -0
  131. package/lib/types/scrutins.js +144 -61
  132. package/lib/types/scrutins.mjs +528 -0
  133. package/lib/urls.js +44 -25
  134. package/lib/urls.mjs +201 -0
  135. package/package.json +33 -12
@@ -0,0 +1,292 @@
1
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+
3
+ import commandLineArgs from "command-line-args";
4
+ import commandLineUsage from "command-line-usage";
5
+ import * as git from "../../src/git.mjs";
6
+ import fs from "fs-extra";
7
+
8
+ let fetch = require("node-fetch");
9
+
10
+ import path from "path";
11
+ import { load, getFiles } from "../file_systems.mjs";
12
+ import { DocumentUrlFormat, urlFromDocument } from "../urls.mjs";
13
+
14
+ function parseArgs(argv) {
15
+ const optionsDefinitions = [{
16
+ alias: "c",
17
+ help: "commit documents",
18
+ name: "commit",
19
+ type: Boolean
20
+ }, {
21
+ help: "dry run",
22
+ name: "dry-run",
23
+ type: Boolean
24
+ }, {
25
+ help: "retry failed documents",
26
+ name: "retry-failed",
27
+ type: Boolean
28
+ }, {
29
+ help: "retry all documents",
30
+ name: "retry",
31
+ type: Boolean
32
+ }, {
33
+ alias: "l",
34
+ defaultValue: "16",
35
+ name: "legislature",
36
+ type: String
37
+ }, {
38
+ alias: "r",
39
+ help: "push commit to given remote",
40
+ name: "remote",
41
+ type: String
42
+ }, {
43
+ alias: "s",
44
+ help: "don't log anything",
45
+ name: "silent",
46
+ type: Boolean
47
+ }, {
48
+ help: "textes dir",
49
+ name: "textes",
50
+ type: String
51
+ }, {
52
+ alias: "v",
53
+ help: "verbose logs",
54
+ name: "verbose",
55
+ type: Boolean
56
+ }, {
57
+ defaultOption: true,
58
+ help: "files or globs to documents",
59
+ multiple: true,
60
+ name: "data",
61
+ type: String
62
+ }];
63
+ const sections = [{
64
+ header: "Retrieve documents",
65
+ content: "Retrieve documents"
66
+ }, {
67
+ header: "Options",
68
+ optionList: optionsDefinitions
69
+ }];
70
+ const options = commandLineArgs(optionsDefinitions, {
71
+ argv: argv
72
+ });
73
+
74
+ if ("help" in options) {
75
+ const usage = commandLineUsage(sections);
76
+ console.warn(usage);
77
+ return null;
78
+ }
79
+
80
+ return options;
81
+ }
82
+
83
+ class Retrieve {
84
+ constructor(options) {
85
+ _defineProperty(this, "options", void 0);
86
+
87
+ this.options = options;
88
+ }
89
+
90
+ getDivisions(division) {
91
+ let divisions = [division];
92
+
93
+ if (division.divisions != undefined) {
94
+ for (const d of division.divisions) divisions = divisions.concat(this.getDivisions(d));
95
+ }
96
+
97
+ return divisions;
98
+ }
99
+
100
+ getDivisionsOrDocument(document) {
101
+ if (document.divisions != undefined) return [].concat(...document.divisions.map(d => this.getDivisions(d)));else return [document];
102
+ }
103
+
104
+ async commitAndPush(repositoryDir) {
105
+ if (this.options.commit == undefined) return;
106
+ git.commit(repositoryDir, "Nouvelle moisson");
107
+ if (this.options.remote == undefined) return;
108
+ git.run(repositoryDir, `push ${this.options.remote} HEAD:master`);
109
+ }
110
+
111
+ getUrls(divisionOrDocument, format) {
112
+ const ext = format == "html" ? "raw" : "pdf";
113
+ let urls = [`http://www.assemblee-nationale.fr/dyn/docs/${divisionOrDocument.uid}.${ext}`];
114
+
115
+ if (format == "html") {
116
+ urls.push(urlFromDocument(divisionOrDocument, DocumentUrlFormat.RawHtml));
117
+ urls.push(urlFromDocument(divisionOrDocument, DocumentUrlFormat.Html));
118
+ } else if (format == "pdf") {
119
+ urls.push(urlFromDocument(divisionOrDocument, DocumentUrlFormat.Pdf));
120
+ }
121
+
122
+ return urls;
123
+ }
124
+
125
+ static sanityCheckFormat(page, format) {
126
+ if (format == "pdf") {
127
+ const length = Math.min(page.length, 4);
128
+ const head = page.slice(0, length).toString();
129
+ if (!head.startsWith("%PDF")) return [Buffer.from(""), `bad pdf ${encodeURIComponent(head)}...`];
130
+ } else if (format == "html") {
131
+ const length = Math.min(page.length, 50);
132
+ const head = page.slice(0, length).toString();
133
+
134
+ if (!head.includes("DOCTYPE") && !head.includes("<?xml")) {
135
+ return [Buffer.from(""), `bad html ${encodeURIComponent(head.slice(0, 4))}...`];
136
+ }
137
+ }
138
+
139
+ return [page, "OK"];
140
+ }
141
+
142
+ async needsDownload(filePath, uid) {
143
+ if (fs.existsSync(filePath)) {
144
+ const isNotEmpty = fs.statSync(filePath).size > 0;
145
+ const retryFailed = ("retry-failed" in this.options);
146
+
147
+ if (!retryFailed || isNotEmpty) {
148
+ if (this.options.verbose) {
149
+ if (isNotEmpty) {
150
+ const urlPath = `${filePath}.url`;
151
+ let url;
152
+ if (fs.existsSync(urlPath)) url = fs.readFileSync(urlPath).toString();else url = "<unknown url>";
153
+ console.log(`${uid}: Cached OK ${filePath} from ${url}`);
154
+ } else {
155
+ console.log(`${uid}: Cached FAIL ${filePath}`);
156
+ }
157
+ }
158
+
159
+ return false;
160
+ }
161
+ }
162
+
163
+ return true;
164
+ }
165
+
166
+ async get(url, filePath, format, uid) {
167
+ if (this.options.verbose) console.log(`${uid}: fetch(${url})`);
168
+ const response = await fetch(url);
169
+ let page = await response.buffer();
170
+ let status;
171
+
172
+ if (!response.ok) {
173
+ status = response.status;
174
+
175
+ if (response.status !== 404) {
176
+ if (this.options.verbose) {
177
+ console.error(`Error while getting page "${url}" (uid: ${uid}):\n\nError:\n${JSON.stringify({
178
+ code: response.status,
179
+ message: response.statusText
180
+ }, null, 2)}`);
181
+ }
182
+ }
183
+
184
+ fs.writeFileSync(filePath, "");
185
+ } else {
186
+ ;
187
+ [page, status] = Retrieve.sanityCheckFormat(page, format);
188
+ fs.writeFileSync(filePath, page);
189
+ }
190
+
191
+ return status;
192
+ }
193
+
194
+ static urlFromUid(uid) {
195
+ const url = "https://git.en-root.org/tricoteuses/data.tricoteuses.fr/Dossiers_Legislatifs_XV/-/tree/master/documents";
196
+ return `[${uid}](${url}/uid/${uid}.json)`;
197
+ }
198
+
199
+ async download(textesDir, divisionOrDocument, format) {
200
+ const uid = divisionOrDocument.uid;
201
+ const filePath = `${textesDir}/uid/${uid}.${format}`;
202
+ if (!(await this.needsDownload(filePath, uid))) return 0;
203
+ if (this.options.verbose) console.log(`${uid}: Checking ${filePath}`);
204
+ let success = false;
205
+ let info = "";
206
+ let url;
207
+
208
+ for (url of this.getUrls(divisionOrDocument, format)) {
209
+ if ("dry-run" in this.options) {
210
+ info += ` * ${url}\n`;
211
+ continue;
212
+ } else {
213
+ info += ` * ${url} `;
214
+ }
215
+
216
+ const status = await this.get(url, filePath, format, uid);
217
+ info += `${status}\n`;
218
+
219
+ if (status == "OK") {
220
+ success = true;
221
+ break;
222
+ }
223
+ }
224
+
225
+ const urlPath = `${filePath}.url`;
226
+
227
+ if (success) {
228
+ fs.writeFileSync(urlPath, url);
229
+ } else if (fs.existsSync(urlPath)) {
230
+ fs.unlinkSync(urlPath);
231
+ }
232
+
233
+ if (info != "" && !this.options.silent) {
234
+ console.log(`* ${Retrieve.urlFromUid(uid)}: Retrieving ${filePath}\n${info.slice(0, -1)}`);
235
+ return 1;
236
+ } else {
237
+ return 0;
238
+ }
239
+ }
240
+
241
+ async retrieveDocuments() {
242
+ const gitDir = `${this.options.textes}/.git`;
243
+
244
+ if (!fs.existsSync(gitDir)) {
245
+ console.error(`${gitDir} is expected to exist but does not`);
246
+ return 1;
247
+ }
248
+
249
+ const textesDir = path.join(this.options.textes, this.options.legislature);
250
+ fs.ensureDirSync(`${textesDir}/uid`);
251
+
252
+ for (const filename of getFiles(this.options.data)) {
253
+ const document = load(filename);
254
+ if (/^....SN/.test(document.uid) || /^DECL/.test(document.uid)) continue;
255
+
256
+ for (const divisionOrDocument of this.getDivisionsOrDocument(document)) {
257
+ if (/-COMPA$/.test(divisionOrDocument.uid)) continue;
258
+ let status = 0;
259
+
260
+ for (const format of ["html", "pdf"]) {
261
+ status |= await this.download(textesDir, divisionOrDocument, format);
262
+ }
263
+
264
+ if (status && !this.options.silent) console.log("---");
265
+ }
266
+ }
267
+
268
+ if (!("dry-run" in this.options)) {
269
+ await this.commitAndPush(textesDir);
270
+ }
271
+
272
+ return 0;
273
+ }
274
+
275
+ }
276
+
277
+ async function main(argv) {
278
+ const options = parseArgs(argv);
279
+ if (options === null) return 1;
280
+ const retrieve = new Retrieve(options);
281
+ return retrieve.retrieveDocuments();
282
+ }
283
+ /* istanbul ignore if */
284
+
285
+
286
+ if (process.argv[1].endsWith("retrieve_documents.ts")) main(process.argv).then(status => {
287
+ process.exit(status);
288
+ }).catch(error => {
289
+ console.error(error);
290
+ process.exit(1);
291
+ });
292
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kTGluZUFyZ3MiLCJjb21tYW5kTGluZVVzYWdlIiwiZ2l0IiwiZnMiLCJmZXRjaCIsInJlcXVpcmUiLCJwYXRoIiwibG9hZCIsImdldEZpbGVzIiwiRG9jdW1lbnRVcmxGb3JtYXQiLCJ1cmxGcm9tRG9jdW1lbnQiLCJwYXJzZUFyZ3MiLCJhcmd2Iiwib3B0aW9uc0RlZmluaXRpb25zIiwiYWxpYXMiLCJoZWxwIiwibmFtZSIsInR5cGUiLCJCb29sZWFuIiwiZGVmYXVsdFZhbHVlIiwiU3RyaW5nIiwiZGVmYXVsdE9wdGlvbiIsIm11bHRpcGxlIiwic2VjdGlvbnMiLCJoZWFkZXIiLCJjb250ZW50Iiwib3B0aW9uTGlzdCIsIm9wdGlvbnMiLCJ1c2FnZSIsImNvbnNvbGUiLCJ3YXJuIiwiUmV0cmlldmUiLCJjb25zdHJ1Y3RvciIsImdldERpdmlzaW9ucyIsImRpdmlzaW9uIiwiZGl2aXNpb25zIiwidW5kZWZpbmVkIiwiZCIsImNvbmNhdCIsImdldERpdmlzaW9uc09yRG9jdW1lbnQiLCJkb2N1bWVudCIsIm1hcCIsImNvbW1pdEFuZFB1c2giLCJyZXBvc2l0b3J5RGlyIiwiY29tbWl0IiwicmVtb3RlIiwicnVuIiwiZ2V0VXJscyIsImRpdmlzaW9uT3JEb2N1bWVudCIsImZvcm1hdCIsImV4dCIsInVybHMiLCJ1aWQiLCJwdXNoIiwiUmF3SHRtbCIsIkh0bWwiLCJQZGYiLCJzYW5pdHlDaGVja0Zvcm1hdCIsInBhZ2UiLCJsZW5ndGgiLCJNYXRoIiwibWluIiwiaGVhZCIsInNsaWNlIiwidG9TdHJpbmciLCJzdGFydHNXaXRoIiwiQnVmZmVyIiwiZnJvbSIsImVuY29kZVVSSUNvbXBvbmVudCIsImluY2x1ZGVzIiwibmVlZHNEb3dubG9hZCIsImZpbGVQYXRoIiwiZXhpc3RzU3luYyIsImlzTm90RW1wdHkiLCJzdGF0U3luYyIsInNpemUiLCJyZXRyeUZhaWxlZCIsInZlcmJvc2UiLCJ1cmxQYXRoIiwidXJsIiwicmVhZEZpbGVTeW5jIiwibG9nIiwiZ2V0IiwicmVzcG9uc2UiLCJidWZmZXIiLCJzdGF0dXMiLCJvayIsImVycm9yIiwiSlNPTiIsInN0cmluZ2lmeSIsImNvZGUiLCJtZXNzYWdlIiwic3RhdHVzVGV4dCIsIndyaXRlRmlsZVN5bmMiLCJ1cmxGcm9tVWlkIiwiZG93bmxvYWQiLCJ0ZXh0ZXNEaXIiLCJzdWNjZXNzIiwiaW5mbyIsInVubGlua1N5bmMiLCJzaWxlbnQiLCJyZXRyaWV2ZURvY3VtZW50cyIsImdpdERpciIsInRleHRlcyIsImpvaW4iLCJsZWdpc2xhdHVyZSIsImVuc3VyZURpclN5bmMiLCJmaWxlbmFtZSIsImRhdGEiLCJ0ZXN0IiwibWFpbiIsInJldHJpZXZlIiwicHJvY2VzcyIsImVuZHNXaXRoIiwidGhlbiIsImV4aXQiLCJjYXRjaCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JpcHRzL3JldHJpZXZlX2RvY3VtZW50cy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29tbWFuZExpbmVBcmdzIGZyb20gXCJjb21tYW5kLWxpbmUtYXJnc1wiXG5pbXBvcnQgY29tbWFuZExpbmVVc2FnZSBmcm9tIFwiY29tbWFuZC1saW5lLXVzYWdlXCJcbmltcG9ydCAqIGFzIGdpdCBmcm9tIFwiLi4vLi4vc3JjL2dpdFwiXG5pbXBvcnQgZnMgZnJvbSBcImZzLWV4dHJhXCJcbmxldCBmZXRjaCA9IHJlcXVpcmUoXCJub2RlLWZldGNoXCIpXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5cbmltcG9ydCB7IGxvYWQsIGdldEZpbGVzIH0gZnJvbSBcIi4uL2ZpbGVfc3lzdGVtc1wiXG5pbXBvcnQgeyBEb2N1bWVudFVybEZvcm1hdCwgdXJsRnJvbURvY3VtZW50IH0gZnJvbSBcIi4uL3VybHNcIlxuXG5mdW5jdGlvbiBwYXJzZUFyZ3MoYXJndjogc3RyaW5nW10pOiBhbnkge1xuICBjb25zdCBvcHRpb25zRGVmaW5pdGlvbnMgPSBbXG4gICAge1xuICAgICAgYWxpYXM6IFwiY1wiLFxuICAgICAgaGVscDogXCJjb21taXQgZG9jdW1lbnRzXCIsXG4gICAgICBuYW1lOiBcImNvbW1pdFwiLFxuICAgICAgdHlwZTogQm9vbGVhbixcbiAgICB9LFxuICAgIHtcbiAgICAgIGhlbHA6IFwiZHJ5IHJ1blwiLFxuICAgICAgbmFtZTogXCJkcnktcnVuXCIsXG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgIH0sXG4gICAge1xuICAgICAgaGVscDogXCJyZXRyeSBmYWlsZWQgZG9jdW1lbnRzXCIsXG4gICAgICBuYW1lOiBcInJldHJ5LWZhaWxlZFwiLFxuICAgICAgdHlwZTogQm9vbGVhbixcbiAgICB9LFxuICAgIHtcbiAgICAgIGhlbHA6IFwicmV0cnkgYWxsIGRvY3VtZW50c1wiLFxuICAgICAgbmFtZTogXCJyZXRyeVwiLFxuICAgICAgdHlwZTogQm9vbGVhbixcbiAgICB9LFxuICAgIHtcbiAgICAgIGFsaWFzOiBcImxcIixcbiAgICAgIGRlZmF1bHRWYWx1ZTogXCIxNlwiLFxuICAgICAgbmFtZTogXCJsZWdpc2xhdHVyZVwiLFxuICAgICAgdHlwZTogU3RyaW5nLFxuICAgIH0sXG4gICAge1xuICAgICAgYWxpYXM6IFwiclwiLFxuICAgICAgaGVscDogXCJwdXNoIGNvbW1pdCB0byBnaXZlbiByZW1vdGVcIixcbiAgICAgIG5hbWU6IFwicmVtb3RlXCIsXG4gICAgICB0eXBlOiBTdHJpbmcsXG4gICAgfSxcbiAgICB7XG4gICAgICBhbGlhczogXCJzXCIsXG4gICAgICBoZWxwOiBcImRvbid0IGxvZyBhbnl0aGluZ1wiLFxuICAgICAgbmFtZTogXCJzaWxlbnRcIixcbiAgICAgIHR5cGU6IEJvb2xlYW4sXG4gICAgfSxcbiAgICB7XG4gICAgICBoZWxwOiBcInRleHRlcyBkaXJcIixcbiAgICAgIG5hbWU6IFwidGV4dGVzXCIsXG4gICAgICB0eXBlOiBTdHJpbmcsXG4gICAgfSxcbiAgICB7XG4gICAgICBhbGlhczogXCJ2XCIsXG4gICAgICBoZWxwOiBcInZlcmJvc2UgbG9nc1wiLFxuICAgICAgbmFtZTogXCJ2ZXJib3NlXCIsXG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVmYXVsdE9wdGlvbjogdHJ1ZSxcbiAgICAgIGhlbHA6IFwiZmlsZXMgb3IgZ2xvYnMgdG8gZG9jdW1lbnRzXCIsXG4gICAgICBtdWx0aXBsZTogdHJ1ZSxcbiAgICAgIG5hbWU6IFwiZGF0YVwiLFxuICAgICAgdHlwZTogU3RyaW5nLFxuICAgIH0sXG4gIF1cbiAgY29uc3Qgc2VjdGlvbnMgPSBbXG4gICAge1xuICAgICAgaGVhZGVyOiBcIlJldHJpZXZlIGRvY3VtZW50c1wiLFxuICAgICAgY29udGVudDogXCJSZXRyaWV2ZSBkb2N1bWVudHNcIixcbiAgICB9LFxuICAgIHtcbiAgICAgIGhlYWRlcjogXCJPcHRpb25zXCIsXG4gICAgICBvcHRpb25MaXN0OiBvcHRpb25zRGVmaW5pdGlvbnMsXG4gICAgfSxcbiAgXVxuICBjb25zdCBvcHRpb25zID0gY29tbWFuZExpbmVBcmdzKG9wdGlvbnNEZWZpbml0aW9ucywge1xuICAgIGFyZ3Y6IGFyZ3YsXG4gIH0pXG5cbiAgaWYgKFwiaGVscFwiIGluIG9wdGlvbnMpIHtcbiAgICBjb25zdCB1c2FnZSA9IGNvbW1hbmRMaW5lVXNhZ2Uoc2VjdGlvbnMpXG4gICAgY29uc29sZS53YXJuKHVzYWdlKVxuICAgIHJldHVybiBudWxsXG4gIH1cbiAgcmV0dXJuIG9wdGlvbnNcbn1cblxuY2xhc3MgUmV0cmlldmUge1xuICBvcHRpb25zOiBhbnlcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBhbnkpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIH1cblxuICBnZXREaXZpc2lvbnMoZGl2aXNpb246IGFueSkge1xuICAgIGxldCBkaXZpc2lvbnMgPSBbZGl2aXNpb25dXG4gICAgaWYgKGRpdmlzaW9uLmRpdmlzaW9ucyAhPSB1bmRlZmluZWQpIHtcbiAgICAgIGZvciAoY29uc3QgZCBvZiBkaXZpc2lvbi5kaXZpc2lvbnMpXG4gICAgICAgIGRpdmlzaW9ucyA9IGRpdmlzaW9ucy5jb25jYXQodGhpcy5nZXREaXZpc2lvbnMoZCkpXG4gICAgfVxuICAgIHJldHVybiBkaXZpc2lvbnNcbiAgfVxuXG4gIGdldERpdmlzaW9uc09yRG9jdW1lbnQoZG9jdW1lbnQ6IGFueSkge1xuICAgIGlmIChkb2N1bWVudC5kaXZpc2lvbnMgIT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIFtdLmNvbmNhdChcbiAgICAgICAgLi4uZG9jdW1lbnQuZGl2aXNpb25zLm1hcCgoZDogYW55KSA9PiB0aGlzLmdldERpdmlzaW9ucyhkKSksXG4gICAgICApXG4gICAgZWxzZSByZXR1cm4gW2RvY3VtZW50XVxuICB9XG5cbiAgYXN5bmMgY29tbWl0QW5kUHVzaChyZXBvc2l0b3J5RGlyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5vcHRpb25zLmNvbW1pdCA9PSB1bmRlZmluZWQpIHJldHVyblxuICAgIGdpdC5jb21taXQocmVwb3NpdG9yeURpciwgXCJOb3V2ZWxsZSBtb2lzc29uXCIpXG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnJlbW90ZSA9PSB1bmRlZmluZWQpIHJldHVyblxuICAgIGdpdC5ydW4ocmVwb3NpdG9yeURpciwgYHB1c2ggJHt0aGlzLm9wdGlvbnMucmVtb3RlfSBIRUFEOm1hc3RlcmApXG4gIH1cblxuICBnZXRVcmxzKGRpdmlzaW9uT3JEb2N1bWVudDogYW55LCBmb3JtYXQ6IHN0cmluZykge1xuICAgIGNvbnN0IGV4dCA9IGZvcm1hdCA9PSBcImh0bWxcIiA/IFwicmF3XCIgOiBcInBkZlwiXG4gICAgbGV0IHVybHM6IGFueSA9IFtcbiAgICAgIGBodHRwOi8vd3d3LmFzc2VtYmxlZS1uYXRpb25hbGUuZnIvZHluL2RvY3MvJHtkaXZpc2lvbk9yRG9jdW1lbnQudWlkfS4ke2V4dH1gLFxuICAgIF1cbiAgICBpZiAoZm9ybWF0ID09IFwiaHRtbFwiKSB7XG4gICAgICB1cmxzLnB1c2godXJsRnJvbURvY3VtZW50KGRpdmlzaW9uT3JEb2N1bWVudCwgRG9jdW1lbnRVcmxGb3JtYXQuUmF3SHRtbCkpXG4gICAgICB1cmxzLnB1c2godXJsRnJvbURvY3VtZW50KGRpdmlzaW9uT3JEb2N1bWVudCwgRG9jdW1lbnRVcmxGb3JtYXQuSHRtbCkpXG4gICAgfSBlbHNlIGlmIChmb3JtYXQgPT0gXCJwZGZcIikge1xuICAgICAgdXJscy5wdXNoKHVybEZyb21Eb2N1bWVudChkaXZpc2lvbk9yRG9jdW1lbnQsIERvY3VtZW50VXJsRm9ybWF0LlBkZikpXG4gICAgfVxuICAgIHJldHVybiB1cmxzXG4gIH1cblxuICBzdGF0aWMgc2FuaXR5Q2hlY2tGb3JtYXQocGFnZTogQnVmZmVyLCBmb3JtYXQ6IHN0cmluZyk6IFtCdWZmZXIsIHN0cmluZ10ge1xuICAgIGlmIChmb3JtYXQgPT0gXCJwZGZcIikge1xuICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5taW4ocGFnZS5sZW5ndGgsIDQpXG4gICAgICBjb25zdCBoZWFkID0gcGFnZS5zbGljZSgwLCBsZW5ndGgpLnRvU3RyaW5nKClcbiAgICAgIGlmICghaGVhZC5zdGFydHNXaXRoKFwiJVBERlwiKSlcbiAgICAgICAgcmV0dXJuIFtCdWZmZXIuZnJvbShcIlwiKSwgYGJhZCBwZGYgJHtlbmNvZGVVUklDb21wb25lbnQoaGVhZCl9Li4uYF1cbiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PSBcImh0bWxcIikge1xuICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5taW4ocGFnZS5sZW5ndGgsIDUwKVxuICAgICAgY29uc3QgaGVhZCA9IHBhZ2Uuc2xpY2UoMCwgbGVuZ3RoKS50b1N0cmluZygpXG4gICAgICBpZiAoIWhlYWQuaW5jbHVkZXMoXCJET0NUWVBFXCIpICYmICFoZWFkLmluY2x1ZGVzKFwiPD94bWxcIikpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICBCdWZmZXIuZnJvbShcIlwiKSxcbiAgICAgICAgICBgYmFkIGh0bWwgJHtlbmNvZGVVUklDb21wb25lbnQoaGVhZC5zbGljZSgwLCA0KSl9Li4uYCxcbiAgICAgICAgXVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW3BhZ2UsIFwiT0tcIl1cbiAgfVxuXG4gIGFzeW5jIG5lZWRzRG93bmxvYWQoZmlsZVBhdGg6IHN0cmluZywgdWlkOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhmaWxlUGF0aCkpIHtcbiAgICAgIGNvbnN0IGlzTm90RW1wdHkgPSBmcy5zdGF0U3luYyhmaWxlUGF0aCkuc2l6ZSA+IDBcbiAgICAgIGNvbnN0IHJldHJ5RmFpbGVkID0gXCJyZXRyeS1mYWlsZWRcIiBpbiB0aGlzLm9wdGlvbnNcbiAgICAgIGlmICghcmV0cnlGYWlsZWQgfHwgaXNOb3RFbXB0eSkge1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICBpZiAoaXNOb3RFbXB0eSkge1xuICAgICAgICAgICAgY29uc3QgdXJsUGF0aCA9IGAke2ZpbGVQYXRofS51cmxgXG4gICAgICAgICAgICBsZXQgdXJsXG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyh1cmxQYXRoKSlcbiAgICAgICAgICAgICAgdXJsID0gZnMucmVhZEZpbGVTeW5jKHVybFBhdGgpLnRvU3RyaW5nKClcbiAgICAgICAgICAgIGVsc2UgdXJsID0gXCI8dW5rbm93biB1cmw+XCJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAke3VpZH06IENhY2hlZCBPSyAke2ZpbGVQYXRofSBmcm9tICR7dXJsfWApXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAke3VpZH06IENhY2hlZCBGQUlMICR7ZmlsZVBhdGh9YClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBhc3luYyBnZXQoXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgZmlsZVBhdGg6IHN0cmluZyxcbiAgICBmb3JtYXQ6IHN0cmluZyxcbiAgICB1aWQ6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBpZiAodGhpcy5vcHRpb25zLnZlcmJvc2UpIGNvbnNvbGUubG9nKGAke3VpZH06IGZldGNoKCR7dXJsfSlgKVxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKVxuICAgIGxldCBwYWdlOiBhbnkgPSBhd2FpdCByZXNwb25zZS5idWZmZXIoKVxuICAgIGxldCBzdGF0dXNcbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBzdGF0dXMgPSByZXNwb25zZS5zdGF0dXNcbiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDQwNCkge1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgYEVycm9yIHdoaWxlIGdldHRpbmcgcGFnZSBcIiR7dXJsfVwiICh1aWQ6ICR7dWlkfSk6XFxuXFxuRXJyb3I6XFxuJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgeyBjb2RlOiByZXNwb25zZS5zdGF0dXMsIG1lc3NhZ2U6IHJlc3BvbnNlLnN0YXR1c1RleHQgfSxcbiAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgMixcbiAgICAgICAgICAgICl9YCxcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIFwiXCIpXG4gICAgfSBlbHNlIHtcbiAgICAgIDtbcGFnZSwgc3RhdHVzXSA9IFJldHJpZXZlLnNhbml0eUNoZWNrRm9ybWF0KHBhZ2UsIGZvcm1hdClcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIHBhZ2UpXG4gICAgfVxuICAgIHJldHVybiBzdGF0dXNcbiAgfVxuXG4gIHN0YXRpYyB1cmxGcm9tVWlkKHVpZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB1cmwgPVxuICAgICAgXCJodHRwczovL2dpdC5lbi1yb290Lm9yZy90cmljb3RldXNlcy9kYXRhLnRyaWNvdGV1c2VzLmZyL0Rvc3NpZXJzX0xlZ2lzbGF0aWZzX1hWLy0vdHJlZS9tYXN0ZXIvZG9jdW1lbnRzXCJcbiAgICByZXR1cm4gYFske3VpZH1dKCR7dXJsfS91aWQvJHt1aWR9Lmpzb24pYFxuICB9XG5cbiAgYXN5bmMgZG93bmxvYWQoXG4gICAgdGV4dGVzRGlyOiBzdHJpbmcsXG4gICAgZGl2aXNpb25PckRvY3VtZW50OiBhbnksXG4gICAgZm9ybWF0OiBzdHJpbmcsXG4gICk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgdWlkID0gZGl2aXNpb25PckRvY3VtZW50LnVpZFxuICAgIGNvbnN0IGZpbGVQYXRoID0gYCR7dGV4dGVzRGlyfS91aWQvJHt1aWR9LiR7Zm9ybWF0fWBcbiAgICBpZiAoIShhd2FpdCB0aGlzLm5lZWRzRG93bmxvYWQoZmlsZVBhdGgsIHVpZCkpKSByZXR1cm4gMFxuICAgIGlmICh0aGlzLm9wdGlvbnMudmVyYm9zZSkgY29uc29sZS5sb2coYCR7dWlkfTogQ2hlY2tpbmcgJHtmaWxlUGF0aH1gKVxuICAgIGxldCBzdWNjZXNzID0gZmFsc2VcbiAgICBsZXQgaW5mbyA9IFwiXCJcbiAgICBsZXQgdXJsXG5cbiAgICBmb3IgKHVybCBvZiB0aGlzLmdldFVybHMoZGl2aXNpb25PckRvY3VtZW50LCBmb3JtYXQpKSB7XG4gICAgICBpZiAoXCJkcnktcnVuXCIgaW4gdGhpcy5vcHRpb25zKSB7XG4gICAgICAgIGluZm8gKz0gYCAgKiAke3VybH1cXG5gXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmZvICs9IGAgICogJHt1cmx9IGBcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgdGhpcy5nZXQodXJsLCBmaWxlUGF0aCwgZm9ybWF0LCB1aWQpXG5cbiAgICAgIGluZm8gKz0gYCR7c3RhdHVzfVxcbmBcbiAgICAgIGlmIChzdGF0dXMgPT0gXCJPS1wiKSB7XG4gICAgICAgIHN1Y2Nlc3MgPSB0cnVlXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHVybFBhdGggPSBgJHtmaWxlUGF0aH0udXJsYFxuICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKHVybFBhdGgsIHVybClcbiAgICB9IGVsc2UgaWYgKGZzLmV4aXN0c1N5bmModXJsUGF0aCkpIHtcbiAgICAgIGZzLnVubGlua1N5bmModXJsUGF0aClcbiAgICB9XG4gICAgaWYgKGluZm8gIT0gXCJcIiAmJiAhdGhpcy5vcHRpb25zLnNpbGVudCkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGAqICR7UmV0cmlldmUudXJsRnJvbVVpZCh1aWQpfTogUmV0cmlldmluZyAke2ZpbGVQYXRofVxcbiR7aW5mby5zbGljZShcbiAgICAgICAgICAwLFxuICAgICAgICAgIC0xLFxuICAgICAgICApfWAsXG4gICAgICApXG4gICAgICByZXR1cm4gMVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMFxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHJldHJpZXZlRG9jdW1lbnRzKCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgZ2l0RGlyID0gYCR7dGhpcy5vcHRpb25zLnRleHRlc30vLmdpdGBcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZ2l0RGlyKSkge1xuICAgICAgY29uc29sZS5lcnJvcihgJHtnaXREaXJ9IGlzIGV4cGVjdGVkIHRvIGV4aXN0IGJ1dCBkb2VzIG5vdGApXG4gICAgICByZXR1cm4gMVxuICAgIH1cblxuICAgIGNvbnN0IHRleHRlc0RpciA9IHBhdGguam9pbih0aGlzLm9wdGlvbnMudGV4dGVzLCB0aGlzLm9wdGlvbnMubGVnaXNsYXR1cmUpXG4gICAgZnMuZW5zdXJlRGlyU3luYyhgJHt0ZXh0ZXNEaXJ9L3VpZGApXG5cbiAgICBmb3IgKGNvbnN0IGZpbGVuYW1lIG9mIGdldEZpbGVzKHRoaXMub3B0aW9ucy5kYXRhKSkge1xuICAgICAgY29uc3QgZG9jdW1lbnQgPSBsb2FkKGZpbGVuYW1lKVxuICAgICAgaWYgKC9eLi4uLlNOLy50ZXN0KGRvY3VtZW50LnVpZCkgfHwgL15ERUNMLy50ZXN0KGRvY3VtZW50LnVpZCkpIGNvbnRpbnVlXG4gICAgICBmb3IgKGNvbnN0IGRpdmlzaW9uT3JEb2N1bWVudCBvZiB0aGlzLmdldERpdmlzaW9uc09yRG9jdW1lbnQoZG9jdW1lbnQpKSB7XG4gICAgICAgIGlmICgvLUNPTVBBJC8udGVzdChkaXZpc2lvbk9yRG9jdW1lbnQudWlkKSkgY29udGludWVcbiAgICAgICAgbGV0IHN0YXR1cyA9IDBcbiAgICAgICAgZm9yIChjb25zdCBmb3JtYXQgb2YgW1wiaHRtbFwiLCBcInBkZlwiXSkge1xuICAgICAgICAgIHN0YXR1cyB8PSBhd2FpdCB0aGlzLmRvd25sb2FkKHRleHRlc0RpciwgZGl2aXNpb25PckRvY3VtZW50LCBmb3JtYXQpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXR1cyAmJiAhdGhpcy5vcHRpb25zLnNpbGVudCkgY29uc29sZS5sb2coXCItLS1cIilcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIShcImRyeS1ydW5cIiBpbiB0aGlzLm9wdGlvbnMpKSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbW1pdEFuZFB1c2godGV4dGVzRGlyKVxuICAgIH1cblxuICAgIHJldHVybiAwXG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gbWFpbihhcmd2OiBhbnkpOiBQcm9taXNlPG51bWJlcj4ge1xuICBjb25zdCBvcHRpb25zID0gcGFyc2VBcmdzKGFyZ3YpXG4gIGlmIChvcHRpb25zID09PSBudWxsKSByZXR1cm4gMVxuICBjb25zdCByZXRyaWV2ZSA9IG5ldyBSZXRyaWV2ZShvcHRpb25zKVxuICByZXR1cm4gcmV0cmlldmUucmV0cmlldmVEb2N1bWVudHMoKVxufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbmlmIChwcm9jZXNzLmFyZ3ZbMV0uZW5kc1dpdGgoXCJyZXRyaWV2ZV9kb2N1bWVudHMudHNcIikpXG4gIG1haW4ocHJvY2Vzcy5hcmd2KVxuICAgIC50aGVuKChzdGF0dXMpID0+IHtcbiAgICAgIHByb2Nlc3MuZXhpdChzdGF0dXMpXG4gICAgfSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKVxuICAgICAgcHJvY2Vzcy5leGl0KDEpXG4gICAgfSlcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPQSxlQUFQLE1BQTRCLG1CQUE1QjtBQUNBLE9BQU9DLGdCQUFQLE1BQTZCLG9CQUE3QjtPQUNPLEtBQUtDLEc7QUFDWixPQUFPQyxFQUFQLE1BQWUsVUFBZjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQW5COztBQUNBLE9BQU9DLElBQVAsTUFBaUIsTUFBakI7U0FFU0MsSSxFQUFNQyxRO1NBQ05DLGlCLEVBQW1CQyxlOztBQUU1QixTQUFTQyxTQUFULENBQW1CQyxJQUFuQixFQUF3QztFQUN0QyxNQUFNQyxrQkFBa0IsR0FBRyxDQUN6QjtJQUNFQyxLQUFLLEVBQUUsR0FEVDtJQUVFQyxJQUFJLEVBQUUsa0JBRlI7SUFHRUMsSUFBSSxFQUFFLFFBSFI7SUFJRUMsSUFBSSxFQUFFQztFQUpSLENBRHlCLEVBT3pCO0lBQ0VILElBQUksRUFBRSxTQURSO0lBRUVDLElBQUksRUFBRSxTQUZSO0lBR0VDLElBQUksRUFBRUM7RUFIUixDQVB5QixFQVl6QjtJQUNFSCxJQUFJLEVBQUUsd0JBRFI7SUFFRUMsSUFBSSxFQUFFLGNBRlI7SUFHRUMsSUFBSSxFQUFFQztFQUhSLENBWnlCLEVBaUJ6QjtJQUNFSCxJQUFJLEVBQUUscUJBRFI7SUFFRUMsSUFBSSxFQUFFLE9BRlI7SUFHRUMsSUFBSSxFQUFFQztFQUhSLENBakJ5QixFQXNCekI7SUFDRUosS0FBSyxFQUFFLEdBRFQ7SUFFRUssWUFBWSxFQUFFLElBRmhCO0lBR0VILElBQUksRUFB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