@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,189 @@
1
+ import assert from "assert"; // Note: "/index.js" added to imports, because of issue
2
+ // https://github.com/date-fns/date-fns/issues/2964
3
+
4
+ import formatISO from "date-fns/formatISO/index.js";
5
+ import frLocale from "date-fns/locale/fr/index.js";
6
+ import parseDate from "date-fns/parse/index.js";
7
+ import deepEqual from "deep-equal";
8
+ import fs from "fs-extra";
9
+ import frontMatter from "front-matter";
10
+ import jsYaml from "js-yaml";
11
+ import fetch from "node-fetch";
12
+ import { parse as parseHtml } from "node-html-parser";
13
+ import path from "path";
14
+ import { cleanAmendement } from "../cleaners/index.mjs";
15
+ import { Convert as AmendementsConvert } from "../types/amendements.mjs";
16
+ export async function* iterRechercheAmendements(amendementsSearchCacheDir, url, incremental, minDateDepot, minDateExamen, options = {}) {
17
+ for await (const [amendementUrlPath, amendement] of iterRechercheRawAmendements(amendementsSearchCacheDir, url, incremental, minDateDepot, minDateExamen, options)) {
18
+ cleanAmendement(amendement); // Double conversion, to convert strings to dates.
19
+
20
+ yield [amendementUrlPath, AmendementsConvert.toAmendement(JSON.stringify(amendement))];
21
+ }
22
+ }
23
+ export async function* iterRechercheRawAmendements(amendementsSearchCacheDir, url, incremental, minDateDepot, minDateExamen, options = {}) {
24
+ await fs.ensureDir(amendementsSearchCacheDir);
25
+ assert.strictEqual(/[?&]date_depot=/.exec(url), null, `URL ${url} already contains a deposit date`);
26
+ assert.strictEqual(/[?&]order=/.exec(url), null, `URL ${url} already contains a sort order`);
27
+ assert.strictEqual(/[?&]page=/.exec(url), null, `URL ${url} already contains a page number`);
28
+
29
+ if (incremental) {
30
+ assert.notStrictEqual(/[?&]etat=/.exec(url), null, `In incremental mode, URL ${url} must contain an "etat" query parameter`);
31
+ }
32
+
33
+ url += (url.includes("?") ? "&" : "?") + "order=date_depot,desc&page=1";
34
+
35
+ if (minDateDepot != null) {
36
+ assert.notStrictEqual(/\d{4}-\d{2}-\d{2}/.exec(minDateDepot), null, `Invalid format for minimum date: ${minDateDepot}`);
37
+ }
38
+
39
+ let amendementNumber = 0;
40
+
41
+ iterSearchPages: while (true) {
42
+ if (options.verbose) {
43
+ console.log(`Fetching amendements search page at ${url}…`);
44
+ }
45
+
46
+ const response = await fetch(url);
47
+ assert(response.ok, `Retrieval of search page at ${url} failed with error: ${response.status} ${response.statusText}`);
48
+ const page = await response.text();
49
+ const html = parseHtml(page);
50
+
51
+ if (html.querySelector("div.no-result") !== null) {
52
+ break;
53
+ }
54
+
55
+ const amendementsCountDiv = html.querySelector("div.mirror-card-subtitle");
56
+ assert.notStrictEqual(amendementsCountDiv, null);
57
+ const amendementsCount = parseInt(/\d+/.exec(amendementsCountDiv.text)[0]);
58
+ const amendementsDiv = html.querySelector("div.amendement-list--results-table");
59
+ assert.notStrictEqual(amendementsDiv, null);
60
+ const amendementsTable = amendementsDiv.querySelector("table");
61
+ assert.notStrictEqual(amendementsTable, null);
62
+ const tfootTr = amendementsTable.querySelector("tfoot > tr");
63
+ assert.notStrictEqual(tfootTr, null);
64
+ const tfootTrCells = tfootTr.querySelectorAll("td, th").map(cell => cell.text);
65
+ assert(deepEqual(tfootTrCells, ["", "n°", "Dossier législatif", "Emplacement", "Auteur", "État", "Sort", "Date d'examen", "Examiné par", "Texte visé", "Date de dépôt"]), `Unexpected columns in ${JSON.stringify(tfootTrCells, null, 2)}`);
66
+ const amendementsTr = amendementsTable.querySelectorAll("tbody > tr");
67
+ assert.notStrictEqual(amendementsTr.length, 0);
68
+
69
+ for (const amendementTr of amendementsTr) {
70
+ amendementNumber++;
71
+
72
+ if (minDateDepot != null || minDateExamen != null) {
73
+ const amendementTdList = amendementTr.querySelectorAll("td");
74
+ assert.strictEqual(amendementTdList.length, 11, `Unexpected number of columns in amendment row: ${amendementTr.outerHTML}`);
75
+
76
+ if (minDateDepot != null) {
77
+ const dateDepotTd = amendementTdList[10];
78
+ const dateDepot = formatISO(parseDate(dateDepotTd.text, "d MMMM y", new Date(), {
79
+ locale: frLocale
80
+ }), {
81
+ representation: "date"
82
+ });
83
+
84
+ if (dateDepot < minDateDepot) {
85
+ // Since the amendments are sorted by deposit date, once an amendment
86
+ // with an old deposit date is encountered, the full search can be stopped.
87
+ break iterSearchPages;
88
+ }
89
+ }
90
+
91
+ if (minDateExamen != null) {
92
+ const dateExamenTd = amendementTdList[7];
93
+
94
+ if (dateExamenTd.text) {
95
+ const dateExamen = formatISO(parseDate(dateExamenTd.text, "d MMMM y", new Date(), {
96
+ locale: frLocale
97
+ }), {
98
+ representation: "date"
99
+ });
100
+
101
+ if (dateExamen < minDateExamen) {
102
+ // This amendment has been discussed since a few days.
103
+ // => Ignore it, because it should be in Assemblée open data.
104
+ continue;
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ const amendementUrlPath = amendementTr.getAttribute("data-href");
111
+ assert.notStrictEqual(amendementUrlPath, undefined);
112
+ const amendementUrlPathSplitted = amendementUrlPath.split("/");
113
+ assert.strictEqual(amendementUrlPathSplitted[0], "", `Unexpected URL path for amendement: ${amendementUrlPath}`);
114
+ assert.strictEqual(amendementUrlPathSplitted[1], "dyn", `Unexpected URL path for amendement: ${amendementUrlPath}`);
115
+ const amendementSearchCacheFilePath = path.join(amendementsSearchCacheDir, ...amendementUrlPathSplitted.slice(2)) + ".html";
116
+ await fs.ensureDir(path.dirname(amendementSearchCacheFilePath));
117
+ const existingAmendementSearchCache = (await fs.pathExists(amendementSearchCacheFilePath)) ? await fs.readFile(amendementSearchCacheFilePath, "utf8") : null;
118
+ const amendementTrOuterHtml = amendementTr.outerHTML;
119
+ const amendementSearchCache = `---\n${jsYaml.dump({
120
+ position: amendementsCount - amendementNumber,
121
+ search: url.replace(/&page=[\d]+/, "")
122
+ }, {
123
+ sortKeys: true
124
+ })}---\n\n${amendementTrOuterHtml}`;
125
+
126
+ if (amendementSearchCache === existingAmendementSearchCache) {
127
+ if (incremental) {
128
+ // The same <tr> is already in cache and in the same position.
129
+ // Assume that following amendments are not changed and stop looking
130
+ // for amendments to upsert.
131
+ break iterSearchPages;
132
+ }
133
+
134
+ continue;
135
+ }
136
+
137
+ if (existingAmendementSearchCache !== null && frontMatter(existingAmendementSearchCache).body === amendementTrOuterHtml) {
138
+ // The same <tr> is already in cache, but in a different position.
139
+ // Assume the amendment is unchanged.
140
+ continue;
141
+ }
142
+
143
+ if (options.verbose) {
144
+ if (existingAmendementSearchCache === null) {
145
+ console.log(`Adding amendement search cache: ${amendementSearchCacheFilePath}…`);
146
+ } else {
147
+ console.log(`Updating amendement search cache: ${amendementSearchCacheFilePath}…`);
148
+ }
149
+ }
150
+
151
+ const amendementHtmlUrl = new URL(amendementUrlPath, "https://www.assemblee-nationale.fr/").toString();
152
+ const amendementHtmlResponse = await fetch(amendementHtmlUrl);
153
+ assert(amendementHtmlResponse.ok, `Retrieval of amendement HTML page at ${amendementHtmlUrl} failed with error: ${amendementHtmlResponse.status} ${amendementHtmlResponse.statusText}`);
154
+ const amendementHtmlPage = await amendementHtmlResponse.text();
155
+ const amendementHtml = parseHtml(amendementHtmlPage);
156
+ const formatsLi = amendementHtml.querySelectorAll("li.mirror-card-header--options--content--item");
157
+ assert.notStrictEqual(formatsLi.length, 0);
158
+ const jsonLi = formatsLi.find(formatLi => {
159
+ const formatSpan = formatLi.querySelector("a > span");
160
+ assert.notStrictEqual(formatSpan, null, `No <span> in <a> found in ${formatLi.toString()}`);
161
+ return formatSpan.text === "Version JSON";
162
+ });
163
+ assert.notStrictEqual(jsonLi, undefined, `No JSON version found for amendement at ${amendementHtmlUrl}`);
164
+ const jsonA = jsonLi.querySelector("a");
165
+ assert.notStrictEqual(jsonA, null, `No <a> found in ${jsonLi.toString()}`);
166
+ const amendementJsonUrlPath = jsonA.getAttribute("href");
167
+ assert.notStrictEqual(amendementJsonUrlPath, undefined, `No URL found for JSON version of amendement: ${jsonLi.toString()}`);
168
+ const amendementJsonUrl = new URL(amendementJsonUrlPath, "https://www.assemblee-nationale.fr/").toString();
169
+ const amendementJsonResponse = await fetch(amendementJsonUrl);
170
+ assert(amendementJsonResponse.ok, `Retrieval of amendement JSON page at ${amendementJsonUrl} failed with error: ${amendementJsonResponse.status} ${amendementJsonResponse.statusText}`);
171
+ const amendement = await amendementJsonResponse.json();
172
+ yield [amendementUrlPath, amendement]; // SearchCache must be written at the end to ensure that everything is in a consistent state,
173
+ // even if script fails abruptly.
174
+
175
+ await fs.writeFile(amendementSearchCacheFilePath, amendementSearchCache, "utf8");
176
+ }
177
+
178
+ const paginationA = html.querySelector("div.an-pagination--item > i.an-icons-chevron-right ~ a");
179
+
180
+ if (paginationA === null) {
181
+ break;
182
+ }
183
+
184
+ const urlPath = paginationA.getAttribute("href");
185
+ assert.notStrictEqual(urlPath, undefined);
186
+ url = new URL(urlPath, "https://www.assemblee-nationale.fr/").toString();
187
+ }
188
+ }
189
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhc3NlcnQiLCJmb3JtYXRJU08iLCJmckxvY2FsZSIsInBhcnNlRGF0ZSIsImRlZXBFcXVhbCIsImZzIiwiZnJvbnRNYXR0ZXIiLCJqc1lhbWwiLCJmZXRjaCIsInBhcnNlIiwicGFyc2VIdG1sIiwicGF0aCIsImNsZWFuQW1lbmRlbWVudCIsIkNvbnZlcnQiLCJBbWVuZGVtZW50c0NvbnZlcnQiLCJpdGVyUmVjaGVyY2hlQW1lbmRlbWVudHMiLCJhbWVuZGVtZW50c1NlYXJjaENhY2hlRGlyIiwidXJsIiwiaW5jcmVtZW50YWwiLCJtaW5EYXRlRGVwb3QiLCJtaW5EYXRlRXhhbWVuIiwib3B0aW9ucyIsImFtZW5kZW1lbnRVcmxQYXRoIiwiYW1lbmRlbWVudCIsIml0ZXJSZWNoZXJjaGVSYXdBbWVuZGVtZW50cyIsInRvQW1lbmRlbWVudCIsIkpTT04iLCJzdHJpbmdpZnkiLCJlbnN1cmVEaXIiLCJzdHJpY3RFcXVhbCIsImV4ZWMiLCJub3RTdHJpY3RFcXVhbCIsImluY2x1ZGVzIiwiYW1lbmRlbWVudE51bWJlciIsIml0ZXJTZWFyY2hQYWdlcyIsInZlcmJvc2UiLCJjb25zb2xlIiwibG9nIiwicmVzcG9uc2UiLCJvayIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJwYWdlIiwidGV4dCIsImh0bWwiLCJxdWVyeVNlbGVjdG9yIiwiYW1lbmRlbWVudHNDb3VudERpdiIsImFtZW5kZW1lbnRzQ291bnQiLCJwYXJzZUludCIsImFtZW5kZW1lbnRzRGl2IiwiYW1lbmRlbWVudHNUYWJsZSIsInRmb290VHIiLCJ0Zm9vdFRyQ2VsbHMiLCJxdWVyeVNlbGVjdG9yQWxsIiwibWFwIiwiY2VsbCIsImFtZW5kZW1lbnRzVHIiLCJsZW5ndGgiLCJhbWVuZGVtZW50VHIiLCJhbWVuZGVtZW50VGRMaXN0Iiwib3V0ZXJIVE1MIiwiZGF0ZURlcG90VGQiLCJkYXRlRGVwb3QiLCJEYXRlIiwibG9jYWxlIiwicmVwcmVzZW50YXRpb24iLCJkYXRlRXhhbWVuVGQiLCJkYXRlRXhhbWVuIiwiZ2V0QXR0cmlidXRlIiwidW5kZWZpbmVkIiwiYW1lbmRlbWVudFVybFBhdGhTcGxpdHRlZCIsInNwbGl0IiwiYW1lbmRlbWVudFNlYXJjaENhY2hlRmlsZVBhdGgiLCJqb2luIiwic2xpY2UiLCJkaXJuYW1lIiwiZXhpc3RpbmdBbWVuZGVtZW50U2VhcmNoQ2FjaGUiLCJwYXRoRXhpc3RzIiwicmVhZEZpbGUiLCJhbWVuZGVtZW50VHJPdXRlckh0bWwiLCJhbWVuZGVtZW50U2VhcmNoQ2FjaGUiLCJkdW1wIiwicG9zaXRpb24iLCJzZWFyY2giLCJyZXBsYWNlIiwic29ydEtleXMiLCJib2R5IiwiYW1lbmRlbWVudEh0bWxVcmwiLCJVUkwiLCJ0b1N0cmluZyIsImFtZW5kZW1lbnRIdG1sUmVzcG9uc2UiLCJhbWVuZGVtZW50SHRtbFBhZ2UiLCJhbWVuZGVtZW50SHRtbCIsImZvcm1hdHNMaSIsImpzb25MaSIsImZpbmQiLCJmb3JtYXRMaSIsImZvcm1hdFNwYW4iLCJqc29uQSIsImFtZW5kZW1lbnRKc29uVXJsUGF0aCIsImFtZW5kZW1lbnRKc29uVXJsIiwiYW1lbmRlbWVudEpzb25SZXNwb25zZSIsImpzb24iLCJ3cml0ZUZpbGUiLCJwYWdpbmF0aW9uQSIsInVybFBhdGgiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFyc2Vycy9yZWNoZXJjaGVfYW1lbmRlbWVudHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCJcbi8vIE5vdGU6IFwiL2luZGV4LmpzXCIgYWRkZWQgdG8gaW1wb3J0cywgYmVjYXVzZSBvZiBpc3N1ZVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2RhdGUtZm5zL2RhdGUtZm5zL2lzc3Vlcy8yOTY0XG5pbXBvcnQgZm9ybWF0SVNPIGZyb20gXCJkYXRlLWZucy9mb3JtYXRJU08vaW5kZXguanNcIlxuaW1wb3J0IGZyTG9jYWxlIGZyb20gXCJkYXRlLWZucy9sb2NhbGUvZnIvaW5kZXguanNcIlxuaW1wb3J0IHBhcnNlRGF0ZSBmcm9tIFwiZGF0ZS1mbnMvcGFyc2UvaW5kZXguanNcIlxuaW1wb3J0IGRlZXBFcXVhbCBmcm9tIFwiZGVlcC1lcXVhbFwiXG5pbXBvcnQgZnMgZnJvbSBcImZzLWV4dHJhXCJcbmltcG9ydCBmcm9udE1hdHRlciBmcm9tIFwiZnJvbnQtbWF0dGVyXCJcbmltcG9ydCBqc1lhbWwgZnJvbSBcImpzLXlhbWxcIlxuaW1wb3J0IGZldGNoIGZyb20gXCJub2RlLWZldGNoXCJcbmltcG9ydCB7IHBhcnNlIGFzIHBhcnNlSHRtbCB9IGZyb20gXCJub2RlLWh0bWwtcGFyc2VyXCJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcblxuaW1wb3J0IHsgY2xlYW5BbWVuZGVtZW50IH0gZnJvbSBcIi4uL2NsZWFuZXJzXCJcbmltcG9ydCB7IEFtZW5kZW1lbnQgYXMgUmF3QW1lbmRlbWVudCB9IGZyb20gXCIuLi9yYXdfdHlwZXMvYW1lbmRlbWVudHNcIlxuaW1wb3J0IHsgQW1lbmRlbWVudCwgQ29udmVydCBhcyBBbWVuZGVtZW50c0NvbnZlcnQgfSBmcm9tIFwiLi4vdHlwZXMvYW1lbmRlbWVudHNcIlxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24qIGl0ZXJSZWNoZXJjaGVBbWVuZGVtZW50cyhcbiAgYW1lbmRlbWVudHNTZWFyY2hDYWNoZURpcjogc3RyaW5nLFxuICB1cmw6IHN0cmluZyxcbiAgaW5jcmVtZW50YWw6IGJvb2xlYW4sXG4gIG1pbkRhdGVEZXBvdD86IHN0cmluZyB8IG51bGwsXG4gIG1pbkRhdGVFeGFtZW4/OiBzdHJpbmcgfCBudWxsLFxuICBvcHRpb25zOiB7IHNpbGVudD86IGJvb2xlYW47IHZlcmJvc2U/OiBib29sZWFuIH0gPSB7fSxcbik6IEFzeW5jR2VuZXJhdG9yPFtzdHJpbmcsIEFtZW5kZW1lbnRdLCB2b2lkLCB1bmtub3duPiB7XG4gIGZvciBhd2FpdCAoY29uc3QgW1xuICAgIGFtZW5kZW1lbnRVcmxQYXRoLFxuICAgIGFtZW5kZW1lbnQsXG4gIF0gb2YgaXRlclJlY2hlcmNoZVJhd0FtZW5kZW1lbnRzKFxuICAgIGFtZW5kZW1lbnRzU2VhcmNoQ2FjaGVEaXIsXG4gICAgdXJsLFxuICAgIGluY3JlbWVudGFsLFxuICAgIG1pbkRhdGVEZXBvdCxcbiAgICBtaW5EYXRlRXhhbWVuLFxuICAgIG9wdGlvbnMsXG4gICkpIHtcbiAgICBjbGVhbkFtZW5kZW1lbnQoYW1lbmRlbWVudClcbiAgICAvLyBEb3VibGUgY29udmVyc2lvbiwgdG8gY29udmVydCBzdHJpbmdzIHRvIGRhdGVzLlxuICAgIHlpZWxkIFtcbiAgICAgIGFtZW5kZW1lbnRVcmxQYXRoLFxuICAgICAgQW1lbmRlbWVudHNDb252ZXJ0LnRvQW1lbmRlbWVudChKU09OLnN0cmluZ2lmeShhbWVuZGVtZW50KSksXG4gICAgXVxuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiogaXRlclJlY2hlcmNoZVJhd0FtZW5kZW1lbnRzKFxuICBhbWVuZGVtZW50c1NlYXJjaENhY2hlRGlyOiBzdHJpbmcsXG4gIHVybDogc3RyaW5nLFxuICBpbmNyZW1lbnRhbDogYm9vbGVhbixcbiAgbWluRGF0ZURlcG90Pzogc3RyaW5nIHwgbnVsbCxcbiAgbWluRGF0ZUV4YW1lbj86IHN0cmluZyB8IG51bGwsXG4gIG9wdGlvbnM6IHsgc2lsZW50PzogYm9vbGVhbjsgdmVyYm9zZT86IGJvb2xlYW4gfSA9IHt9LFxuKTogQXN5bmNHZW5lcmF0b3I8W3N0cmluZywgUmF3QW1lbmRlbWVudF0sIHZvaWQsIHVua25vd24+IHtcbiAgYXdhaXQgZnMuZW5zdXJlRGlyKGFtZW5kZW1lbnRzU2VhcmNoQ2FjaGVEaXIpXG5cbiAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgIC9bPyZdZGF0ZV9kZXBvdD0vLmV4ZWModXJsKSxcbiAgICBudWxsLFxuICAgIGBVUkwgJHt1cmx9IGFscmVhZHkgY29udGFpbnMgYSBkZXBvc2l0IGRhdGVgLFxuICApXG4gIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAvWz8mXW9yZGVyPS8uZXhlYyh1cmwpLFxuICAgIG51bGwsXG4gICAgYFVSTCAke3VybH0gYWxyZWFkeSBjb250YWlucyBhIHNvcnQgb3JkZXJgLFxuICApXG4gIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAvWz8mXXBhZ2U9Ly5leGVjKHVybCksXG4gICAgbnVsbCxcbiAgICBgVVJMICR7dXJsfSBhbHJlYWR5IGNvbnRhaW5zIGEgcGFnZSBudW1iZXJgLFxuICApXG4gIGlmIChpbmNyZW1lbnRhbCkge1xuICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbChcbiAgICAgIC9bPyZdZXRhdD0vLmV4ZWModXJsKSxcbiAgICAgIG51bGwsXG4gICAgICBgSW4gaW5jcmVtZW50YWwgbW9kZSwgVVJMICR7dXJsfSBtdXN0IGNvbnRhaW4gYW4gXCJldGF0XCIgcXVlcnkgcGFyYW1ldGVyYCxcbiAgICApXG4gIH1cbiAgdXJsICs9ICh1cmwuaW5jbHVkZXMoXCI/XCIpID8gXCImXCIgOiBcIj9cIikgKyBcIm9yZGVyPWRhdGVfZGVwb3QsZGVzYyZwYWdlPTFcIlxuXG4gIGlmIChtaW5EYXRlRGVwb3QgIT0gbnVsbCkge1xuICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbChcbiAgICAgIC9cXGR7NH0tXFxkezJ9LVxcZHsyfS8uZXhlYyhtaW5EYXRlRGVwb3QpLFxuICAgICAgbnVsbCxcbiAgICAgIGBJbnZhbGlkIGZvcm1hdCBmb3IgbWluaW11bSBkYXRlOiAke21pbkRhdGVEZXBvdH1gLFxuICAgIClcbiAgfVxuXG4gIGxldCBhbWVuZGVtZW50TnVtYmVyID0gMFxuICBpdGVyU2VhcmNoUGFnZXM6IHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgY29uc29sZS5sb2coYEZldGNoaW5nIGFtZW5kZW1lbnRzIHNlYXJjaCBwYWdlIGF0ICR7dXJsfeKApmApXG4gICAgfVxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKVxuICAgIGFzc2VydChcbiAgICAgIHJlc3BvbnNlLm9rLFxuICAgICAgYFJldHJpZXZhbCBvZiBzZWFyY2ggcGFnZSBhdCAke3VybH0gZmFpbGVkIHdpdGggZXJyb3I6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCxcbiAgICApXG4gICAgY29uc3QgcGFnZSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKVxuICAgIGNvbnN0IGh0bWwgPSBwYXJzZUh0bWwocGFnZSlcbiAgICBpZiAoaHRtbC5xdWVyeVNlbGVjdG9yKFwiZGl2Lm5vLXJlc3VsdFwiKSAhPT0gbnVsbCkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gICAgY29uc3QgYW1lbmRlbWVudHNDb3VudERpdiA9IGh0bWwucXVlcnlTZWxlY3RvcihcImRpdi5taXJyb3ItY2FyZC1zdWJ0aXRsZVwiKVxuICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbChhbWVuZGVtZW50c0NvdW50RGl2LCBudWxsKVxuICAgIGNvbnN0IGFtZW5kZW1lbnRzQ291bnQgPSBwYXJzZUludCgvXFxkKy8uZXhlYyhhbWVuZGVtZW50c0NvdW50RGl2IS50ZXh0KSFbMF0pXG4gICAgY29uc3QgYW1lbmRlbWVudHNEaXYgPSBodG1sLnF1ZXJ5U2VsZWN0b3IoXG4gICAgICBcImRpdi5hbWVuZGVtZW50LWxpc3QtLXJlc3VsdHMtdGFibGVcIixcbiAgICApXG4gICAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKGFtZW5kZW1lbnRzRGl2LCBudWxsKVxuICAgIGNvbnN0IGFtZW5kZW1lbnRzVGFibGUgPSBhbWVuZGVtZW50c0RpdiEucXVlcnlTZWxlY3RvcihcInRhYmxlXCIpXG4gICAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKGFtZW5kZW1lbnRzVGFibGUsIG51bGwpXG4gICAgY29uc3QgdGZvb3RUciA9IGFtZW5kZW1lbnRzVGFibGUhLnF1ZXJ5U2VsZWN0b3IoXCJ0Zm9vdCA+IHRyXCIpXG4gICAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKHRmb290VHIsIG51bGwpXG4gICAgY29uc3QgdGZvb3RUckNlbGxzID0gdGZvb3RUciFcbiAgICAgIC5xdWVyeVNlbGVjdG9yQWxsKFwidGQsIHRoXCIpXG4gICAgICAubWFwKChjZWxsKSA9PiBjZWxsLnRleHQpXG4gICAgYXNzZXJ0KFxuICAgICAgZGVlcEVxdWFsKHRmb290VHJDZWxscywgW1xuICAgICAgICBcIlwiLFxuICAgICAgICBcIm7CsFwiLFxuICAgICAgICBcIkRvc3NpZXIgbMOpZ2lzbGF0aWZcIixcbiAgICAgICAgXCJFbXBsYWNlbWVudFwiLFxuICAgICAgICBcIkF1dGV1clwiLFxuICAgICAgICBcIsOJdGF0XCIsXG4gICAgICAgIFwiU29ydFwiLFxuICAgICAgICBcIkRhdGUgZCdleGFtZW5cIixcbiAgICAgICAgXCJFeGFtaW7DqSBwYXJcIixcbiAgICAgICAgXCJUZXh0ZSB2aXPDqVwiLFxuICAgICAgICBcIkRhdGUgZGUgZMOpcMO0dFwiLFxuICAgICAgXSksXG4gICAgICBgVW5leHBlY3RlZCBjb2x1bW5zIGluICR7SlNPTi5zdHJpbmdpZnkodGZvb3RUckNlbGxzLCBudWxsLCAyKX1gLFxuICAgIClcbiAgICBjb25zdCBhbWVuZGVtZW50c1RyID0gYW1lbmRlbWVudHNUYWJsZSEucXVlcnlTZWxlY3RvckFsbChcInRib2R5ID4gdHJcIilcbiAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwoYW1lbmRlbWVudHNUci5sZW5ndGgsIDApXG4gICAgZm9yIChjb25zdCBhbWVuZGVtZW50VHIgb2YgYW1lbmRlbWVudHNUcikge1xuICAgICAgYW1lbmRlbWVudE51bWJlcisrXG5cbiAgICAgIGlmIChtaW5EYXRlRGVwb3QgIT0gbnVsbCB8fCBtaW5EYXRlRXhhbWVuICE9IG51bGwpIHtcbiAgICAgICAgY29uc3QgYW1lbmRlbWVudFRkTGlzdCA9IGFtZW5kZW1lbnRUci5xdWVyeVNlbGVjdG9yQWxsKFwidGRcIilcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgICAgIGFtZW5kZW1lbnRUZExpc3QubGVuZ3RoLFxuICAgICAgICAgIDExLFxuICAgICAgICAgIGBVbmV4cGVjdGVkIG51bWJlciBvZiBjb2x1bW5zIGluIGFtZW5kbWVudCByb3c6ICR7YW1lbmRlbWVudFRyLm91dGVySFRNTH1gLFxuICAgICAgICApXG4gICAgICAgIGlmIChtaW5EYXRlRGVwb3QgIT0gbnVsbCkge1xuICAgICAgICAgIGNvbnN0IGRhdGVEZXBvdFRkID0gYW1lbmRlbWVudFRkTGlzdFsxMF1cbiAgICAgICAgICBjb25zdCBkYXRlRGVwb3QgPSBmb3JtYXRJU08oXG4gICAgICAgICAgICBwYXJzZURhdGUoZGF0ZURlcG90VGQudGV4dCwgXCJkIE1NTU0geVwiLCBuZXcgRGF0ZSgpLCB7IGxvY2FsZTogZnJMb2NhbGUgfSksXG4gICAgICAgICAgICB7IHJlcHJlc2VudGF0aW9uOiBcImRhdGVcIiB9LFxuICAgICAgICAgIClcbiAgICAgICAgICBpZiAoZGF0ZURlcG90IDwgbWluRGF0ZURlcG90KSB7XG4gICAgICAgICAgICAvLyBTaW5jZSB0aGUgYW1lbmRtZW50cyBhcmUgc29ydGVkIGJ5IGRlcG9zaXQgZGF0ZSwgb25jZSBhbiBhbWVuZG1lbnRcbiAgICAgICAgICAgIC8vIHdpdGggYW4gb2xkIGRlcG9zaXQgZGF0ZSBpcyBlbmNvdW50ZXJlZCwgdGhlIGZ1bGwgc2VhcmNoIGNhbiBiZSBzdG9wcGVkLlxuICAgICAgICAgICAgYnJlYWsgaXRlclNlYXJjaFBhZ2VzXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChtaW5EYXRlRXhhbWVuICE9IG51bGwpIHtcbiAgICAgICAgICBjb25zdCBkYXRlRXhhbWVuVGQgPSBhbWVuZGVtZW50VGRMaXN0WzddXG4gICAgICAgICAgaWYgKGRhdGVFeGFtZW5UZC50ZXh0KSB7XG4gICAgICAgICAgICBjb25zdCBkYXRlRXhhbWVuID0gZm9ybWF0SVNPKFxuICAgICAgICAgICAgICBwYXJzZURhdGUoZGF0ZUV4YW1lblRkLnRleHQsIFwiZCBNTU1NIHlcIiwgbmV3IERhdGUoKSwge1xuICAgICAgICAgICAgICAgIGxvY2FsZTogZnJMb2NhbGUsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB7IHJlcHJlc2VudGF0aW9uOiBcImRhdGVcIiB9LFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgaWYgKGRhdGVFeGFtZW4gPCBtaW5EYXRlRXhhbWVuKSB7XG4gICAgICAgICAgICAgIC8vIFRoaXMgYW1lbmRtZW50IGhhcyBiZWVuIGRpc2N1c3NlZCBzaW5jZSBhIGZldyBkYXlzLlxuICAgICAgICAgICAgICAvLyA9PiBJZ25vcmUgaXQsIGJlY2F1c2UgaXQgc2hvdWxkIGJlIGluIEFzc2VtYmzDqWUgb3BlbiBkYXRhLlxuICAgICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBhbWVuZGVtZW50VXJsUGF0aCA9IGFtZW5kZW1lbnRUci5nZXRBdHRyaWJ1dGUoXCJkYXRhLWhyZWZcIilcbiAgICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbChhbWVuZGVtZW50VXJsUGF0aCwgdW5kZWZpbmVkKVxuICAgICAgY29uc3QgYW1lbmRlbWVudFVybFBhdGhTcGxpdHRlZCA9IGFtZW5kZW1lbnRVcmxQYXRoIS5zcGxpdChcIi9cIilcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgYW1lbmRlbWVudFVybFBhdGhTcGxpdHRlZFswXSxcbiAgICAgICAgXCJcIixcbiAgICAgICAgYFVuZXhwZWN0ZWQgVVJMIHBhdGggZm9yIGFtZW5kZW1lbnQ6ICR7YW1lbmRlbWVudFVybFBhdGh9YCxcbiAgICAgIClcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgYW1lbmRlbWVudFVybFBhdGhTcGxpdHRlZFsxXSxcbiAgICAgICAgXCJkeW5cIixcbiAgICAgICAgYFVuZXhwZWN0ZWQgVVJMIHBhdGggZm9yIGFtZW5kZW1lbnQ6ICR7YW1lbmRlbWVudFVybFBhdGh9YCxcbiAgICAgIClcbiAgICAgIGNvbnN0IGFtZW5kZW1lbnRTZWFyY2hDYWNoZUZpbGVQYXRoID1cbiAgICAgICAgcGF0aC5qb2luKFxuICAgICAgICAgIGFtZW5kZW1lbnRzU2VhcmNoQ2FjaGVEaXIsXG4gICAgICAgICAgLi4uYW1lbmRlbWVudFVybFBhdGhTcGxpdHRlZC5zbGljZSgyKSxcbiAgICAgICAgKSArIFwiLmh0bWxcIlxuICAgICAgYXdhaXQgZnMuZW5zdXJlRGlyKHBhdGguZGlybmFtZShhbWVuZGVtZW50U2VhcmNoQ2FjaGVGaWxlUGF0aCkpXG4gICAgICBjb25zdCBleGlzdGluZ0FtZW5kZW1lbnRTZWFyY2hDYWNoZSA9IChhd2FpdCBmcy5wYXRoRXhpc3RzKFxuICAgICAgICBhbWVuZGVtZW50U2VhcmNoQ2FjaGVGaWxlUGF0aCxcbiAgICAgICkpXG4gICAgICAgID8gYXdhaXQgZnMucmVhZEZpbGUoYW1lbmRlbWVudFNlYXJjaENhY2hlRmlsZVBhdGgsIFwidXRmOFwiKVxuICAgICAgICA6IG51bGxcbiAgICAgIGNvbnN0IGFtZW5kZW1lbnRUck91dGVySHRtbCA9IGFtZW5kZW1lbnRUci5vdXRlckhUTUxcbiAgICAgIGNvbnN0IGFtZW5kZW1lbnRTZWFyY2hDYWNoZSA9IGAtLS1cXG4ke2pzWWFtbC5kdW1wKFxuICAgICAgICB7XG4gICAgICAgICAgcG9zaXRpb246IGFtZW5kZW1lbnRzQ291bnQgLSBhbWVuZGVtZW50TnVtYmVyLFxuICAgICAgICAgIHNlYXJjaDogdXJsLnJlcGxhY2UoLyZwYWdlPVtcXGRdKy8sIFwiXCIpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc29ydEtleXM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICApfS0tLVxcblxcbiR7YW1lbmRlbWVudFRyT3V0ZXJIdG1sfWBcbiAgICAgIGlmIChhbWVuZGVtZW50U2VhcmNoQ2FjaGUgPT09IGV4aXN0aW5nQW1lbmRlbWVudFNlYXJjaENhY2hlKSB7XG4gICAgICAgIGlmIChpbmNyZW1lbnRhbCkge1xuICAgICAgICAgIC8vIFRoZSBzYW1lIDx0cj4gaXMgYWxyZWFkeSBpbiBjYWNoZSBhbmQgaW4gdGhlIHNhbWUgcG9zaXRpb24uXG4gICAgICAgICAgLy8gQXNzdW1lIHRoYXQgZm9sbG93aW5nIGFtZW5kbWVudHMgYXJlIG5vdCBjaGFuZ2VkIGFuZCBzdG9wIGxvb2tpbmdcbiAgICAgICAgICAvLyBmb3IgYW1lbmRtZW50cyB0byB1cHNlcnQuXG4gICAgICAgICAgYnJlYWsgaXRlclNlYXJjaFBhZ2VzXG4gICAgICAgIH1cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgZXhpc3RpbmdBbWVuZGVtZW50U2VhcmNoQ2FjaGUgIT09IG51bGwgJiZcbiAgICAgICAgZnJvbnRNYXR0ZXIoZXhpc3RpbmdBbWVuZGVtZW50U2VhcmNoQ2FjaGUpLmJvZHkgPT09XG4gICAgICAgICAgYW1lbmRlbWVudFRyT3V0ZXJIdG1sXG4gICAgICApIHtcbiAgICAgICAgLy8gVGhlIHNhbWUgPHRyPiBpcyBhbHJlYWR5IGluIGNhY2hlLCBidXQgaW4gYSBkaWZmZXJlbnQgcG9zaXRpb24uXG4gICAgICAgIC8vIEFzc3VtZSB0aGUgYW1lbmRtZW50IGlzIHVuY2hhbmdlZC5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgaWYgKGV4aXN0aW5nQW1lbmRlbWVudFNlYXJjaENhY2hlID09PSBudWxsKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgQWRkaW5nIGFtZW5kZW1lbnQgc2VhcmNoIGNhY2hlOiAke2FtZW5kZW1lbnRTZWFyY2hDYWNoZUZpbGVQYXRofeKApmAsXG4gICAgICAgICAgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYFVwZGF0aW5nIGFtZW5kZW1lbnQgc2VhcmNoIGNhY2hlOiAke2FtZW5kZW1lbnRTZWFyY2hDYWNoZUZpbGVQYXRofeKApmAsXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBhbWVuZGVtZW50SHRtbFVybCA9IG5ldyBVUkwoXG4gICAgICAgIGFtZW5kZW1lbnRVcmxQYXRoISxcbiAgICAgICAgXCJodHRwczovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyL1wiLFxuICAgICAgKS50b1N0cmluZygpXG4gICAgICBjb25zdCBhbWVuZGVtZW50SHRtbFJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYW1lbmRlbWVudEh0bWxVcmwpXG4gICAgICBhc3NlcnQoXG4gICAgICAgIGFtZW5kZW1lbnRIdG1sUmVzcG9uc2Uub2ssXG4gICAgICAgIGBSZXRyaWV2YWwgb2YgYW1lbmRlbWVudCBIVE1MIHBhZ2UgYXQgJHthbWVuZGVtZW50SHRtbFVybH0gZmFpbGVkIHdpdGggZXJyb3I6ICR7YW1lbmRlbWVudEh0bWxSZXNwb25zZS5zdGF0dXN9ICR7YW1lbmRlbWVudEh0bWxSZXNwb25zZS5zdGF0dXNUZXh0fWAsXG4gICAgICApXG4gICAgICBjb25zdCBhbWVuZGVtZW50SHRtbFBhZ2UgPSBhd2FpdCBhbWVuZGVtZW50SHRtbFJlc3BvbnNlLnRleHQoKVxuICAgICAgY29uc3QgYW1lbmRlbWVudEh0bWwgPSBwYXJzZUh0bWwoYW1lbmRlbWVudEh0bWxQYWdlKVxuICAgICAgY29uc3QgZm9ybWF0c0xpID0gYW1lbmRlbWVudEh0bWwucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgXCJsaS5taXJyb3ItY2FyZC1oZWFkZXItLW9wdGlvbnMtLWNvbnRlbnQtLWl0ZW1cIixcbiAgICAgIClcbiAgICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbChmb3JtYXRzTGkubGVuZ3RoLCAwKVxuICAgICAgY29uc3QganNvbkxpID0gZm9ybWF0c0xpLmZpbmQoKGZvcm1hdExpKSA9PiB7XG4gICAgICAgIGNvbnN0IGZvcm1hdFNwYW4gPSBmb3JtYXRMaS5xdWVyeVNlbGVjdG9yKFwiYSA+IHNwYW5cIilcbiAgICAgICAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKFxuICAgICAgICAgIGZvcm1hdFNwYW4sXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICBgTm8gPHNwYW4+IGluIDxhPiBmb3VuZCBpbiAke2Zvcm1hdExpLnRvU3RyaW5nKCl9YCxcbiAgICAgICAgKVxuICAgICAgICByZXR1cm4gZm9ybWF0U3BhbiEudGV4dCA9PT0gXCJWZXJzaW9uIEpTT05cIlxuICAgICAgfSlcbiAgICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbChcbiAgICAgICAganNvbkxpLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIGBObyBKU09OIHZlcnNpb24gZm91bmQgZm9yIGFtZW5kZW1lbnQgYXQgJHthbWVuZGVtZW50SHRtbFVybH1gLFxuICAgICAgKVxuICAgICAgY29uc3QganNvbkEgPSBqc29uTGkhLnF1ZXJ5U2VsZWN0b3IoXCJhXCIpXG4gICAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwoXG4gICAgICAgIGpzb25BLFxuICAgICAgICBudWxsLFxuICAgICAgICBgTm8gPGE+IGZvdW5kIGluICR7anNvbkxpIS50b1N0cmluZygpfWAsXG4gICAgICApXG4gICAgICBjb25zdCBhbWVuZGVtZW50SnNvblVybFBhdGggPSBqc29uQSEuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKVxuICAgICAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKFxuICAgICAgICBhbWVuZGVtZW50SnNvblVybFBhdGgsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgYE5vIFVSTCBmb3VuZCBmb3IgSlNPTiB2ZXJzaW9uIG9mIGFtZW5kZW1lbnQ6ICR7anNvbkxpIS50b1N0cmluZygpfWAsXG4gICAgICApXG4gICAgICBjb25zdCBhbWVuZGVtZW50SnNvblVybCA9IG5ldyBVUkwoXG4gICAgICAgIGFtZW5kZW1lbnRKc29uVXJsUGF0aCEsXG4gICAgICAgIFwiaHR0cHM6Ly93d3cuYXNzZW1ibGVlLW5hdGlvbmFsZS5mci9cIixcbiAgICAgICkudG9TdHJpbmcoKVxuICAgICAgY29uc3QgYW1lbmRlbWVudEpzb25SZXNwb25zZSA9IGF3YWl0IGZldGNoKGFtZW5kZW1lbnRKc29uVXJsKVxuICAgICAgYXNzZXJ0KFxuICAgICAgICBhbWVuZGVtZW50SnNvblJlc3BvbnNlLm9rLFxuICAgICAgICBgUmV0cmlldmFsIG9mIGFtZW5kZW1lbnQgSlNPTiBwYWdlIGF0ICR7YW1lbmRlbWVudEpzb25Vcmx9IGZhaWxlZCB3aXRoIGVycm9yOiAke2FtZW5kZW1lbnRKc29uUmVzcG9uc2Uuc3RhdHVzfSAke2FtZW5kZW1lbnRKc29uUmVzcG9uc2Uuc3RhdHVzVGV4dH1gLFxuICAgICAgKVxuICAgICAgY29uc3QgYW1lbmRlbWVudCA9IGF3YWl0IGFtZW5kZW1lbnRKc29uUmVzcG9uc2UuanNvbigpXG4gICAgICB5aWVsZCBbYW1lbmRlbWVudFVybFBhdGghLCBhbWVuZGVtZW50XVxuXG4gICAgICAvLyBTZWFyY2hDYWNoZSBtdXN0IGJlIHdyaXR0ZW4gYXQgdGhlIGVuZCB0byBlbnN1cmUgdGhhdCBldmVyeXRoaW5nIGlzIGluIGEgY29uc2lzdGVudCBzdGF0ZSxcbiAgICAgIC8vIGV2ZW4gaWYgc2NyaXB0IGZhaWxzIGFicnVwdGx5LlxuICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKFxuICAgICAgICBhbWVuZGVtZW50U2VhcmNoQ2FjaGVGaWxlUGF0aCxcbiAgICAgICAgYW1lbmRlbWVudFNlYXJjaENhY2hlLFxuICAgICAgICBcInV0ZjhcIixcbiAgICAgIClcbiAgICB9XG5cbiAgICBjb25zdCBwYWdpbmF0aW9uQSA9IGh0bWwucXVlcnlTZWxlY3RvcihcbiAgICAgIFwiZGl2LmFuLXBhZ2luYXRpb24tLWl0ZW0gPiBpLmFuLWljb25zLWNoZXZyb24tcmlnaHQgfiBhXCIsXG4gICAgKVxuICAgIGlmIChwYWdpbmF0aW9uQSA9PT0gbnVsbCkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gICAgY29uc3QgdXJsUGF0aCA9IHBhZ2luYXRpb25BLmdldEF0dHJpYnV0ZShcImhyZWZcIilcbiAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwodXJsUGF0aCwgdW5kZWZpbmVkKVxuICAgIHVybCA9IG5ldyBVUkwodXJsUGF0aCEsIFwiaHR0cHM6Ly93d3cuYXNzZW1ibGVlLW5hdGlvbmFsZS5mci9cIikudG9TdHJpbmcoKVxuICB9XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLE9BQU9BLE1BQVAsTUFBbUIsUUFBbkIsQyxDQUNBO0FBQ0E7O0FBQ0EsT0FBT0MsU0FBUCxNQUFzQiw2QkFBdEI7QUFDQSxPQUFPQyxRQUFQLE1BQXFCLDZCQUFyQjtBQUNBLE9BQU9DLFNBQVAsTUFBc0IseUJBQXRCO0FBQ0EsT0FBT0MsU0FBUCxNQUFzQixZQUF0QjtBQUNBLE9BQU9DLEVBQVAsTUFBZSxVQUFmO0FBQ0EsT0FBT0MsV0FBUCxNQUF3QixjQUF4QjtBQUNBLE9BQU9DLE1BQVAsTUFBbUIsU0FBbkI7QUFDQSxPQUFPQyxLQUFQLE1BQWtCLFlBQWxCO0FBQ0EsU0FBU0MsS0FBSyxJQUFJQyxTQUFsQixRQUFtQyxrQkFBbkM7QUFDQSxPQUFPQyxJQUFQLE1BQWlCLE1BQWpCO1NBRVNDLGU7U0FFWUMsT0FBTyxJQUFJQyxrQjtBQUVoQyxPQUFPLGdCQUFnQkMsd0JBQWhCLENBQ0xDLHlCQURLLEVBRUxDLEdBRkssRUFHTEMsV0FISyxFQUlMQyxZQUpLLEVBS0xDLGFBTEssRUFNTEMsT0FBZ0QsR0FBRyxFQU45QyxFQU9nRDtFQUNyRCxXQUFXLE1BQU0sQ0FDZkMsaUJBRGUsRUFFZkMsVUFGZSxDQUFqQixJQUdLQywyQkFBMkIsQ0FDOUJSLHlCQUQ4QixFQUU5QkMsR0FGOEIsRUFHOUJDLFdBSDhCLEVBSTlCQyxZQUo4QixFQUs5QkMsYUFMOEIsRUFNOUJDLE9BTjhCLENBSGhDLEVBVUc7SUFDRFQsZUFBZSxDQUFDVyxVQUFELENBQWYsQ0FEQyxDQUVEOztJQUNBLE1BQU0sQ0FDSkQsaUJBREksRUFFSlIsa0JBQWtCLENBQUNXLFlBQW5CLENBQWdDQyxJQUFJLENBQUNDLFNBQUwsQ0FBZUosVUFBZixDQUFoQyxDQUZJLENBQU47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
@@ -3,12 +3,12 @@ export interface Acteur {
3
3
  }
4
4
  export interface ActeurActeur {
5
5
  "@xmlns"?: string;
6
- uid: PurpleUid;
7
- etatCivil: PurpleEtatCivil;
6
+ uid: Uid;
7
+ etatCivil: EtatCivil;
8
8
  profession: Profession;
9
- uri_hatvp: UriHatvpClass | null | string;
9
+ uri_hatvp: Nil | null | string;
10
10
  adresses: Adresses | null;
11
- mandats?: PurpleMandats;
11
+ mandats?: Mandats;
12
12
  "@xmlns:xsi"?: string;
13
13
  }
14
14
  export interface Adresses {
@@ -20,31 +20,31 @@ export interface Adresses {
20
20
  "@xmlns:xsi"?: string;
21
21
  "@xsi:nil"?: string;
22
22
  }
23
- export interface PurpleEtatCivil {
24
- ident: PurpleIdent;
25
- infoNaissance: PurpleInfoNaissance;
26
- dateDeces: UriHatvpClass | Date | null;
23
+ export interface EtatCivil {
24
+ ident: Ident;
25
+ infoNaissance: InfoNaissance;
26
+ dateDeces: Nil | Date | null;
27
27
  }
28
- export interface UriHatvpClass {
28
+ export interface Nil {
29
29
  "@xmlns:xsi": string;
30
30
  "@xsi:nil": string;
31
31
  }
32
- export interface PurpleIdent {
32
+ export interface Ident {
33
33
  civ: Civ;
34
34
  prenom: string;
35
35
  nom: string;
36
36
  alpha: string;
37
- trigramme: UriHatvpClass | null | string;
37
+ trigramme: Nil | null | string;
38
38
  }
39
39
  export declare enum Civ {
40
40
  M = "M.",
41
41
  Mme = "Mme"
42
42
  }
43
- export interface PurpleInfoNaissance {
44
- dateNais: UriHatvpClass | Date | null;
45
- villeNais: UriHatvpClass | null | string;
46
- depNais: UriHatvpClass | DepNais | null;
47
- paysNais: UriHatvpClass | null | string;
43
+ export interface InfoNaissance {
44
+ dateNais: Nil | Date | null;
45
+ villeNais: Nil | null | string;
46
+ depNais: Nil | DepNais | null;
47
+ paysNais: Nil | null | string;
48
48
  }
49
49
  export declare enum DepNais {
50
50
  Ain = "Ain",
@@ -160,12 +160,12 @@ export declare enum DepNais {
160
160
  Yonne = "Yonne",
161
161
  Yvelines = "Yvelines"
162
162
  }
163
- export interface PurpleMandats {
164
- mandat: PurpleMandat[] | FluffyMandat;
163
+ export interface Mandats {
164
+ mandat: Mandat[] | Mandat;
165
165
  }
166
- export interface PurpleMandat {
166
+ export interface Mandat {
167
167
  "@xmlns:xsi"?: string;
168
- "@xsi:type": MandatXsiType;
168
+ "@xsi:type"?: MandatXsiType;
169
169
  uid: string;
170
170
  acteurRef: string;
171
171
  legislature: null | string;
@@ -176,13 +176,14 @@ export interface PurpleMandat {
176
176
  preseance: null | string;
177
177
  nominPrincipale: string;
178
178
  infosQualite: InfosQualite;
179
- organes: PurpleOrganes;
179
+ organes: Organes;
180
180
  libelle?: null | string;
181
181
  missionSuivanteRef?: null | string;
182
182
  missionPrecedenteRef?: null | string;
183
183
  suppleants?: Suppleants | null;
184
184
  chambre?: null;
185
- election?: PurpleElection;
185
+ election?: Election;
186
+ InfosHorsSIAN?: InfosHorsSian;
186
187
  mandature?: Mandature;
187
188
  collaborateurs?: null[] | Collaborateurs | null;
188
189
  }
@@ -202,7 +203,7 @@ export interface CollaborateurElement {
202
203
  dateDebut: null;
203
204
  dateFin: null;
204
205
  }
205
- export interface PurpleElection {
206
+ export interface Election {
206
207
  lieu: ElectionLieu;
207
208
  causeMandat: null | string;
208
209
  refCirconscription?: null | string;
@@ -259,7 +260,7 @@ export interface Mandature {
259
260
  mandatRemplaceRef?: null | string;
260
261
  matriculeVote?: null | string;
261
262
  }
262
- export interface PurpleOrganes {
263
+ export interface Organes {
263
264
  organeRef: string[] | string;
264
265
  }
265
266
  export interface Suppleants {
@@ -305,36 +306,13 @@ export declare enum CodeType {
305
306
  Presrep = "PRESREP",
306
307
  Senat = "SENAT"
307
308
  }
308
- export interface FluffyMandat {
309
- "@xmlns:xsi": string;
310
- "@xsi:type": MandatXsiType;
311
- uid: string;
312
- acteurRef: string;
313
- legislature: null | string;
314
- typeOrgane: CodeType;
315
- dateDebut: Date;
316
- datePublication: null;
317
- dateFin: Date | null;
318
- preseance: null | string;
319
- nominPrincipale: string;
320
- infosQualite: InfosQualite;
321
- organes: FluffyOrganes;
322
- suppleants: null;
323
- chambre: null;
324
- election: PurpleElection;
325
- mandature: Mandature;
326
- collaborateurs?: null[] | Collaborateurs | null;
327
- }
328
- export interface FluffyOrganes {
329
- organeRef: string;
330
- }
331
309
  export interface Profession {
332
- libelleCourant: UriHatvpClass | null | string;
310
+ libelleCourant: Nil | null | string;
333
311
  socProcINSEE: SocProcInsee;
334
312
  }
335
313
  export interface SocProcInsee {
336
- catSocPro: UriHatvpClass | null | string;
337
- famSocPro: UriHatvpClass | FamSocProEnum | null;
314
+ catSocPro: Nil | null | string;
315
+ famSocPro: Nil | FamSocProEnum | null;
338
316
  }
339
317
  export declare enum FamSocProEnum {
340
318
  AgriculteursExploitants = "Agriculteurs exploitants",
@@ -347,7 +325,7 @@ export declare enum FamSocProEnum {
347
325
  Retraités = "Retrait\u00E9s",
348
326
  SansProfessionDéclarée = "Sans profession d\u00E9clar\u00E9e"
349
327
  }
350
- export interface PurpleUid {
328
+ export interface Uid {
351
329
  "@xmlns:xsi"?: string;
352
330
  "@xsi:type": UidXsiType;
353
331
  "#text": string;
@@ -491,30 +469,8 @@ export interface ViMoDe {
491
469
  dateAgrement: Date | null;
492
470
  dateFin: Date | null;
493
471
  }
494
- export interface Mandat {
495
- mandat: TentacledMandat;
496
- }
497
- export interface TentacledMandat {
498
- "@xmlns:xsi"?: string;
499
- uid: string;
500
- acteurRef: string;
501
- legislature: null | string;
502
- typeOrgane: CodeType;
503
- dateDebut: Date;
504
- datePublication: Date | null;
505
- dateFin: Date | null;
506
- preseance: null | string;
507
- nominPrincipale: string;
508
- infosQualite: InfosQualite;
509
- organes: PurpleOrganes;
510
- suppleants?: Suppleants | null;
511
- chambre?: null;
512
- election?: PurpleElection;
513
- mandature?: Mandature;
514
- collaborateurs?: null[] | Collaborateurs | null;
515
- libelle?: null | string;
516
- missionSuivanteRef?: null | string;
517
- missionPrecedenteRef?: null | string;
472
+ export interface MandatWrapper {
473
+ mandat: Mandat;
518
474
  }
519
475
  export interface ActeursEtOrganes {
520
476
  export: Export;
@@ -528,82 +484,14 @@ export interface Acteurs {
528
484
  acteur: ActeurElement[];
529
485
  }
530
486
  export interface ActeurElement {
531
- uid: FluffyUid;
532
- etatCivil: FluffyEtatCivil;
487
+ uid: Uid;
488
+ etatCivil: EtatCivil;
533
489
  uri_hatvp?: null | string;
534
- mandats: FluffyMandats;
535
- }
536
- export interface FluffyEtatCivil {
537
- ident: FluffyIdent;
538
- infoNaissance: FluffyInfoNaissance;
539
- dateDeces: Date | null;
540
- }
541
- export interface FluffyIdent {
542
- civ: Civ;
543
- prenom: string;
544
- nom: string;
545
- alpha: string;
546
- trigramme: null | string;
547
- }
548
- export interface FluffyInfoNaissance {
549
- dateNais: Date;
550
- villeNais: null | string;
551
- depNais: DepNais | null;
552
- paysNais: null | string;
553
- }
554
- export interface FluffyMandats {
555
- mandat: StickyMandat[] | IndigoMandat;
556
- }
557
- export interface StickyMandat {
558
- "@xsi:type": MandatXsiType;
559
- uid: string;
560
- acteurRef: string;
561
- legislature: null | string;
562
- typeOrgane: CodeType;
563
- dateDebut: Date;
564
- datePublication: Date | null;
565
- dateFin: Date | null;
566
- preseance: null | string;
567
- nominPrincipale: string;
568
- infosQualite: InfosQualite;
569
- organes: PurpleOrganes;
570
- suppleants?: Suppleants | null;
571
- election?: PurpleElection;
572
- InfosHorsSIAN?: InfosHorsSian;
573
- mandature?: Mandature;
574
- libelle?: null | string;
575
- missionPrecedenteRef?: null | string;
576
- missionSuivanteRef?: null | string;
490
+ mandats: Mandats;
577
491
  }
578
492
  export interface InfosHorsSian {
579
493
  HATVP_URI: null;
580
494
  }
581
- export interface IndigoMandat {
582
- "@xsi:type": MandatXsiType;
583
- uid: string;
584
- acteurRef: string;
585
- legislature: null;
586
- typeOrgane: CodeType;
587
- dateDebut: Date;
588
- datePublication: null;
589
- dateFin: Date;
590
- preseance: null | string;
591
- nominPrincipale: string;
592
- infosQualite: InfosQualite;
593
- organes: FluffyOrganes;
594
- suppleants: null;
595
- election: FluffyElection;
596
- InfosHorsSIAN: InfosHorsSian;
597
- mandature: Mandature;
598
- }
599
- export interface FluffyElection {
600
- lieu: ElectionLieu;
601
- causeMandat: null;
602
- }
603
- export interface FluffyUid {
604
- "@xsi:type": UidXsiType;
605
- "#text": string;
606
- }
607
495
  export interface ExportOrganes {
608
496
  organe: OrganeElement[];
609
497
  }
@@ -629,8 +517,8 @@ export declare class Convert {
629
517
  static deportToJson(value: Deport): string;
630
518
  static toOrgane(json: string): Organe;
631
519
  static organeToJson(value: Organe): string;
632
- static toMandat(json: string): Mandat;
633
- static mandatToJson(value: Mandat): string;
520
+ static toMandatWrapper(json: string): MandatWrapper;
521
+ static mandatWrapperToJson(value: MandatWrapper): string;
634
522
  static toActeursEtOrganes(json: string): ActeursEtOrganes;
635
523
  static acteursEtOrganesToJson(value: ActeursEtOrganes): string;
636
524
  }