@tricoteuses/assemblee 1.9.13 → 1.10.0

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 (235) hide show
  1. package/README.md +0 -5
  2. package/lib/api.js +1 -1
  3. package/lib/api.mjs +1 -1
  4. package/lib/bugs/acteur-00010/plugin.test.js +5 -5
  5. package/lib/bugs/acteur-00010/plugin.test.mjs +1 -1
  6. package/lib/bugs/acteur-00010.js +17 -18
  7. package/lib/bugs/acteur-00010.mjs +1 -1
  8. package/lib/bugs/agenda-00002/plugin.test.js +6 -6
  9. package/lib/bugs/agenda-00002/plugin.test.mjs +1 -1
  10. package/lib/bugs/agenda-00002.js +31 -32
  11. package/lib/bugs/agenda-00002.mjs +3 -3
  12. package/lib/bugs/agenda-00008/plugin.test.js +5 -5
  13. package/lib/bugs/agenda-00008/plugin.test.mjs +1 -1
  14. package/lib/bugs/agenda-00008.js +17 -18
  15. package/lib/bugs/agenda-00008.mjs +1 -1
  16. package/lib/bugs/agenda-00011/plugin.test.js +10 -10
  17. package/lib/bugs/agenda-00011/plugin.test.mjs +1 -1
  18. package/lib/bugs/agenda-00011.js +28 -29
  19. package/lib/bugs/agenda-00011.mjs +3 -3
  20. package/lib/bugs.js +27 -29
  21. package/lib/bugs.mjs +3 -3
  22. package/lib/cleaners/actes_legislatifs.js +5 -5
  23. package/lib/cleaners/actes_legislatifs.mjs +1 -1
  24. package/lib/cleaners/acteurs.js +5 -5
  25. package/lib/cleaners/acteurs.mjs +1 -1
  26. package/lib/cleaners/amendements.js +5 -5
  27. package/lib/cleaners/amendements.mjs +1 -1
  28. package/lib/cleaners/debats.js +1 -1
  29. package/lib/cleaners/debats.mjs +1 -1
  30. package/lib/cleaners/documents.js +5 -5
  31. package/lib/cleaners/documents.mjs +1 -1
  32. package/lib/cleaners/dossiers_legislatifs.js +5 -5
  33. package/lib/cleaners/dossiers_legislatifs.mjs +1 -1
  34. package/lib/cleaners/index.d.ts +0 -1
  35. package/lib/cleaners/index.js +1 -8
  36. package/lib/cleaners/index.mjs +1 -2
  37. package/lib/cleaners/organes.js +2 -2
  38. package/lib/cleaners/organes.mjs +1 -1
  39. package/lib/cleaners/questions.js +1 -1
  40. package/lib/cleaners/questions.mjs +1 -1
  41. package/lib/cleaners/reunions.js +5 -5
  42. package/lib/cleaners/reunions.mjs +1 -1
  43. package/lib/cleaners/scrutins.js +8 -8
  44. package/lib/cleaners/scrutins.mjs +1 -1
  45. package/lib/cleaners/xml.js +8 -8
  46. package/lib/cleaners/xml.mjs +1 -1
  47. package/lib/datasets.d.ts +1 -13
  48. package/lib/datasets.js +10 -29
  49. package/lib/datasets.mjs +2 -21
  50. package/lib/dates.js +3 -4
  51. package/lib/dates.mjs +1 -1
  52. package/lib/dossiers_legislatifs.js +8 -8
  53. package/lib/dossiers_legislatifs.mjs +1 -1
  54. package/lib/file_systems.js +15 -14
  55. package/lib/file_systems.mjs +3 -3
  56. package/lib/git.js +5 -5
  57. package/lib/git.mjs +1 -1
  58. package/lib/index.d.ts +1 -0
  59. package/lib/index.js +8 -1
  60. package/lib/index.mjs +2 -1
  61. package/lib/inserters.js +4 -4
  62. package/lib/inserters.mjs +1 -1
  63. package/lib/loaders.d.ts +0 -5
  64. package/lib/loaders.js +255 -299
  65. package/lib/loaders.mjs +1 -13
  66. package/lib/logger.js +1 -1
  67. package/lib/logger.mjs +1 -1
  68. package/lib/organes.js +1 -1
  69. package/lib/organes.mjs +1 -1
  70. package/lib/parsers/documents.js +11 -11
  71. package/lib/parsers/documents.mjs +1 -1
  72. package/lib/parsers/index.d.ts +1 -0
  73. package/lib/parsers/index.js +8 -1
  74. package/lib/parsers/index.mjs +2 -1
  75. package/lib/parsers/recherche_amendements.js +17 -15
  76. package/lib/parsers/recherche_amendements.mjs +1 -1
  77. package/lib/parsers/textes_lois.d.ts +22 -15
  78. package/lib/parsers/textes_lois.js +264 -752
  79. package/lib/parsers/textes_lois.mjs +249 -597
  80. package/lib/raw_types/acteurs_et_organes.js +9 -9
  81. package/lib/raw_types/acteurs_et_organes.mjs +1 -1
  82. package/lib/raw_types/agendas.d.ts +1 -0
  83. package/lib/raw_types/agendas.js +11 -10
  84. package/lib/raw_types/agendas.mjs +3 -2
  85. package/lib/raw_types/amendements.js +9 -9
  86. package/lib/raw_types/amendements.mjs +1 -1
  87. package/lib/raw_types/debats.js +9 -9
  88. package/lib/raw_types/debats.mjs +1 -1
  89. package/lib/raw_types/dossiers_legislatifs.js +9 -9
  90. package/lib/raw_types/dossiers_legislatifs.mjs +1 -1
  91. package/lib/raw_types/questions.js +9 -9
  92. package/lib/raw_types/questions.mjs +1 -1
  93. package/lib/raw_types/scrutins.js +9 -9
  94. package/lib/raw_types/scrutins.mjs +1 -1
  95. package/lib/scripts/bugs_helper.js +25 -26
  96. package/lib/scripts/bugs_helper.mjs +3 -3
  97. package/lib/scripts/clean_reorganized_data.js +256 -245
  98. package/lib/scripts/clean_reorganized_data.mjs +18 -29
  99. package/lib/scripts/diff_amendements.js +9 -8
  100. package/lib/scripts/diff_amendements.mjs +1 -1
  101. package/lib/scripts/document_dossiers_legislatifs.js +24 -27
  102. package/lib/scripts/document_dossiers_legislatifs.mjs +3 -3
  103. package/lib/scripts/get_today_reunions.js +3 -2
  104. package/lib/scripts/get_today_reunions.mjs +1 -1
  105. package/lib/scripts/merge_scrutins.js +9 -8
  106. package/lib/scripts/merge_scrutins.mjs +1 -1
  107. package/lib/scripts/parse_textes_lois.js +6 -5
  108. package/lib/scripts/parse_textes_lois.mjs +1 -1
  109. package/lib/scripts/process_open_dataset.d.ts +0 -2
  110. package/lib/scripts/process_open_dataset.js +19 -19
  111. package/lib/scripts/process_open_dataset.mjs +3 -5
  112. package/lib/scripts/raw_types_from_amendements.d.ts +0 -1
  113. package/lib/scripts/raw_types_from_amendements.js +122 -198
  114. package/lib/scripts/raw_types_from_amendements.mjs +105 -60
  115. package/lib/scripts/reorganize_data.js +14 -15
  116. package/lib/scripts/reorganize_data.mjs +3 -3
  117. package/lib/scripts/retrieve_deputes_photos.js +40 -31
  118. package/lib/scripts/retrieve_deputes_photos.mjs +10 -2
  119. package/lib/scripts/retrieve_documents.d.ts +1 -1
  120. package/lib/scripts/retrieve_documents.js +230 -138
  121. package/lib/scripts/retrieve_documents.mjs +87 -38
  122. package/lib/scripts/retrieve_open_data.js +27 -30
  123. package/lib/scripts/retrieve_open_data.mjs +5 -8
  124. package/lib/scripts/retrieve_pending_amendments.js +14 -14
  125. package/lib/scripts/retrieve_pending_amendments.mjs +1 -1
  126. package/lib/scripts/retrieve_senateurs_photos.js +10 -10
  127. package/lib/scripts/retrieve_senateurs_photos.mjs +1 -1
  128. package/lib/scripts/retrieve_textes_lois.js +17 -15
  129. package/lib/scripts/retrieve_textes_lois.mjs +1 -1
  130. package/lib/scripts/shared/cli_helpers.d.ts +11 -0
  131. package/lib/scripts/shared/cli_helpers.js +13 -2
  132. package/lib/scripts/shared/cli_helpers.mjs +12 -1
  133. package/lib/scripts/test_iter_load.js +5 -19
  134. package/lib/scripts/test_iter_load.mjs +2 -9
  135. package/lib/scripts/test_load.js +2 -2
  136. package/lib/scripts/test_load.mjs +1 -1
  137. package/lib/scripts/test_load_big_files.js +2 -2
  138. package/lib/scripts/test_load_big_files.mjs +1 -1
  139. package/lib/scripts/validate_json.js +17 -18
  140. package/lib/scripts/validate_json.mjs +3 -3
  141. package/lib/shared_types/codes_actes.js +1 -1
  142. package/lib/shared_types/codes_actes.mjs +1 -1
  143. package/lib/strings.js +1 -1
  144. package/lib/strings.mjs +1 -1
  145. package/lib/types/acteurs_et_organes.js +9 -9
  146. package/lib/types/acteurs_et_organes.mjs +1 -1
  147. package/lib/types/agendas.d.ts +1 -0
  148. package/lib/types/agendas.js +11 -10
  149. package/lib/types/agendas.mjs +3 -2
  150. package/lib/types/amendements.js +9 -9
  151. package/lib/types/amendements.mjs +1 -1
  152. package/lib/types/debats.js +9 -9
  153. package/lib/types/debats.mjs +1 -1
  154. package/lib/types/dossiers_legislatifs.d.ts +13 -0
  155. package/lib/types/dossiers_legislatifs.js +47 -9
  156. package/lib/types/dossiers_legislatifs.mjs +39 -1
  157. package/lib/types/legislatures.js +1 -1
  158. package/lib/types/legislatures.mjs +1 -1
  159. package/lib/types/questions.js +9 -9
  160. package/lib/types/questions.mjs +1 -1
  161. package/lib/types/scrutins.js +9 -9
  162. package/lib/types/scrutins.mjs +1 -1
  163. package/lib/urls.js +2 -2
  164. package/lib/urls.mjs +1 -1
  165. package/package.json +14 -20
  166. package/lib/cleaners/textes_loi.d.ts +0 -1
  167. package/lib/cleaners/textes_loi.js +0 -12
  168. package/lib/cleaners/textes_loi.mjs +0 -5
  169. package/lib/examples/PIONANR5L15B0020/input.d.ts +0 -2
  170. package/lib/examples/PIONANR5L15B0020/input.js +0 -10
  171. package/lib/examples/PIONANR5L15B0020/input.mjs +0 -193
  172. package/lib/examples/PIONANR5L15B0020/input.ts +0 -193
  173. package/lib/examples/PIONANR5L15B0020/loi.json +0 -26
  174. package/lib/examples/PIONANR5L15B0020/loi_populated.json +0 -29
  175. package/lib/examples/PIONANR5L15B0020/meta.json +0 -28
  176. package/lib/examples/PIONANR5L15B0020/motifs.json +0 -5
  177. package/lib/examples/PIONANR5L15B0020/motifs_populated.json +0 -6
  178. package/lib/examples/PIONANR5L15B0020/sommaire.json +0 -3
  179. package/lib/examples/PRJLANR5L16B0914/input.d.ts +0 -2
  180. package/lib/examples/PRJLANR5L16B0914/input.js +0 -10
  181. package/lib/examples/PRJLANR5L16B0914/input.mjs +0 -322
  182. package/lib/examples/PRJLANR5L16B0914/input.ts +0 -322
  183. package/lib/examples/PRJLANR5L16B0914/loi.json +0 -14
  184. package/lib/examples/PRJLANR5L16B0914/loi_populated.json +0 -20
  185. package/lib/examples/PRJLANR5L16B0914/meta.json +0 -35
  186. package/lib/examples/PRJLANR5L16B0914/motifs.json +0 -4
  187. package/lib/examples/PRJLANR5L16B0914/motifs_populated.json +0 -5
  188. package/lib/examples/PRJLANR5L16B0914/sommaire.json +0 -3
  189. package/lib/examples/PRJLANR5L16B2014/README.md +0 -2
  190. package/lib/examples/PRJLANR5L16B2014/input.d.ts +0 -2
  191. package/lib/examples/PRJLANR5L16B2014/input.js +0 -10
  192. package/lib/examples/PRJLANR5L16B2014/input.mjs +0 -577
  193. package/lib/examples/PRJLANR5L16B2014/input.ts +0 -577
  194. package/lib/examples/PRJLANR5L16B2014/loi.json +0 -369
  195. package/lib/examples/PRJLANR5L16B2014/meta.json +0 -31
  196. package/lib/examples/PRJLANR5L16B2014/motifs.json +0 -5
  197. package/lib/examples/PRJLANR5L16B2014/sommaire.json +0 -51
  198. package/lib/examples/PRJLANR5L16B2424/alineas.json +0 -44
  199. package/lib/examples/PRJLANR5L16B2424/input.d.ts +0 -2
  200. package/lib/examples/PRJLANR5L16B2424/input.js +0 -10
  201. package/lib/examples/PRJLANR5L16B2424/input.mjs +0 -322
  202. package/lib/examples/PRJLANR5L16B2424/input.ts +0 -322
  203. package/lib/examples/PRJLANR5L16B2424/loi.json +0 -74
  204. package/lib/examples/PRJLANR5L16B2424/loi_populated.json +0 -87
  205. package/lib/examples/PRJLANR5L16B2424/meta.json +0 -31
  206. package/lib/examples/PRJLANR5L16B2424/motifs.json +0 -4
  207. package/lib/examples/PRJLANR5L16B2424/motifs_populated.json +0 -5
  208. package/lib/examples/PRJLANR5L16B2424/sommaire.json +0 -3
  209. package/lib/examples/PRJLANR5L16B2462/input.d.ts +0 -2
  210. package/lib/examples/PRJLANR5L16B2462/input.js +0 -10
  211. package/lib/examples/PRJLANR5L16B2462/input.mjs +0 -1308
  212. package/lib/examples/PRJLANR5L16B2462/input.ts +0 -1308
  213. package/lib/examples/PRJLANR5L16B2462/loi.json +0 -74
  214. package/lib/examples/PRJLANR5L16B2462/loi_populated.json +0 -310
  215. package/lib/examples/PRJLANR5L16B2462/meta.json +0 -29
  216. package/lib/examples/PRJLANR5L16B2462/motifs.json +0 -6
  217. package/lib/examples/PRJLANR5L16B2462/motifs_populated.json +0 -6
  218. package/lib/examples/PRJLANR5L16B2462/sommaire.json +0 -50
  219. package/lib/examples/README.md +0 -3
  220. package/lib/raw_types/textes_loi.d.ts +0 -93
  221. package/lib/raw_types/textes_loi.js +0 -429
  222. package/lib/raw_types/textes_loi.mjs +0 -378
  223. package/lib/schemas/texte_loi/Alinea.json +0 -36
  224. package/lib/schemas/texte_loi/ExposeMotifs.json +0 -24
  225. package/lib/schemas/texte_loi/MetaDonnees.json +0 -126
  226. package/lib/schemas/texte_loi/ProjetLoi.json +0 -64
  227. package/lib/schemas/texte_loi/Sommaire.json +0 -48
  228. package/lib/schemas/texte_loi/TexteLoi.json +0 -225
  229. package/lib/schemas/texte_loi/TexteLoiPartiel.json +0 -237
  230. package/lib/scripts/process_textes_loi_dataset.d.ts +0 -7
  231. package/lib/scripts/process_textes_loi_dataset.js +0 -373
  232. package/lib/scripts/process_textes_loi_dataset.mjs +0 -239
  233. package/lib/types/textes_loi.d.ts +0 -94
  234. package/lib/types/textes_loi.js +0 -429
  235. package/lib/types/textes_loi.mjs +0 -378
@@ -1,608 +1,260 @@
1
- import { ChatOpenAI } from "@langchain/openai";
2
- import { ChatPromptTemplate } from "@langchain/core/prompts";
3
- import Ajv from "ajv";
4
- import { delimiter, runLogFun } from "../logger.mjs";
5
- const ALINEA_SCHEMA = require("../schemas/texte_loi/Alinea.json");
6
- const EXPOSE_MOTIFS_SCHEMA = require("../schemas/texte_loi/ExposeMotifs.json");
7
- const META_DONNEES_SCHEMA = require("../schemas/texte_loi/MetaDonnees.json");
8
- const PROJET_LOI_SCHEMA = require("../schemas/texte_loi/ProjetLoi.json");
9
- const SOMMAIRE_SCHEMA = require("../schemas/texte_loi/Sommaire.json");
10
-
11
- /**
12
- * Object containing input examples and their output schemas.
13
- * Used to train the LLM.
14
- * @type {Record<string, {motifs: any, input: any, loi: any, meta: any, sommaire: any}>}
15
- */
16
- const EXAMPLES = {
17
- PRJLANR5L16B0914: {
18
- motifs: require("../examples/PRJLANR5L16B0914/motifs.json"),
19
- input: require("../examples/PRJLANR5L16B0914/input"),
20
- loi: require("../examples/PRJLANR5L16B0914/loi.json"),
21
- meta: require("../examples/PRJLANR5L16B0914/meta.json"),
22
- sommaire: require("../examples/PRJLANR5L16B0914/sommaire.json")
23
- },
24
- PRJLANR5L16B2014: {
25
- motifs: require("../examples/PRJLANR5L16B2014/motifs.json"),
26
- input: require("../examples/PRJLANR5L16B2014/input"),
27
- loi: require("../examples/PRJLANR5L16B2014/loi.json"),
28
- meta: require("../examples/PRJLANR5L16B2014/meta.json"),
29
- sommaire: require("../examples/PRJLANR5L16B2014/sommaire.json")
30
- },
31
- PRJLANR5L16B2424: {
32
- alineas: require("../examples/PRJLANR5L16B2424/alineas.json"),
33
- motifs: require("../examples/PRJLANR5L16B2424/motifs.json"),
34
- input: require("../examples/PRJLANR5L16B2424/input"),
35
- loi: require("../examples/PRJLANR5L16B2424/loi.json"),
36
- meta: require("../examples/PRJLANR5L16B2424/meta.json"),
37
- sommaire: require("../examples/PRJLANR5L16B2424/sommaire.json")
38
- }
39
- };
40
- const FULL_TEXTE_SCHEMA = {
41
- $schema: "http://json-schema.org/draft-07/schema#",
42
- title: "Sommaire",
43
- description: "Récupération d'un texte complet",
44
- type: "object",
45
- properties: {
46
- texte: {
47
- description: "Texte complet de la section indiquée.",
48
- type: "string"
49
- }
50
- },
51
- required: ["texte"]
52
- };
53
-
54
- /**
55
- * LLM model.
56
- */
57
- let MODEL = null;
58
- if (process.env.OPENAI_API_KEY) {
59
- MODEL = new ChatOpenAI({
60
- temperature: 0,
61
- topP: 0.0,
62
- model: "gpt-4o-mini",
63
- apiKey: process.env.OPENAI_API_KEY,
64
- maxTokens: -1
65
- });
66
- }
67
-
68
- /**
69
- * System input template for the LLM.
70
- */
71
- const SYSTEM_TEMPLATE = `
72
- # Instructions :
73
-
74
- Tu es un expert de la loi et de l'analyse de pages HTML.
75
- Tu dois analyser un texte de loi afin de séparer et de structurer les éléments qui le composent. Le format d'entrée est HTML.
76
-
77
- Le texte est divisé en deux parties :
78
- A) un exposé des motifs qui indique les raisons pour lesquelles ce projet est soumis au Parlement. Il peut contenir 3 éléments : 1) une citation au début d'un document, 2) le texte principal qui développe les arguments de l'auteur à l'appui de la modification législative ou des dispositions nouvelles qu'il propose, 3) des paragraphes qui présentent les articles.
79
- B) le dispositif qui est la partie normative et rédigée en articles. Il peut comporter des divisions nommées titres, chapitres, sections, sous-sections. Lorsqu'il y a un seul niveau de structure, on retrouvera le chapitre ; s’il y a deux niveaux de structure, on retrouvera des chapitres puis des sections. S’il y a trois niveaux de structure, on retrouvera des titres puis des chapitres puis des sections.
80
-
81
- Si le texte de loi ne comporte pas de division, le sommaire doit rester vide.
82
- Toutes les lignes qui débutent par un '«' ne sont pas à prendre en compte dans les divisions
83
- Ta réponse doit être un JSON structuré avec les éléments du texte de loi en respectant le schéma JSON fourni.
84
- `;
85
- let SILENT_LOG = false;
86
-
87
- /**
88
- * Parses the given HTML string and returns the parsed textes loi.
89
- *
90
- * @param {string} html - The HTML string to parse.
91
- * @return {Promise<{partial: {sommaire: any, loi: any, motifs: any, meta: any}, completed: {sommaire: any, loi: any, motifs: any, meta: any}}>} - The parsed textes loi, including the partial and completed versions.
92
- */
93
- export async function parseTexteLoi(html, options = {
94
- silent: false
95
- }) {
96
- SILENT_LOG = options.silent;
97
- runLogFun(console.info("Start extracting loi..."), options);
98
- const meta = await extractMetaDonnees(html);
99
- const sommaire = await extractSommaire(html);
100
- const partialMotifs = await extractMotifs(html);
101
- const partialLoi = await extractProjetLoi(html);
102
- const exposeMotifs = await populateMotifs(partialMotifs, html);
103
- const loi = await populateProjetLoi(partialLoi, html);
104
- return {
105
- sommaire,
106
- loi,
107
- exposeMotifs,
108
- meta
109
- };
110
- }
111
-
112
- /**
113
- * Cleans the given HTML string by removing unnecessary tags and content.
114
- *
115
- * @param {string} html - The HTML string to be cleaned.
116
- * @return {string} The cleaned HTML string.
117
- */
118
- function cleanHtml(html) {
119
- let cleanedHtml = html.replace(/(<style[\w\W]+style>)/g, "");
120
- cleanedHtml = cleanedHtml.replace(/(<head[\w\W]+head>)/g, "");
121
- cleanedHtml = cleanedHtml.replace(/<img[^>]*>/g, "");
122
- return cleanedHtml;
123
- }
124
-
125
- /**
126
- * Removes all HTML tags from the given HTML string and returns the cleaned text.
127
- *
128
- * @param {string} html - The HTML string from which to remove tags.
129
- * @return {string} The cleaned text without any HTML tags.
130
- */
131
- function removeHtmlTags(html) {
132
- // Regular expression to match HTML tags
133
- const htmlTagRegex = /<[^>]*>/g;
134
-
135
- // Replace all HTML tags with an empty string
136
- const textWithoutTags = html.replace(htmlTagRegex, "");
137
- return textWithoutTags;
138
- }
139
-
140
- /**
141
- * Populates the motifs object with the extracted text from the given HTML.
142
- *
143
- * @param {Record<string, any>} motifs - The motifs object to be populated.
144
- * @param {string} html - The HTML string from which to extract the text.
145
- * @return {Promise<Record<string, any>>} - The populated motifs object.
146
- */
147
- async function populateMotifs(motifs, html) {
148
- runLogFun(console.info("Populating expose motifs..."));
149
- let cleanedHtml = cleanHtml(html);
150
- if (motifs.debut === motifs.fin || !motifs.fin) {
151
- motifs.texte = motifs.debut;
152
- } else {
153
- const systemTemplate = `
154
- # Instructions :
155
-
156
- Tu es un expert de la loi et de l'analyse de pages HTML.
157
- Tu dois analyser un texte de loi afin d'en extraire certaines parties.
158
- Le format d'entrée est du HTML. Le format de sortie est du texte.
159
- Récupère l'intégralité du texte commençant par :
160
-
161
- """
162
- {debut}
163
- """
164
-
165
- Et finissant par :
166
-
167
- """
168
- {fin}
169
- """
170
- `;
171
- const prompt = ChatPromptTemplate.fromMessages([["system", systemTemplate], ["human", "{input}"]]);
172
- const structuredModel = MODEL.withStructuredOutput(FULL_TEXTE_SCHEMA);
173
- const chain = prompt.pipe(structuredModel);
174
- const articlePromptResult = await chain.invoke({
175
- input: cleanedHtml,
176
- debut: motifs.debut,
177
- fin: motifs.fin
178
- });
179
- motifs.texte = articlePromptResult.texte;
180
- }
181
- runLogFun(console.info("Opération de peuplement de l'exposé des motifs terminée ✅"), {
182
- silent: SILENT_LOG
183
- });
184
- delimiter(SILENT_LOG);
185
- delete motifs.debut;
186
- delete motifs.fin;
187
- return motifs;
188
- }
189
-
190
- /**
191
- * Asynchronously populates a projet loi object with the full text of each article and alinea in the given HTML.
192
- *
193
- * @param {Record<string, any>} partial - The partial projet loi object to be populated.
194
- * @param {string} html - The HTML containing the text of the articles and alineas.
195
- * @return {Promise<Record<string, any>>} A Promise that resolves to the fully populated projet loi object.
196
- */
197
- async function populateProjetLoi(partial, html) {
198
- runLogFun(console.group("Peuplement du projet loi..."), {
199
- silent: SILENT_LOG
200
- });
201
- let cleanedHtml = cleanHtml(html);
202
- const articles = partial.articles;
203
- const fullArticles = [];
204
- const systemTemplate = `
205
- # Instructions :
206
-
207
- Tu es un expert de la loi et de l'analyse de pages HTML.
208
- Tu dois analyser un texte de loi afin d'en extraire certaines parties.
209
- Le format d'entrée est du HTML. Le format de sortie est du texte.
210
- Récupère l'intégralité du texte commençant par :
211
-
212
- """
213
- {debut}
214
- """
215
-
216
- Et finissant par :
217
-
218
- """
219
- {fin}
220
- """
221
- `;
222
- const prompt = ChatPromptTemplate.fromMessages([["system", systemTemplate], ["human", "{input}"]]);
223
- const structuredModel = MODEL.withStructuredOutput(FULL_TEXTE_SCHEMA);
224
- const chain = prompt.pipe(structuredModel);
225
- for (const article of articles) {
226
- if (article.debut === article.fin || !article.fin) {
227
- article.texte = article.debut;
228
- } else {
229
- const articlePromptResult = await chain.invoke({
230
- input: cleanedHtml,
231
- debut: article.debut,
232
- fin: article.fin
233
- });
234
- article.texte = articlePromptResult.texte;
1
+ import assert from "assert";
2
+ import { JSDOM } from "jsdom";
3
+ function parseHeader(header) {
4
+ const headersMapping = [{
5
+ regex: /^(RAPPORT_)?ANNEXE(_|$)|^ETAT_/,
6
+ level: 0,
7
+ name: "Annexe"
8
+ }, {
9
+ regex: /^TOME_/,
10
+ level: 1,
11
+ name: "Tome"
12
+ }, {
13
+ regex: /^PARTIE_|^(PREMIERE|SECONDE|DEUXIEME|TROISIEME|QUATRIEME)_PARTIE(_|$)/,
14
+ level: 2,
15
+ name: "Partie"
16
+ }, {
17
+ regex: /^LIVRE_/,
18
+ level: 3,
19
+ name: "Livre"
20
+ }, {
21
+ regex: /^TITRE_/,
22
+ level: 4,
23
+ name: "Titre"
24
+ }, {
25
+ regex: /^SOUSTITRE_/,
26
+ level: 5,
27
+ name: "SousTitre"
28
+ }, {
29
+ regex: /^CHAPITRE_/,
30
+ level: 6,
31
+ name: "Chapitre"
32
+ }, {
33
+ regex: /^SECTION_/,
34
+ level: 7,
35
+ name: "Section"
36
+ }, {
37
+ regex: /^SOUSSECTION_/,
38
+ level: 8,
39
+ name: "SousSection"
40
+ }, {
41
+ regex: /^ARTICLES?_|^EXPOSE_DES_MOTIFS$/,
42
+ level: 9,
43
+ name: "Article"
44
+ }];
45
+ for (let {
46
+ regex,
47
+ level,
48
+ name
49
+ } of headersMapping) {
50
+ if (header.match(regex)) {
51
+ return [level, name];
235
52
  }
236
- for (const alinea of article.alineas) {
237
- if (alinea.debut === alinea.fin || !alinea.fin) {
238
- alinea.texte = alinea.debut;
239
- continue;
240
- }
241
- const alineaPromptResult = await chain.invoke({
242
- input: article.texte,
243
- debut: alinea.debut,
244
- fin: alinea.fin
245
- });
246
- delete alinea.debut;
247
- delete alinea.fin;
248
- alinea.texte = alineaPromptResult.texte;
249
- }
250
- runLogFun(console.info("Opération de peuplement du contenu du projet de loi terminée ✅"), {
251
- silent: SILENT_LOG
252
- });
253
- delete article.debut;
254
- delete article.fin;
255
- fullArticles.push(article);
256
53
  }
257
- const projetLoi = {
258
- ...partial,
259
- articles: fullArticles
260
- };
261
- runLogFun(console.groupEnd(), {
262
- silent: SILENT_LOG
263
- });
264
- delimiter();
265
- return projetLoi;
54
+ return [null, ""];
266
55
  }
267
-
268
- /**
269
- * Asynchronously extracts the "expose motifs" from the given HTML.
270
- *
271
- * @param {string} html - The HTML string from which to extract the "expose motifs".
272
- * @return {Promise<Record<string, any>>} - A Promise that resolves to the extracted "expose motifs" object.
273
- * The object contains the following properties:
274
- * - `debut`: The beginning of the "expose motifs".
275
- * - `fin`: The end of the "expose motifs".
276
- * @throws {Error} - If the extracted "expose motifs" do not validate against the EXPOSE_MOTIFS_SCHEMA.
277
- */
278
- async function extractMotifs(html) {
279
- runLogFun(console.group("Parsing expose motifs..."), {
280
- silent: SILENT_LOG
281
- });
282
- let cleanedHtml = cleanHtml(html);
283
- cleanedHtml = removeHtmlTags(cleanedHtml);
284
- const structuredModel = MODEL.withStructuredOutput(EXPOSE_MOTIFS_SCHEMA);
285
- const motifsSystemTemplate = `
286
- ${SYSTEM_TEMPLATE}
287
-
288
- # Examples:
289
-
290
- ## Exemple 1 User Input :
291
- """
292
- {example1}
293
- """
294
-
295
- ## Exemple 1 JSON Output :
296
- """
297
- {output1}
298
- """
299
-
300
- ## Exemple 2 User Input :
301
- """
302
- {example2}
303
- """
304
-
305
- ## Exemple 2 JSON Output :
306
- """
307
- {output2}
308
- """
309
- `;
310
- const prompt = ChatPromptTemplate.fromMessages([["system", motifsSystemTemplate], ["human", "{input}"]]);
311
- const chain = prompt.pipe(structuredModel);
312
- const motifsPromptResult = await chain.invoke({
313
- input: cleanedHtml,
314
- example1: EXAMPLES.PRJLANR5L16B0914.input,
315
- example2: EXAMPLES.PRJLANR5L16B2424.input,
316
- output1: EXAMPLES.PRJLANR5L16B0914.motifs,
317
- output2: EXAMPLES.PRJLANR5L16B2424.motifs
318
- });
319
-
320
- // console.log(JSON.stringify(motifsPromptResult))
321
- runLogFun(console.table([["Début", motifsPromptResult.debut.substring(0, 30)], ["Fin", motifsPromptResult.fin.substring(0, 30)]]), {
322
- silent: SILENT_LOG
323
- });
324
- runLogFun(console.groupEnd(), {
325
- silent: SILENT_LOG
326
- });
327
- delimiter();
328
- const ajv = new Ajv();
329
- if (ajv.validate(EXPOSE_MOTIFS_SCHEMA, motifsPromptResult)) {
330
- runLogFun(console.info("Exposé des motifs OK 👌"), {
331
- silent: SILENT_LOG
332
- });
333
- return motifsPromptResult;
334
- }
335
- runLogFun(console.warn("Exposé des motifs KO ❌"), {
336
- silent: SILENT_LOG
337
- });
338
- return {};
56
+ function cleanText(text) {
57
+ return text?.replace(/[\n\t]+/g, "").trim() || "";
339
58
  }
340
-
341
- /**
342
- * Asynchronously extracts the metadata from the given HTML.
343
- *
344
- * @param {string} html - The HTML string from which to extract the metadata.
345
- * @return {Promise<Record<string, any>>} - A Promise that resolves to the extracted metadata object.
346
- * The object contains the following properties:
347
- * - `documentRef`: The reference of the document.
348
- * - `titre`: The title of the document.
349
- * - `numeroTexte`: The number of the text.
350
- * - `procedureAcceleree`: The accelerated procedure.
351
- * @throws {Error} - If the extracted metadata do not validate against the META_DONNEES_SCHEMA.
352
- */
353
- async function extractMetaDonnees(html) {
354
- delimiter();
355
- let cleanedHtml = cleanHtml(html);
356
- cleanedHtml = removeHtmlTags(cleanedHtml);
357
- const structuredModel = MODEL.withStructuredOutput(META_DONNEES_SCHEMA);
358
- const metaDonneesSystemTemplate = `
359
- ${SYSTEM_TEMPLATE}
360
- `;
361
- const prompt = ChatPromptTemplate.fromMessages([["system", metaDonneesSystemTemplate], ["human", "{input}"]]);
362
- const chain = prompt.pipe(structuredModel);
363
- const result = await chain.invoke({
364
- input: cleanedHtml,
365
- example1: EXAMPLES.PRJLANR5L16B0914.input,
366
- example2: EXAMPLES.PRJLANR5L16B2424.input,
367
- output1: EXAMPLES.PRJLANR5L16B0914.meta,
368
- output2: EXAMPLES.PRJLANR5L16B2424.meta
369
- });
370
- console.group("Meta-données");
371
- console.table([["Référence", result.documentRef], ["Titre", result.titre], ["Numéro du texte", result.numeroTexte], ["Procédure accéléré", result.procedureAcceleree]]);
372
- console.groupEnd();
373
- delimiter();
374
- const ajv = new Ajv();
375
- if (ajv.validate(META_DONNEES_SCHEMA, result)) {
376
- runLogFun(console.warn("Meta-données OK 👌"), {
377
- silent: SILENT_LOG
378
- });
379
- return result;
380
- }
381
- runLogFun(console.warn("Meta-données non-conforme ❌"), {
382
- silent: SILENT_LOG
383
- });
384
- return {};
385
- }
386
-
387
- /**
388
- * Asynchronously extracts the "projet de loi" from the given HTML.
389
- *
390
- * @param {string} html - The HTML string from which to extract the "projet de loi".
391
- * @return {Promise<Record<string, any>>} - A Promise that resolves to the extracted "projet de loi" object.
392
- * The object contains the following properties:
393
- * - `articles`: An array of article objects, each containing the following properties:
394
- * - `numeroArticle`: The number of the article.
395
- * - `cardinal`: The cardinal of the article.
396
- * - `titre`: The title of the article.
397
- * - `debut`: The beginning of the article.
398
- * - `fin`: The end of the article.
399
- * - `alineas`: An array of alineas.
400
- * @throws {Error} - If the extracted "projet de loi" does not validate against the PROJET_LOI_SCHEMA.
401
- */
402
- async function extractProjetLoi(html) {
403
- runLogFun(console.group("Parsing loi..."), {
404
- silent: SILENT_LOG
405
- });
406
- let cleanedHtml = cleanHtml(html);
407
- const structuredModel = MODEL.withStructuredOutput(PROJET_LOI_SCHEMA);
408
- const projetLoiSystemTemplate = `
409
- ${SYSTEM_TEMPLATE}
410
-
411
- # Examples:
412
-
413
- ## Exemple 1 User Input :
414
- """
415
- {example1}
416
- """
417
-
418
- ## Exemple 1 JSON Output :
419
- """
420
- {output1}
421
- """
422
-
423
- ## Exemple 2 User Input :
424
- """
425
- {example2}
426
- """
427
-
428
- ## Exemple 2 JSON Output :
429
- """
430
- {output2}
431
- """
432
- `;
433
- const prompt = ChatPromptTemplate.fromMessages([["system", projetLoiSystemTemplate], ["human", "{input}"]]);
434
- const chain = prompt.pipe(structuredModel);
435
- const articlesPromptResult = await chain.invoke({
436
- input: cleanedHtml,
437
- example1: EXAMPLES.PRJLANR5L16B0914.input,
438
- example2: EXAMPLES.PRJLANR5L16B2424.input,
439
- output1: EXAMPLES.PRJLANR5L16B0914.loi,
440
- output2: EXAMPLES.PRJLANR5L16B2424.loi
441
- });
442
- runLogFun(console.log("Found ", articlesPromptResult.articles.length, " articles."), {
443
- silent: SILENT_LOG
444
- });
445
- for (const article of articlesPromptResult.articles) {
446
- article.alineas = await extractAlineas(html, article);
447
- }
448
- runLogFun(console.table(articlesPromptResult.articles.map(article => [article.numeroArticle, article.titre, article.debut.substring(0, 10), article.fin.substring(0, 10), `Nombre d'alineas : ${article.alineas.length}`])), {
449
- silent: SILENT_LOG
450
- });
451
- runLogFun(console.groupEnd(), {
452
- silent: SILENT_LOG
453
- });
454
- const ajv = new Ajv();
455
- if (ajv.validate(PROJET_LOI_SCHEMA, articlesPromptResult)) {
456
- runLogFun(console.info("Projet de loi OK 👌"), {
457
- silent: SILENT_LOG
458
- });
459
- delimiter();
460
- return articlesPromptResult;
461
- }
462
- runLogFun(console.warn("Projet de loi KO ❌"), {
463
- silent: SILENT_LOG
464
- });
465
- delimiter();
466
- return {};
467
- }
468
- async function extractAlineas(html, article) {
469
- runLogFun(console.group("Parsing alineas..."), {
470
- silent: SILENT_LOG
471
- });
472
- let cleanedHtml = cleanHtml(html);
473
- const structuredModel = MODEL.withStructuredOutput(ALINEA_SCHEMA);
474
- const alineasSystemTemplate = `
475
- ${SYSTEM_TEMPLATE}
476
-
477
- Extrais tous les alineas de la portion de texte commençant par « {debut} » et finissant par « {fin} ».
478
- Un alinéa contiennent toujours une balise « <img ».
479
-
480
- # Examples:
481
-
482
- ## Exemple 1 User Input :
483
- """
484
- {example1}
485
- """
486
-
487
- ## Exemple 1 JSON Output :
488
- """
489
- {output1}
490
- """
491
- `;
492
- const prompt = ChatPromptTemplate.fromMessages([["system", alineasSystemTemplate], ["human", "{input}"]]);
493
- const chain = prompt.pipe(structuredModel);
494
- const alineasPromptResult = await chain.invoke({
495
- input: cleanedHtml,
496
- debut: article.debut,
497
- fin: article.fin,
498
- example1: EXAMPLES.PRJLANR5L16B2424.input,
499
- output1: EXAMPLES.PRJLANR5L16B2424.alineas
500
- });
501
- const ajv = new Ajv();
502
- if (ajv.validate(ALINEA_SCHEMA, alineasPromptResult)) {
503
- runLogFun(console.info("Found ", alineasPromptResult.alineas.length, " alineas for Article ", article.numeroArticle, article.titre), {
504
- silent: SILENT_LOG
505
- });
506
- runLogFun(console.groupEnd(), {
507
- silent: SILENT_LOG
508
- });
509
- delimiter();
510
- return alineasPromptResult.alineas;
511
- }
512
- runLogFun(console.warn("Alineas KO"), {
513
- silent: SILENT_LOG
514
- });
515
- delimiter();
516
- return {};
517
- }
518
-
519
- /**
520
- * Asynchronously extracts the "sommaire" (outline) from the given HTML.
521
- *
522
- * @param {string} html - The HTML string from which to extract the "sommaire".
523
- * @return {Promise<Record<string, any>>} - A Promise that resolves to the extracted "sommaire" object.
524
- * The object contains the following properties:
525
- * - `sommaire`: An array of main division objects, each containing the following properties:
526
- * - `numeroDivision`: The number of the main division.
527
- * - `titre`: The title of the main division.
528
- * - `typeDivision`: The type of content in the main division.
529
- * - `sequence`: The sequence of the main division.
530
- * - `parent`: The parent of the main division.
531
- * @throws {Error} - If the extracted "sommaire" does not validate against the SOMMAIRE_SCHEMA.
532
- */
533
- async function extractSommaire(html) {
534
- let cleanedHtml = cleanHtml(html);
535
- cleanedHtml = removeHtmlTags(cleanedHtml);
536
- const structuredModel = MODEL.withStructuredOutput(SOMMAIRE_SCHEMA);
537
- const sommaireSystemTemplate = `
538
- ${SYSTEM_TEMPLATE}
539
-
540
- # Examples:
541
-
542
- ## Exemple 1 User Input :
543
- """
544
- {example1}
545
- """
546
-
547
- ## Exemple 1 JSON Output :
548
- """
549
- {output1}
550
- """
551
-
552
- ## Exemple 2 User Input :
553
- """
554
- {example2}
555
- """
556
-
557
- ## Exemple 2 JSON Output :
558
- """
559
- {output2}
560
- """
561
- `;
562
- const prompt = ChatPromptTemplate.fromMessages([["system", sommaireSystemTemplate], ["human", "{input}"]]);
563
- const chain = prompt.pipe(structuredModel);
564
- const sommairePromptResult = await chain.invoke({
565
- input: cleanedHtml,
566
- example1: EXAMPLES.PRJLANR5L16B2014.input,
567
- output1: EXAMPLES.PRJLANR5L16B2014.sommaire,
568
- example2: EXAMPLES.PRJLANR5L16B0914.input,
569
- output2: EXAMPLES.PRJLANR5L16B0914.sommaire
570
- });
571
- if (!sommairePromptResult.sommaire) {
572
- runLogFun(console.warn("Aucun sommaire n'a été trouvé ❓"), {
573
- silent: SILENT_LOG
574
- });
575
- delimiter();
59
+ const excludedAlineas = [/^Délibéré en séance publique/, /^Fait le/, /^Le Président,$/, /^Signé/];
60
+ export function parseTexte(assembleeUrl, page) {
61
+ // Repair HTML.
62
+ let html = page.replace(/(<style[\w\W]+style>)/g, "");
63
+
64
+ // Extract subdivisions from HTML.
65
+ const {
66
+ window
67
+ } = new JSDOM(html);
68
+ const {
69
+ document
70
+ } = window;
71
+ assert.strictEqual(document.children.length, 1);
72
+ const htmlElement = document.children[0];
73
+ assert.strictEqual(htmlElement.children.length, 2);
74
+ const bodyElement = htmlElement.children[1];
75
+ if (bodyElement.children.length < 3) {
76
+ // Occurs in http://www.assemblee-nationale.fr/15/textes/0326.asp.
77
+ window.close(); // Free memory.
576
78
  return {
577
- sommaire: []
79
+ error: {
80
+ code: -1,
81
+ message: "Texte de loi sans contenu"
82
+ },
83
+ html,
84
+ page
578
85
  };
579
86
  }
580
- runLogFun(console.group("Sommaire"), {
581
- silent: SILENT_LOG
582
- });
583
- runLogFun(console.log("Found ", sommairePromptResult.sommaire.length, " main divisions (level 1)."), {
584
- silent: SILENT_LOG
585
- });
586
- runLogFun(console.table(sommairePromptResult.sommaire.map(item => [item.sequence, item.titre, item.typeDivision, item.parent])), {
587
- silent: SILENT_LOG
588
- });
589
- runLogFun(console.groupEnd(), {
590
- silent: SILENT_LOG
591
- });
592
- const ajv = new Ajv();
593
- if (ajv.validate(SOMMAIRE_SCHEMA, sommairePromptResult)) {
594
- runLogFun(console.info("Sommaire OK 👌"), {
595
- silent: SILENT_LOG
596
- });
597
- delimiter();
598
- return sommairePromptResult.sommaire;
87
+ assert.strictEqual(bodyElement.children[0].tagName, "DIV");
88
+ // First child is a DIV describing the document (Assemblée's header). Skip it for now.
89
+ let bodyChild = bodyElement.children[1];
90
+ assert.strictEqual(bodyChild.tagName, "BR");
91
+ let alineaElement = null;
92
+ let isMultiLinesHeader = false;
93
+ let level = null;
94
+ let levels = [];
95
+ let nextParentState = null;
96
+ let state = "nextBodyChild";
97
+ const subdivisions = [];
98
+ let subdivisionAlineas = null;
99
+ let subdivisionHeaders = null;
100
+ while (state !== null) {
101
+ switch (state) {
102
+ case "nextBodyChild":
103
+ if (bodyChild.nextElementSibling === null) {
104
+ // The document has been fully parsed.
105
+ state = null;
106
+ } else {
107
+ bodyChild = bodyChild.nextElementSibling;
108
+ if (bodyChild.tagName === "DIV") {
109
+ alineaElement = bodyChild.children[0];
110
+ if (alineaElement === undefined || bodyChild.id.includes("ftn")) {
111
+ // No alinea in current bodyChild: go to next bodyChild.
112
+ state = "nextBodyChild";
113
+ } else {
114
+ state = "alineaElement";
115
+ }
116
+ } else {
117
+ // <P/> is for footnotes
118
+ assert(["BR", "HR", "P"].includes(bodyChild.tagName), `Unexpected tag name "${bodyChild.tagName}" for body child`);
119
+ // Stay in the same state to go to next bodyChild.
120
+ }
121
+ }
122
+ break;
123
+ case "alineaElement":
124
+ switch (alineaElement.tagName) {
125
+ case "DIV":
126
+ state = "nextAlineaElement";
127
+ break;
128
+ case "H4":
129
+ // TODO
130
+ nextParentState = "nextAlineaElement";
131
+ state = "firstParagraphChild";
132
+ break;
133
+ case "P":
134
+ nextParentState = "nextAlineaElement";
135
+ state = "firstParagraphChild";
136
+ break;
137
+ case "OL":
138
+ // TODO
139
+ state = "nextAlineaElement";
140
+ break;
141
+ case "TABLE":
142
+ nextParentState = "nextAlineaElement";
143
+ state = "firstParagraphChild";
144
+ break;
145
+ default:
146
+ return {
147
+ error: {
148
+ code: -2,
149
+ message: `Unexpected tag name for alinea element: ${alineaElement.tagName}`
150
+ },
151
+ html,
152
+ page
153
+ };
154
+ }
155
+ break;
156
+ case "firstParagraphChild":
157
+ const headerText = alineaElement.textContent;
158
+ const nameComputed = (headerText || "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\(nouveau\)/, "").replace(/\(Pour coordination\)/, "").replace(/\(Supprimés?\)/, "").replace(/ /g, " ").replace(/[\-,.…]/g, "").trim().replace(/ {1,}/g, "_");
159
+ const nameUpper = nameComputed.toUpperCase();
160
+ const [nextLevel, paragraphType] = parseHeader(nameUpper);
161
+ if (!nameUpper || nameUpper.match(/^(PROJET|PROPOSITION)_DE_LOI(_|$)/) !== null) {
162
+ // Occurs in:
163
+ // * http://www.assemblee-nationale.fr/15/textes/0232.asp
164
+ // * http://www.assemblee-nationale.fr/15/textes/0626.asp
165
+ // * http://www.assemblee-nationale.fr/15/textes/0676.asp
166
+ state = nextParentState;
167
+ break;
168
+ } else if (nameUpper === "JEUX_OLYMPIQUES_ET_PARALYMPIQUES_DE_2024") {
169
+ // Occurs in http://www.assemblee-nationale.fr/15/textes/0676.asp
170
+ state = nextParentState;
171
+ break;
172
+ } else if (nameUpper === "TEXTE_DE_LA_COMMISSION_MIXTE_PARITAIRE") {
173
+ // Occurs in http://www.assemblee-nationale.fr/15/textes/1294.asp
174
+ state = nextParentState;
175
+ break;
176
+ }
177
+ const lineHtml = cleanText(alineaElement.outerHTML);
178
+ const lineText = cleanText(alineaElement.textContent);
179
+ if (nextLevel === null) {
180
+ // It is a regular alinea
181
+ // Exclude some alineas
182
+ let excludeAlinea = false;
183
+ for (let regex of excludedAlineas) {
184
+ if (regex.test(lineText)) {
185
+ excludeAlinea = true;
186
+ }
187
+ }
188
+ if (excludeAlinea) {
189
+ state = nextParentState;
190
+ break;
191
+ }
192
+ if (subdivisionHeaders.length === 0 || isMultiLinesHeader && subdivisionAlineas.length === 0) {
193
+ subdivisionHeaders.push({
194
+ texte: lineText,
195
+ html: lineHtml
196
+ });
197
+ } else {
198
+ subdivisionAlineas.push({
199
+ texte: lineText,
200
+ html: lineHtml
201
+ });
202
+ }
203
+ if (isMultiLinesHeader && subdivisionHeaders.length >= 2) {
204
+ isMultiLinesHeader = false;
205
+ }
206
+ // Skip paragraph.
207
+ state = nextParentState;
208
+ break;
209
+ } else if (nextLevel !== null) {
210
+ // It is a header
211
+ level = nextLevel;
212
+ while (levels.length > 0 && level < levels[levels.length - 1]) {
213
+ levels.pop();
214
+ }
215
+ if (levels.length === 0 || level > levels[levels.length - 1]) {
216
+ levels.push(level);
217
+ }
218
+ subdivisionAlineas = [];
219
+ subdivisionHeaders = [{
220
+ texte: lineText,
221
+ html: lineHtml
222
+ }];
223
+
224
+ // Articles & "Exposé des motifs" are the only divisions without second title.
225
+ isMultiLinesHeader = nameUpper.match(/^ARTICLES?_/) === null && nameUpper.match(/^EXPOSE_DES_MOTIFS$/) === null;
226
+ subdivisions.push({
227
+ id: "D_" + nameComputed,
228
+ type: paragraphType,
229
+ niveau: level + 1,
230
+ niveauRelatif: levels.length,
231
+ titres: subdivisionHeaders,
232
+ alineas: subdivisionAlineas
233
+ });
234
+ }
235
+ state = nextParentState;
236
+ break;
237
+ case "nextAlineaElement":
238
+ alineaElement = alineaElement.nextElementSibling;
239
+ if (alineaElement === null) {
240
+ // The bodyChild has been fully parsed. Go to next bodyChild
241
+ state = "nextBodyChild";
242
+ } else {
243
+ state = "alineaElement";
244
+ }
245
+ break;
246
+ default:
247
+ throw `Unexpected state: ${state}`;
248
+ }
599
249
  }
600
- runLogFun(console.warn("La construction du sommaire est KO ❌"), {
601
- silent: SILENT_LOG
602
- });
603
- delimiter();
250
+ window.close(); // Free memory.
251
+
604
252
  return {
605
- sommaire: []
253
+ error: null,
254
+ html,
255
+ page,
256
+ subdivisions,
257
+ url: assembleeUrl
606
258
  };
607
259
  }
608
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDaGF0T3BlbkFJIiwiQ2hhdFByb21wdFRlbXBsYXRlIiwiQWp2IiwiZGVsaW1pdGVyIiwicnVuTG9nRnVuIiwiQUxJTkVBX1NDSEVNQSIsInJlcXVpcmUiLCJFWFBPU0VfTU9USUZTX1NDSEVNQSIsIk1FVEFfRE9OTkVFU19TQ0hFTUEiLCJQUk9KRVRfTE9JX1NDSEVNQSIsIlNPTU1BSVJFX1NDSEVNQSIsIkVYQU1QTEVTIiwiUFJKTEFOUjVMMTZCMDkxNCIsIm1vdGlmcyIsImlucHV0IiwibG9pIiwibWV0YSIsInNvbW1haXJlIiwiUFJKTEFOUjVMMTZCMjAxNCIsIlBSSkxBTlI1TDE2QjI0MjQiLCJhbGluZWFzIiwiRlVMTF9URVhURV9TQ0hFTUEiLCIkc2NoZW1hIiwidGl0bGUiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJwcm9wZXJ0aWVzIiwidGV4dGUiLCJyZXF1aXJlZCIsIk1PREVMIiwicHJvY2VzcyIsImVudiIsIk9QRU5BSV9BUElfS0VZIiwidGVtcGVyYXR1cmUiLCJ0b3BQIiwibW9kZWwiLCJhcGlLZXkiLCJtYXhUb2tlbnMiLCJTWVNURU1fVEVNUExBVEUiLCJTSUxFTlRfTE9HIiwicGFyc2VUZXh0ZUxvaSIsImh0bWwiLCJvcHRpb25zIiwic2lsZW50IiwiY29uc29sZSIsImluZm8iLCJleHRyYWN0TWV0YURvbm5lZXMiLCJleHRyYWN0U29tbWFpcmUiLCJwYXJ0aWFsTW90aWZzIiwiZXh0cmFjdE1vdGlmcyIsInBhcnRpYWxMb2kiLCJleHRyYWN0UHJvamV0TG9pIiwiZXhwb3NlTW90aWZzIiwicG9wdWxhdGVNb3RpZnMiLCJwb3B1bGF0ZVByb2pldExvaSIsImNsZWFuSHRtbCIsImNsZWFuZWRIdG1sIiwicmVwbGFjZSIsInJlbW92ZUh0bWxUYWdzIiwiaHRtbFRhZ1JlZ2V4IiwidGV4dFdpdGhvdXRUYWdzIiwiZGVidXQiLCJmaW4iLCJzeXN0ZW1UZW1wbGF0ZSIsInByb21wdCIsImZyb21NZXNzYWdlcyIsInN0cnVjdHVyZWRNb2RlbCIsIndpdGhTdHJ1Y3R1cmVkT3V0cHV0IiwiY2hhaW4iLCJwaXBlIiwiYXJ0aWNsZVByb21wdFJlc3VsdCIsImludm9rZSIsInBhcnRpYWwiLCJncm91cCIsImFydGljbGVzIiwiZnVsbEFydGljbGVzIiwiYXJ0aWNsZSIsImFsaW5lYSIsImFsaW5lYVByb21wdFJlc3VsdCIsInB1c2giLCJwcm9qZXRMb2kiLCJncm91cEVuZCIsIm1vdGlmc1N5c3RlbVRlbXBsYXRlIiwibW90aWZzUHJvbXB0UmVzdWx0IiwiZXhhbXBsZTEiLCJleGFtcGxlMiIsIm91dHB1dDEiLCJvdXRwdXQyIiwidGFibGUiLCJzdWJzdHJpbmciLCJhanYiLCJ2YWxpZGF0ZSIsIndhcm4iLCJtZXRhRG9ubmVlc1N5c3RlbVRlbXBsYXRlIiwicmVzdWx0IiwiZG9jdW1lbnRSZWYiLCJ0aXRyZSIsIm51bWVyb1RleHRlIiwicHJvY2VkdXJlQWNjZWxlcmVlIiwicHJvamV0TG9pU3lzdGVtVGVtcGxhdGUiLCJhcnRpY2xlc1Byb21wdFJlc3VsdCIsImxvZyIsImxlbmd0aCIsImV4dHJhY3RBbGluZWFzIiwibWFwIiwibnVtZXJvQXJ0aWNsZSIsImFsaW5lYXNTeXN0ZW1UZW1wbGF0ZSIsImFsaW5lYXNQcm9tcHRSZXN1bHQiLCJzb21tYWlyZVN5c3RlbVRlbXBsYXRlIiwic29tbWFpcmVQcm9tcHRSZXN1bHQiLCJpdGVtIiwic2VxdWVuY2UiLCJ0eXBlRGl2aXNpb24iLCJwYXJlbnQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFyc2Vycy90ZXh0ZXNfbG9pcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGF0T3BlbkFJIH0gZnJvbSBcIkBsYW5nY2hhaW4vb3BlbmFpXCJcbmltcG9ydCB7IENoYXRQcm9tcHRUZW1wbGF0ZSB9IGZyb20gXCJAbGFuZ2NoYWluL2NvcmUvcHJvbXB0c1wiXG5pbXBvcnQgQWp2IGZyb20gXCJhanZcIlxuXG5pbXBvcnQgeyBkZWxpbWl0ZXIsIHJ1bkxvZ0Z1biB9IGZyb20gXCIuLi9sb2dnZXJcIlxuXG5jb25zdCBBTElORUFfU0NIRU1BID0gcmVxdWlyZShcIi4uL3NjaGVtYXMvdGV4dGVfbG9pL0FsaW5lYS5qc29uXCIpXG5jb25zdCBFWFBPU0VfTU9USUZTX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9FeHBvc2VNb3RpZnMuanNvblwiKVxuY29uc3QgTUVUQV9ET05ORUVTX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9NZXRhRG9ubmVlcy5qc29uXCIpXG5jb25zdCBQUk9KRVRfTE9JX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9Qcm9qZXRMb2kuanNvblwiKVxuY29uc3QgU09NTUFJUkVfU0NIRU1BID0gcmVxdWlyZShcIi4uL3NjaGVtYXMvdGV4dGVfbG9pL1NvbW1haXJlLmpzb25cIilcblxuLyoqXG4gKiBPYmplY3QgY29udGFpbmluZyBpbnB1dCBleGFtcGxlcyBhbmQgdGhlaXIgb3V0cHV0IHNjaGVtYXMuXG4gKiBVc2VkIHRvIHRyYWluIHRoZSBMTE0uXG4gKiBAdHlwZSB7UmVjb3JkPHN0cmluZywge21vdGlmczogYW55LCBpbnB1dDogYW55LCBsb2k6IGFueSwgbWV0YTogYW55LCBzb21tYWlyZTogYW55fT59XG4gKi9cbmNvbnN0IEVYQU1QTEVTID0ge1xuICBQUkpMQU5SNUwxNkIwOTE0OiB7XG4gICAgbW90aWZzOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMDkxNC9tb3RpZnMuanNvblwiKSxcbiAgICBpbnB1dDogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjA5MTQvaW5wdXRcIiksXG4gICAgbG9pOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMDkxNC9sb2kuanNvblwiKSxcbiAgICBtZXRhOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMDkxNC9tZXRhLmpzb25cIiksXG4gICAgc29tbWFpcmU6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIwOTE0L3NvbW1haXJlLmpzb25cIiksXG4gIH0sXG4gIFBSSkxBTlI1TDE2QjIwMTQ6IHtcbiAgICBtb3RpZnM6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyMDE0L21vdGlmcy5qc29uXCIpLFxuICAgIGlucHV0OiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjAxNC9pbnB1dFwiKSxcbiAgICBsb2k6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyMDE0L2xvaS5qc29uXCIpLFxuICAgIG1ldGE6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyMDE0L21ldGEuanNvblwiKSxcbiAgICBzb21tYWlyZTogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjIwMTQvc29tbWFpcmUuanNvblwiKSxcbiAgfSxcbiAgUFJKTEFOUjVMMTZCMjQyNDoge1xuICAgIGFsaW5lYXM6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L2FsaW5lYXMuanNvblwiKSxcbiAgICBtb3RpZnM6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L21vdGlmcy5qc29uXCIpLFxuICAgIGlucHV0OiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjQyNC9pbnB1dFwiKSxcbiAgICBsb2k6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L2xvaS5qc29uXCIpLFxuICAgIG1ldGE6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L21ldGEuanNvblwiKSxcbiAgICBzb21tYWlyZTogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjI0MjQvc29tbWFpcmUuanNvblwiKSxcbiAgfSxcbn1cblxuY29uc3QgRlVMTF9URVhURV9TQ0hFTUEgPSB7XG4gICRzY2hlbWE6IFwiaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjXCIsXG4gIHRpdGxlOiBcIlNvbW1haXJlXCIsXG4gIGRlc2NyaXB0aW9uOiBcIlLDqWN1cMOpcmF0aW9uIGQndW4gdGV4dGUgY29tcGxldFwiLFxuICB0eXBlOiBcIm9iamVjdFwiLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgdGV4dGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlRleHRlIGNvbXBsZXQgZGUgbGEgc2VjdGlvbiBpbmRpcXXDqWUuXCIsXG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgIH0sXG4gIH0sXG4gIHJlcXVpcmVkOiBbXCJ0ZXh0ZVwiXSxcbn1cblxuLyoqXG4gKiBMTE0gbW9kZWwuXG4gKi9cbmxldCBNT0RFTDogYW55ID0gbnVsbFxuXG5pZiAocHJvY2Vzcy5lbnYuT1BFTkFJX0FQSV9LRVkpIHtcbiAgTU9ERUwgPSBuZXcgQ2hhdE9wZW5BSSh7XG4gICAgdGVtcGVyYXR1cmU6IDAsXG4gICAgdG9wUDogMC4wLFxuICAgIG1vZGVsOiBcImdwdC00by1taW5pXCIsXG4gICAgYXBpS2V5OiBwcm9jZXNzLmVudi5PUEVOQUlfQVBJX0tFWSxcbiAgICBtYXhUb2tlbnM6IC0xLFxuICB9KVxufVxuXG4vKipcbiAqIFN5c3RlbSBpbnB1dCB0ZW1wbGF0ZSBmb3IgdGhlIExMTS5cbiAqL1xuY29uc3QgU1lTVEVNX1RFTVBMQVRFOiBzdHJpbmcgPSBgXG4gICMgSW5zdHJ1Y3Rpb25zIDpcbiAgXG4gIFR1IGVzIHVuIGV4cGVydCBkZSBsYSBsb2kgZXQgZGUgbCdhbmFseXNlIGRlIHBhZ2VzIEhUTUwuXG4gIFR1IGRvaXMgYW5hbHlzZXIgdW4gdGV4dGUgZGUgbG9pIGFmaW4gZGUgc8OpcGFyZXIgZXQgZGUgc3RydWN0dXJlciBsZXMgw6lsw6ltZW50cyBxdWkgbGUgY29tcG9zZW50LiBMZSBmb3JtYXQgZCdlbnRyw6llIGVzdCBIVE1MLlxuXG4gIExlIHRleHRlIGVzdCBkaXZpc8OpIGVuIGRldXggcGFydGllcyA6XG4gIEEpIHVuIGV4cG9zw6kgZGVzIG1vdGlmcyBxdWkgaW5kaXF1ZSBsZXMgcmFpc29ucyBwb3VyIGxlc3F1ZWxsZXMgY2UgcHJvamV0IGVzdCBzb3VtaXMgYXUgUGFybGVtZW50LiBJbCBwZXV0IGNvbnRlbmlyIDMgw6lsw6ltZW50cyA6IDEpIHVuZSBjaXRhdGlvbiBhdSBkw6lidXQgZCd1biBkb2N1bWVudCwgMikgbGUgdGV4dGUgcHJpbmNpcGFsIHF1aSBkw6l2ZWxvcHBlIGxlcyBhcmd1bWVudHMgZGUgbCdhdXRldXIgw6AgbCdhcHB1aSBkZSBsYSBtb2RpZmljYXRpb24gbMOpZ2lzbGF0aXZlIG91IGRlcyBkaXNwb3NpdGlvbnMgbm91dmVsbGVzIHF1J2lsIHByb3Bvc2UsIDMpIGRlcyBwYXJhZ3JhcGhlcyBxdWkgcHLDqXNlbnRlbnQgbGVzIGFydGljbGVzLlxuICBCKSBsZSBkaXNwb3NpdGlmIHF1aSBlc3QgbGEgcGFydGllIG5vcm1hdGl2ZSBldCByw6lkaWfDqWUgZW4gYXJ0aWNsZXMuIElsIHBldXQgY29tcG9ydGVyIGRlcyBkaXZpc2lvbnMgbm9tbcOpZXMgdGl0cmVzLCBjaGFwaXRyZXMsIHNlY3Rpb25zLCBzb3VzLXNlY3Rpb25zLiBMb3JzcXUnaWwgeSBhIHVuIHNldWwgbml2ZWF1IGRlIHN0cnVjdHVyZSwgb24gcmV0cm91dmVyYSBsZSBjaGFwaXRyZSA7IHPigJlpbCB5IGEgZGV1eCBuaXZlYXV4IGRlIHN0cnVjdHVyZSwgb24gcmV0cm91dmVyYSBkZXMgY2hhcGl0cmVzIHB1aXMgZGVzIHNlY3Rpb25zLiBT4oCZaWwgeSBhIHRyb2lzIG5pdmVhdXggZGUgc3RydWN0dXJlLCBvbiByZXRyb3V2ZXJhIGRlcyB0aXRyZXMgcHVpcyBkZXMgY2hhcGl0cmVzIHB1aXMgZGVzIHNlY3Rpb25zLlxuXG4gIFNpIGxlIHRleHRlIGRlIGxvaSBuZSBjb21wb3J0ZSBwYXMgZGUgZGl2aXNpb24sIGxlIHNvbW1haXJlIGRvaXQgcmVzdGVyIHZpZGUuXG4gIFRvdXRlcyBsZXMgbGlnbmVzIHF1aSBkw6lidXRlbnQgcGFyIHVuICfCqycgbmUgc29udCBwYXMgw6AgcHJlbmRyZSBlbiBjb21wdGUgZGFucyBsZXMgZGl2aXNpb25zXG4gIFRhIHLDqXBvbnNlIGRvaXQgw6p0cmUgdW4gSlNPTiBzdHJ1Y3R1csOpIGF2ZWMgbGVzIMOpbMOpbWVudHMgZHUgdGV4dGUgZGUgbG9pIGVuIHJlc3BlY3RhbnQgbGUgc2Now6ltYSBKU09OIGZvdXJuaS5cbmBcblxubGV0IFNJTEVOVF9MT0cgPSBmYWxzZVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgZ2l2ZW4gSFRNTCBzdHJpbmcgYW5kIHJldHVybnMgdGhlIHBhcnNlZCB0ZXh0ZXMgbG9pLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIHRvIHBhcnNlLlxuICogQHJldHVybiB7UHJvbWlzZTx7cGFydGlhbDoge3NvbW1haXJlOiBhbnksIGxvaTogYW55LCBtb3RpZnM6IGFueSwgbWV0YTogYW55fSwgY29tcGxldGVkOiB7c29tbWFpcmU6IGFueSwgbG9pOiBhbnksIG1vdGlmczogYW55LCBtZXRhOiBhbnl9fT59IC0gVGhlIHBhcnNlZCB0ZXh0ZXMgbG9pLCBpbmNsdWRpbmcgdGhlIHBhcnRpYWwgYW5kIGNvbXBsZXRlZCB2ZXJzaW9ucy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBhcnNlVGV4dGVMb2koaHRtbDogc3RyaW5nLCBvcHRpb25zID0geyBzaWxlbnQ6IGZhbHNlIH0pIHtcbiAgU0lMRU5UX0xPRyA9IG9wdGlvbnMuc2lsZW50XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlN0YXJ0IGV4dHJhY3RpbmcgbG9pLi4uXCIpLCBvcHRpb25zKVxuICBjb25zdCBtZXRhID0gYXdhaXQgZXh0cmFjdE1ldGFEb25uZWVzKGh0bWwpXG4gIGNvbnN0IHNvbW1haXJlID0gYXdhaXQgZXh0cmFjdFNvbW1haXJlKGh0bWwpXG4gIGNvbnN0IHBhcnRpYWxNb3RpZnM6IGFueSA9IGF3YWl0IGV4dHJhY3RNb3RpZnMoaHRtbClcbiAgY29uc3QgcGFydGlhbExvaTogYW55ID0gYXdhaXQgZXh0cmFjdFByb2pldExvaShodG1sKVxuICBjb25zdCBleHBvc2VNb3RpZnMgPSBhd2FpdCBwb3B1bGF0ZU1vdGlmcyhwYXJ0aWFsTW90aWZzLCBodG1sKVxuICBjb25zdCBsb2kgPSBhd2FpdCBwb3B1bGF0ZVByb2pldExvaShwYXJ0aWFsTG9pLCBodG1sKVxuXG4gIHJldHVybiB7XG4gICAgc29tbWFpcmUsXG4gICAgbG9pLFxuICAgIGV4cG9zZU1vdGlmcyxcbiAgICBtZXRhLFxuICB9XG59XG5cbi8qKlxuICogQ2xlYW5zIHRoZSBnaXZlbiBIVE1MIHN0cmluZyBieSByZW1vdmluZyB1bm5lY2Vzc2FyeSB0YWdzIGFuZCBjb250ZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIHRvIGJlIGNsZWFuZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBjbGVhbmVkIEhUTUwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBjbGVhbkh0bWwoaHRtbDogc3RyaW5nKSB7XG4gIGxldCBjbGVhbmVkSHRtbCA9IGh0bWwucmVwbGFjZSgvKDxzdHlsZVtcXHdcXFddK3N0eWxlPikvZywgXCJcIilcbiAgY2xlYW5lZEh0bWwgPSBjbGVhbmVkSHRtbC5yZXBsYWNlKC8oPGhlYWRbXFx3XFxXXStoZWFkPikvZywgXCJcIilcbiAgY2xlYW5lZEh0bWwgPSBjbGVhbmVkSHRtbC5yZXBsYWNlKC88aW1nW14+XSo+L2csIFwiXCIpXG5cbiAgcmV0dXJuIGNsZWFuZWRIdG1sXG59XG5cbi8qKlxuICogUmVtb3ZlcyBhbGwgSFRNTCB0YWdzIGZyb20gdGhlIGdpdmVuIEhUTUwgc3RyaW5nIGFuZCByZXR1cm5zIHRoZSBjbGVhbmVkIHRleHQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGh0bWwgLSBUaGUgSFRNTCBzdHJpbmcgZnJvbSB3aGljaCB0byByZW1vdmUgdGFncy5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNsZWFuZWQgdGV4dCB3aXRob3V0IGFueSBIVE1MIHRhZ3MuXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUh0bWxUYWdzKGh0bWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIFJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCBIVE1MIHRhZ3NcbiAgY29uc3QgaHRtbFRhZ1JlZ2V4ID0gLzxbXj5dKj4vZ1xuXG4gIC8vIFJlcGxhY2UgYWxsIEhUTUwgdGFncyB3aXRoIGFuIGVtcHR5IHN0cmluZ1xuICBjb25zdCB0ZXh0V2l0aG91dFRhZ3MgPSBodG1sLnJlcGxhY2UoaHRtbFRhZ1JlZ2V4LCBcIlwiKVxuICByZXR1cm4gdGV4dFdpdGhvdXRUYWdzXG59XG5cbi8qKlxuICogUG9wdWxhdGVzIHRoZSBtb3RpZnMgb2JqZWN0IHdpdGggdGhlIGV4dHJhY3RlZCB0ZXh0IGZyb20gdGhlIGdpdmVuIEhUTUwuXG4gKlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb3RpZnMgLSBUaGUgbW90aWZzIG9iamVjdCB0byBiZSBwb3B1bGF0ZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIHRleHQuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIFRoZSBwb3B1bGF0ZWQgbW90aWZzIG9iamVjdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcG9wdWxhdGVNb3RpZnMobW90aWZzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBodG1sOiBzdHJpbmcpIHtcbiAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlBvcHVsYXRpbmcgZXhwb3NlIG1vdGlmcy4uLlwiKSlcbiAgbGV0IGNsZWFuZWRIdG1sID0gY2xlYW5IdG1sKGh0bWwpXG5cbiAgaWYgKG1vdGlmcy5kZWJ1dCA9PT0gbW90aWZzLmZpbiB8fCAhbW90aWZzLmZpbikge1xuICAgIG1vdGlmcy50ZXh0ZSA9IG1vdGlmcy5kZWJ1dFxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHN5c3RlbVRlbXBsYXRlID0gYFxuICAgICAgIyBJbnN0cnVjdGlvbnMgOlxuXG4gICAgICBUdSBlcyB1biBleHBlcnQgZGUgbGEgbG9pIGV0IGRlIGwnYW5hbHlzZSBkZSBwYWdlcyBIVE1MLlxuICAgICAgVHUgZG9pcyBhbmFseXNlciB1biB0ZXh0ZSBkZSBsb2kgYWZpbiBkJ2VuIGV4dHJhaXJlIGNlcnRhaW5lcyBwYXJ0aWVzLiBcbiAgICAgIExlIGZvcm1hdCBkJ2VudHLDqWUgZXN0IGR1IEhUTUwuIExlIGZvcm1hdCBkZSBzb3J0aWUgZXN0IGR1IHRleHRlLlxuICAgICAgUsOpY3Vww6hyZSBsJ2ludMOpZ3JhbGl0w6kgZHUgdGV4dGUgY29tbWVuw6dhbnQgcGFyIDpcblxuICAgICAgXCJcIlwiXG4gICAgICB7ZGVidXR9XG4gICAgICBcIlwiXCJcblxuICAgICAgRXQgZmluaXNzYW50IHBhciA6XG5cbiAgICAgIFwiXCJcIlxuICAgICAge2Zpbn1cbiAgICAgIFwiXCJcIlxuICAgIGBcblxuICAgIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgICAgW1wic3lzdGVtXCIsIHN5c3RlbVRlbXBsYXRlXSxcbiAgICAgIFtcImh1bWFuXCIsIFwie2lucHV0fVwiXSxcbiAgICBdKVxuXG4gICAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoRlVMTF9URVhURV9TQ0hFTUEpXG4gICAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG5cbiAgICBjb25zdCBhcnRpY2xlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgICAgaW5wdXQ6IGNsZWFuZWRIdG1sLFxuICAgICAgZGVidXQ6IG1vdGlmcy5kZWJ1dCxcbiAgICAgIGZpbjogbW90aWZzLmZpbixcbiAgICB9KVxuXG4gICAgbW90aWZzLnRleHRlID0gYXJ0aWNsZVByb21wdFJlc3VsdC50ZXh0ZVxuICB9XG5cbiAgcnVuTG9nRnVuKFxuICAgIGNvbnNvbGUuaW5mbyhcIk9ww6lyYXRpb24gZGUgcGV1cGxlbWVudCBkZSBsJ2V4cG9zw6kgZGVzIG1vdGlmcyB0ZXJtaW7DqWUg4pyFXCIpLFxuICAgIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0sXG4gIClcbiAgZGVsaW1pdGVyKFNJTEVOVF9MT0cpXG5cbiAgZGVsZXRlIG1vdGlmcy5kZWJ1dFxuICBkZWxldGUgbW90aWZzLmZpblxuICByZXR1cm4gbW90aWZzXG59XG5cbi8qKlxuICogQXN5bmNocm9ub3VzbHkgcG9wdWxhdGVzIGEgcHJvamV0IGxvaSBvYmplY3Qgd2l0aCB0aGUgZnVsbCB0ZXh0IG9mIGVhY2ggYXJ0aWNsZSBhbmQgYWxpbmVhIGluIHRoZSBnaXZlbiBIVE1MLlxuICpcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gcGFydGlhbCAtIFRoZSBwYXJ0aWFsIHByb2pldCBsb2kgb2JqZWN0IHRvIGJlIHBvcHVsYXRlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgY29udGFpbmluZyB0aGUgdGV4dCBvZiB0aGUgYXJ0aWNsZXMgYW5kIGFsaW5lYXMuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZnVsbHkgcG9wdWxhdGVkIHByb2pldCBsb2kgb2JqZWN0LlxuICovXG5hc3luYyBmdW5jdGlvbiBwb3B1bGF0ZVByb2pldExvaShwYXJ0aWFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBodG1sOiBzdHJpbmcpIHtcbiAgcnVuTG9nRnVuKGNvbnNvbGUuZ3JvdXAoXCJQZXVwbGVtZW50IGR1IHByb2pldCBsb2kuLi5cIiksIHtcbiAgICBzaWxlbnQ6IFNJTEVOVF9MT0csXG4gIH0pXG4gIGxldCBjbGVhbmVkSHRtbCA9IGNsZWFuSHRtbChodG1sKVxuXG4gIGNvbnN0IGFydGljbGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10gPSBwYXJ0aWFsLmFydGljbGVzXG4gIGNvbnN0IGZ1bGxBcnRpY2xlczogUmVjb3JkPHN0cmluZywgYW55PltdID0gW11cblxuICBjb25zdCBzeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAjIEluc3RydWN0aW9ucyA6XG5cbiAgICBUdSBlcyB1biBleHBlcnQgZGUgbGEgbG9pIGV0IGRlIGwnYW5hbHlzZSBkZSBwYWdlcyBIVE1MLlxuICAgIFR1IGRvaXMgYW5hbHlzZXIgdW4gdGV4dGUgZGUgbG9pIGFmaW4gZCdlbiBleHRyYWlyZSBjZXJ0YWluZXMgcGFydGllcy4gXG4gICAgTGUgZm9ybWF0IGQnZW50csOpZSBlc3QgZHUgSFRNTC4gTGUgZm9ybWF0IGRlIHNvcnRpZSBlc3QgZHUgdGV4dGUuXG4gICAgUsOpY3Vww6hyZSBsJ2ludMOpZ3JhbGl0w6kgZHUgdGV4dGUgY29tbWVuw6dhbnQgcGFyIDpcblxuICAgIFwiXCJcIlxuICAgIHtkZWJ1dH1cbiAgICBcIlwiXCJcblxuICAgIEV0IGZpbmlzc2FudCBwYXIgOlxuXG4gICAgXCJcIlwiXG4gICAge2Zpbn1cbiAgICBcIlwiXCJcbiAgYFxuXG4gIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgIFtcInN5c3RlbVwiLCBzeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IHN0cnVjdHVyZWRNb2RlbCA9IE1PREVMLndpdGhTdHJ1Y3R1cmVkT3V0cHV0KEZVTExfVEVYVEVfU0NIRU1BKVxuICBjb25zdCBjaGFpbiA9IHByb21wdC5waXBlKHN0cnVjdHVyZWRNb2RlbClcblxuICBmb3IgKGNvbnN0IGFydGljbGUgb2YgYXJ0aWNsZXMpIHtcbiAgICBpZiAoYXJ0aWNsZS5kZWJ1dCA9PT0gYXJ0aWNsZS5maW4gfHwgIWFydGljbGUuZmluKSB7XG4gICAgICBhcnRpY2xlLnRleHRlID0gYXJ0aWNsZS5kZWJ1dFxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBhcnRpY2xlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgICAgICBpbnB1dDogY2xlYW5lZEh0bWwsXG4gICAgICAgIGRlYnV0OiBhcnRpY2xlLmRlYnV0LFxuICAgICAgICBmaW46IGFydGljbGUuZmluLFxuICAgICAgfSlcblxuICAgICAgYXJ0aWNsZS50ZXh0ZSA9IGFydGljbGVQcm9tcHRSZXN1bHQudGV4dGVcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGFsaW5lYSBvZiBhcnRpY2xlLmFsaW5lYXMpIHtcbiAgICAgIGlmIChhbGluZWEuZGVidXQgPT09IGFsaW5lYS5maW4gfHwgIWFsaW5lYS5maW4pIHtcbiAgICAgICAgYWxpbmVhLnRleHRlID0gYWxpbmVhLmRlYnV0XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFsaW5lYVByb21wdFJlc3VsdDogYW55ID0gYXdhaXQgY2hhaW4uaW52b2tlKHtcbiAgICAgICAgaW5wdXQ6IGFydGljbGUudGV4dGUsXG4gICAgICAgIGRlYnV0OiBhbGluZWEuZGVidXQsXG4gICAgICAgIGZpbjogYWxpbmVhLmZpbixcbiAgICAgIH0pXG5cbiAgICAgIGRlbGV0ZSBhbGluZWEuZGVidXRcbiAgICAgIGRlbGV0ZSBhbGluZWEuZmluXG4gICAgICBhbGluZWEudGV4dGUgPSBhbGluZWFQcm9tcHRSZXN1bHQudGV4dGVcbiAgICB9XG5cbiAgICBydW5Mb2dGdW4oXG4gICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgIFwiT3DDqXJhdGlvbiBkZSBwZXVwbGVtZW50IGR1IGNvbnRlbnUgZHUgcHJvamV0IGRlIGxvaSB0ZXJtaW7DqWUg4pyFXCIsXG4gICAgICApLFxuICAgICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgICApXG4gICAgZGVsZXRlIGFydGljbGUuZGVidXRcbiAgICBkZWxldGUgYXJ0aWNsZS5maW5cbiAgICBmdWxsQXJ0aWNsZXMucHVzaChhcnRpY2xlKVxuICB9XG5cbiAgY29uc3QgcHJvamV0TG9pID0ge1xuICAgIC4uLnBhcnRpYWwsXG4gICAgYXJ0aWNsZXM6IGZ1bGxBcnRpY2xlcyxcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG4gIHJldHVybiBwcm9qZXRMb2lcbn1cblxuLyoqXG4gKiBBc3luY2hyb25vdXNseSBleHRyYWN0cyB0aGUgXCJleHBvc2UgbW90aWZzXCIgZnJvbSB0aGUgZ2l2ZW4gSFRNTC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIFwiZXhwb3NlIG1vdGlmc1wiLlxuICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gLSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZXh0cmFjdGVkIFwiZXhwb3NlIG1vdGlmc1wiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgZGVidXRgOiBUaGUgYmVnaW5uaW5nIG9mIHRoZSBcImV4cG9zZSBtb3RpZnNcIi5cbiAqIC0gYGZpbmA6IFRoZSBlbmQgb2YgdGhlIFwiZXhwb3NlIG1vdGlmc1wiLlxuICogQHRocm93cyB7RXJyb3J9IC0gSWYgdGhlIGV4dHJhY3RlZCBcImV4cG9zZSBtb3RpZnNcIiBkbyBub3QgdmFsaWRhdGUgYWdhaW5zdCB0aGUgRVhQT1NFX01PVElGU19TQ0hFTUEuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RNb3RpZnMoaHRtbDogc3RyaW5nKSB7XG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiUGFyc2luZyBleHBvc2UgbW90aWZzLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcbiAgY2xlYW5lZEh0bWwgPSByZW1vdmVIdG1sVGFncyhjbGVhbmVkSHRtbClcblxuICBjb25zdCBzdHJ1Y3R1cmVkTW9kZWwgPSBNT0RFTC53aXRoU3RydWN0dXJlZE91dHB1dChFWFBPU0VfTU9USUZTX1NDSEVNQSlcblxuICBjb25zdCBtb3RpZnNTeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAke1NZU1RFTV9URU1QTEFURX1cblxuICAgICMgRXhhbXBsZXM6IFxuXG4gICAgIyMgRXhlbXBsZSAxIFVzZXIgSW5wdXQgOlxuICAgIFwiXCJcIlxuICAgIHtleGFtcGxlMX1cbiAgICBcIlwiXCJcbiAgICBcbiAgICAjIyBFeGVtcGxlIDEgSlNPTiBPdXRwdXQgOlxuICAgIFwiXCJcIlxuICAgIHtvdXRwdXQxfVxuICAgIFwiXCJcIlxuXG4gICAgIyMgRXhlbXBsZSAyIFVzZXIgSW5wdXQgOlxuICAgIFwiXCJcIlxuICAgIHtleGFtcGxlMn1cbiAgICBcIlwiXCJcbiAgICBcbiAgICAjIyBFeGVtcGxlIDIgSlNPTiBPdXRwdXQgOlxuICAgIFwiXCJcIlxuICAgIHtvdXRwdXQyfVxuICAgIFwiXCJcIlxuICAgIGBcblxuICBjb25zdCBwcm9tcHQgPSBDaGF0UHJvbXB0VGVtcGxhdGUuZnJvbU1lc3NhZ2VzKFtcbiAgICBbXCJzeXN0ZW1cIiwgbW90aWZzU3lzdGVtVGVtcGxhdGVdLFxuICAgIFtcImh1bWFuXCIsIFwie2lucHV0fVwiXSxcbiAgXSlcblxuICBjb25zdCBjaGFpbiA9IHByb21wdC5waXBlKHN0cnVjdHVyZWRNb2RlbClcbiAgY29uc3QgbW90aWZzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMDkxNC5pbnB1dCxcbiAgICBleGFtcGxlMjogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjQyNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0Lm1vdGlmcyxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0Lm1vdGlmcyxcbiAgfSlcblxuICAvLyBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShtb3RpZnNQcm9tcHRSZXN1bHQpKVxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS50YWJsZShbXG4gICAgICBbXCJEw6lidXRcIiwgbW90aWZzUHJvbXB0UmVzdWx0LmRlYnV0LnN1YnN0cmluZygwLCAzMCldLFxuICAgICAgW1wiRmluXCIsIG1vdGlmc1Byb21wdFJlc3VsdC5maW4uc3Vic3RyaW5nKDAsIDMwKV0sXG4gICAgXSksXG4gICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgKVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoRVhQT1NFX01PVElGU19TQ0hFTUEsIG1vdGlmc1Byb21wdFJlc3VsdCkpIHtcbiAgICBydW5Mb2dGdW4oY29uc29sZS5pbmZvKFwiRXhwb3PDqSBkZXMgbW90aWZzIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgcmV0dXJuIG1vdGlmc1Byb21wdFJlc3VsdFxuICB9XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIkV4cG9zw6kgZGVzIG1vdGlmcyBLTyDinYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIHJldHVybiB7fVxufVxuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IGV4dHJhY3RzIHRoZSBtZXRhZGF0YSBmcm9tIHRoZSBnaXZlbiBIVE1MLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIGZyb20gd2hpY2ggdG8gZXh0cmFjdCB0aGUgbWV0YWRhdGEuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBleHRyYWN0ZWQgbWV0YWRhdGEgb2JqZWN0LlxuICogVGhlIG9iamVjdCBjb250YWlucyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAtIGBkb2N1bWVudFJlZmA6IFRoZSByZWZlcmVuY2Ugb2YgdGhlIGRvY3VtZW50LlxuICogLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIGRvY3VtZW50LlxuICogLSBgbnVtZXJvVGV4dGVgOiBUaGUgbnVtYmVyIG9mIHRoZSB0ZXh0LlxuICogLSBgcHJvY2VkdXJlQWNjZWxlcmVlYDogVGhlIGFjY2VsZXJhdGVkIHByb2NlZHVyZS5cbiAqIEB0aHJvd3Mge0Vycm9yfSAtIElmIHRoZSBleHRyYWN0ZWQgbWV0YWRhdGEgZG8gbm90IHZhbGlkYXRlIGFnYWluc3QgdGhlIE1FVEFfRE9OTkVFU19TQ0hFTUEuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RNZXRhRG9ubmVlcyhodG1sOiBzdHJpbmcpIHtcbiAgZGVsaW1pdGVyKClcbiAgbGV0IGNsZWFuZWRIdG1sID0gY2xlYW5IdG1sKGh0bWwpXG4gIGNsZWFuZWRIdG1sID0gcmVtb3ZlSHRtbFRhZ3MoY2xlYW5lZEh0bWwpXG5cbiAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoTUVUQV9ET05ORUVTX1NDSEVNQSlcblxuICBjb25zdCBtZXRhRG9ubmVlc1N5c3RlbVRlbXBsYXRlID0gYFxuICAgICR7U1lTVEVNX1RFTVBMQVRFfVxuICAgIGBcblxuICBjb25zdCBwcm9tcHQgPSBDaGF0UHJvbXB0VGVtcGxhdGUuZnJvbU1lc3NhZ2VzKFtcbiAgICBbXCJzeXN0ZW1cIiwgbWV0YURvbm5lZXNTeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IGNoYWluID0gcHJvbXB0LnBpcGUoc3RydWN0dXJlZE1vZGVsKVxuICBjb25zdCByZXN1bHQ6IGFueSA9IGF3YWl0IGNoYWluLmludm9rZSh7XG4gICAgaW5wdXQ6IGNsZWFuZWRIdG1sLFxuICAgIGV4YW1wbGUxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmlucHV0LFxuICAgIGV4YW1wbGUyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmlucHV0LFxuICAgIG91dHB1dDE6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjA5MTQubWV0YSxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0Lm1ldGEsXG4gIH0pXG5cbiAgY29uc29sZS5ncm91cChcIk1ldGEtZG9ubsOpZXNcIilcbiAgY29uc29sZS50YWJsZShbXG4gICAgW1wiUsOpZsOpcmVuY2VcIiwgcmVzdWx0LmRvY3VtZW50UmVmXSxcbiAgICBbXCJUaXRyZVwiLCByZXN1bHQudGl0cmVdLFxuICAgIFtcIk51bcOpcm8gZHUgdGV4dGVcIiwgcmVzdWx0Lm51bWVyb1RleHRlXSxcbiAgICBbXCJQcm9jw6lkdXJlIGFjY8OpbMOpcsOpXCIsIHJlc3VsdC5wcm9jZWR1cmVBY2NlbGVyZWVdLFxuICBdKVxuICBjb25zb2xlLmdyb3VwRW5kKClcbiAgZGVsaW1pdGVyKClcblxuICBjb25zdCBhanYgPSBuZXcgQWp2KClcbiAgaWYgKGFqdi52YWxpZGF0ZShNRVRBX0RPTk5FRVNfU0NIRU1BLCByZXN1bHQpKSB7XG4gICAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIk1ldGEtZG9ubsOpZXMgT0sg8J+RjFwiKSwgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBydW5Mb2dGdW4oY29uc29sZS53YXJuKFwiTWV0YS1kb25uw6llcyBub24tY29uZm9ybWUg4p2MXCIpLCB7XG4gICAgc2lsZW50OiBTSUxFTlRfTE9HLFxuICB9KVxuICByZXR1cm4ge31cbn1cblxuLyoqXG4gKiBBc3luY2hyb25vdXNseSBleHRyYWN0cyB0aGUgXCJwcm9qZXQgZGUgbG9pXCIgZnJvbSB0aGUgZ2l2ZW4gSFRNTC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIFwicHJvamV0IGRlIGxvaVwiLlxuICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gLSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZXh0cmFjdGVkIFwicHJvamV0IGRlIGxvaVwiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgYXJ0aWNsZXNgOiBBbiBhcnJheSBvZiBhcnRpY2xlIG9iamVjdHMsIGVhY2ggY29udGFpbmluZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAgIC0gYG51bWVyb0FydGljbGVgOiBUaGUgbnVtYmVyIG9mIHRoZSBhcnRpY2xlLlxuICogICAtIGBjYXJkaW5hbGA6IFRoZSBjYXJkaW5hbCBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIGFydGljbGUuXG4gKiAgIC0gYGRlYnV0YDogVGhlIGJlZ2lubmluZyBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgZmluYDogVGhlIGVuZCBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgYWxpbmVhc2A6IEFuIGFycmF5IG9mIGFsaW5lYXMuXG4gKiBAdGhyb3dzIHtFcnJvcn0gLSBJZiB0aGUgZXh0cmFjdGVkIFwicHJvamV0IGRlIGxvaVwiIGRvZXMgbm90IHZhbGlkYXRlIGFnYWluc3QgdGhlIFBST0pFVF9MT0lfU0NIRU1BLlxuICovXG5hc3luYyBmdW5jdGlvbiBleHRyYWN0UHJvamV0TG9pKGh0bWw6IHN0cmluZykge1xuICBydW5Mb2dGdW4oY29uc29sZS5ncm91cChcIlBhcnNpbmcgbG9pLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcbiAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoUFJPSkVUX0xPSV9TQ0hFTUEpXG5cbiAgY29uc3QgcHJvamV0TG9pU3lzdGVtVGVtcGxhdGUgPSBgXG4gICAgJHtTWVNURU1fVEVNUExBVEV9XG5cbiAgICAjIEV4YW1wbGVzOiBcblxuICAgICMjIEV4ZW1wbGUgMSBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTF9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAxIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0MX1cbiAgICBcIlwiXCJcblxuICAgICMjIEV4ZW1wbGUgMiBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTJ9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAyIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0Mn1cbiAgICBcIlwiXCJcbiAgICBgXG5cbiAgY29uc3QgcHJvbXB0ID0gQ2hhdFByb21wdFRlbXBsYXRlLmZyb21NZXNzYWdlcyhbXG4gICAgW1wic3lzdGVtXCIsIHByb2pldExvaVN5c3RlbVRlbXBsYXRlXSxcbiAgICBbXCJodW1hblwiLCBcIntpbnB1dH1cIl0sXG4gIF0pXG5cbiAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG4gIGNvbnN0IGFydGljbGVzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMDkxNC5pbnB1dCxcbiAgICBleGFtcGxlMjogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjQyNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmxvaSxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmxvaSxcbiAgfSlcblxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS5sb2coXCJGb3VuZCBcIiwgYXJ0aWNsZXNQcm9tcHRSZXN1bHQuYXJ0aWNsZXMubGVuZ3RoLCBcIiBhcnRpY2xlcy5cIiksXG4gICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgKVxuXG4gIGZvciAoY29uc3QgYXJ0aWNsZSBvZiBhcnRpY2xlc1Byb21wdFJlc3VsdC5hcnRpY2xlcykge1xuICAgIGFydGljbGUuYWxpbmVhcyA9IGF3YWl0IGV4dHJhY3RBbGluZWFzKGh0bWwsIGFydGljbGUpXG4gIH1cblxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS50YWJsZShcbiAgICAgIGFydGljbGVzUHJvbXB0UmVzdWx0LmFydGljbGVzLm1hcCgoYXJ0aWNsZTogYW55KSA9PiBbXG4gICAgICAgIGFydGljbGUubnVtZXJvQXJ0aWNsZSxcbiAgICAgICAgYXJ0aWNsZS50aXRyZSxcbiAgICAgICAgYXJ0aWNsZS5kZWJ1dC5zdWJzdHJpbmcoMCwgMTApLFxuICAgICAgICBhcnRpY2xlLmZpbi5zdWJzdHJpbmcoMCwgMTApLFxuICAgICAgICBgTm9tYnJlIGQnYWxpbmVhcyA6ICR7YXJ0aWNsZS5hbGluZWFzLmxlbmd0aH1gLFxuICAgICAgXSksXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoUFJPSkVUX0xPSV9TQ0hFTUEsIGFydGljbGVzUHJvbXB0UmVzdWx0KSkge1xuICAgIHJ1bkxvZ0Z1bihjb25zb2xlLmluZm8oXCJQcm9qZXQgZGUgbG9pIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgZGVsaW1pdGVyKClcbiAgICByZXR1cm4gYXJ0aWNsZXNQcm9tcHRSZXN1bHRcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJQcm9qZXQgZGUgbG9pIEtPIOKdjFwiKSwgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSlcbiAgZGVsaW1pdGVyKClcbiAgcmV0dXJuIHt9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RBbGluZWFzKGh0bWw6IHN0cmluZywgYXJ0aWNsZTogYW55KSB7XG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiUGFyc2luZyBhbGluZWFzLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcblxuICBjb25zdCBzdHJ1Y3R1cmVkTW9kZWwgPSBNT0RFTC53aXRoU3RydWN0dXJlZE91dHB1dChBTElORUFfU0NIRU1BKVxuXG4gIGNvbnN0IGFsaW5lYXNTeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAke1NZU1RFTV9URU1QTEFURX1cblxuICAgIEV4dHJhaXMgdG91cyBsZXMgYWxpbmVhcyBkZSBsYSBwb3J0aW9uIGRlIHRleHRlIGNvbW1lbsOnYW50IHBhciDCqyB7ZGVidXR9IMK7IGV0IGZpbmlzc2FudCBwYXIgwqsge2Zpbn0gwrsuXG4gICAgVW4gYWxpbsOpYSBjb250aWVubmVudCB0b3Vqb3VycyB1bmUgYmFsaXNlIMKrIDxpbWcgwrsuXG5cbiAgICAjIEV4YW1wbGVzOiBcblxuICAgICMjIEV4ZW1wbGUgMSBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTF9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAxIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0MX1cbiAgICBcIlwiXCJcbiAgICBgXG5cbiAgY29uc3QgcHJvbXB0ID0gQ2hhdFByb21wdFRlbXBsYXRlLmZyb21NZXNzYWdlcyhbXG4gICAgW1wic3lzdGVtXCIsIGFsaW5lYXNTeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IGNoYWluID0gcHJvbXB0LnBpcGUoc3RydWN0dXJlZE1vZGVsKVxuICBjb25zdCBhbGluZWFzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBkZWJ1dDogYXJ0aWNsZS5kZWJ1dCxcbiAgICBmaW46IGFydGljbGUuZmluLFxuICAgIGV4YW1wbGUxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmlucHV0LFxuICAgIG91dHB1dDE6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjI0MjQuYWxpbmVhcyxcbiAgfSlcblxuICBjb25zdCBhanYgPSBuZXcgQWp2KClcbiAgaWYgKGFqdi52YWxpZGF0ZShBTElORUFfU0NIRU1BLCBhbGluZWFzUHJvbXB0UmVzdWx0IGFzIGFueSkpIHtcbiAgICBydW5Mb2dGdW4oXG4gICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgIFwiRm91bmQgXCIsXG4gICAgICAgIGFsaW5lYXNQcm9tcHRSZXN1bHQuYWxpbmVhcy5sZW5ndGgsXG4gICAgICAgIFwiIGFsaW5lYXMgZm9yIEFydGljbGUgXCIsXG4gICAgICAgIGFydGljbGUubnVtZXJvQXJ0aWNsZSxcbiAgICAgICAgYXJ0aWNsZS50aXRyZSxcbiAgICAgICksXG4gICAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICAgIClcbiAgICBydW5Mb2dGdW4oY29uc29sZS5ncm91cEVuZCgpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICAgIGRlbGltaXRlcigpXG4gICAgcmV0dXJuIGFsaW5lYXNQcm9tcHRSZXN1bHQuYWxpbmVhc1xuICB9XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIkFsaW5lYXMgS09cIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG4gIHJldHVybiB7fVxufVxuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IGV4dHJhY3RzIHRoZSBcInNvbW1haXJlXCIgKG91dGxpbmUpIGZyb20gdGhlIGdpdmVuIEhUTUwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGh0bWwgLSBUaGUgSFRNTCBzdHJpbmcgZnJvbSB3aGljaCB0byBleHRyYWN0IHRoZSBcInNvbW1haXJlXCIuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBleHRyYWN0ZWQgXCJzb21tYWlyZVwiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgc29tbWFpcmVgOiBBbiBhcnJheSBvZiBtYWluIGRpdmlzaW9uIG9iamVjdHMsIGVhY2ggY29udGFpbmluZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAgIC0gYG51bWVyb0RpdmlzaW9uYDogVGhlIG51bWJlciBvZiB0aGUgbWFpbiBkaXZpc2lvbi5cbiAqICAgLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIG1haW4gZGl2aXNpb24uXG4gKiAgIC0gYHR5cGVEaXZpc2lvbmA6IFRoZSB0eXBlIG9mIGNvbnRlbnQgaW4gdGhlIG1haW4gZGl2aXNpb24uXG4gKiAgIC0gYHNlcXVlbmNlYDogVGhlIHNlcXVlbmNlIG9mIHRoZSBtYWluIGRpdmlzaW9uLlxuICogICAtIGBwYXJlbnRgOiBUaGUgcGFyZW50IG9mIHRoZSBtYWluIGRpdmlzaW9uLlxuICogQHRocm93cyB7RXJyb3J9IC0gSWYgdGhlIGV4dHJhY3RlZCBcInNvbW1haXJlXCIgZG9lcyBub3QgdmFsaWRhdGUgYWdhaW5zdCB0aGUgU09NTUFJUkVfU0NIRU1BLlxuICovXG5hc3luYyBmdW5jdGlvbiBleHRyYWN0U29tbWFpcmUoaHRtbDogc3RyaW5nKSB7XG4gIGxldCBjbGVhbmVkSHRtbCA9IGNsZWFuSHRtbChodG1sKVxuICBjbGVhbmVkSHRtbCA9IHJlbW92ZUh0bWxUYWdzKGNsZWFuZWRIdG1sKVxuXG4gIGNvbnN0IHN0cnVjdHVyZWRNb2RlbCA9IE1PREVMLndpdGhTdHJ1Y3R1cmVkT3V0cHV0KFNPTU1BSVJFX1NDSEVNQSlcblxuICBjb25zdCBzb21tYWlyZVN5c3RlbVRlbXBsYXRlID0gYFxuICAgICR7U1lTVEVNX1RFTVBMQVRFfVxuXG4gICAgIyBFeGFtcGxlczogXG5cbiAgICAjIyBFeGVtcGxlIDEgVXNlciBJbnB1dCA6XG4gICAgXCJcIlwiXG4gICAge2V4YW1wbGUxfVxuICAgIFwiXCJcIlxuICAgIFxuICAgICMjIEV4ZW1wbGUgMSBKU09OIE91dHB1dCA6XG4gICAgXCJcIlwiXG4gICAge291dHB1dDF9XG4gICAgXCJcIlwiXG5cbiAgICAjIyBFeGVtcGxlIDIgVXNlciBJbnB1dCA6XG4gICAgXCJcIlwiXG4gICAge2V4YW1wbGUyfVxuICAgIFwiXCJcIlxuICAgIFxuICAgICMjIEV4ZW1wbGUgMiBKU09OIE91dHB1dCA6XG4gICAgXCJcIlwiXG4gICAge291dHB1dDJ9XG4gICAgXCJcIlwiXG4gICAgYFxuXG4gIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgIFtcInN5c3RlbVwiLCBzb21tYWlyZVN5c3RlbVRlbXBsYXRlXSxcbiAgICBbXCJodW1hblwiLCBcIntpbnB1dH1cIl0sXG4gIF0pXG5cbiAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG4gIGNvbnN0IHNvbW1haXJlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjAxNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyMDE0LnNvbW1haXJlLFxuICAgIGV4YW1wbGUyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmlucHV0LFxuICAgIG91dHB1dDI6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjA5MTQuc29tbWFpcmUsXG4gIH0pXG5cbiAgaWYgKCFzb21tYWlyZVByb21wdFJlc3VsdC5zb21tYWlyZSkge1xuICAgIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJBdWN1biBzb21tYWlyZSBuJ2Egw6l0w6kgdHJvdXbDqSDinZNcIiksIHtcbiAgICAgIHNpbGVudDogU0lMRU5UX0xPRyxcbiAgICB9KVxuICAgIGRlbGltaXRlcigpXG4gICAgcmV0dXJuIHsgc29tbWFpcmU6IFtdIH1cbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiU29tbWFpcmVcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIHJ1bkxvZ0Z1bihcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIFwiRm91bmQgXCIsXG4gICAgICBzb21tYWlyZVByb21wdFJlc3VsdC5zb21tYWlyZS5sZW5ndGgsXG4gICAgICBcIiBtYWluIGRpdmlzaW9ucyAobGV2ZWwgMSkuXCIsXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihcbiAgICBjb25zb2xlLnRhYmxlKFxuICAgICAgc29tbWFpcmVQcm9tcHRSZXN1bHQuc29tbWFpcmUubWFwKChpdGVtOiBhbnkpID0+IFtcbiAgICAgICAgaXRlbS5zZXF1ZW5jZSxcbiAgICAgICAgaXRlbS50aXRyZSxcbiAgICAgICAgaXRlbS50eXBlRGl2aXNpb24sXG4gICAgICAgIGl0ZW0ucGFyZW50LFxuICAgICAgXSksXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoU09NTUFJUkVfU0NIRU1BLCBzb21tYWlyZVByb21wdFJlc3VsdCBhcyBhbnkpKSB7XG4gICAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlNvbW1haXJlIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgZGVsaW1pdGVyKClcbiAgICByZXR1cm4gc29tbWFpcmVQcm9tcHRSZXN1bHQuc29tbWFpcmVcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJMYSBjb25zdHJ1Y3Rpb24gZHUgc29tbWFpcmUgZXN0IEtPIOKdjFwiKSwge1xuICAgIHNpbGVudDogU0lMRU5UX0xPRyxcbiAgfSlcbiAgZGVsaW1pdGVyKClcbiAgcmV0dXJuIHsgc29tbWFpcmU6IFtdIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsVUFBVSxRQUFRLG1CQUFtQjtBQUM5QyxTQUFTQyxrQkFBa0IsUUFBUSx5QkFBeUI7QUFDNUQsT0FBT0MsR0FBRyxNQUFNLEtBQUs7QUFBQSxTQUVaQyxTQUFTLEVBQUVDLFNBQVM7QUFFN0IsTUFBTUMsYUFBYSxHQUFHQyxPQUFPLENBQUMsa0NBQWtDLENBQUM7QUFDakUsTUFBTUMsb0JBQW9CLEdBQUdELE9BQU8sQ0FBQyx3Q0FBd0MsQ0FBQztBQUM5RSxNQUFNRSxtQkFBbUIsR0FBR0YsT0FBTyxDQUFDLHVDQUF1QyxDQUFDO0FBQzVFLE1BQU1HLGlCQUFpQixHQUFHSCxPQUFPLENBQUMscUNBQXFDLENBQUM7QUFDeEUsTUFBTUksZUFBZSxHQUFHSixPQUFPLENBQUMsb0NBQW9DLENBQUM7O0FBRXJFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNSyxRQUFRLEdBQUc7RUFDZkMsZ0JBQWdCLEVBQUU7SUFDaEJDLE1BQU0sRUFBRVAsT0FBTyxDQUFDLDBDQUEwQyxDQUFDO0lBQzNEUSxLQUFLLEVBQUVSLE9BQU8sQ0FBQyxvQ0FBb0MsQ0FBQztJQUNwRFMsR0FBRyxFQUFFVCxPQUFPLENBQUMsdUNBQXVDLENBQUM7SUFDckRVLElBQUksRUFBRVYsT0FBTyxDQUFDLHdDQUF3QyxDQUFDO0lBQ3ZEVyxRQUFRLEVBQUVYLE9BQU8sQ0FBQyw0Q0FBNEM7RUFDaEUsQ0FBQztFQUNEWSxnQkFBZ0IsRUFBRTtJQUNoQkwsTUFB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
260
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhc3NlcnQiLCJKU0RPTSIsInBhcnNlSGVhZGVyIiwiaGVhZGVyIiwiaGVhZGVyc01hcHBpbmciLCJyZWdleCIsImxldmVsIiwibmFtZSIsIm1hdGNoIiwiY2xlYW5UZXh0IiwidGV4dCIsInJlcGxhY2UiLCJ0cmltIiwiZXhjbHVkZWRBbGluZWFzIiwicGFyc2VUZXh0ZSIsImFzc2VtYmxlZVVybCIsInBhZ2UiLCJodG1sIiwid2luZG93IiwiZG9jdW1lbnQiLCJzdHJpY3RFcXVhbCIsImNoaWxkcmVuIiwibGVuZ3RoIiwiaHRtbEVsZW1lbnQiLCJib2R5RWxlbWVudCIsImNsb3NlIiwiZXJyb3IiLCJjb2RlIiwibWVzc2FnZSIsInRhZ05hbWUiLCJib2R5Q2hpbGQiLCJhbGluZWFFbGVtZW50IiwiaXNNdWx0aUxpbmVzSGVhZGVyIiwibGV2ZWxzIiwibmV4dFBhcmVudFN0YXRlIiwic3RhdGUiLCJzdWJkaXZpc2lvbnMiLCJzdWJkaXZpc2lvbkFsaW5lYXMiLCJzdWJkaXZpc2lvbkhlYWRlcnMiLCJuZXh0RWxlbWVudFNpYmxpbmciLCJ1bmRlZmluZWQiLCJpZCIsImluY2x1ZGVzIiwiaGVhZGVyVGV4dCIsInRleHRDb250ZW50IiwibmFtZUNvbXB1dGVkIiwibm9ybWFsaXplIiwibmFtZVVwcGVyIiwidG9VcHBlckNhc2UiLCJuZXh0TGV2ZWwiLCJwYXJhZ3JhcGhUeXBlIiwibGluZUh0bWwiLCJvdXRlckhUTUwiLCJsaW5lVGV4dCIsImV4Y2x1ZGVBbGluZWEiLCJ0ZXN0IiwicHVzaCIsInRleHRlIiwicG9wIiwidHlwZSIsIm5pdmVhdSIsIm5pdmVhdVJlbGF0aWYiLCJ0aXRyZXMiLCJhbGluZWFzIiwidXJsIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BhcnNlcnMvdGV4dGVzX2xvaXMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCJcbmltcG9ydCB7IEpTRE9NIH0gZnJvbSBcImpzZG9tXCJcblxuZnVuY3Rpb24gcGFyc2VIZWFkZXIoaGVhZGVyOiBzdHJpbmcpOiBbbnVtYmVyIHwgbnVsbCwgc3RyaW5nXSB7XG4gIGNvbnN0IGhlYWRlcnNNYXBwaW5nOiB7IHJlZ2V4OiBSZWdFeHA7IGxldmVsOiBudW1iZXI7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gICAgeyByZWdleDogL14oUkFQUE9SVF8pP0FOTkVYRShffCQpfF5FVEFUXy8sIGxldmVsOiAwLCBuYW1lOiBcIkFubmV4ZVwiIH0sXG4gICAgeyByZWdleDogL15UT01FXy8sIGxldmVsOiAxLCBuYW1lOiBcIlRvbWVcIiB9LFxuICAgIHtcbiAgICAgIHJlZ2V4OlxuICAgICAgICAvXlBBUlRJRV98XihQUkVNSUVSRXxTRUNPTkRFfERFVVhJRU1FfFRST0lTSUVNRXxRVUFUUklFTUUpX1BBUlRJRShffCQpLyxcbiAgICAgIGxldmVsOiAyLFxuICAgICAgbmFtZTogXCJQYXJ0aWVcIixcbiAgICB9LFxuICAgIHsgcmVnZXg6IC9eTElWUkVfLywgbGV2ZWw6IDMsIG5hbWU6IFwiTGl2cmVcIiB9LFxuICAgIHsgcmVnZXg6IC9eVElUUkVfLywgbGV2ZWw6IDQsIG5hbWU6IFwiVGl0cmVcIiB9LFxuICAgIHsgcmVnZXg6IC9eU09VU1RJVFJFXy8sIGxldmVsOiA1LCBuYW1lOiBcIlNvdXNUaXRyZVwiIH0sXG4gICAgeyByZWdleDogL15DSEFQSVRSRV8vLCBsZXZlbDogNiwgbmFtZTogXCJDaGFwaXRyZVwiIH0sXG4gICAgeyByZWdleDogL15TRUNUSU9OXy8sIGxldmVsOiA3LCBuYW1lOiBcIlNlY3Rpb25cIiB9LFxuICAgIHsgcmVnZXg6IC9eU09VU1NFQ1RJT05fLywgbGV2ZWw6IDgsIG5hbWU6IFwiU291c1NlY3Rpb25cIiB9LFxuICAgIHsgcmVnZXg6IC9eQVJUSUNMRVM/X3xeRVhQT1NFX0RFU19NT1RJRlMkLywgbGV2ZWw6IDksIG5hbWU6IFwiQXJ0aWNsZVwiIH0sXG4gIF1cblxuICBmb3IgKGxldCB7IHJlZ2V4LCBsZXZlbCwgbmFtZSB9IG9mIGhlYWRlcnNNYXBwaW5nKSB7XG4gICAgaWYgKGhlYWRlci5tYXRjaChyZWdleCkpIHtcbiAgICAgIHJldHVybiBbbGV2ZWwsIG5hbWVdXG4gICAgfVxuICB9XG4gIHJldHVybiBbbnVsbCwgXCJcIl1cbn1cblxuZnVuY3Rpb24gY2xlYW5UZXh0KHRleHQ6IHN0cmluZyB8IG51bGwpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dD8ucmVwbGFjZSgvW1xcblxcdF0rL2csIFwiXCIpLnRyaW0oKSB8fCBcIlwiXG59XG5cbmNvbnN0IGV4Y2x1ZGVkQWxpbmVhcyA9IFtcbiAgL15Ew6lsaWLDqXLDqSBlbiBzw6lhbmNlIHB1YmxpcXVlLyxcbiAgL15GYWl0IGxlLyxcbiAgL15MZSBQcsOpc2lkZW50LCQvLFxuICAvXlNpZ27DqS8sXG5dXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVRleHRlKGFzc2VtYmxlZVVybDogc3RyaW5nLCBwYWdlOiBzdHJpbmcpIHtcbiAgLy8gUmVwYWlyIEhUTUwuXG4gIGxldCBodG1sID0gcGFnZS5yZXBsYWNlKC8oPHN0eWxlW1xcd1xcV10rc3R5bGU+KS9nLCBcIlwiKVxuXG4gIC8vIEV4dHJhY3Qgc3ViZGl2aXNpb25zIGZyb20gSFRNTC5cbiAgY29uc3QgeyB3aW5kb3cgfSA9IG5ldyBKU0RPTShodG1sKVxuICBjb25zdCB7IGRvY3VtZW50IH0gPSB3aW5kb3dcbiAgYXNzZXJ0LnN0cmljdEVxdWFsKGRvY3VtZW50LmNoaWxkcmVuLmxlbmd0aCwgMSlcbiAgY29uc3QgaHRtbEVsZW1lbnQgPSBkb2N1bWVudC5jaGlsZHJlblswXVxuICBhc3NlcnQuc3RyaWN0RXF1YWwoaHRtbEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoLCAyKVxuICBjb25zdCBib2R5RWxlbWVudCA9IGh0bWxFbGVtZW50LmNoaWxkcmVuWzFdXG5cbiAgaWYgKGJvZHlFbGVtZW50LmNoaWxkcmVuLmxlbmd0aCA8IDMpIHtcbiAgICAvLyBPY2N1cnMgaW4gaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8wMzI2LmFzcC5cbiAgICB3aW5kb3cuY2xvc2UoKSAvLyBGcmVlIG1lbW9yeS5cbiAgICByZXR1cm4ge1xuICAgICAgZXJyb3I6IHsgY29kZTogLTEsIG1lc3NhZ2U6IFwiVGV4dGUgZGUgbG9pIHNhbnMgY29udGVudVwiIH0sXG4gICAgICBodG1sLFxuICAgICAgcGFnZSxcbiAgICB9XG4gIH1cbiAgYXNzZXJ0LnN0cmljdEVxdWFsKGJvZHlFbGVtZW50LmNoaWxkcmVuWzBdLnRhZ05hbWUsIFwiRElWXCIpXG4gIC8vIEZpcnN0IGNoaWxkIGlzIGEgRElWIGRlc2NyaWJpbmcgdGhlIGRvY3VtZW50IChBc3NlbWJsw6llJ3MgaGVhZGVyKS4gU2tpcCBpdCBmb3Igbm93LlxuICBsZXQgYm9keUNoaWxkID0gYm9keUVsZW1lbnQuY2hpbGRyZW5bMV1cblxuICBhc3NlcnQuc3RyaWN0RXF1YWwoYm9keUNoaWxkLnRhZ05hbWUsIFwiQlJcIilcbiAgbGV0IGFsaW5lYUVsZW1lbnQ6IEVsZW1lbnQgfCBudWxsID0gbnVsbFxuICBsZXQgaXNNdWx0aUxpbmVzSGVhZGVyOiBib29sZWFuID0gZmFsc2VcbiAgbGV0IGxldmVsOiBudW1iZXIgfCBudWxsID0gbnVsbFxuICBsZXQgbGV2ZWxzOiBudW1iZXJbXSA9IFtdXG4gIGxldCBuZXh0UGFyZW50U3RhdGUgPSBudWxsXG4gIGxldCBzdGF0ZTogc3RyaW5nIHwgbnVsbCA9IFwibmV4dEJvZHlDaGlsZFwiXG4gIGNvbnN0IHN1YmRpdmlzaW9ucyA9IFtdXG4gIGxldCBzdWJkaXZpc2lvbkFsaW5lYXM6IG9iamVjdFtdIHwgbnVsbCA9IG51bGxcbiAgbGV0IHN1YmRpdmlzaW9uSGVhZGVyczogb2JqZWN0W10gfCBudWxsID0gbnVsbFxuICB3aGlsZSAoc3RhdGUgIT09IG51bGwpIHtcbiAgICBzd2l0Y2ggKHN0YXRlKSB7XG4gICAgICBjYXNlIFwibmV4dEJvZHlDaGlsZFwiOlxuICAgICAgICBpZiAoYm9keUNoaWxkLm5leHRFbGVtZW50U2libGluZyA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFRoZSBkb2N1bWVudCBoYXMgYmVlbiBmdWxseSBwYXJzZWQuXG4gICAgICAgICAgc3RhdGUgPSBudWxsXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYm9keUNoaWxkID0gYm9keUNoaWxkLm5leHRFbGVtZW50U2libGluZ1xuICAgICAgICAgIGlmIChib2R5Q2hpbGQudGFnTmFtZSA9PT0gXCJESVZcIikge1xuICAgICAgICAgICAgYWxpbmVhRWxlbWVudCA9IGJvZHlDaGlsZC5jaGlsZHJlblswXVxuXG4gICAgICAgICAgICBpZiAoYWxpbmVhRWxlbWVudCA9PT0gdW5kZWZpbmVkIHx8IGJvZHlDaGlsZC5pZC5pbmNsdWRlcyhcImZ0blwiKSkge1xuICAgICAgICAgICAgICAvLyBObyBhbGluZWEgaW4gY3VycmVudCBib2R5Q2hpbGQ6IGdvIHRvIG5leHQgYm9keUNoaWxkLlxuICAgICAgICAgICAgICBzdGF0ZSA9IFwibmV4dEJvZHlDaGlsZFwiXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzdGF0ZSA9IFwiYWxpbmVhRWxlbWVudFwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIDxQLz4gaXMgZm9yIGZvb3Rub3Rlc1xuICAgICAgICAgICAgYXNzZXJ0KFxuICAgICAgICAgICAgICBbXCJCUlwiLCBcIkhSXCIsIFwiUFwiXS5pbmNsdWRlcyhib2R5Q2hpbGQudGFnTmFtZSksXG4gICAgICAgICAgICAgIGBVbmV4cGVjdGVkIHRhZyBuYW1lIFwiJHtib2R5Q2hpbGQudGFnTmFtZX1cIiBmb3IgYm9keSBjaGlsZGAsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAvLyBTdGF5IGluIHRoZSBzYW1lIHN0YXRlIHRvIGdvIHRvIG5leHQgYm9keUNoaWxkLlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBcImFsaW5lYUVsZW1lbnRcIjpcbiAgICAgICAgc3dpdGNoIChhbGluZWFFbGVtZW50IS50YWdOYW1lKSB7XG4gICAgICAgICAgY2FzZSBcIkRJVlwiOlxuICAgICAgICAgICAgc3RhdGUgPSBcIm5leHRBbGluZWFFbGVtZW50XCJcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSBcIkg0XCI6XG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICBuZXh0UGFyZW50U3RhdGUgPSBcIm5leHRBbGluZWFFbGVtZW50XCJcbiAgICAgICAgICAgIHN0YXRlID0gXCJmaXJzdFBhcmFncmFwaENoaWxkXCJcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSBcIlBcIjpcbiAgICAgICAgICAgIG5leHRQYXJlbnRTdGF0ZSA9IFwibmV4dEFsaW5lYUVsZW1lbnRcIlxuICAgICAgICAgICAgc3RhdGUgPSBcImZpcnN0UGFyYWdyYXBoQ2hpbGRcIlxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlIFwiT0xcIjpcbiAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgIHN0YXRlID0gXCJuZXh0QWxpbmVhRWxlbWVudFwiXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGNhc2UgXCJUQUJMRVwiOlxuICAgICAgICAgICAgbmV4dFBhcmVudFN0YXRlID0gXCJuZXh0QWxpbmVhRWxlbWVudFwiXG4gICAgICAgICAgICBzdGF0ZSA9IFwiZmlyc3RQYXJhZ3JhcGhDaGlsZFwiXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgICAgIGNvZGU6IC0yLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBVbmV4cGVjdGVkIHRhZyBuYW1lIGZvciBhbGluZWEgZWxlbWVudDogJHtcbiAgICAgICAgICAgICAgICAgIGFsaW5lYUVsZW1lbnQhLnRhZ05hbWVcbiAgICAgICAgICAgICAgICB9YCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgaHRtbCxcbiAgICAgICAgICAgICAgcGFnZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBcImZpcnN0UGFyYWdyYXBoQ2hpbGRcIjpcbiAgICAgICAgY29uc3QgaGVhZGVyVGV4dCA9IGFsaW5lYUVsZW1lbnQhLnRleHRDb250ZW50XG4gICAgICAgIGNvbnN0IG5hbWVDb21wdXRlZCA9IChoZWFkZXJUZXh0IHx8IFwiXCIpXG4gICAgICAgICAgLm5vcm1hbGl6ZShcIk5GRFwiKVxuICAgICAgICAgIC5yZXBsYWNlKC9bXFx1MDMwMC1cXHUwMzZmXS9nLCBcIlwiKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXChub3V2ZWF1XFwpLywgXCJcIilcbiAgICAgICAgICAucmVwbGFjZSgvXFwoUG91ciBjb29yZGluYXRpb25cXCkvLCBcIlwiKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXChTdXBwcmltw6lzP1xcKS8sIFwiXCIpXG4gICAgICAgICAgLnJlcGxhY2UoL8KgL2csIFwiIFwiKVxuICAgICAgICAgIC5yZXBsYWNlKC9bXFwtLC7igKZdL2csIFwiXCIpXG4gICAgICAgICAgLnRyaW0oKVxuICAgICAgICAgIC5yZXBsYWNlKC8gezEsfS9nLCBcIl9cIilcblxuICAgICAgICBjb25zdCBuYW1lVXBwZXIgPSBuYW1lQ29tcHV0ZWQudG9VcHBlckNhc2UoKVxuICAgICAgICBjb25zdCBbbmV4dExldmVsLCBwYXJhZ3JhcGhUeXBlXSA9IHBhcnNlSGVhZGVyKG5hbWVVcHBlcilcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgIW5hbWVVcHBlciB8fFxuICAgICAgICAgIG5hbWVVcHBlci5tYXRjaCgvXihQUk9KRVR8UFJPUE9TSVRJT04pX0RFX0xPSShffCQpLykgIT09IG51bGxcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gT2NjdXJzIGluOlxuICAgICAgICAgIC8vICogaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8wMjMyLmFzcFxuICAgICAgICAgIC8vICogaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8wNjI2LmFzcFxuICAgICAgICAgIC8vICogaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8wNjc2LmFzcFxuICAgICAgICAgIHN0YXRlID0gbmV4dFBhcmVudFN0YXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfSBlbHNlIGlmIChuYW1lVXBwZXIgPT09IFwiSkVVWF9PTFlNUElRVUVTX0VUX1BBUkFMWU1QSVFVRVNfREVfMjAyNFwiKSB7XG4gICAgICAgICAgLy8gT2NjdXJzIGluIGh0dHA6Ly93d3cuYXNzZW1ibGVlLW5hdGlvbmFsZS5mci8xNS90ZXh0ZXMvMDY3Ni5hc3BcbiAgICAgICAgICBzdGF0ZSA9IG5leHRQYXJlbnRTdGF0ZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH0gZWxzZSBpZiAobmFtZVVwcGVyID09PSBcIlRFWFRFX0RFX0xBX0NPTU1JU1NJT05fTUlYVEVfUEFSSVRBSVJFXCIpIHtcbiAgICAgICAgICAvLyBPY2N1cnMgaW4gaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8xMjk0LmFzcFxuICAgICAgICAgIHN0YXRlID0gbmV4dFBhcmVudFN0YXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpbmVIdG1sID0gY2xlYW5UZXh0KGFsaW5lYUVsZW1lbnQhLm91dGVySFRNTClcbiAgICAgICAgY29uc3QgbGluZVRleHQgPSBjbGVhblRleHQoYWxpbmVhRWxlbWVudCEudGV4dENvbnRlbnQpXG5cbiAgICAgICAgaWYgKG5leHRMZXZlbCA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIEl0IGlzIGEgcmVndWxhciBhbGluZWFcbiAgICAgICAgICAvLyBFeGNsdWRlIHNvbWUgYWxpbmVhc1xuICAgICAgICAgIGxldCBleGNsdWRlQWxpbmVhID0gZmFsc2VcbiAgICAgICAgICBmb3IgKGxldCByZWdleCBvZiBleGNsdWRlZEFsaW5lYXMpIHtcbiAgICAgICAgICAgIGlmIChyZWdleC50ZXN0KGxpbmVUZXh0KSkge1xuICAgICAgICAgICAgICBleGNsdWRlQWxpbmVhID0gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXhjbHVkZUFsaW5lYSkge1xuICAgICAgICAgICAgc3RhdGUgPSBuZXh0UGFyZW50U3RhdGVcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHN1YmRpdmlzaW9uSGVhZGVycyEubGVuZ3RoID09PSAwIHx8XG4gICAgICAgICAgICAoaXNNdWx0aUxpbmVzSGVhZGVyICYmIHN1YmRpdmlzaW9uQWxpbmVhcyEubGVuZ3RoID09PSAwKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgc3ViZGl2aXNpb25IZWFkZXJzIS5wdXNoKHtcbiAgICAgICAgICAgICAgdGV4dGU6IGxpbmVUZXh0LFxuICAgICAgICAgICAgICBodG1sOiBsaW5lSHRtbCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN1YmRpdmlzaW9uQWxpbmVhcyEucHVzaCh7XG4gICAgICAgICAgICAgIHRleHRlOiBsaW5lVGV4dCxcbiAgICAgICAgICAgICAgaHRtbDogbGluZUh0bWwsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaXNNdWx0aUxpbmVzSGVhZGVyICYmIHN1YmRpdmlzaW9uSGVhZGVycyEubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgIGlzTXVsdGlMaW5lc0hlYWRlciA9IGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFNraXAgcGFyYWdyYXBoLlxuICAgICAgICAgIHN0YXRlID0gbmV4dFBhcmVudFN0YXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfSBlbHNlIGlmIChuZXh0TGV2ZWwgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBJdCBpcyBhIGhlYWRlclxuICAgICAgICAgIGxldmVsID0gbmV4dExldmVsXG4gICAgICAgICAgd2hpbGUgKGxldmVscy5sZW5ndGggPiAwICYmIGxldmVsIDwgbGV2ZWxzW2xldmVscy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgICAgbGV2ZWxzLnBvcCgpXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChsZXZlbHMubGVuZ3RoID09PSAwIHx8IGxldmVsID4gbGV2ZWxzW2xldmVscy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgICAgbGV2ZWxzLnB1c2gobGV2ZWwpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3ViZGl2aXNpb25BbGluZWFzID0gW11cbiAgICAgICAgICBzdWJkaXZpc2lvbkhlYWRlcnMgPSBbeyB0ZXh0ZTogbGluZVRleHQsIGh0bWw6IGxpbmVIdG1sIH1dXG5cbiAgICAgICAgICAvLyBBcnRpY2xlcyAmIFwiRXhwb3PDqSBkZXMgbW90aWZzXCIgYXJlIHRoZSBvbmx5IGRpdmlzaW9ucyB3aXRob3V0IHNlY29uZCB0aXRsZS5cbiAgICAgICAgICBpc011bHRpTGluZXNIZWFkZXIgPVxuICAgICAgICAgICAgbmFtZVVwcGVyLm1hdGNoKC9eQVJUSUNMRVM/Xy8pID09PSBudWxsICYmXG4gICAgICAgICAgICBuYW1lVXBwZXIubWF0Y2goL15FWFBPU0VfREVTX01PVElGUyQvKSA9PT0gbnVsbFxuXG4gICAgICAgICAgc3ViZGl2aXNpb25zLnB1c2goe1xuICAgICAgICAgICAgaWQ6IFwiRF9cIiArIG5hbWVDb21wdXRlZCxcbiAgICAgICAgICAgIHR5cGU6IHBhcmFncmFwaFR5cGUsXG4gICAgICAgICAgICBuaXZlYXU6IGxldmVsICsgMSxcbiAgICAgICAgICAgIG5pdmVhdVJlbGF0aWY6IGxldmVscy5sZW5ndGgsXG4gICAgICAgICAgICB0aXRyZXM6IHN1YmRpdmlzaW9uSGVhZGVycyxcbiAgICAgICAgICAgIGFsaW5lYXM6IHN1YmRpdmlzaW9uQWxpbmVhcyxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUgPSBuZXh0UGFyZW50U3RhdGVcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgXCJuZXh0QWxpbmVhRWxlbWVudFwiOlxuICAgICAgICBhbGluZWFFbGVtZW50ID0gYWxpbmVhRWxlbWVudCEubmV4dEVsZW1lbnRTaWJsaW5nXG4gICAgICAgIGlmIChhbGluZWFFbGVtZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gVGhlIGJvZHlDaGlsZCBoYXMgYmVlbiBmdWxseSBwYXJzZWQuIEdvIHRvIG5leHQgYm9keUNoaWxkXG4gICAgICAgICAgc3RhdGUgPSBcIm5leHRCb2R5Q2hpbGRcIlxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXRlID0gXCJhbGluZWFFbGVtZW50XCJcbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgYFVuZXhwZWN0ZWQgc3RhdGU6ICR7c3RhdGV9YFxuICAgIH1cbiAgfVxuXG4gIHdpbmRvdy5jbG9zZSgpIC8vIEZyZWUgbWVtb3J5LlxuXG4gIHJldHVybiB7XG4gICAgZXJyb3I6IG51bGwsXG4gICAgaHRtbCxcbiAgICBwYWdlLFxuICAgIHN1YmRpdmlzaW9ucyxcbiAgICB1cmw6IGFzc2VtYmxlZVVybCxcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPQSxNQUFNLE1BQU0sUUFBUTtBQUMzQixTQUFTQyxLQUFLLFFBQVEsT0FBTztBQUU3QixTQUFTQyxXQUFXQSxDQUFDQyxNQUFjLEVBQTJCO0VBQzVELE1BQU1DLGNBQWdFLEdBQUcsQ0FDdkU7SUFBRUMsS0FBSyxFQUFFLGdDQUFnQztJQUFFQyxLQUFLLEVBQUUsQ0FBQztJQUFFQyxJQUFJLEVBQUU7RUFBUyxD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