@tricoteuses/assemblee 1.8.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bugs/acteur-00010/plugin.test.js +2 -2
- package/lib/bugs/acteur-00010.js +3 -3
- package/lib/bugs/agenda-00002/plugin.test.js +3 -3
- package/lib/bugs/agenda-00002.js +5 -5
- package/lib/bugs/agenda-00008/plugin.test.js +2 -2
- package/lib/bugs/agenda-00008.js +3 -3
- package/lib/bugs/agenda-00011/plugin.test.js +6 -6
- package/lib/bugs/agenda-00011.js +8 -8
- package/lib/bugs.js +11 -11
- package/lib/cleaners/index.d.ts +1 -0
- package/lib/cleaners/index.js +8 -1
- package/lib/cleaners/index.mjs +2 -1
- package/lib/cleaners/scrutins.js +2 -1
- package/lib/cleaners/scrutins.mjs +3 -2
- package/lib/cleaners/textes_loi.d.ts +1 -0
- package/lib/cleaners/textes_loi.js +12 -0
- package/lib/cleaners/textes_loi.mjs +5 -0
- package/lib/cleaners/xml.d.ts +3 -0
- package/lib/cleaners/xml.js +13 -1
- package/lib/cleaners/xml.mjs +11 -1
- package/lib/datasets.d.ts +9 -2
- package/lib/datasets.js +24 -3
- package/lib/datasets.mjs +24 -3
- package/lib/dates.js +3 -3
- package/lib/examples/PIONANR5L15B0020/input.d.ts +2 -0
- package/lib/examples/PIONANR5L15B0020/input.js +10 -0
- package/lib/examples/PIONANR5L15B0020/input.mjs +193 -0
- package/lib/examples/PRJLANR5L16B0914/input.d.ts +2 -0
- package/lib/examples/PRJLANR5L16B0914/input.js +10 -0
- package/lib/examples/PRJLANR5L16B0914/input.mjs +322 -0
- package/lib/examples/PRJLANR5L16B2014/input.d.ts +2 -0
- package/lib/examples/PRJLANR5L16B2014/input.js +10 -0
- package/lib/examples/PRJLANR5L16B2014/input.mjs +577 -0
- package/lib/examples/PRJLANR5L16B2424/input.d.ts +2 -0
- package/lib/examples/PRJLANR5L16B2424/input.js +10 -0
- package/lib/examples/PRJLANR5L16B2424/input.mjs +322 -0
- package/lib/examples/PRJLANR5L16B2462/input.d.ts +2 -0
- package/lib/examples/PRJLANR5L16B2462/input.js +10 -0
- package/lib/examples/PRJLANR5L16B2462/input.mjs +1308 -0
- package/lib/loaders.d.ts +5 -0
- package/lib/loaders.js +308 -262
- package/lib/loaders.mjs +16 -3
- package/lib/logger.d.ts +16 -0
- package/lib/logger.js +35 -0
- package/lib/logger.mjs +26 -0
- package/lib/parsers/documents.js +2 -2
- package/lib/parsers/textes_lois.d.ts +16 -1
- package/lib/parsers/textes_lois.js +733 -28
- package/lib/parsers/textes_lois.mjs +587 -22
- package/lib/raw_types/acteurs_et_organes.js +1 -1
- package/lib/raw_types/agendas.js +1 -1
- package/lib/raw_types/amendements.js +1 -1
- package/lib/raw_types/debats.js +1 -1
- package/lib/raw_types/dossiers_legislatifs.js +1 -1
- package/lib/raw_types/questions.js +1 -1
- package/lib/raw_types/scrutins.d.ts +18 -13
- package/lib/raw_types/scrutins.js +28 -14
- package/lib/raw_types/scrutins.mjs +28 -14
- package/lib/raw_types/textes_loi.d.ts +93 -0
- package/lib/raw_types/textes_loi.js +429 -0
- package/lib/raw_types/textes_loi.mjs +378 -0
- package/lib/scripts/bugs_helper.js +9 -9
- package/lib/scripts/document_dossiers_legislatifs.js +1 -1
- package/lib/scripts/process_open_dataset.d.ts +17 -0
- package/lib/scripts/process_open_dataset.js +302 -0
- package/lib/scripts/process_open_dataset.mjs +136 -0
- package/lib/scripts/process_textes_loi_dataset.d.ts +7 -0
- package/lib/scripts/process_textes_loi_dataset.js +374 -0
- package/lib/scripts/process_textes_loi_dataset.mjs +237 -0
- package/lib/scripts/raw_types_from_amendements.js +2 -2
- package/lib/scripts/reorganize_data.js +1 -1
- package/lib/scripts/reorganize_data.mjs +1 -1
- package/lib/scripts/retrieve_deputes_photos.js +3 -3
- package/lib/scripts/retrieve_documents.js +4 -4
- package/lib/scripts/retrieve_open_data.js +41 -279
- package/lib/scripts/retrieve_open_data.mjs +13 -126
- package/lib/scripts/retrieve_pending_amendments.js +2 -2
- package/lib/scripts/retrieve_senateurs_photos.js +2 -2
- package/lib/scripts/retrieve_textes_lois.js +2 -2
- package/lib/scripts/shared/cli_helpers.d.ts +5 -0
- package/lib/scripts/shared/cli_helpers.js +7 -2
- package/lib/scripts/shared/cli_helpers.mjs +6 -1
- package/lib/scripts/test_iter_load.js +25 -10
- package/lib/scripts/test_iter_load.mjs +19 -11
- package/lib/scripts/validate_json.js +3 -3
- package/lib/types/acteurs_et_organes.js +1 -1
- package/lib/types/agendas.js +1 -1
- package/lib/types/amendements.js +1 -1
- package/lib/types/debats.js +1 -1
- package/lib/types/dossiers_legislatifs.js +1 -1
- package/lib/types/questions.js +1 -1
- package/lib/types/scrutins.d.ts +6 -3
- package/lib/types/scrutins.js +13 -7
- package/lib/types/scrutins.mjs +13 -7
- package/lib/types/textes_loi.d.ts +94 -0
- package/lib/types/textes_loi.js +429 -0
- package/lib/types/textes_loi.mjs +378 -0
- package/package.json +13 -12
- package/lib/scripts/retrieve_textes_lois_llm.d.ts +0 -1
- package/lib/scripts/retrieve_textes_lois_llm.js +0 -188
- package/lib/scripts/retrieve_textes_lois_llm.mjs +0 -85
|
@@ -1,43 +1,608 @@
|
|
|
1
1
|
import { ChatOpenAI } from "@langchain/openai";
|
|
2
2
|
import { ChatPromptTemplate } from "@langchain/core/prompts";
|
|
3
3
|
import Ajv from "ajv";
|
|
4
|
-
|
|
4
|
+
import { delimiter, runLogFun } from "../logger.mjs";
|
|
5
|
+
const EXPOSE_MOTIFS_SCHEMA = require("../schemas/texte_loi/ExposeMotifs");
|
|
6
|
+
const META_DONNEES_SCHEMA = require("../schemas/texte_loi/MetaDonnees");
|
|
7
|
+
const PROJET_LOI_SCHEMA = require("../schemas/texte_loi/ProjetLoi");
|
|
8
|
+
const ALINEA_SCHEMA = require("../schemas/texte_loi/Alinea");
|
|
9
|
+
const SOMMAIRE_SCHEMA = require("../schemas/texte_loi/Sommaire");
|
|
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"),
|
|
19
|
+
input: require("../examples/PRJLANR5L16B0914/input"),
|
|
20
|
+
loi: require("../examples/PRJLANR5L16B0914/loi"),
|
|
21
|
+
meta: require("../examples/PRJLANR5L16B0914/meta"),
|
|
22
|
+
sommaire: require("../examples/PRJLANR5L16B0914/sommaire")
|
|
23
|
+
},
|
|
24
|
+
PRJLANR5L16B2014: {
|
|
25
|
+
motifs: require("../examples/PRJLANR5L16B2014/motifs"),
|
|
26
|
+
input: require("../examples/PRJLANR5L16B2014/input"),
|
|
27
|
+
loi: require("../examples/PRJLANR5L16B2014/loi"),
|
|
28
|
+
meta: require("../examples/PRJLANR5L16B2014/meta"),
|
|
29
|
+
sommaire: require("../examples/PRJLANR5L16B2014/sommaire")
|
|
30
|
+
},
|
|
31
|
+
PRJLANR5L16B2424: {
|
|
32
|
+
alineas: require("../examples/PRJLANR5L16B2424/alineas"),
|
|
33
|
+
motifs: require("../examples/PRJLANR5L16B2424/motifs"),
|
|
34
|
+
input: require("../examples/PRJLANR5L16B2424/input"),
|
|
35
|
+
loi: require("../examples/PRJLANR5L16B2424/loi"),
|
|
36
|
+
meta: require("../examples/PRJLANR5L16B2424/meta"),
|
|
37
|
+
sommaire: require("../examples/PRJLANR5L16B2424/sommaire")
|
|
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
|
+
*/
|
|
5
118
|
function cleanHtml(html) {
|
|
6
119
|
let cleanedHtml = html.replace(/(<style[\w\W]+style>)/g, "");
|
|
7
120
|
cleanedHtml = cleanedHtml.replace(/(<head[\w\W]+head>)/g, "");
|
|
8
121
|
cleanedHtml = cleanedHtml.replace(/<img[^>]*>/g, "");
|
|
9
122
|
return cleanedHtml;
|
|
10
123
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
17
183
|
});
|
|
18
|
-
|
|
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 = [];
|
|
19
204
|
const systemTemplate = `
|
|
20
|
-
|
|
21
|
-
Tu dois analyser un texte de loi afin de séparer et structurer les éléments qui le composent. Le format d'entrée est HTML.
|
|
205
|
+
# Instructions :
|
|
22
206
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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 :
|
|
26
211
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
212
|
+
"""
|
|
213
|
+
{debut}
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
Et finissant par :
|
|
217
|
+
|
|
218
|
+
"""
|
|
219
|
+
{fin}
|
|
220
|
+
"""
|
|
221
|
+
`;
|
|
32
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;
|
|
235
|
+
}
|
|
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
|
+
}
|
|
257
|
+
const projetLoi = {
|
|
258
|
+
...partial,
|
|
259
|
+
articles: fullArticles
|
|
260
|
+
};
|
|
261
|
+
runLogFun(console.groupEnd(), {
|
|
262
|
+
silent: SILENT_LOG
|
|
263
|
+
});
|
|
264
|
+
delimiter();
|
|
265
|
+
return projetLoi;
|
|
266
|
+
}
|
|
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 {};
|
|
339
|
+
}
|
|
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}"]]);
|
|
33
362
|
const chain = prompt.pipe(structuredModel);
|
|
34
363
|
const result = await chain.invoke({
|
|
35
|
-
input: cleanedHtml
|
|
364
|
+
input: cleanedHtml,
|
|
365
|
+
example1: EXAMPLES.PRJLANR5L16B0914.input,
|
|
366
|
+
example2: EXAMPLES.PRJLANR5L16B2424.input,
|
|
367
|
+
output1: EXAMPLES.PRJLANR5L16B0914.meta,
|
|
368
|
+
output2: EXAMPLES.PRJLANR5L16B2424.meta
|
|
36
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();
|
|
37
374
|
const ajv = new Ajv();
|
|
38
|
-
if (ajv.validate(
|
|
375
|
+
if (ajv.validate(META_DONNEES_SCHEMA, result)) {
|
|
376
|
+
runLogFun(console.warn("Meta-données OK 👌"), {
|
|
377
|
+
silent: SILENT_LOG
|
|
378
|
+
});
|
|
39
379
|
return result;
|
|
40
380
|
}
|
|
41
|
-
|
|
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();
|
|
576
|
+
return {
|
|
577
|
+
sommaire: []
|
|
578
|
+
};
|
|
579
|
+
}
|
|
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;
|
|
599
|
+
}
|
|
600
|
+
runLogFun(console.warn("La construction du sommaire est KO ❌"), {
|
|
601
|
+
silent: SILENT_LOG
|
|
602
|
+
});
|
|
603
|
+
delimiter();
|
|
604
|
+
return {
|
|
605
|
+
sommaire: []
|
|
606
|
+
};
|
|
42
607
|
}
|
|
43
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDaGF0T3BlbkFJIiwiQ2hhdFByb21wdFRlbXBsYXRlIiwiQWp2IiwidGV4dGVMb2lTY2hlbWEiLCJyZXF1aXJlIiwiY2xlYW5IdG1sIiwiaHRtbCIsImNsZWFuZWRIdG1sIiwicmVwbGFjZSIsInBhcnNlVGV4dGVMb2kiLCJtb2RlbCIsInRlbXBlcmF0dXJlIiwiYXBpS2V5IiwicHJvY2VzcyIsImVudiIsIk9QRU5BSV9BUElfS0VZIiwic3RydWN0dXJlZE1vZGVsIiwid2l0aFN0cnVjdHVyZWRPdXRwdXQiLCJzeXN0ZW1UZW1wbGF0ZSIsInByb21wdCIsImZyb21NZXNzYWdlcyIsImNoYWluIiwicGlwZSIsInJlc3VsdCIsImludm9rZSIsImlucHV0IiwiYWp2IiwidmFsaWRhdGUiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFyc2Vycy90ZXh0ZXNfbG9pcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGF0T3BlbkFJIH0gZnJvbSBcIkBsYW5nY2hhaW4vb3BlbmFpXCJcbmltcG9ydCB7IENoYXRQcm9tcHRUZW1wbGF0ZSB9IGZyb20gXCJAbGFuZ2NoYWluL2NvcmUvcHJvbXB0c1wiXG5pbXBvcnQgQWp2IGZyb20gXCJhanZcIlxuY29uc3QgdGV4dGVMb2lTY2hlbWEgPSByZXF1aXJlKFwiLi4vc2NoZW1hcy90ZXh0ZV9sb2kvVGV4dGVMb2kuanNvblwiKVxuXG5mdW5jdGlvbiBjbGVhbkh0bWwoaHRtbDogc3RyaW5nKSB7XG4gIGxldCBjbGVhbmVkSHRtbCA9IGh0bWwucmVwbGFjZSgvKDxzdHlsZVtcXHdcXFddK3N0eWxlPikvZywgXCJcIilcbiAgY2xlYW5lZEh0bWwgPSBjbGVhbmVkSHRtbC5yZXBsYWNlKC8oPGhlYWRbXFx3XFxXXStoZWFkPikvZywgXCJcIilcbiAgY2xlYW5lZEh0bWwgPSBjbGVhbmVkSHRtbC5yZXBsYWNlKC88aW1nW14+XSo+L2csIFwiXCIpXG5cbiAgcmV0dXJuIGNsZWFuZWRIdG1sXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZVRleHRlTG9pKGh0bWw6IHN0cmluZykge1xuICBjb25zdCBjbGVhbmVkSHRtbCA9IGNsZWFuSHRtbChodG1sKVxuXG4gIGNvbnN0IG1vZGVsID0gbmV3IENoYXRPcGVuQUkoe1xuICAgIHRlbXBlcmF0dXJlOiAwLFxuICAgIG1vZGVsOiBcImdwdC00b1wiLFxuICAgIGFwaUtleTogcHJvY2Vzcy5lbnYuT1BFTkFJX0FQSV9LRVksXG4gIH0pXG5cbiAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gbW9kZWwud2l0aFN0cnVjdHVyZWRPdXRwdXQodGV4dGVMb2lTY2hlbWEpXG5cbiAgY29uc3Qgc3lzdGVtVGVtcGxhdGUgPSBgXG4gICAgICAgIFR1IGVzIHVuIGV4cGVydCBkZSBsYSBsb2kgZXQgZGUgbCdhbmFseXNlIGRlIHBhZ2VzIEhUTUwuXG4gICAgICAgIFR1IGRvaXMgYW5hbHlzZXIgdW4gdGV4dGUgZGUgbG9pIGFmaW4gZGUgc8OpcGFyZXIgZXQgc3RydWN0dXJlciBsZXMgw6lsw6ltZW50cyBxdWkgbGUgY29tcG9zZW50LiBMZSBmb3JtYXQgZCdlbnRyw6llIGVzdCBIVE1MLlxuXG4gICAgICAgIExlIHRleHRlIGVzdCBkaXZpc8OpIGVuIGRldXggcGFydGllcyA6XG4gICAgICAgIEEpIHVuIGV4cG9zw6kgZGVzIG1vdGlmcyBxdWkgaW5kaXF1ZSBsZXMgcmFpc29ucyBwb3VyIGxlc3F1ZWxsZXMgY2UgcHJvamV0IGVzdCBzb3VtaXMgYXUgUGFybGVtZW50LiBJbCBwZXV0IGNvbnRlbmlyIDMgw6lsw6ltZW50cyA6IDEpIHVuZSBjaXRhdGlvbiBhdSBkw6lidXQgZCd1biBkb2N1bWVudCwgMikgbGUgdGV4dGUgcHJpbmNpcGFsIHF1aSBkw6l2ZWxvcHBlIGxlcyBhcmd1bWVudHMgZGUgbCdhdXRldXIgw6AgbCdhcHB1aSBkZSBsYSBtb2RpZmljYXRpb24gbMOpZ2lzbGF0aXZlIG91IGRlcyBkaXNwb3NpdGlvbnMgbm91dmVsbGVzIHF1J2lsIHByb3Bvc2UsIDMpIGRlcyBwYXJhZ3JhcGhlcyBxdWkgcHLDqXNlbnRlbnQgbGVzIGFydGljbGVzLlxuICAgICAgICBCKSBsZSBkaXNwb3NpdGlmIHF1aSBlc3QgbGEgcGFydGllIG5vcm1hdGl2ZSBldCByw6lkaWfDqWUgZW4gYXJ0aWNsZXMuIElsIHBldXQgY29tcG9ydGVyIGRlcyBkaXZpc2lvbnMgbm9tbcOpZXMgdGl0cmVzLCBjaGFwaXRyZXMsIHNlY3Rpb25zLCBzb3VzLXNlY3Rpb25zLiBMb3JzcXUnaWwgeSBhIHVuIHNldWwgbml2ZWF1IGRlIHN0cnVjdHVyZSwgb24gcmV0cm91dmVyYSBsZSBjaGFwaXRyZSA7IHPigJlpbCB5IGEgZGV1eCBuaXZlYXV4IGRlIHN0cnVjdHVyZSwgb24gcmV0cm91dmVyYSBkZXMgY2hhcGl0cmVzIHB1aXMgZGVzIHNlY3Rpb25zLiBT4oCZaWwgeSBhIHRyb2lzIG5pdmVhdXggZGUgc3RydWN0dXJlLCBvbiByZXRyb3V2ZXJhIGRlcyB0aXRyZXMgcHVpcyBkZXMgY2hhcGl0cmVzIHB1aXMgZGVzIHNlY3Rpb25zLlxuXG4gICAgICAgIFNpIGxlIHRleHRlIGRlIGxvaSBuZSBjb21wb3J0ZSBwYXMgZGUgZGl2aXNpb24sIGxlIHNvbW1haXJlIGRvaXQgcmVzdGVyIHZpZGUuXG4gICAgICAgIFRvdXRlcyBsZXMgbGlnbmVzIHF1aSBkw6lidXRlbnQgcGFyIHVuICfCqycgbmUgc29udCBwYXMgw6AgcHJlbmRyZSBlbiBjb21wdGUgZGFucyBsZXMgZGl2aXNpb25zXG4gICAgICAgIExvcnNxdWUgbGVzIHRleHRlcyBvbnQgw6l0w6kgbW9kaWZpw6lzLCBpbCBuJ3kgcGFzIGQnZXhwb3PDqSBkZXMgbW90aWZzLlxuICAgICAgICBUYSByw6lwb25zZSBkb2l0IMOqdHJlIHVuIEpTT04gc3RydWN0dXLDqSBhdmVjIGxlcyDDqWzDqW1lbnRzIGR1IHRleHRlIGRlIGxvaSBlbiByZXNwZWN0YW50IGxlIHNjaMOpbWEgSlNPTiBmb3VybmkuXG4gICAgYFxuXG4gIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgIFtcInN5c3RlbVwiLCBzeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IGNoYWluID0gcHJvbXB0LnBpcGUoc3RydWN0dXJlZE1vZGVsKVxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBjaGFpbi5pbnZva2UoeyBpbnB1dDogY2xlYW5lZEh0bWwgfSlcblxuICBjb25zdCBhanYgPSBuZXcgQWp2KClcbiAgaWYgKGFqdi52YWxpZGF0ZSh0ZXh0ZUxvaVNjaGVtYSwgcmVzdWx0KSkge1xuICAgIHJldHVybiByZXN1bHRcbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsVUFBVSxRQUFRLG1CQUFtQjtBQUM5QyxTQUFTQyxrQkFBa0IsUUFBUSx5QkFBeUI7QUFDNUQsT0FBT0MsR0FBRyxNQUFNLEtBQUs7QUFDckIsTUFBTUMsY0FBYyxHQUFHQyxPQUFPLENBQUMsb0NBQW9DLENBQUM7QUFFcEUsU0FBU0MsU0FBU0EsQ0FBQ0MsSUFBWSxFQUFFO0VBQy9CLElBQUlDLFdBQVcsR0FBR0QsSUFBSSxDQUFDRSxPQUFPLENBQUMsd0JBQXdCLEVBQUUsRUFBRSxDQUFDO0VBQzVERCxXQUFXLEdBQUdBLFdBQVcsQ0FBQ0MsT0FBTyxDQUFDLHNCQUFzQixFQUFFLEVBQUUsQ0FBQztFQUM3REQsV0FBVyxHQUFHQSxXQUFXLENBQUNDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDO0VBRXBELE9BQU9ELFdBQVc7QUFDcEI7QUFFQSxPQUFPLGVBQWVFLGFBQWFBLENBQUNILElBQVksRUFBRTtFQUNoRCxNQUFNQyxXQUFXLEdBQUdGLFNBQVMsQ0FBQ0MsSUFBSSxDQUFDO0VBRW5DLE1BQU1JLEtBQUssR0FBRyxJQUFJVixVQUFVLENBQUM7SUFDM0JXLFdBQVcsRUFBRSxDQUFDO0lBQ2RELEtBQUssRUFBRSxRQUFRO0lBQ2ZFLE1BQU0sRUFBRUMsT0FBTyxDQUFDQyxHQUFHLENBQUNDO0VBQ3RCLENBQUMsQ0FBQztFQUVGLE1BQU1DLGVBQWUsR0FBR04sS0FBSyxDQUFDTyxvQkFBb0IsQ0FBQ2QsY0FBYyxDQUFDO0VBRWxFLE1BQU1lLGNBQWMsR0FBRztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztFQUVILE1BQU1DLE1BQU0sR0FBR2xCLGtCQUFrQixDQUFDbUIsWUFBWSxDQUFDLENBQzdDLENBQUMsUUFBUSxFQUFFRixjQUFjLENBQUMsRUFDMUIsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQ3JCLENBQUM7RUFFRixNQUFNRyxLQUFLLEdBQUdGLE1BQU0sQ0FBQ0csSUFBSSxDQUFDTixlQUFlLENBQUM7RUFDMUMsTUFBTU8sTUFBTSxHQUFHLE1BQU1GLEtBQUssQ0FBQ0csTUFBTSxDQUFDO0lBQUVDLEtBQUssRUFBRWxCO0VBQVksQ0FBQyxDQUFDO0VBRXpELE1BQU1tQixHQUFHLEdBQUcsSUFBSXhCLEdBQUcsQ0FBQyxDQUFDO0VBQ3JCLElBQUl3QixHQUFHLENBQUNDLFFBQVEsQ0FBQ3hCLGNBQWMsRUFBRW9CLE1BQU0sQ0FBQyxFQUFFO0lBQ3hDLE9BQU9BLE1BQU07RUFDZjtFQUNBLE9BQU8sS0FBSztBQUNkIiwiaWdub3JlTGlzdCI6W119
|
|
608
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDaGF0T3BlbkFJIiwiQ2hhdFByb21wdFRlbXBsYXRlIiwiQWp2IiwiZGVsaW1pdGVyIiwicnVuTG9nRnVuIiwiRVhQT1NFX01PVElGU19TQ0hFTUEiLCJyZXF1aXJlIiwiTUVUQV9ET05ORUVTX1NDSEVNQSIsIlBST0pFVF9MT0lfU0NIRU1BIiwiQUxJTkVBX1NDSEVNQSIsIlNPTU1BSVJFX1NDSEVNQSIsIkVYQU1QTEVTIiwiUFJKTEFOUjVMMTZCMDkxNCIsIm1vdGlmcyIsImlucHV0IiwibG9pIiwibWV0YSIsInNvbW1haXJlIiwiUFJKTEFOUjVMMTZCMjAxNCIsIlBSSkxBTlI1TDE2QjI0MjQiLCJhbGluZWFzIiwiRlVMTF9URVhURV9TQ0hFTUEiLCIkc2NoZW1hIiwidGl0bGUiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJwcm9wZXJ0aWVzIiwidGV4dGUiLCJyZXF1aXJlZCIsIk1PREVMIiwicHJvY2VzcyIsImVudiIsIk9QRU5BSV9BUElfS0VZIiwidGVtcGVyYXR1cmUiLCJ0b3BQIiwibW9kZWwiLCJhcGlLZXkiLCJtYXhUb2tlbnMiLCJTWVNURU1fVEVNUExBVEUiLCJTSUxFTlRfTE9HIiwicGFyc2VUZXh0ZUxvaSIsImh0bWwiLCJvcHRpb25zIiwic2lsZW50IiwiY29uc29sZSIsImluZm8iLCJleHRyYWN0TWV0YURvbm5lZXMiLCJleHRyYWN0U29tbWFpcmUiLCJwYXJ0aWFsTW90aWZzIiwiZXh0cmFjdE1vdGlmcyIsInBhcnRpYWxMb2kiLCJleHRyYWN0UHJvamV0TG9pIiwiZXhwb3NlTW90aWZzIiwicG9wdWxhdGVNb3RpZnMiLCJwb3B1bGF0ZVByb2pldExvaSIsImNsZWFuSHRtbCIsImNsZWFuZWRIdG1sIiwicmVwbGFjZSIsInJlbW92ZUh0bWxUYWdzIiwiaHRtbFRhZ1JlZ2V4IiwidGV4dFdpdGhvdXRUYWdzIiwiZGVidXQiLCJmaW4iLCJzeXN0ZW1UZW1wbGF0ZSIsInByb21wdCIsImZyb21NZXNzYWdlcyIsInN0cnVjdHVyZWRNb2RlbCIsIndpdGhTdHJ1Y3R1cmVkT3V0cHV0IiwiY2hhaW4iLCJwaXBlIiwiYXJ0aWNsZVByb21wdFJlc3VsdCIsImludm9rZSIsInBhcnRpYWwiLCJncm91cCIsImFydGljbGVzIiwiZnVsbEFydGljbGVzIiwiYXJ0aWNsZSIsImFsaW5lYSIsImFsaW5lYVByb21wdFJlc3VsdCIsInB1c2giLCJwcm9qZXRMb2kiLCJncm91cEVuZCIsIm1vdGlmc1N5c3RlbVRlbXBsYXRlIiwibW90aWZzUHJvbXB0UmVzdWx0IiwiZXhhbXBsZTEiLCJleGFtcGxlMiIsIm91dHB1dDEiLCJvdXRwdXQyIiwidGFibGUiLCJzdWJzdHJpbmciLCJhanYiLCJ2YWxpZGF0ZSIsIndhcm4iLCJtZXRhRG9ubmVlc1N5c3RlbVRlbXBsYXRlIiwicmVzdWx0IiwiZG9jdW1lbnRSZWYiLCJ0aXRyZSIsIm51bWVyb1RleHRlIiwicHJvY2VkdXJlQWNjZWxlcmVlIiwicHJvamV0TG9pU3lzdGVtVGVtcGxhdGUiLCJhcnRpY2xlc1Byb21wdFJlc3VsdCIsImxvZyIsImxlbmd0aCIsImV4dHJhY3RBbGluZWFzIiwibWFwIiwibnVtZXJvQXJ0aWNsZSIsImFsaW5lYXNTeXN0ZW1UZW1wbGF0ZSIsImFsaW5lYXNQcm9tcHRSZXN1bHQiLCJzb21tYWlyZVN5c3RlbVRlbXBsYXRlIiwic29tbWFpcmVQcm9tcHRSZXN1bHQiLCJpdGVtIiwic2VxdWVuY2UiLCJ0eXBlRGl2aXNpb24iLCJwYXJlbnQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFyc2Vycy90ZXh0ZXNfbG9pcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGF0T3BlbkFJIH0gZnJvbSBcIkBsYW5nY2hhaW4vb3BlbmFpXCJcbmltcG9ydCB7IENoYXRQcm9tcHRUZW1wbGF0ZSB9IGZyb20gXCJAbGFuZ2NoYWluL2NvcmUvcHJvbXB0c1wiXG5pbXBvcnQgQWp2IGZyb20gXCJhanZcIlxuXG5pbXBvcnQgeyBkZWxpbWl0ZXIsIHJ1bkxvZ0Z1biB9IGZyb20gXCIuLi9sb2dnZXJcIlxuXG5jb25zdCBFWFBPU0VfTU9USUZTX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9FeHBvc2VNb3RpZnNcIilcbmNvbnN0IE1FVEFfRE9OTkVFU19TQ0hFTUEgPSByZXF1aXJlKFwiLi4vc2NoZW1hcy90ZXh0ZV9sb2kvTWV0YURvbm5lZXNcIilcbmNvbnN0IFBST0pFVF9MT0lfU0NIRU1BID0gcmVxdWlyZShcIi4uL3NjaGVtYXMvdGV4dGVfbG9pL1Byb2pldExvaVwiKVxuY29uc3QgQUxJTkVBX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9BbGluZWFcIilcbmNvbnN0IFNPTU1BSVJFX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9Tb21tYWlyZVwiKVxuXG4vKipcbiAqIE9iamVjdCBjb250YWluaW5nIGlucHV0IGV4YW1wbGVzIGFuZCB0aGVpciBvdXRwdXQgc2NoZW1hcy5cbiAqIFVzZWQgdG8gdHJhaW4gdGhlIExMTS5cbiAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB7bW90aWZzOiBhbnksIGlucHV0OiBhbnksIGxvaTogYW55LCBtZXRhOiBhbnksIHNvbW1haXJlOiBhbnl9Pn1cbiAqL1xuY29uc3QgRVhBTVBMRVMgPSB7XG4gIFBSSkxBTlI1TDE2QjA5MTQ6IHtcbiAgICBtb3RpZnM6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIwOTE0L21vdGlmc1wiKSxcbiAgICBpbnB1dDogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjA5MTQvaW5wdXRcIiksXG4gICAgbG9pOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMDkxNC9sb2lcIiksXG4gICAgbWV0YTogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjA5MTQvbWV0YVwiKSxcbiAgICBzb21tYWlyZTogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjA5MTQvc29tbWFpcmVcIiksXG4gIH0sXG4gIFBSSkxBTlI1TDE2QjIwMTQ6IHtcbiAgICBtb3RpZnM6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyMDE0L21vdGlmc1wiKSxcbiAgICBpbnB1dDogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjIwMTQvaW5wdXRcIiksXG4gICAgbG9pOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjAxNC9sb2lcIiksXG4gICAgbWV0YTogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjIwMTQvbWV0YVwiKSxcbiAgICBzb21tYWlyZTogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjIwMTQvc29tbWFpcmVcIiksXG4gIH0sXG4gIFBSSkxBTlI1TDE2QjI0MjQ6IHtcbiAgICBhbGluZWFzOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjQyNC9hbGluZWFzXCIpLFxuICAgIG1vdGlmczogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjI0MjQvbW90aWZzXCIpLFxuICAgIGlucHV0OiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjQyNC9pbnB1dFwiKSxcbiAgICBsb2k6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L2xvaVwiKSxcbiAgICBtZXRhOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjQyNC9tZXRhXCIpLFxuICAgIHNvbW1haXJlOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjQyNC9zb21tYWlyZVwiKSxcbiAgfSxcbn1cblxuY29uc3QgRlVMTF9URVhURV9TQ0hFTUEgPSB7XG4gICRzY2hlbWE6IFwiaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjXCIsXG4gIHRpdGxlOiBcIlNvbW1haXJlXCIsXG4gIGRlc2NyaXB0aW9uOiBcIlLDqWN1cMOpcmF0aW9uIGQndW4gdGV4dGUgY29tcGxldFwiLFxuICB0eXBlOiBcIm9iamVjdFwiLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgdGV4dGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlRleHRlIGNvbXBsZXQgZGUgbGEgc2VjdGlvbiBpbmRpcXXDqWUuXCIsXG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgIH0sXG4gIH0sXG4gIHJlcXVpcmVkOiBbXCJ0ZXh0ZVwiXSxcbn1cblxuLyoqXG4gKiBMTE0gbW9kZWwuXG4gKi9cbmxldCBNT0RFTDogYW55ID0gbnVsbFxuXG5pZiAocHJvY2Vzcy5lbnYuT1BFTkFJX0FQSV9LRVkpIHtcbiAgTU9ERUwgPSBuZXcgQ2hhdE9wZW5BSSh7XG4gICAgdGVtcGVyYXR1cmU6IDAsXG4gICAgdG9wUDogMC4wLFxuICAgIG1vZGVsOiBcImdwdC00by1taW5pXCIsXG4gICAgYXBpS2V5OiBwcm9jZXNzLmVudi5PUEVOQUlfQVBJX0tFWSxcbiAgICBtYXhUb2tlbnM6IC0xLFxuICB9KVxufVxuXG4vKipcbiAqIFN5c3RlbSBpbnB1dCB0ZW1wbGF0ZSBmb3IgdGhlIExMTS5cbiAqL1xuY29uc3QgU1lTVEVNX1RFTVBMQVRFOiBzdHJpbmcgPSBgXG4gICMgSW5zdHJ1Y3Rpb25zIDpcbiAgXG4gIFR1IGVzIHVuIGV4cGVydCBkZSBsYSBsb2kgZXQgZGUgbCdhbmFseXNlIGRlIHBhZ2VzIEhUTUwuXG4gIFR1IGRvaXMgYW5hbHlzZXIgdW4gdGV4dGUgZGUgbG9pIGFmaW4gZGUgc8OpcGFyZXIgZXQgZGUgc3RydWN0dXJlciBsZXMgw6lsw6ltZW50cyBxdWkgbGUgY29tcG9zZW50LiBMZSBmb3JtYXQgZCdlbnRyw6llIGVzdCBIVE1MLlxuXG4gIExlIHRleHRlIGVzdCBkaXZpc8OpIGVuIGRldXggcGFydGllcyA6XG4gIEEpIHVuIGV4cG9zw6kgZGVzIG1vdGlmcyBxdWkgaW5kaXF1ZSBsZXMgcmFpc29ucyBwb3VyIGxlc3F1ZWxsZXMgY2UgcHJvamV0IGVzdCBzb3VtaXMgYXUgUGFybGVtZW50LiBJbCBwZXV0IGNvbnRlbmlyIDMgw6lsw6ltZW50cyA6IDEpIHVuZSBjaXRhdGlvbiBhdSBkw6lidXQgZCd1biBkb2N1bWVudCwgMikgbGUgdGV4dGUgcHJpbmNpcGFsIHF1aSBkw6l2ZWxvcHBlIGxlcyBhcmd1bWVudHMgZGUgbCdhdXRldXIgw6AgbCdhcHB1aSBkZSBsYSBtb2RpZmljYXRpb24gbMOpZ2lzbGF0aXZlIG91IGRlcyBkaXNwb3NpdGlvbnMgbm91dmVsbGVzIHF1J2lsIHByb3Bvc2UsIDMpIGRlcyBwYXJhZ3JhcGhlcyBxdWkgcHLDqXNlbnRlbnQgbGVzIGFydGljbGVzLlxuICBCKSBsZSBkaXNwb3NpdGlmIHF1aSBlc3QgbGEgcGFydGllIG5vcm1hdGl2ZSBldCByw6lkaWfDqWUgZW4gYXJ0aWNsZXMuIElsIHBldXQgY29tcG9ydGVyIGRlcyBkaXZpc2lvbnMgbm9tbcOpZXMgdGl0cmVzLCBjaGFwaXRyZXMsIHNlY3Rpb25zLCBzb3VzLXNlY3Rpb25zLiBMb3JzcXUnaWwgeSBhIHVuIHNldWwgbml2ZWF1IGRlIHN0cnVjdHVyZSwgb24gcmV0cm91dmVyYSBsZSBjaGFwaXRyZSA7IHPigJlpbCB5IGEgZGV1eCBuaXZlYXV4IGRlIHN0cnVjdHVyZSwgb24gcmV0cm91dmVyYSBkZXMgY2hhcGl0cmVzIHB1aXMgZGVzIHNlY3Rpb25zLiBT4oCZaWwgeSBhIHRyb2lzIG5pdmVhdXggZGUgc3RydWN0dXJlLCBvbiByZXRyb3V2ZXJhIGRlcyB0aXRyZXMgcHVpcyBkZXMgY2hhcGl0cmVzIHB1aXMgZGVzIHNlY3Rpb25zLlxuXG4gIFNpIGxlIHRleHRlIGRlIGxvaSBuZSBjb21wb3J0ZSBwYXMgZGUgZGl2aXNpb24sIGxlIHNvbW1haXJlIGRvaXQgcmVzdGVyIHZpZGUuXG4gIFRvdXRlcyBsZXMgbGlnbmVzIHF1aSBkw6lidXRlbnQgcGFyIHVuICfCqycgbmUgc29udCBwYXMgw6AgcHJlbmRyZSBlbiBjb21wdGUgZGFucyBsZXMgZGl2aXNpb25zXG4gIFRhIHLDqXBvbnNlIGRvaXQgw6p0cmUgdW4gSlNPTiBzdHJ1Y3R1csOpIGF2ZWMgbGVzIMOpbMOpbWVudHMgZHUgdGV4dGUgZGUgbG9pIGVuIHJlc3BlY3RhbnQgbGUgc2Now6ltYSBKU09OIGZvdXJuaS5cbmBcblxubGV0IFNJTEVOVF9MT0cgPSBmYWxzZVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgZ2l2ZW4gSFRNTCBzdHJpbmcgYW5kIHJldHVybnMgdGhlIHBhcnNlZCB0ZXh0ZXMgbG9pLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIHRvIHBhcnNlLlxuICogQHJldHVybiB7UHJvbWlzZTx7cGFydGlhbDoge3NvbW1haXJlOiBhbnksIGxvaTogYW55LCBtb3RpZnM6IGFueSwgbWV0YTogYW55fSwgY29tcGxldGVkOiB7c29tbWFpcmU6IGFueSwgbG9pOiBhbnksIG1vdGlmczogYW55LCBtZXRhOiBhbnl9fT59IC0gVGhlIHBhcnNlZCB0ZXh0ZXMgbG9pLCBpbmNsdWRpbmcgdGhlIHBhcnRpYWwgYW5kIGNvbXBsZXRlZCB2ZXJzaW9ucy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBhcnNlVGV4dGVMb2koaHRtbDogc3RyaW5nLCBvcHRpb25zID0geyBzaWxlbnQ6IGZhbHNlIH0pIHtcbiAgU0lMRU5UX0xPRyA9IG9wdGlvbnMuc2lsZW50XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlN0YXJ0IGV4dHJhY3RpbmcgbG9pLi4uXCIpLCBvcHRpb25zKVxuICBjb25zdCBtZXRhID0gYXdhaXQgZXh0cmFjdE1ldGFEb25uZWVzKGh0bWwpXG4gIGNvbnN0IHNvbW1haXJlID0gYXdhaXQgZXh0cmFjdFNvbW1haXJlKGh0bWwpXG4gIGNvbnN0IHBhcnRpYWxNb3RpZnM6IGFueSA9IGF3YWl0IGV4dHJhY3RNb3RpZnMoaHRtbClcbiAgY29uc3QgcGFydGlhbExvaTogYW55ID0gYXdhaXQgZXh0cmFjdFByb2pldExvaShodG1sKVxuICBjb25zdCBleHBvc2VNb3RpZnMgPSBhd2FpdCBwb3B1bGF0ZU1vdGlmcyhwYXJ0aWFsTW90aWZzLCBodG1sKVxuICBjb25zdCBsb2kgPSBhd2FpdCBwb3B1bGF0ZVByb2pldExvaShwYXJ0aWFsTG9pLCBodG1sKVxuXG4gIHJldHVybiB7XG4gICAgc29tbWFpcmUsXG4gICAgbG9pLFxuICAgIGV4cG9zZU1vdGlmcyxcbiAgICBtZXRhLFxuICB9XG59XG5cbi8qKlxuICogQ2xlYW5zIHRoZSBnaXZlbiBIVE1MIHN0cmluZyBieSByZW1vdmluZyB1bm5lY2Vzc2FyeSB0YWdzIGFuZCBjb250ZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIHRvIGJlIGNsZWFuZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBjbGVhbmVkIEhUTUwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBjbGVhbkh0bWwoaHRtbDogc3RyaW5nKSB7XG4gIGxldCBjbGVhbmVkSHRtbCA9IGh0bWwucmVwbGFjZSgvKDxzdHlsZVtcXHdcXFddK3N0eWxlPikvZywgXCJcIilcbiAgY2xlYW5lZEh0bWwgPSBjbGVhbmVkSHRtbC5yZXBsYWNlKC8oPGhlYWRbXFx3XFxXXStoZWFkPikvZywgXCJcIilcbiAgY2xlYW5lZEh0bWwgPSBjbGVhbmVkSHRtbC5yZXBsYWNlKC88aW1nW14+XSo+L2csIFwiXCIpXG5cbiAgcmV0dXJuIGNsZWFuZWRIdG1sXG59XG5cbi8qKlxuICogUmVtb3ZlcyBhbGwgSFRNTCB0YWdzIGZyb20gdGhlIGdpdmVuIEhUTUwgc3RyaW5nIGFuZCByZXR1cm5zIHRoZSBjbGVhbmVkIHRleHQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGh0bWwgLSBUaGUgSFRNTCBzdHJpbmcgZnJvbSB3aGljaCB0byByZW1vdmUgdGFncy5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNsZWFuZWQgdGV4dCB3aXRob3V0IGFueSBIVE1MIHRhZ3MuXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUh0bWxUYWdzKGh0bWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIFJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCBIVE1MIHRhZ3NcbiAgY29uc3QgaHRtbFRhZ1JlZ2V4ID0gLzxbXj5dKj4vZ1xuXG4gIC8vIFJlcGxhY2UgYWxsIEhUTUwgdGFncyB3aXRoIGFuIGVtcHR5IHN0cmluZ1xuICBjb25zdCB0ZXh0V2l0aG91dFRhZ3MgPSBodG1sLnJlcGxhY2UoaHRtbFRhZ1JlZ2V4LCBcIlwiKVxuICByZXR1cm4gdGV4dFdpdGhvdXRUYWdzXG59XG5cbi8qKlxuICogUG9wdWxhdGVzIHRoZSBtb3RpZnMgb2JqZWN0IHdpdGggdGhlIGV4dHJhY3RlZCB0ZXh0IGZyb20gdGhlIGdpdmVuIEhUTUwuXG4gKlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb3RpZnMgLSBUaGUgbW90aWZzIG9iamVjdCB0byBiZSBwb3B1bGF0ZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIHRleHQuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIFRoZSBwb3B1bGF0ZWQgbW90aWZzIG9iamVjdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcG9wdWxhdGVNb3RpZnMobW90aWZzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBodG1sOiBzdHJpbmcpIHtcbiAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlBvcHVsYXRpbmcgZXhwb3NlIG1vdGlmcy4uLlwiKSlcbiAgbGV0IGNsZWFuZWRIdG1sID0gY2xlYW5IdG1sKGh0bWwpXG5cbiAgaWYgKG1vdGlmcy5kZWJ1dCA9PT0gbW90aWZzLmZpbiB8fCAhbW90aWZzLmZpbikge1xuICAgIG1vdGlmcy50ZXh0ZSA9IG1vdGlmcy5kZWJ1dFxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHN5c3RlbVRlbXBsYXRlID0gYFxuICAgICAgIyBJbnN0cnVjdGlvbnMgOlxuXG4gICAgICBUdSBlcyB1biBleHBlcnQgZGUgbGEgbG9pIGV0IGRlIGwnYW5hbHlzZSBkZSBwYWdlcyBIVE1MLlxuICAgICAgVHUgZG9pcyBhbmFseXNlciB1biB0ZXh0ZSBkZSBsb2kgYWZpbiBkJ2VuIGV4dHJhaXJlIGNlcnRhaW5lcyBwYXJ0aWVzLiBcbiAgICAgIExlIGZvcm1hdCBkJ2VudHLDqWUgZXN0IGR1IEhUTUwuIExlIGZvcm1hdCBkZSBzb3J0aWUgZXN0IGR1IHRleHRlLlxuICAgICAgUsOpY3Vww6hyZSBsJ2ludMOpZ3JhbGl0w6kgZHUgdGV4dGUgY29tbWVuw6dhbnQgcGFyIDpcblxuICAgICAgXCJcIlwiXG4gICAgICB7ZGVidXR9XG4gICAgICBcIlwiXCJcblxuICAgICAgRXQgZmluaXNzYW50IHBhciA6XG5cbiAgICAgIFwiXCJcIlxuICAgICAge2Zpbn1cbiAgICAgIFwiXCJcIlxuICAgIGBcblxuICAgIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgICAgW1wic3lzdGVtXCIsIHN5c3RlbVRlbXBsYXRlXSxcbiAgICAgIFtcImh1bWFuXCIsIFwie2lucHV0fVwiXSxcbiAgICBdKVxuXG4gICAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoRlVMTF9URVhURV9TQ0hFTUEpXG4gICAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG5cbiAgICBjb25zdCBhcnRpY2xlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgICAgaW5wdXQ6IGNsZWFuZWRIdG1sLFxuICAgICAgZGVidXQ6IG1vdGlmcy5kZWJ1dCxcbiAgICAgIGZpbjogbW90aWZzLmZpbixcbiAgICB9KVxuXG4gICAgbW90aWZzLnRleHRlID0gYXJ0aWNsZVByb21wdFJlc3VsdC50ZXh0ZVxuICB9XG5cbiAgcnVuTG9nRnVuKFxuICAgIGNvbnNvbGUuaW5mbyhcIk9ww6lyYXRpb24gZGUgcGV1cGxlbWVudCBkZSBsJ2V4cG9zw6kgZGVzIG1vdGlmcyB0ZXJtaW7DqWUg4pyFXCIpLFxuICAgIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0sXG4gIClcbiAgZGVsaW1pdGVyKFNJTEVOVF9MT0cpXG5cbiAgZGVsZXRlIG1vdGlmcy5kZWJ1dFxuICBkZWxldGUgbW90aWZzLmZpblxuICByZXR1cm4gbW90aWZzXG59XG5cbi8qKlxuICogQXN5bmNocm9ub3VzbHkgcG9wdWxhdGVzIGEgcHJvamV0IGxvaSBvYmplY3Qgd2l0aCB0aGUgZnVsbCB0ZXh0IG9mIGVhY2ggYXJ0aWNsZSBhbmQgYWxpbmVhIGluIHRoZSBnaXZlbiBIVE1MLlxuICpcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gcGFydGlhbCAtIFRoZSBwYXJ0aWFsIHByb2pldCBsb2kgb2JqZWN0IHRvIGJlIHBvcHVsYXRlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgY29udGFpbmluZyB0aGUgdGV4dCBvZiB0aGUgYXJ0aWNsZXMgYW5kIGFsaW5lYXMuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZnVsbHkgcG9wdWxhdGVkIHByb2pldCBsb2kgb2JqZWN0LlxuICovXG5hc3luYyBmdW5jdGlvbiBwb3B1bGF0ZVByb2pldExvaShwYXJ0aWFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBodG1sOiBzdHJpbmcpIHtcbiAgcnVuTG9nRnVuKGNvbnNvbGUuZ3JvdXAoXCJQZXVwbGVtZW50IGR1IHByb2pldCBsb2kuLi5cIiksIHtcbiAgICBzaWxlbnQ6IFNJTEVOVF9MT0csXG4gIH0pXG4gIGxldCBjbGVhbmVkSHRtbCA9IGNsZWFuSHRtbChodG1sKVxuXG4gIGNvbnN0IGFydGljbGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10gPSBwYXJ0aWFsLmFydGljbGVzXG4gIGNvbnN0IGZ1bGxBcnRpY2xlczogUmVjb3JkPHN0cmluZywgYW55PltdID0gW11cblxuICBjb25zdCBzeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAjIEluc3RydWN0aW9ucyA6XG5cbiAgICBUdSBlcyB1biBleHBlcnQgZGUgbGEgbG9pIGV0IGRlIGwnYW5hbHlzZSBkZSBwYWdlcyBIVE1MLlxuICAgIFR1IGRvaXMgYW5hbHlzZXIgdW4gdGV4dGUgZGUgbG9pIGFmaW4gZCdlbiBleHRyYWlyZSBjZXJ0YWluZXMgcGFydGllcy4gXG4gICAgTGUgZm9ybWF0IGQnZW50csOpZSBlc3QgZHUgSFRNTC4gTGUgZm9ybWF0IGRlIHNvcnRpZSBlc3QgZHUgdGV4dGUuXG4gICAgUsOpY3Vww6hyZSBsJ2ludMOpZ3JhbGl0w6kgZHUgdGV4dGUgY29tbWVuw6dhbnQgcGFyIDpcblxuICAgIFwiXCJcIlxuICAgIHtkZWJ1dH1cbiAgICBcIlwiXCJcblxuICAgIEV0IGZpbmlzc2FudCBwYXIgOlxuXG4gICAgXCJcIlwiXG4gICAge2Zpbn1cbiAgICBcIlwiXCJcbiAgYFxuXG4gIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgIFtcInN5c3RlbVwiLCBzeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IHN0cnVjdHVyZWRNb2RlbCA9IE1PREVMLndpdGhTdHJ1Y3R1cmVkT3V0cHV0KEZVTExfVEVYVEVfU0NIRU1BKVxuICBjb25zdCBjaGFpbiA9IHByb21wdC5waXBlKHN0cnVjdHVyZWRNb2RlbClcblxuICBmb3IgKGNvbnN0IGFydGljbGUgb2YgYXJ0aWNsZXMpIHtcbiAgICBpZiAoYXJ0aWNsZS5kZWJ1dCA9PT0gYXJ0aWNsZS5maW4gfHwgIWFydGljbGUuZmluKSB7XG4gICAgICBhcnRpY2xlLnRleHRlID0gYXJ0aWNsZS5kZWJ1dFxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBhcnRpY2xlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgICAgICBpbnB1dDogY2xlYW5lZEh0bWwsXG4gICAgICAgIGRlYnV0OiBhcnRpY2xlLmRlYnV0LFxuICAgICAgICBmaW46IGFydGljbGUuZmluLFxuICAgICAgfSlcblxuICAgICAgYXJ0aWNsZS50ZXh0ZSA9IGFydGljbGVQcm9tcHRSZXN1bHQudGV4dGVcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGFsaW5lYSBvZiBhcnRpY2xlLmFsaW5lYXMpIHtcbiAgICAgIGlmIChhbGluZWEuZGVidXQgPT09IGFsaW5lYS5maW4gfHwgIWFsaW5lYS5maW4pIHtcbiAgICAgICAgYWxpbmVhLnRleHRlID0gYWxpbmVhLmRlYnV0XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFsaW5lYVByb21wdFJlc3VsdDogYW55ID0gYXdhaXQgY2hhaW4uaW52b2tlKHtcbiAgICAgICAgaW5wdXQ6IGFydGljbGUudGV4dGUsXG4gICAgICAgIGRlYnV0OiBhbGluZWEuZGVidXQsXG4gICAgICAgIGZpbjogYWxpbmVhLmZpbixcbiAgICAgIH0pXG5cbiAgICAgIGRlbGV0ZSBhbGluZWEuZGVidXRcbiAgICAgIGRlbGV0ZSBhbGluZWEuZmluXG4gICAgICBhbGluZWEudGV4dGUgPSBhbGluZWFQcm9tcHRSZXN1bHQudGV4dGVcbiAgICB9XG5cbiAgICBydW5Mb2dGdW4oXG4gICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgIFwiT3DDqXJhdGlvbiBkZSBwZXVwbGVtZW50IGR1IGNvbnRlbnUgZHUgcHJvamV0IGRlIGxvaSB0ZXJtaW7DqWUg4pyFXCIsXG4gICAgICApLFxuICAgICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgICApXG4gICAgZGVsZXRlIGFydGljbGUuZGVidXRcbiAgICBkZWxldGUgYXJ0aWNsZS5maW5cbiAgICBmdWxsQXJ0aWNsZXMucHVzaChhcnRpY2xlKVxuICB9XG5cbiAgY29uc3QgcHJvamV0TG9pID0ge1xuICAgIC4uLnBhcnRpYWwsXG4gICAgYXJ0aWNsZXM6IGZ1bGxBcnRpY2xlcyxcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG4gIHJldHVybiBwcm9qZXRMb2lcbn1cblxuLyoqXG4gKiBBc3luY2hyb25vdXNseSBleHRyYWN0cyB0aGUgXCJleHBvc2UgbW90aWZzXCIgZnJvbSB0aGUgZ2l2ZW4gSFRNTC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIFwiZXhwb3NlIG1vdGlmc1wiLlxuICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gLSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZXh0cmFjdGVkIFwiZXhwb3NlIG1vdGlmc1wiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgZGVidXRgOiBUaGUgYmVnaW5uaW5nIG9mIHRoZSBcImV4cG9zZSBtb3RpZnNcIi5cbiAqIC0gYGZpbmA6IFRoZSBlbmQgb2YgdGhlIFwiZXhwb3NlIG1vdGlmc1wiLlxuICogQHRocm93cyB7RXJyb3J9IC0gSWYgdGhlIGV4dHJhY3RlZCBcImV4cG9zZSBtb3RpZnNcIiBkbyBub3QgdmFsaWRhdGUgYWdhaW5zdCB0aGUgRVhQT1NFX01PVElGU19TQ0hFTUEuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RNb3RpZnMoaHRtbDogc3RyaW5nKSB7XG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiUGFyc2luZyBleHBvc2UgbW90aWZzLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcbiAgY2xlYW5lZEh0bWwgPSByZW1vdmVIdG1sVGFncyhjbGVhbmVkSHRtbClcblxuICBjb25zdCBzdHJ1Y3R1cmVkTW9kZWwgPSBNT0RFTC53aXRoU3RydWN0dXJlZE91dHB1dChFWFBPU0VfTU9USUZTX1NDSEVNQSlcblxuICBjb25zdCBtb3RpZnNTeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAke1NZU1RFTV9URU1QTEFURX1cblxuICAgICMgRXhhbXBsZXM6IFxuXG4gICAgIyMgRXhlbXBsZSAxIFVzZXIgSW5wdXQgOlxuICAgIFwiXCJcIlxuICAgIHtleGFtcGxlMX1cbiAgICBcIlwiXCJcbiAgICBcbiAgICAjIyBFeGVtcGxlIDEgSlNPTiBPdXRwdXQgOlxuICAgIFwiXCJcIlxuICAgIHtvdXRwdXQxfVxuICAgIFwiXCJcIlxuXG4gICAgIyMgRXhlbXBsZSAyIFVzZXIgSW5wdXQgOlxuICAgIFwiXCJcIlxuICAgIHtleGFtcGxlMn1cbiAgICBcIlwiXCJcbiAgICBcbiAgICAjIyBFeGVtcGxlIDIgSlNPTiBPdXRwdXQgOlxuICAgIFwiXCJcIlxuICAgIHtvdXRwdXQyfVxuICAgIFwiXCJcIlxuICAgIGBcblxuICBjb25zdCBwcm9tcHQgPSBDaGF0UHJvbXB0VGVtcGxhdGUuZnJvbU1lc3NhZ2VzKFtcbiAgICBbXCJzeXN0ZW1cIiwgbW90aWZzU3lzdGVtVGVtcGxhdGVdLFxuICAgIFtcImh1bWFuXCIsIFwie2lucHV0fVwiXSxcbiAgXSlcblxuICBjb25zdCBjaGFpbiA9IHByb21wdC5waXBlKHN0cnVjdHVyZWRNb2RlbClcbiAgY29uc3QgbW90aWZzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMDkxNC5pbnB1dCxcbiAgICBleGFtcGxlMjogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjQyNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0Lm1vdGlmcyxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0Lm1vdGlmcyxcbiAgfSlcblxuICAvLyBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShtb3RpZnNQcm9tcHRSZXN1bHQpKVxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS50YWJsZShbXG4gICAgICBbXCJEw6lidXRcIiwgbW90aWZzUHJvbXB0UmVzdWx0LmRlYnV0LnN1YnN0cmluZygwLCAzMCldLFxuICAgICAgW1wiRmluXCIsIG1vdGlmc1Byb21wdFJlc3VsdC5maW4uc3Vic3RyaW5nKDAsIDMwKV0sXG4gICAgXSksXG4gICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgKVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoRVhQT1NFX01PVElGU19TQ0hFTUEsIG1vdGlmc1Byb21wdFJlc3VsdCkpIHtcbiAgICBydW5Mb2dGdW4oY29uc29sZS5pbmZvKFwiRXhwb3PDqSBkZXMgbW90aWZzIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgcmV0dXJuIG1vdGlmc1Byb21wdFJlc3VsdFxuICB9XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIkV4cG9zw6kgZGVzIG1vdGlmcyBLTyDinYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIHJldHVybiB7fVxufVxuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IGV4dHJhY3RzIHRoZSBtZXRhZGF0YSBmcm9tIHRoZSBnaXZlbiBIVE1MLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIGZyb20gd2hpY2ggdG8gZXh0cmFjdCB0aGUgbWV0YWRhdGEuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBleHRyYWN0ZWQgbWV0YWRhdGEgb2JqZWN0LlxuICogVGhlIG9iamVjdCBjb250YWlucyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAtIGBkb2N1bWVudFJlZmA6IFRoZSByZWZlcmVuY2Ugb2YgdGhlIGRvY3VtZW50LlxuICogLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIGRvY3VtZW50LlxuICogLSBgbnVtZXJvVGV4dGVgOiBUaGUgbnVtYmVyIG9mIHRoZSB0ZXh0LlxuICogLSBgcHJvY2VkdXJlQWNjZWxlcmVlYDogVGhlIGFjY2VsZXJhdGVkIHByb2NlZHVyZS5cbiAqIEB0aHJvd3Mge0Vycm9yfSAtIElmIHRoZSBleHRyYWN0ZWQgbWV0YWRhdGEgZG8gbm90IHZhbGlkYXRlIGFnYWluc3QgdGhlIE1FVEFfRE9OTkVFU19TQ0hFTUEuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RNZXRhRG9ubmVlcyhodG1sOiBzdHJpbmcpIHtcbiAgZGVsaW1pdGVyKClcbiAgbGV0IGNsZWFuZWRIdG1sID0gY2xlYW5IdG1sKGh0bWwpXG4gIGNsZWFuZWRIdG1sID0gcmVtb3ZlSHRtbFRhZ3MoY2xlYW5lZEh0bWwpXG5cbiAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoTUVUQV9ET05ORUVTX1NDSEVNQSlcblxuICBjb25zdCBtZXRhRG9ubmVlc1N5c3RlbVRlbXBsYXRlID0gYFxuICAgICR7U1lTVEVNX1RFTVBMQVRFfVxuICAgIGBcblxuICBjb25zdCBwcm9tcHQgPSBDaGF0UHJvbXB0VGVtcGxhdGUuZnJvbU1lc3NhZ2VzKFtcbiAgICBbXCJzeXN0ZW1cIiwgbWV0YURvbm5lZXNTeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IGNoYWluID0gcHJvbXB0LnBpcGUoc3RydWN0dXJlZE1vZGVsKVxuICBjb25zdCByZXN1bHQ6IGFueSA9IGF3YWl0IGNoYWluLmludm9rZSh7XG4gICAgaW5wdXQ6IGNsZWFuZWRIdG1sLFxuICAgIGV4YW1wbGUxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmlucHV0LFxuICAgIGV4YW1wbGUyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmlucHV0LFxuICAgIG91dHB1dDE6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjA5MTQubWV0YSxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0Lm1ldGEsXG4gIH0pXG5cbiAgY29uc29sZS5ncm91cChcIk1ldGEtZG9ubsOpZXNcIilcbiAgY29uc29sZS50YWJsZShbXG4gICAgW1wiUsOpZsOpcmVuY2VcIiwgcmVzdWx0LmRvY3VtZW50UmVmXSxcbiAgICBbXCJUaXRyZVwiLCByZXN1bHQudGl0cmVdLFxuICAgIFtcIk51bcOpcm8gZHUgdGV4dGVcIiwgcmVzdWx0Lm51bWVyb1RleHRlXSxcbiAgICBbXCJQcm9jw6lkdXJlIGFjY8OpbMOpcsOpXCIsIHJlc3VsdC5wcm9jZWR1cmVBY2NlbGVyZWVdLFxuICBdKVxuICBjb25zb2xlLmdyb3VwRW5kKClcbiAgZGVsaW1pdGVyKClcblxuICBjb25zdCBhanYgPSBuZXcgQWp2KClcbiAgaWYgKGFqdi52YWxpZGF0ZShNRVRBX0RPTk5FRVNfU0NIRU1BLCByZXN1bHQpKSB7XG4gICAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIk1ldGEtZG9ubsOpZXMgT0sg8J+RjFwiKSwgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBydW5Mb2dGdW4oY29uc29sZS53YXJuKFwiTWV0YS1kb25uw6llcyBub24tY29uZm9ybWUg4p2MXCIpLCB7XG4gICAgc2lsZW50OiBTSUxFTlRfTE9HLFxuICB9KVxuICByZXR1cm4ge31cbn1cblxuLyoqXG4gKiBBc3luY2hyb25vdXNseSBleHRyYWN0cyB0aGUgXCJwcm9qZXQgZGUgbG9pXCIgZnJvbSB0aGUgZ2l2ZW4gSFRNTC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIFwicHJvamV0IGRlIGxvaVwiLlxuICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gLSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZXh0cmFjdGVkIFwicHJvamV0IGRlIGxvaVwiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgYXJ0aWNsZXNgOiBBbiBhcnJheSBvZiBhcnRpY2xlIG9iamVjdHMsIGVhY2ggY29udGFpbmluZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAgIC0gYG51bWVyb0FydGljbGVgOiBUaGUgbnVtYmVyIG9mIHRoZSBhcnRpY2xlLlxuICogICAtIGBjYXJkaW5hbGA6IFRoZSBjYXJkaW5hbCBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIGFydGljbGUuXG4gKiAgIC0gYGRlYnV0YDogVGhlIGJlZ2lubmluZyBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgZmluYDogVGhlIGVuZCBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgYWxpbmVhc2A6IEFuIGFycmF5IG9mIGFsaW5lYXMuXG4gKiBAdGhyb3dzIHtFcnJvcn0gLSBJZiB0aGUgZXh0cmFjdGVkIFwicHJvamV0IGRlIGxvaVwiIGRvZXMgbm90IHZhbGlkYXRlIGFnYWluc3QgdGhlIFBST0pFVF9MT0lfU0NIRU1BLlxuICovXG5hc3luYyBmdW5jdGlvbiBleHRyYWN0UHJvamV0TG9pKGh0bWw6IHN0cmluZykge1xuICBydW5Mb2dGdW4oY29uc29sZS5ncm91cChcIlBhcnNpbmcgbG9pLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcbiAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoUFJPSkVUX0xPSV9TQ0hFTUEpXG5cbiAgY29uc3QgcHJvamV0TG9pU3lzdGVtVGVtcGxhdGUgPSBgXG4gICAgJHtTWVNURU1fVEVNUExBVEV9XG5cbiAgICAjIEV4YW1wbGVzOiBcblxuICAgICMjIEV4ZW1wbGUgMSBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTF9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAxIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0MX1cbiAgICBcIlwiXCJcblxuICAgICMjIEV4ZW1wbGUgMiBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTJ9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAyIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0Mn1cbiAgICBcIlwiXCJcbiAgICBgXG5cbiAgY29uc3QgcHJvbXB0ID0gQ2hhdFByb21wdFRlbXBsYXRlLmZyb21NZXNzYWdlcyhbXG4gICAgW1wic3lzdGVtXCIsIHByb2pldExvaVN5c3RlbVRlbXBsYXRlXSxcbiAgICBbXCJodW1hblwiLCBcIntpbnB1dH1cIl0sXG4gIF0pXG5cbiAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG4gIGNvbnN0IGFydGljbGVzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMDkxNC5pbnB1dCxcbiAgICBleGFtcGxlMjogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjQyNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmxvaSxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmxvaSxcbiAgfSlcblxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS5sb2coXCJGb3VuZCBcIiwgYXJ0aWNsZXNQcm9tcHRSZXN1bHQuYXJ0aWNsZXMubGVuZ3RoLCBcIiBhcnRpY2xlcy5cIiksXG4gICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgKVxuXG4gIGZvciAoY29uc3QgYXJ0aWNsZSBvZiBhcnRpY2xlc1Byb21wdFJlc3VsdC5hcnRpY2xlcykge1xuICAgIGFydGljbGUuYWxpbmVhcyA9IGF3YWl0IGV4dHJhY3RBbGluZWFzKGh0bWwsIGFydGljbGUpXG4gIH1cblxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS50YWJsZShcbiAgICAgIGFydGljbGVzUHJvbXB0UmVzdWx0LmFydGljbGVzLm1hcCgoYXJ0aWNsZTogYW55KSA9PiBbXG4gICAgICAgIGFydGljbGUubnVtZXJvQXJ0aWNsZSxcbiAgICAgICAgYXJ0aWNsZS50aXRyZSxcbiAgICAgICAgYXJ0aWNsZS5kZWJ1dC5zdWJzdHJpbmcoMCwgMTApLFxuICAgICAgICBhcnRpY2xlLmZpbi5zdWJzdHJpbmcoMCwgMTApLFxuICAgICAgICBgTm9tYnJlIGQnYWxpbmVhcyA6ICR7YXJ0aWNsZS5hbGluZWFzLmxlbmd0aH1gLFxuICAgICAgXSksXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoUFJPSkVUX0xPSV9TQ0hFTUEsIGFydGljbGVzUHJvbXB0UmVzdWx0KSkge1xuICAgIHJ1bkxvZ0Z1bihjb25zb2xlLmluZm8oXCJQcm9qZXQgZGUgbG9pIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgZGVsaW1pdGVyKClcbiAgICByZXR1cm4gYXJ0aWNsZXNQcm9tcHRSZXN1bHRcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJQcm9qZXQgZGUgbG9pIEtPIOKdjFwiKSwgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSlcbiAgZGVsaW1pdGVyKClcbiAgcmV0dXJuIHt9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RBbGluZWFzKGh0bWw6IHN0cmluZywgYXJ0aWNsZTogYW55KSB7XG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiUGFyc2luZyBhbGluZWFzLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcblxuICBjb25zdCBzdHJ1Y3R1cmVkTW9kZWwgPSBNT0RFTC53aXRoU3RydWN0dXJlZE91dHB1dChBTElORUFfU0NIRU1BKVxuXG4gIGNvbnN0IGFsaW5lYXNTeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAke1NZU1RFTV9URU1QTEFURX1cblxuICAgIEV4dHJhaXMgdG91cyBsZXMgYWxpbmVhcyBkZSBsYSBwb3J0aW9uIGRlIHRleHRlIGNvbW1lbsOnYW50IHBhciDCqyB7ZGVidXR9IMK7IGV0IGZpbmlzc2FudCBwYXIgwqsge2Zpbn0gwrsuXG4gICAgVW4gYWxpbsOpYSBjb250aWVubmVudCB0b3Vqb3VycyB1bmUgYmFsaXNlIMKrIDxpbWcgwrsuXG5cbiAgICAjIEV4YW1wbGVzOiBcblxuICAgICMjIEV4ZW1wbGUgMSBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTF9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAxIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0MX1cbiAgICBcIlwiXCJcbiAgICBgXG5cbiAgY29uc3QgcHJvbXB0ID0gQ2hhdFByb21wdFRlbXBsYXRlLmZyb21NZXNzYWdlcyhbXG4gICAgW1wic3lzdGVtXCIsIGFsaW5lYXNTeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IGNoYWluID0gcHJvbXB0LnBpcGUoc3RydWN0dXJlZE1vZGVsKVxuICBjb25zdCBhbGluZWFzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBkZWJ1dDogYXJ0aWNsZS5kZWJ1dCxcbiAgICBmaW46IGFydGljbGUuZmluLFxuICAgIGV4YW1wbGUxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmlucHV0LFxuICAgIG91dHB1dDE6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjI0MjQuYWxpbmVhcyxcbiAgfSlcblxuICBjb25zdCBhanYgPSBuZXcgQWp2KClcbiAgaWYgKGFqdi52YWxpZGF0ZShBTElORUFfU0NIRU1BLCBhbGluZWFzUHJvbXB0UmVzdWx0IGFzIGFueSkpIHtcbiAgICBydW5Mb2dGdW4oXG4gICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgIFwiRm91bmQgXCIsXG4gICAgICAgIGFsaW5lYXNQcm9tcHRSZXN1bHQuYWxpbmVhcy5sZW5ndGgsXG4gICAgICAgIFwiIGFsaW5lYXMgZm9yIEFydGljbGUgXCIsXG4gICAgICAgIGFydGljbGUubnVtZXJvQXJ0aWNsZSxcbiAgICAgICAgYXJ0aWNsZS50aXRyZSxcbiAgICAgICksXG4gICAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICAgIClcbiAgICBydW5Mb2dGdW4oY29uc29sZS5ncm91cEVuZCgpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICAgIGRlbGltaXRlcigpXG4gICAgcmV0dXJuIGFsaW5lYXNQcm9tcHRSZXN1bHQuYWxpbmVhc1xuICB9XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIkFsaW5lYXMgS09cIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG4gIHJldHVybiB7fVxufVxuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IGV4dHJhY3RzIHRoZSBcInNvbW1haXJlXCIgKG91dGxpbmUpIGZyb20gdGhlIGdpdmVuIEhUTUwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGh0bWwgLSBUaGUgSFRNTCBzdHJpbmcgZnJvbSB3aGljaCB0byBleHRyYWN0IHRoZSBcInNvbW1haXJlXCIuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBleHRyYWN0ZWQgXCJzb21tYWlyZVwiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgc29tbWFpcmVgOiBBbiBhcnJheSBvZiBtYWluIGRpdmlzaW9uIG9iamVjdHMsIGVhY2ggY29udGFpbmluZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAgIC0gYG51bWVyb0RpdmlzaW9uYDogVGhlIG51bWJlciBvZiB0aGUgbWFpbiBkaXZpc2lvbi5cbiAqICAgLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIG1haW4gZGl2aXNpb24uXG4gKiAgIC0gYHR5cGVEaXZpc2lvbmA6IFRoZSB0eXBlIG9mIGNvbnRlbnQgaW4gdGhlIG1haW4gZGl2aXNpb24uXG4gKiAgIC0gYHNlcXVlbmNlYDogVGhlIHNlcXVlbmNlIG9mIHRoZSBtYWluIGRpdmlzaW9uLlxuICogICAtIGBwYXJlbnRgOiBUaGUgcGFyZW50IG9mIHRoZSBtYWluIGRpdmlzaW9uLlxuICogQHRocm93cyB7RXJyb3J9IC0gSWYgdGhlIGV4dHJhY3RlZCBcInNvbW1haXJlXCIgZG9lcyBub3QgdmFsaWRhdGUgYWdhaW5zdCB0aGUgU09NTUFJUkVfU0NIRU1BLlxuICovXG5hc3luYyBmdW5jdGlvbiBleHRyYWN0U29tbWFpcmUoaHRtbDogc3RyaW5nKSB7XG4gIGxldCBjbGVhbmVkSHRtbCA9IGNsZWFuSHRtbChodG1sKVxuICBjbGVhbmVkSHRtbCA9IHJlbW92ZUh0bWxUYWdzKGNsZWFuZWRIdG1sKVxuXG4gIGNvbnN0IHN0cnVjdHVyZWRNb2RlbCA9IE1PREVMLndpdGhTdHJ1Y3R1cmVkT3V0cHV0KFNPTU1BSVJFX1NDSEVNQSlcblxuICBjb25zdCBzb21tYWlyZVN5c3RlbVRlbXBsYXRlID0gYFxuICAgICR7U1lTVEVNX1RFTVBMQVRFfVxuXG4gICAgIyBFeGFtcGxlczogXG5cbiAgICAjIyBFeGVtcGxlIDEgVXNlciBJbnB1dCA6XG4gICAgXCJcIlwiXG4gICAge2V4YW1wbGUxfVxuICAgIFwiXCJcIlxuICAgIFxuICAgICMjIEV4ZW1wbGUgMSBKU09OIE91dHB1dCA6XG4gICAgXCJcIlwiXG4gICAge291dHB1dDF9XG4gICAgXCJcIlwiXG5cbiAgICAjIyBFeGVtcGxlIDIgVXNlciBJbnB1dCA6XG4gICAgXCJcIlwiXG4gICAge2V4YW1wbGUyfVxuICAgIFwiXCJcIlxuICAgIFxuICAgICMjIEV4ZW1wbGUgMiBKU09OIE91dHB1dCA6XG4gICAgXCJcIlwiXG4gICAge291dHB1dDJ9XG4gICAgXCJcIlwiXG4gICAgYFxuXG4gIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgIFtcInN5c3RlbVwiLCBzb21tYWlyZVN5c3RlbVRlbXBsYXRlXSxcbiAgICBbXCJodW1hblwiLCBcIntpbnB1dH1cIl0sXG4gIF0pXG5cbiAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG4gIGNvbnN0IHNvbW1haXJlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjAxNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyMDE0LnNvbW1haXJlLFxuICAgIGV4YW1wbGUyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmlucHV0LFxuICAgIG91dHB1dDI6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjA5MTQuc29tbWFpcmUsXG4gIH0pXG5cbiAgaWYgKCFzb21tYWlyZVByb21wdFJlc3VsdC5zb21tYWlyZSkge1xuICAgIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJBdWN1biBzb21tYWlyZSBuJ2Egw6l0w6kgdHJvdXbDqSDinZNcIiksIHtcbiAgICAgIHNpbGVudDogU0lMRU5UX0xPRyxcbiAgICB9KVxuICAgIGRlbGltaXRlcigpXG4gICAgcmV0dXJuIHsgc29tbWFpcmU6IFtdIH1cbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiU29tbWFpcmVcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIHJ1bkxvZ0Z1bihcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIFwiRm91bmQgXCIsXG4gICAgICBzb21tYWlyZVByb21wdFJlc3VsdC5zb21tYWlyZS5sZW5ndGgsXG4gICAgICBcIiBtYWluIGRpdmlzaW9ucyAobGV2ZWwgMSkuXCIsXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihcbiAgICBjb25zb2xlLnRhYmxlKFxuICAgICAgc29tbWFpcmVQcm9tcHRSZXN1bHQuc29tbWFpcmUubWFwKChpdGVtOiBhbnkpID0+IFtcbiAgICAgICAgaXRlbS5zZXF1ZW5jZSxcbiAgICAgICAgaXRlbS50aXRyZSxcbiAgICAgICAgaXRlbS50eXBlRGl2aXNpb24sXG4gICAgICAgIGl0ZW0ucGFyZW50LFxuICAgICAgXSksXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoU09NTUFJUkVfU0NIRU1BLCBzb21tYWlyZVByb21wdFJlc3VsdCBhcyBhbnkpKSB7XG4gICAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlNvbW1haXJlIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgZGVsaW1pdGVyKClcbiAgICByZXR1cm4gc29tbWFpcmVQcm9tcHRSZXN1bHQuc29tbWFpcmVcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJMYSBjb25zdHJ1Y3Rpb24gZHUgc29tbWFpcmUgZXN0IEtPIOKdjFwiKSwge1xuICAgIHNpbGVudDogU0lMRU5UX0xPRyxcbiAgfSlcbiAgZGVsaW1pdGVyKClcbiAgcmV0dXJuIHsgc29tbWFpcmU6IFtdIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsVUFBVSxRQUFRLG1CQUFtQjtBQUM5QyxTQUFTQyxrQkFBa0IsUUFBUSx5QkFBeUI7QUFDNUQsT0FBT0MsR0FBRyxNQUFNLEtBQUs7QUFBQSxTQUVaQyxTQUFTLEVBQUVDLFNBQVM7QUFFN0IsTUFBTUMsb0JBQW9CLEdBQUdDLE9BQU8sQ0FBQyxtQ0FBbUMsQ0FBQztBQUN6RSxNQUFNQyxtQkFBbUIsR0FBR0QsT0FBTyxDQUFDLGtDQUFrQyxDQUFDO0FBQ3ZFLE1BQU1FLGlCQUFpQixHQUFHRixPQUFPLENBQUMsZ0NBQWdDLENBQUM7QUFDbkUsTUFBTUcsYUFBYSxHQUFHSCxPQUFPLENBQUMsNkJBQTZCLENBQUM7QUFDNUQsTUFBTUksZUFBZSxHQUFHSixPQUFPLENBQUMsK0JBQStCLENBQUM7O0FBRWhFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNSyxRQUFRLEdBQUc7RUFDZkMsZ0JBQWdCLEVBQUU7SUFDaEJDLE1BQU0sRUFBRVAsT0FBTyxDQUFDLHFDQUFxQyxDQUFDO0lBQ3REUSxLQUFLLEVBQUVSLE9BQU8sQ0FBQyxvQ0FBb0MsQ0FBQztJQUNwRFMsR0FBRyxFQUFFVCxPQUFPLENBQUMsa0NBQWtDLENBQUM7SUFDaERVLElBQUksRUFBRVYsT0FBTyxDQUFDLG1DQUFtQyxDQUFDO0lBQ2xEVyxRQUFRLEVBQUVYLE9BQU8sQ0FBQyx1Q0FBdUM7RUFDM0QsQ0FBQztFQUNEWSxnQkFBZ0IsRUFBRTtJQUNoQkwsTUFBTSxFQUFFUCxPQUFPLENBQUMscUNBQXFDLENBQUM7SUFDdERRLEtBQUssRUFBRVIsT0FBTyxDQUFDLG9DQUFvQyxDQUFDO0lBQ3BEUyxHQUFHLEVBQUVULE9B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QUFFO01BQ3pEakQsTUFBTSxFQUFFSjtJQUNWLENBQUMsQ0FBQztJQUNGcEMsU0FBUyxDQUFDLENBQUM7SUFDWCxPQUFPO01BQUVjLFFBQVEsRUFBRTtJQUFHLENBQUM7RUFDekI7RUFFQWIsU0FBUyxDQUFDd0MsT0FBTyxDQUFDNkIsS0FBSyxDQUFDLFVBQVUsQ0FBQyxFQUFFO0lBQUU5QixNQUFNLEVBQUVKO0VBQVcsQ0FBQyxDQUFDO0VBQzVEbkMsU0FBUyxDQUNQd0MsT0FBTyxDQUFDeUQsR0FBRyxDQUNULFFBQVEsRUFDUlEsb0JBQW9CLENBQUM1RixRQUFRLENBQUNxRixNQUFNLEVBQ3BDLDRCQUNGLENBQUMsRUFDRDtJQUFFM0QsTUFBTSxFQUFFSjtFQUFXLENBQ3ZCLENBQUM7RUFDRG5DLFNBQVMsQ0FDUHdDLE9BQU8sQ0FBQzRDLEtBQUssQ0FDWHFCLG9CQUFvQixDQUFDNUYsUUFBUSxDQUFDdUYsR0FBRyxDQUFFTSxJQUFTLElBQUssQ0FDL0NBLElBQUksQ0FBQ0MsUUFBUSxFQUNiRCxJQUFJLENBQUNkLEtBQUssRUFDVmMsSUFBSSxDQUFDRSxZQUFZLEVBQ2pCRixJQUFJLENBQUNHLE1BQU0sQ0FDWixDQUNILENBQUMsRUFDRDtJQUFFdEUsTUFBTSxFQUFFSjtFQUFXLENBQ3ZCLENBQUM7RUFDRG5DLFNBQVMsQ0FBQ3dDLE9BQU8sQ0FBQ3FDLFFBQVEsQ0FBQyxDQUFDLEVBQUU7SUFBRXRDLE1BQU0sRUFBRUo7RUFBVyxDQUFDLENBQUM7RUFFckQsTUFBTW1ELEdBQUcsR0FBRyxJQUFJeEYsR0FBRyxDQUFDLENBQUM7RUFDckIsSUFBSXdGLEdBQUcsQ0FBQ0MsUUFBUSxDQUFDakYsZUFBZSxFQUFFbUcsb0JBQTJCLENBQUMsRUFBRTtJQUM5RHpHLFNBQVMsQ0FBQ3dDLE9BQU8sQ0FBQ0MsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUU7TUFBRUYsTUFBTSxFQUFFSjtJQUFXLENBQUMsQ0FBQztJQUNqRXBDLFNBQVMsQ0FBQyxDQUFDO0lBQ1gsT0FBTzBHLG9CQUFvQixDQUFDNUYsUUFBUTtFQUN0QztFQUVBYixTQUFTLENBQUN3QyxPQUFPLENBQUNnRCxJQUFJLENBQUMsc0NBQXNDLENBQUMsRUFBRTtJQUM5RGpELE1BQU0sRUFBRUo7RUFDVixDQUFDLENBQUM7RUFDRnBDLFNBQVMsQ0FBQyxDQUFDO0VBQ1gsT0FBTztJQUFFYyxRQUFRLEVBQUU7RUFBRyxDQUFDO0FBQ3pCIiwiaWdub3JlTGlzdCI6W119
|