PageSourceSearch

https://adiron.com/node_modules/.vite/deps/@tmcw_togeojson.js?v=de6acc7b

js adiron.com collected 2026-10-04 22:54:38 UTC 116,991 bytes, 1,023 lines download raw bytes

1//#region node_modules/@tmcw/togeojson/dist/togeojson.es.mjs
2function $(element, tagName) {
3	return Array.from(element.getElementsByTagName(tagName));
4}
5function normalizeId(id) {
6	return id[0] === "#" ? id : `#${id}`;
7}
8function $ns(element, tagName, ns) {
9	return Array.from(element.getElementsByTagNameNS(ns, tagName));
10}
11/**
12* get the content of a text node, if any
13*/
14function nodeVal(node) {
15	node?.normalize();
16	return node?.textContent || "";
17}
18/**
19* Get one Y child of X, if any, otherwise null
20*/
21function get1(node, tagName, callback) {
22	const n = node.getElementsByTagName(tagName);
23	const result = n.length ? n[0] : null;
24	if (result && callback) callback(result);
25	return result;
26}
27function get(node, tagName, callback) {
28	const properties = {};
29	if (!node) return properties;
30	const n = node.getElementsByTagName(tagName);
31	const result = n.length ? n[0] : null;
32	if (result && callback) return callback(result, properties);
33	return properties;
34}
35function val1(node, tagName, callback) {
36	const val = nodeVal(get1(node, tagName));
37	if (val && callback) return callback(val) || {};
38	return {};
39}
40function $num(node, tagName, callback) {
41	const val = Number.parseFloat(nodeVal(get1(node, tagName)));
42	if (Number.isNaN(val)) return void 0;
43	if (val && callback) return callback(val) || {};
44	return {};
45}
46function num1(node, tagName, callback) {
47	const val = Number.parseFloat(nodeVal(get1(node, tagName)));
48	if (Number.isNaN(val)) return void 0;
49	if (callback) callback(val);
50	return val;
51}
52function getMulti(node, propertyNames) {
53	const properties = {};
54	for (const property of propertyNames) val1(node, property, (val) => {
55		properties[property] = val;
56	});
57	return properties;
58}
59function isElement(node) {
60	return node?.nodeType === 1;
61}
62function getExtensions(node) {
63	let values = [];
64	if (node === null) return values;
65	for (const child of Array.from(node.childNodes)) {
66		if (!isElement(child)) continue;
67		const name = abbreviateName(child.nodeName);
68		if (name === "gpxtpx:TrackPointExtension") values = values.concat(getExtensions(child));
69		else {
70			const val = nodeVal(child);
71			values.push([name, parseNumeric(val)]);
72		}
73	}
74	return values;
75}
76function abbreviateName(name) {
77	return [
78		"heart",
79		"gpxtpx:hr",
80		"hr"
81	].includes(name) ? "heart" : name;
82}
83function parseNumeric(val) {
84	const num = Number.parseFloat(val);
85	return Number.isNaN(num) ? val : num;
86}
87function coordPair$1(node) {
88	const ll = [Number.parseFloat(node.getAttribute("lon") || ""), Number.parseFloat(node.getAttribute("lat") || "")];
89	if (Number.isNaN(ll[0]) || Number.isNaN(ll[1])) return null;
90	num1(node, "ele", (val) => {
91		ll.push(val);
92	});
93	const time = get1(node, "time");
94	return {
95		coordinates: ll,
96		time: time ? nodeVal(time) : null,
97		extendedValues: getExtensions(get1(node, "extensions"))
98	};
99}
100function getLineStyle(node) {
101	return get(node, "line", (lineStyle) => {
102		return Object.assign({}, val1(lineStyle, "color", (color) => {
103			return { stroke: `#${color}` };
104		}), $num(lineStyle, "opacity", (opacity) => {
105			return { "stroke-opacity": opacity };
106		}), $num(lineStyle, "width", (width) => {
107			return { "stroke-width": width * 96 / 25.4 };
108		}));
109	});
110}
111function extractProperties(ns, node) {
112	const properties = getMulti(node, [
113		"name",
114		"cmt",
115		"desc",
116		"type",
117		"time",
118		"keywords"
119	]);
120	for (const [n, url] of ns) for (const child of Array.from(node.getElementsByTagNameNS(url, "*"))) properties[child.tagName.replace(":", "_")] = nodeVal(child)?.trim();
121	const links = $(node, "link");
122	if (links.length) properties.links = links.map((link) => Object.assign({ href: link.getAttribute("href") }, getMulti(link, ["text", "type"])));
123	return properties;
124}
125/**
126* Extract points from a trkseg or rte element.
127*/
128function getPoints$1(node, pointname) {
129	const pts = $(node, pointname);
130	const line = [];
131	const times = [];
132	const extendedValues = {};
133	for (let i = 0; i < pts.length; i++) {
134		const c = coordPair$1(pts[i]);
135		if (!c) continue;
136		line.push(c.coordinates);
137		if (c.time) times.push(c.time);
138		for (const [name, val] of c.extendedValues) {
139			const plural = name === "heart" ? name : `${name.replace("gpxtpx:", "")}s`;
140			if (!extendedValues[plural]) extendedValues[plural] = Array(pts.length).fill(null);
141			extendedValues[plural][i] = val;
142		}
143	}
144	if (line.length < 2) return;
145	return {
146		line,
147		times,
148		extendedValues
149	};
150}
151/**
152* Extract a LineString geometry from a rte
153* element.
154*/
155function getRoute(ns, node) {
156	const line = getPoints$1(node, "rtept");
157	if (!line) return;
158	return {
159		type: "Feature",
160		properties: Object.assign({ _gpxType: "rte" }, extractProperties(ns, node), getLineStyle(get1(node, "extensions"))),
161		geometry: {
162			type: "LineString",
163			coordinates: line.line
164		}
165	};
166}
167function getTrack(ns, node) {
168	const segments = $(node, "trkseg");
169	const track = [];
170	const times = [];
171	const extractedLines = [];
172	for (const segment of segments) {
173		const line = getPoints$1(segment, "trkpt");
174		if (line) {
175			extractedLines.push(line);
176			if (line.times?.length) times.push(line.times);
177		}
178	}
179	if (extractedLines.length === 0) return null;
180	const multi = extractedLines.length > 1;
181	const properties = Object.assign({ _gpxType: "trk" }, extractProperties(ns, node), getLineStyle(get1(node, "extensions")), times.length ? { coordinateProperties: { times: multi ? times : times[0] } } : {});
182	for (let i = 0; i < extractedLines.length; i++) {
183		const line = extractedLines[i];
184		track.push(line.line);
185		if (!properties.coordinateProperties) properties.coordinateProperties = {};
186		const props = properties.coordinateProperties;
187		for (const [name, val] of Object.entries(line.extendedValues)) if (multi) {
188			if (!props[name]) props[name] = extractedLines.map((line) => new Array(line.line.length).fill(null));
189			props[name][i] = val;
190		} else props[name] = val;
191	}
192	return {
193		type: "Feature",
194		properties,
195		geometry: multi ? {
196			type: "MultiLineString",
197			coordinates: track
198		} : {
199			type: "LineString",
200			coordinates: track[0]
201		}
202	};
203}
204/**
205* Extract a point, if possible, from a given node,
206* which is usually a wpt or trkpt
207*/
208function getPoint(ns, node) {
209	const properties = Object.assign(extractProperties(ns, node), getMulti(node, ["sym"]));
210	const pair = coordPair$1(node);
211	if (!pair) return null;
212	return {
213		type: "Feature",
214		properties,
215		geometry: {
216			type: "Point",
217			coordinates: pair.coordinates
218		}
219	};
220}
221/**
222* Convert GPX to GeoJSON incrementally, returning
223* a [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
224* that yields output feature by feature.
225*/
226function* gpxGen(node) {
227	const n = node;
228	const GPXX = "gpxx";
229	const GPXX_URI = "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
230	const ns = [[GPXX, GPXX_URI]];
231	const attrs = n.getElementsByTagName("gpx")[0]?.attributes;
232	if (attrs) {
233		for (const attr of Array.from(attrs)) if (attr.name?.startsWith("xmlns:") && attr.value !== GPXX_URI) ns.push([attr.name, attr.value]);
234	}
235	for (const track of $(n, "trk")) {
236		const feature = getTrack(ns, track);
237		if (feature) yield feature;
238	}
239	for (const route of $(n, "rte")) {
240		const feature = getRoute(ns, route);
241		if (feature) yield feature;
242	}
243	for (const waypoint of $(n, "wpt")) {
244		const point = getPoint(ns, waypoint);
245		if (point) yield point;
246	}
247}
248/**
249*
250* Convert a GPX document to GeoJSON. The first argument, `doc`, must be a GPX
251* document as an XML DOM - not as a string. You can get this using jQuery's default
252* `.ajax` function or using a bare XMLHttpRequest with the `.response` property
253* holding an XML DOM.
254*
255* The output is a JavaScript object of GeoJSON data, same as `.kml` outputs, with the
256* addition of a `_gpxType` property on each `LineString` feature that indicates whether
257* the feature was encoded as a route (`rte`) or track (`trk`) in the GPX document.
258*/
259function gpx(node) {
260	return {
261		type: "FeatureCollection",
262		features: Array.from(gpxGen(node))
263	};
264}
265var EXTENSIONS_NS = "http://www.garmin.com/xmlschemas/ActivityExtension/v2";
266var TRACKPOINT_ATTRIBUTES = [
267	["heartRate", "heartRates"],
268	["Cadence", "cadences"],
269	["Speed", "speeds"],
270	["Watts", "watts"]
271];
272var LAP_ATTRIBUTES = [
273	["TotalTimeSeconds", "totalTimeSeconds"],
274	["DistanceMeters", "distanceMeters"],
275	["MaximumSpeed", "maxSpeed"],
276	["AverageHeartRateBpm", "avgHeartRate"],
277	["MaximumHeartRateBpm", "maxHeartRate"],
278	["AvgSpeed", "avgSpeed"],
279	["AvgWatts", "avgWatts"],
280	["MaxWatts", "maxWatts"]
281];
282function getProperties(node, attributeNames) {
283	const properties = [];
284	for (const [tag, alias] of attributeNames) {
285		let elem = get1(node, tag);
286		if (!elem) {
287			const elements = node.getElementsByTagNameNS(EXTENSIONS_NS, tag);
288			if (elements.length) elem = elements[0];
289		}
290		const val = Number.parseFloat(nodeVal(elem));
291		if (!Number.isNaN(val)) properties.push([alias, val]);
292	}
293	return properties;
294}
295function coordPair(node) {
296	const ll = [num1(node, "LongitudeDegrees"), num1(node, "LatitudeDegrees")];
297	if (ll[0] === void 0 || Number.isNaN(ll[0]) || ll[1] === void 0 || Number.isNaN(ll[1])) return null;
298	const heartRate = get1(node, "HeartRateBpm");
299	const time = nodeVal(get1(node, "Time"));
300	get1(node, "AltitudeMeters", (alt) => {
301		const a = Number.parseFloat(nodeVal(alt));
302		if (!Number.isNaN(a)) ll.push(a);
303	});
304	return {
305		coordinates: ll,
306		time: time || null,
307		heartRate: heartRate ? Number.parseFloat(nodeVal(heartRate)) : null,
308		extensions: getProperties(node, TRACKPOINT_ATTRIBUTES)
309	};
310}
311function getPoints(node) {
312	const pts = $(node, "Trackpoint");
313	const line = [];
314	const times = [];
315	const heartRates = [];
316	if (pts.length < 2) return null;
317	const extendedProperties = {};
318	const result = { extendedProperties };
319	for (let i = 0; i < pts.length; i++) {
320		const c = coordPair(pts[i]);
321		if (c === null) continue;
322		line.push(c.coordinates);
323		const { time, heartRate, extensions } = c;
324		if (time) times.push(time);
325		if (heartRate) heartRates.push(heartRate);
326		for (const [alias, value] of extensions) {
327			if (!extendedProperties[alias]) extendedProperties[alias] = Array(pts.length).fill(null);
328			extendedProperties[alias][i] = value;
329		}
330	}
331	if (line.length < 2) return null;
332	return Object.assign(result, {
333		line,
334		times,
335		heartRates
336	});
337}
338function getLap(node) {
339	const segments = $(node, "Track");
340	const track = [];
341	const times = [];
342	const heartRates = [];
343	const allExtendedProperties = [];
344	let line;
345	const properties = Object.assign(Object.fromEntries(getProperties(node, LAP_ATTRIBUTES)), get(node, "Name", (nameElement) => {
346		return { name: nodeVal(nameElement) };
347	}));
348	for (const segment of segments) {
349		line = getPoints(segment);
350		if (line) {
351			track.push(line.line);
352			if (line.times.length) times.push(line.times);
353			if (line.heartRates.length) heartRates.push(line.heartRates);
354			allExtendedProperties.push(line.extendedProperties);
355		}
356	}
357	for (let i = 0; i < allExtendedProperties.length; i++) {
358		const extendedProperties = allExtendedProperties[i];
359		for (const property in extendedProperties) if (segments.length === 1) {
360			if (line) properties[property] = line.extendedProperties[property];
361		} else {
362			if (!properties[property]) properties[property] = track.map((track) => Array(track.length).fill(null));
363			properties[property][i] = extendedProperties[property];
364		}
365	}
366	if (track.length === 0) return null;
367	if (times.length || heartRates.length) properties.coordinateProperties = Object.assign(times.length ? { times: track.length === 1 ? times[0] : times } : {}, heartRates.length ? { heart: track.length === 1 ? heartRates[0] : heartRates } : {});
368	return {
369		type: "Feature",
370		properties,
371		geometry: track.length === 1 ? {
372			type: "LineString",
373			coordinates: track[0]
374		} : {
375			type: "MultiLineString",
376			coordinates: track
377		}
378	};
379}
380/**
381* Incrementally convert a TCX document to GeoJSON. The
382* first argument, `doc`, must be a TCX
383* document as an XML DOM - not as a string.
384*/
385function* tcxGen(node) {
386	for (const lap of $(node, "Lap")) {
387		const feature = getLap(lap);
388		if (feature) yield feature;
389	}
390	for (const course of $(node, "Courses")) {
391		const feature = getLap(course);
392		if (feature) yield feature;
393	}
394}
395/**
396* Convert a TCX document to GeoJSON. The first argument, `doc`, must be a TCX
397* document as an XML DOM - not as a string.
398*/
399function tcx(node) {
400	return {
401		type: "FeatureCollection",
402		features: Array.from(tcxGen(node))
403	};
404}
405function fixColor(v, prefix) {
406	const properties = {};
407	const colorProp = prefix === "stroke" || prefix === "fill" ? prefix : `${prefix}-color`;
408	if (v[0] === "#") v = v.substring(1);
409	if (v.length === 6 || v.length === 3) properties[colorProp] = `#${v}`;
410	else if (v.length === 8) {
411		properties[`${prefix}-opacity`] = Number.parseInt(v.substring(0, 2), 16) / 255;
412		properties[colorProp] = `#${v.substring(6, 8)}${v.substring(4, 6)}${v.substring(2, 4)}`;
413	}
414	return properties;
415}
416function numericProperty(node, source, target) {
417	const properties = {};
418	num1(node, source, (val) => {
419		properties[target] = val;
420	});
421	return properties;
422}
423function getColor(node, output) {
424	return get(node, "color", (elem) => fixColor(nodeVal(elem), output));
425}
426function extractIconHref(node) {
427	return get(node, "Icon", (icon, properties) => {
428		val1(icon, "href", (href) => {
429			properties.icon = href;
430		});
431		return properties;
432	});
433}
434function extractIcon(node) {
435	return get(node, "IconStyle", (iconStyle) => {
436		return Object.assign(getColor(iconStyle, "icon"), numericProperty(iconStyle, "scale", "icon-scale"), numericProperty(iconStyle, "heading", "icon-heading"), get(iconStyle, "hotSpot", (hotspot) => {
437			const left = Number.parseFloat(hotspot.getAttribute("x") || "");
438			const top = Number.parseFloat(hotspot.getAttribute("y") || "");
439			const xunits = hotspot.getAttribute("xunits") || "";
440			const yunits = hotspot.getAttribute("yunits") || "";
441			if (!Number.isNaN(left) && !Number.isNaN(top)) return {
442				"icon-offset": [left, top],
443				"icon-offset-units": [xunits, yunits]
444			};
445			return {};
446		}), extractIconHref(iconStyle));
447	});
448}
449function extractLabel(node) {
450	return get(node, "LabelStyle", (labelStyle) => {
451		return Object.assign(getColor(labelStyle, "label"), numericProperty(labelStyle, "scale", "label-scale"));
452	});
453}
454function extractLine(node) {
455	return get(node, "LineStyle", (lineStyle) => {
456		return Object.assign(getColor(lineStyle, "stroke"), numericProperty(lineStyle, "width", "stroke-width"));
457	});
458}
459function extractPoly(node) {
460	return get(node, "PolyStyle", (polyStyle, properties) => {
461		return Object.assign(properties, get(polyStyle, "color", (elem) => fixColor(nodeVal(elem), "fill")), val1(polyStyle, "fill", (fill) => {
462			if (fill === "0") return { "fill-opacity": 0 };
463		}), val1(polyStyle, "outline", (outline) => {
464			if (outline === "0") return { "stroke-opacity": 0 };
465		}));
466	});
467}
468function extractStyle(node) {
469	return Object.assign({}, extractPoly(node), extractLine(node), extractLabel(node), extractIcon(node));
470}
471var removeSpace = /\s*/g;
472var trimSpace = /^\s*|\s*$/g;
473var splitSpace = /\s+/;
474/**
475* Get one coordinate from a coordinate array, if any
476*/
477function coord1(value) {
478	return value.replace(removeSpace, "").split(",").map(Number.parseFloat).filter((num) => !Number.isNaN(num)).slice(0, 3);
479}
480/**
481* Get all coordinates from a coordinate array as [[],[]]
482*/
483function coord(value) {
484	return value.replace(trimSpace, "").split(splitSpace).map(coord1).filter((coord) => {
485		return coord.length >= 2;
486	});
487}
488function gxCoords(node) {
489	let elems = $(node, "coord");
490	if (elems.length === 0) elems = $ns(node, "coord", "*");
491	const coordinates = elems.map((elem) => {
492		return nodeVal(elem).split(" ").map(Number.parseFloat);
493	});
494	if (coordinates.length === 0) return null;
495	return {
496		geometry: coordinates.length > 2 ? {
497			type: "LineString",
498			coordinates
499		} : {
500			type: "Point",
501			coordinates: coordinates[0]
502		},
503		times: $(node, "when").map((elem) => nodeVal(elem))
504	};
505}
506function fixRing(ring) {
507	if (ring.length === 0) return ring;
508	const first = ring[0];
509	const last = ring[ring.length - 1];
510	let equal = true;
511	for (let i = 0; i < Math.max(first.length, last.length); i++) if (first[i] !== last[i]) {
512		equal = false;
513		break;
514	}
515	if (!equal) return ring.concat([ring[0]]);
516	return ring;
517}
518function getCoordinates(node) {
519	return nodeVal(get1(node, "coordinates"));
520}
521function getGeometry(node) {
522	let geometries = [];
523	let coordTimes = [];
524	for (let i = 0; i < node.childNodes.length; i++) {
525		const child = node.childNodes.item(i);
526		if (isElement(child)) switch (child.tagName) {
527			case "MultiGeometry":
528			case "MultiTrack":
529			case "gx:MultiTrack": {
530				const childGeometries = getGeometry(child);
531				geometries = geometries.concat(childGeometries.geometries);
532				coordTimes = coordTimes.concat(childGeometries.coordTimes);
533				break;
534			}
535			case "Point": {
536				const coordinates = coord1(getCoordinates(child));
537				if (coordinates.length >= 2) geometries.push({
538					type: "Point",
539					coordinates
540				});
541				break;
542			}
543			case "LinearRing":
544			case "LineString": {
545				const coordinates = coord(getCoordinates(child));
546				if (coordinates.length >= 2) geometries.push({
547					type: "LineString",
548					coordinates
549				});
550				break;
551			}
552			case "Polygon": {
553				const coords = [];
554				for (const linearRing of $(child, "LinearRing")) {
555					const ring = fixRing(coord(getCoordinates(linearRing)));
556					if (ring.length >= 4) coords.push(ring);
557				}
558				if (coords.length) geometries.push({
559					type: "Polygon",
560					coordinates: coords
561				});
562				break;
563			}
564			case "Track":
565			case "gx:Track": {
566				const gx = gxCoords(child);
567				if (!gx) break;
568				const { times, geometry } = gx;
569				geometries.push(geometry);
570				if (times.length) coordTimes.push(times);
571				break;
572			}
573		}
574	}
575	return {
576		geometries,
577		coordTimes
578	};
579}
580var toNumber = (x) => Number(x);
581var typeConverters = {
582	string: (x) => x,
583	int: toNumber,
584	uint: toNumber,
585	short: toNumber,
586	ushort: toNumber,
587	float: toNumber,
588	double: toNumber,
589	bool: (x) => Boolean(x)
590};
591function extractExtendedData(node, schema) {
592	return get(node, "ExtendedData", (extendedData, properties) => {
593		for (const data of $(extendedData, "Data")) properties[data.getAttribute("name") || ""] = nodeVal(get1(data, "value"));
594		for (const simpleData of $(extendedData, "SimpleData")) {
595			const name = simpleData.getAttribute("name") || "";
596			properties[name] = (schema[name] || typeConverters.string)(nodeVal(simpleData));
597		}
598		return properties;
599	});
600}
601function getMaybeHTMLDescription(node) {
602	const descriptionNode = get1(node, "description");
603	for (const c of Array.from(descriptionNode?.childNodes || [])) if (c.nodeType === 4) return { description: {
604		"@type": "html",
605		value: nodeVal(c)
606	} };
607	return {};
608}
609function extractTimeSpan(node) {
610	return get(node, "TimeSpan", (timeSpan) => {
611		return { timespan: {
612			begin: nodeVal(get1(timeSpan, "begin")),
613			end: nodeVal(get1(timeSpan, "end"))
614		} };
615	});
616}
617function extractTimeStamp(node) {
618	return get(node, "TimeStamp", (timeStamp) => {
619		return { timestamp: nodeVal(get1(timeStamp, "when")) };
620	});
621}
622function extractCascadedStyle(node, styleMap) {
623	return val1(node, "styleUrl", (styleUrl) => {
624		styleUrl = normalizeId(styleUrl);
625		if (styleMap[styleUrl]) return Object.assign({ styleUrl }, styleMap[styleUrl]);
626		return { styleUrl };
627	});
628}
629var AltitudeMode;
630(function(AltitudeMode) {
631	AltitudeMode["ABSOLUTE"] = "absolute";
632	AltitudeMode["RELATIVE_TO_GROUND"] = "relativeToGround";
633	AltitudeMode["CLAMP_TO_GROUND"] = "clampToGround";
634	AltitudeMode["CLAMP_TO_SEAFLOOR"] = "clampToSeaFloor";
635	AltitudeMode["RELATIVE_TO_SEAFLOOR"] = "relativeToSeaFloor";
636})(AltitudeMode || (AltitudeMode = {}));
637function processAltitudeMode(mode) {
638	switch (mode?.textContent) {
639		case AltitudeMode.ABSOLUTE: return AltitudeMode.ABSOLUTE;
640		case AltitudeMode.CLAMP_TO_GROUND: return AltitudeMode.CLAMP_TO_GROUND;
641		case AltitudeMode.CLAMP_TO_SEAFLOOR: return AltitudeMode.CLAMP_TO_SEAFLOOR;
642		case AltitudeMode.RELATIVE_TO_GROUND: return AltitudeMode.RELATIVE_TO_GROUND;
643		case AltitudeMode.RELATIVE_TO_SEAFLOOR: return AltitudeMode.RELATIVE_TO_SEAFLOOR;
644	}
645	return null;
646}
647function getGroundOverlayBox(node) {
648	if (get1(node, "gx:LatLonQuad")) return { geometry: {
649		type: "Polygon",
650		coordinates: [fixRing(coord(getCoordinates(node)))]
651	} };
652	return getLatLonBox(node);
653}
654var DEGREES_TO_RADIANS = Math.PI / 180;
655function rotateBox(bbox, coordinates, rotation) {
656	const center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2];
657	return [coordinates[0].map((coordinate) => {
658		const dy = coordinate[1] - center[1];
659		const dx = coordinate[0] - center[0];
660		const distance = Math.sqrt(dy ** 2 + dx ** 2);
661		const angle = Math.atan2(dy, dx) + rotation * DEGREES_TO_RADIANS;
662		return [center[0] + Math.cos(angle) * distance, center[1] + Math.sin(angle) * distance];
663	})];
664}
665function getLatLonBox(node) {
666	const latLonBox = get1(node, "LatLonBox");
667	if (latLonBox) {
668		const north = num1(latLonBox, "north");
669		const west = num1(latLonBox, "west");
670		const east = num1(latLonBox, "east");
671		const south = num1(latLonBox, "south");
672		const rotation = num1(latLonBox, "rotation");
673		if (typeof north === "number" && typeof south === "number" && typeof west === "number" && typeof east === "number") {
674			const bbox = [
675				west,
676				south,
677				east,
678				north
679			];
680			let coordinates = [[
681				[west, north],
682				[east, north],
683				[east, south],
684				[west, south],
685				[west, north]
686			]];
687			if (typeof rotation === "number") coordinates = rotateBox(bbox, coordinates, rotation);
688			return {
689				bbox,
690				geometry: {
691					type: "Polygon",
692					coordinates
693				}
694			};
695		}
696	}
697	return null;
698}
699function getGroundOverlay(node, styleMap, schema, options) {
700	const box = getGroundOverlayBox(node);
701	const geometry = box?.geometry || null;
702	if (!geometry && options.skipNullGeometry) return null;
703	const feature = {
704		type: "Feature",
705		geometry,
706		properties: Object.assign(
707			/**
708			* Related to
709			* https://gist.github.com/tmcw/037a1cb6660d74a392e9da7446540f46
710			*/
711			{ "@geometry-type": "groundoverlay" },
712			getMulti(node, [
713				"name",
714				"address",
715				"visibility",
716				"open",
717				"phoneNumber",
718				"description"
719			]),
720			getMaybeHTMLDescription(node),
721			extractCascadedStyle(node, styleMap),
722			extractStyle(node),
723			extractIconHref(node),
724			extractExtendedData(node, schema),
725			extractTimeSpan(node),
726			extractTimeStamp(node)
727		)
728	};
729	if (box?.bbox) feature.bbox = box.bbox;
730	if (feature.properties?.visibility !== void 0) feature.properties.visibility = feature.properties.visibility !== "0";
731	const id = node.getAttribute("id");
732	if (id !== null && id !== "") feature.id = id;
733	return feature;
734}
735function getNetworkLinkRegion(node) {
736	const region = get1(node, "Region");
737	if (region) return {
738		coordinateBox: getLatLonAltBox(region),
739		lod: getLod(node)
740	};
741	return null;
742}
743function getLod(node) {
744	const lod = get1(node, "Lod");
745	if (lod) return [
746		num1(lod, "minLodPixels") ?? -1,
747		num1(lod, "maxLodPixels") ?? -1,
748		num1(lod, "minFadeExtent") ?? null,
749		num1(lod, "maxFadeExtent") ?? null
750	];
751	return null;
752}
753function getLatLonAltBox(node) {
754	const latLonAltBox = get1(node, "LatLonAltBox");
755	if (latLonAltBox) {
756		const north = num1(latLonAltBox, "north");
757		const west = num1(latLonAltBox, "west");
758		const east = num1(latLonAltBox, "east");
759		const south = num1(latLonAltBox, "south");
760		if (processAltitudeMode(get1(latLonAltBox, "altitudeMode") || get1(latLonAltBox, "gx:altitudeMode"))) console.debug("Encountered an unsupported feature of KML for togeojson: please contact developers for support of altitude mode.");
761		if (typeof north === "number" && typeof south === "number" && typeof west === "number" && typeof east === "number") return {
762			bbox: [
763				west,
764				south,
765				east,
766				north
767			],
768			geometry: {
769				type: "Polygon",
770				coordinates: [[
771					[west, north],
772					[east, north],
773					[east, south],
774					[west, south],
775					[west, north]
776				]]
777			}
778		};
779	}
780	return null;
781}
782function getLinkObject(node) {
783	const linkObj = get1(node, "Link");
784	if (linkObj) return getMulti(linkObj, [
785		"href",
786		"refreshMode",
787		"refreshInterval",
788		"viewRefreshMode",
789		"viewRefreshTime",
790		"viewBoundScale",
791		"viewFormat",
792		"httpQuery"
793	]);
794	return {};
795}
796function getNetworkLink(node, styleMap, schema, options) {
797	const box = getNetworkLinkRegion(node);
798	const geometry = box?.coordinateBox?.geometry || null;
799	if (!geometry && options.skipNullGeometry) return null;
800	const feature = {
801		type: "Feature",
802		geometry,
803		properties: Object.assign(
804			/**
805			* Related to
806			* https://gist.github.com/tmcw/037a1cb6660d74a392e9da7446540f46
807			*/
808			{ "@geometry-type": "networklink" },
809			getMulti(node, [
810				"name",
811				"address",
812				"visibility",
813				"open",
814				"phoneNumber",
815				"styleUrl",
816				"refreshVisibility",
817				"flyToView",
818				"description"
819			]),
820			getMaybeHTMLDescription(node),
821			extractCascadedStyle(node, styleMap),
822			extractStyle(node),
823			extractIconHref(node),
824			extractExtendedData(node, schema),
825			extractTimeSpan(node),
826			extractTimeStamp(node),
827			getLinkObject(node),
828			box?.lod ? { lod: box.lod } : {}
829		)
830	};
831	if (box?.coordinateBox?.bbox) feature.bbox = box.coordinateBox.bbox;
832	if (feature.properties?.visibility !== void 0) feature.properties.visibility = feature.properties.visibility !== "0";
833	const id = node.getAttribute("id");
834	if (id !== null && id !== "") feature.id = id;
835	return feature;
836}
837function geometryListToGeometry(geometries) {
838	return geometries.length === 0 ? null : geometries.length === 1 ? geometries[0] : {
839		type: "GeometryCollection",
840		geometries
841	};
842}
843function getPlacemark(node, styleMap, schema, options) {
844	const { coordTimes, geometries } = getGeometry(node);
845	const geometry = geometryListToGeometry(geometries);
846	if (!geometry && options.skipNullGeometry) return null;
847	const feature = {
848		type: "Feature",
849		geometry,
850		properties: Object.assign(getMulti(node, [
851			"name",
852			"address",
853			"visibility",
854			"open",
855			"phoneNumber",
856			"description"
857		]), getMaybeHTMLDescription(node), extractCascadedStyle(node, styleMap), extractStyle(node), extractExtendedData(node, schema), extractTimeSpan(node), extractTimeStamp(node), coordTimes.length ? { coordinateProperties: { times: coordTimes.length === 1 ? coordTimes[0] : coordTimes } } : {})
858	};
859	if (feature.properties?.visibility !== void 0) feature.properties.visibility = feature.properties.visibility !== "0";
860	const id = node.getAttribute("id");
861	if (id !== null && id !== "") feature.id = id;
862	return feature;
863}
864function getStyleId(style) {
865	let id = style.getAttribute("id");
866	const parentNode = style.parentNode;
867	if (!id && isElement(parentNode) && parentNode.localName === "CascadingStyle") id = parentNode.getAttribute("kml:id") || parentNode.getAttribute("id");
868	return normalizeId(id || "");
869}
870function buildStyleMap(node) {
871	const styleMap = {};
872	for (const style of $(node, "Style")) styleMap[getStyleId(style)] = extractStyle(style);
873	for (const map of $(node, "StyleMap")) {
874		const id = normalizeId(map.getAttribute("id") || "");
875		val1(map, "styleUrl", (styleUrl) => {
876			styleUrl = normalizeId(styleUrl);
877			if (styleMap[styleUrl]) styleMap[id] = styleMap[styleUrl];
878		});
879	}
880	return styleMap;
881}
882function buildSchema(node) {
883	const schema = {};
884	for (const field of $(node, "SimpleField")) schema[field.getAttribute("name") || ""] = typeConverters[field.getAttribute("type") || ""] || typeConverters.string;
885	return schema;
886}
887var FOLDER_PROPS = [
888	"name",
889	"visibility",
890	"open",
891	"address",
892	"description",
893	"phoneNumber",
894	"visibility"
895];
896function getFolder(node) {
897	const meta = {};
898	for (const child of Array.from(node.childNodes)) if (isElement(child) && FOLDER_PROPS.includes(child.tagName)) meta[child.tagName] = nodeVal(child);
899	return {
900		type: "folder",
901		meta,
902		children: []
903	};
904}
905/**
906* Yield a nested tree with KML folder structure
907*
908* This generates a tree with the given structure:
909*
910* ```js
911* {
912*   "type": "root",
913*   "children": [
914*     {
915*       "type": "folder",
916*       "meta": {
917*         "name": "Test"
918*       },
919*       "children": [
920*          // ...features and folders
921*       ]
922*     }
923*     // ...features
924*   ]
925* }
926* ```
927*
928* ### GroundOverlay
929*
930* GroundOverlay elements are converted into
931* `Feature` objects with `Polygon` geometries,
932* a property like:
933*
934* ```json
935* {
936*   "@geometry-type": "groundoverlay"
937* }
938* ```
939*
940* And the ground overlay's image URL in the `href`
941* property. Ground overlays will need to be displayed
942* with a separate method to other features, depending
943* on which map framework you're using.
944*/
945function kmlWithFolders(node, options = { skipNullGeometry: false }) {
946	const n = node;
947	const styleMap = buildStyleMap(n);
948	const schema = buildSchema(n);
949	const tree = {
950		type: "root",
951		children: []
952	};
953	function traverse(node, pointer, options) {
954		if (isElement(node)) switch (node.tagName) {
955			case "GroundOverlay": {
956				const placemark = getGroundOverlay(node, styleMap, schema, options);
957				if (placemark) pointer.children.push(placemark);
958				break;
959			}
960			case "Placemark": {
961				const placemark = getPlacemark(node, styleMap, schema, options);
962				if (placemark) pointer.children.push(placemark);
963				break;
964			}
965			case "Folder": {
966				const folder = getFolder(node);
967				pointer.children.push(folder);
968				pointer = folder;
969				break;
970			}
971			case "NetworkLink": {
972				const networkLink = getNetworkLink(node, styleMap, schema, options);
973				if (networkLink) pointer.children.push(networkLink);
974				break;
975			}
976		}
977		if (node.childNodes) for (let i = 0; i < node.childNodes.length; i++) traverse(node.childNodes[i], pointer, options);
978	}
979	traverse(n, tree, options);
980	return tree;
981}
982/**
983* Convert KML to GeoJSON incrementally, returning
984* a [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
985* that yields output feature by feature.
986*/
987function* kmlGen(node, options = { skipNullGeometry: false }) {
988	const n = node;
989	const styleMap = buildStyleMap(n);
990	const schema = buildSchema(n);
991	for (const placemark of $(n, "Placemark")) {
992		const feature = getPlacemark(placemark, styleMap, schema, options);
993		if (feature) yield feature;
994	}
995	for (const groundOverlay of $(n, "GroundOverlay")) {
996		const feature = getGroundOverlay(groundOverlay, styleMap, schema, options);
997		if (feature) yield feature;
998	}
999	for (const networkLink of $(n, "NetworkLink")) {
1000		const feature = getNetworkLink(networkLink, styleMap, schema, options);
1001		if (feature) yield feature;
1002	}
1003}
1004/**
1005* Convert a KML document to GeoJSON. The first argument, `doc`, must be a KML
1006* document as an XML DOM - not as a string. You can get this using jQuery's default
1007* `.ajax` function or using a bare XMLHttpRequest with the `.response` property
1008* holding an XML DOM.
1009*
1010* The output is a JavaScript object of GeoJSON data. You can convert it to a string
1011* with [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
1012* or use it directly in libraries.
1013*/
1014function kml(node, options = { skipNullGeometry: false }) {
1015	return {
1016		type: "FeatureCollection",
1017		features: Array.from(kmlGen(node, options))
1018	};
1019}
1020//#endregion
1021export { gpx, gpxGen, kml, kmlGen, kmlWithFolders, tcx, tcxGen };
1022
1023//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQHRtY3dfdG9nZW9qc29uLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL0B0bWN3L3RvZ2VvanNvbi9kaXN0L3RvZ2VvanNvbi5lcy5tanMiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gJChlbGVtZW50LCB0YWdOYW1lKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSh0YWdOYW1lKSk7XG59XG5mdW5jdGlvbiBub3JtYWxpem
1023VJZChpZCkge1xuICAgIHJldHVybiBpZFswXSA9PT0gXCIjXCIgPyBpZCA6IGAjJHtpZH1gO1xufVxuZnVuY3Rpb24gJG5zKGVsZW1lbnQsIHRhZ05hbWUsIG5zKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5zLCB0YWdOYW1lKSk7XG59XG4vKipcbiAqIGdldCB0aGUgY29udGVudCBvZiBhIHRleHQgbm9kZSwgaWYgYW55XG4gKi9cbmZ1bmN0aW9uIG5vZGVWYWwobm9kZSkge1xuICAgIG5vZGU/Lm5vcm1hbGl6ZSgpO1xuICAgIHJldHVybiBub2RlPy50ZXh0Q29udGVudCB8fCBcIlwiO1xufVxuLyoqXG4gKiBHZXQgb25lIFkgY2hpbGQgb2YgWCwgaWYgYW55LCBvdGhlcndpc2UgbnVsbFxuICovXG5mdW5jdGlvbiBnZXQxKG5vZGUsIHRhZ05hbWUsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgbiA9IG5vZGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnTmFtZSk7XG4gICAgY29uc3QgcmVzdWx0ID0gbi5sZW5ndGggPyBuWzBdIDogbnVsbDtcbiAgICBpZiAocmVzdWx0ICYmIGNhbGxiYWNrKVxuICAgICAgICBjYWxsYmFjayhyZXN1bHQpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBnZXQobm9kZSwgdGFnTmFtZSwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBwcm9wZXJ0aWVzID0ge307XG4gICAgaWYgKCFub2RlKVxuICAgICAgICByZXR1cm4gcHJvcGVydGllcztcbiAgICBjb25zdCBuID0gbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZSh0YWdOYW1lKTtcbiAgICBjb25zdCByZXN1bHQgPSBuLmxlbmd0aCA/IG5bMF0gOiBudWxsO1xuICAgIGlmIChyZXN1bHQgJiYgY2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdCwgcHJvcGVydGllcyk7XG4gICAgfVxuICAgIHJldHVybiBwcm9wZXJ0aWVzO1xufVxuZnVuY3Rpb24gdmFsMShub2RlLCB0YWdOYW1lLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHZhbCA9IG5vZGVWYWwoZ2V0MShub2RlLCB0YWdOYW1lKSk7XG4gICAgaWYgKHZhbCAmJiBjYWxsYmFjaylcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHZhbCkgfHwge307XG4gICAgcmV0dXJuIHt9O1xufVxuZnVuY3Rpb24gJG51bShub2RlLCB0YWdOYW1lLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHZhbCA9IE51bWJlci5wYXJzZUZsb2F0KG5vZGVWYWwoZ2V0MShub2RlLCB0YWdOYW1lKSkpO1xuICAgIGlmIChOdW1iZXIuaXNOYU4odmFsKSlcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAodmFsICYmIGNhbGxiYWNrKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sodmFsKSB8fCB7fTtcbiAgICByZXR1cm4ge307XG59XG5mdW5jdGlvbiBudW0xKG5vZGUsIHRhZ05hbWUsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdmFsID0gTnVtYmVyLnBhcnNlRmxvYXQobm9kZVZhbChnZXQxKG5vZGUsIHRhZ05hbWUpKSk7XG4gICAgaWYgKE51bWJlci5pc05hTih2YWwpKVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGlmIChjYWxsYmFjaylcbiAgICAgICAgY2FsbGJhY2sodmFsKTtcbiAgICByZXR1cm4gdmFsO1xufVxuZnVuY3Rpb24gZ2V0TXVsdGkobm9kZSwgcHJvcGVydHlOYW1lcykge1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7fTtcbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHByb3BlcnR5TmFtZXMpIHtcbiAgICAgICAgdmFsMShub2RlLCBwcm9wZXJ0eSwgKHZhbCkgPT4ge1xuICAgICAgICAgICAgcHJvcGVydGllc1twcm9wZXJ0eV0gPSB2YWw7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcHJvcGVydGllcztcbn1cbmZ1bmN0aW9uIGlzRWxlbWVudChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGU/Lm5vZGVUeXBlID09PSAxO1xufVxuXG5mdW5jdGlvbiBnZXRFeHRlbnNpb25zKG5vZGUpIHtcbiAgICBsZXQgdmFsdWVzID0gW107XG4gICAgaWYgKG5vZGUgPT09IG51bGwpXG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBBcnJheS5mcm9tKG5vZGUuY2hpbGROb2RlcykpIHtcbiAgICAgICAgaWYgKCFpc0VsZW1lbnQoY2hpbGQpKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBhYmJyZXZpYXRlTmFtZShjaGlsZC5ub2RlTmFtZSk7XG4gICAgICAgIGlmIChuYW1lID09PSBcImdweHRweDpUcmFja1BvaW50RXh0ZW5zaW9uXCIpIHtcbiAgICAgICAgICAgIC8vIGxvb3AgYWdhaW4gZm9yIG5lc3RlZCBnYXJtaW4gZXh0ZW5zaW9ucyAoZWcuIFwiZ3B4dHB4OmhyXCIpXG4gICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KGdldEV4dGVuc2lvbnMoY2hpbGQpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHB1c2ggY3VzdG9tIGV4dGVuc2lvbiAoZWcuIFwicG93ZXJcIilcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IG5vZGVWYWwoY2hpbGQpO1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goW25hbWUsIHBhcnNlTnVtZXJpYyh2YWwpXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlcztcbn1cbmZ1bmN0aW9uIGFiYnJldmlhdGVOYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gW1wiaGVhcnRcIiwgXCJncHh0cHg6aHJcIiwgXCJoclwiXS5pbmNsdWRlcyhuYW1lKSA/IFwiaGVhcnRcIiA6IG5hbWU7XG59XG5mdW5jdGlvbiBwYXJzZU51bWVyaWModmFsKSB7XG4gICAgY29uc3QgbnVtID0gTnVtYmVyLnBhcnNlRmxvYXQodmFsKTtcbiAgICByZXR1cm4gTnVtYmVyLmlzTmFOKG51bSkgPyB2YWwgOiBudW07XG59XG5cbmZ1bmN0aW9uIGNvb3JkUGFpciQxKG5vZGUpIHtcbiAgICBjb25zdCBsbCA9IFtcbiAgICAgICAgTnVtYmVyLnBhcnNlRmxvYXQobm9kZS5nZXRBdHRyaWJ1dGUoXCJsb25cIikgfHwgXCJcIiksXG4gICAgICAgIE51bWJlci5wYXJzZUZsb2F0KG5vZGUuZ2V0QXR0cmlidXRlKFwibGF0XCIpIHx8IFwiXCIpLFxuICAgIF07XG4gICAgaWYgKE51bWJlci5pc05hTihsbFswXSkgfHwgTnVtYmVyLmlzTmFOKGxsWzFdKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgbnVtMShub2RlLCBcImVsZVwiLCAodmFsKSA9PiB7XG4gICAgICAgIGxsLnB1c2godmFsKTtcbiAgICB9KTtcbiAgICBjb25zdCB0aW1lID0gZ2V0MShub2RlLCBcInRpbWVcIik7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29vcmRpbmF0ZXM6IGxsLFxuICAgICAgICB0aW1lOiB0aW1lID8gbm9kZVZhbCh0aW1lKSA6IG51bGwsXG4gICAgICAgIGV4dGVuZGVkVmFsdWVzOiBnZXRFeHRlbnNpb25zKGdldDEobm9kZSwgXCJleHRlbnNpb25zXCIpKSxcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRMaW5lU3R5bGUobm9kZSkge1xuICAgIHJldHVybi
1023BnZXQobm9kZSwgXCJsaW5lXCIsIChsaW5lU3R5bGUpID0+IHtcbiAgICAgICAgY29uc3QgdmFsID0gT2JqZWN0LmFzc2lnbih7fSwgdmFsMShsaW5lU3R5bGUsIFwiY29sb3JcIiwgKGNvbG9yKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyBzdHJva2U6IGAjJHtjb2xvcn1gIH07XG4gICAgICAgIH0pLCAkbnVtKGxpbmVTdHlsZSwgXCJvcGFjaXR5XCIsIChvcGFjaXR5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyBcInN0cm9rZS1vcGFjaXR5XCI6IG9wYWNpdHkgfTtcbiAgICAgICAgfSksICRudW0obGluZVN0eWxlLCBcIndpZHRoXCIsICh3aWR0aCkgPT4ge1xuICAgICAgICAgICAgLy8gR1BYIHdpZHRoIGlzIGluIG1tLCBjb252ZXJ0IHRvIHB4IHdpdGggOTYgcHggcGVyIGluY2hcbiAgICAgICAgICAgIHJldHVybiB7IFwic3Ryb2tlLXdpZHRoXCI6ICh3aWR0aCAqIDk2KSAvIDI1LjQgfTtcbiAgICAgICAgfSkpO1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBleHRyYWN0UHJvcGVydGllcyhucywgbm9kZSkge1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPSBnZXRNdWx0aShub2RlLCBbXG4gICAgICAgIFwibmFtZVwiLFxuICAgICAgICBcImNtdFwiLFxuICAgICAgICBcImRlc2NcIixcbiAgICAgICAgXCJ0eXBlXCIsXG4gICAgICAgIFwidGltZVwiLFxuICAgICAgICBcImtleXdvcmRzXCIsXG4gICAgXSk7XG4gICAgZm9yIChjb25zdCBbbiwgdXJsXSBvZiBucykge1xuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIEFycmF5LmZyb20obm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKHVybCwgXCIqXCIpKSkge1xuICAgICAgICAgICAgcHJvcGVydGllc1tjaGlsZC50YWdOYW1lLnJlcGxhY2UoXCI6XCIsIFwiX1wiKV0gPSBub2RlVmFsKGNoaWxkKT8udHJpbSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGxpbmtzID0gJChub2RlLCBcImxpbmtcIik7XG4gICAgaWYgKGxpbmtzLmxlbmd0aCkge1xuICAgICAgICBwcm9wZXJ0aWVzLmxpbmtzID0gbGlua3MubWFwKChsaW5rKSA9PiBPYmplY3QuYXNzaWduKHsgaHJlZjogbGluay5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpIH0sIGdldE11bHRpKGxpbmssIFtcInRleHRcIiwgXCJ0eXBlXCJdKSkpO1xuICAgIH1cbiAgICByZXR1cm4gcHJvcGVydGllcztcbn1cblxuLyoqXG4gKiBFeHRyYWN0IHBvaW50cyBmcm9tIGEgdHJrc2VnIG9yIHJ0ZSBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBnZXRQb2ludHMkMShub2RlLCBwb2ludG5hbWUpIHtcbiAgICBjb25zdCBwdHMgPSAkKG5vZGUsIHBvaW50bmFtZSk7XG4gICAgY29uc3QgbGluZSA9IFtdO1xuICAgIGNvbnN0IHRpbWVzID0gW107XG4gICAgY29uc3QgZXh0ZW5kZWRWYWx1ZXMgPSB7fTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHB0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjID0gY29vcmRQYWlyJDEocHRzW2ldKTtcbiAgICAgICAgaWYgKCFjKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsaW5lLnB1c2goYy5jb29yZGluYXRlcyk7XG4gICAgICAgIGlmIChjLnRpbWUpXG4gICAgICAgICAgICB0aW1lcy5wdXNoKGMudGltZSk7XG4gICAgICAgIGZvciAoY29uc3QgW25hbWUsIHZhbF0gb2YgYy5leHRlbmRlZFZhbHVlcykge1xuICAgICAgICAgICAgY29uc3QgcGx1cmFsID0gbmFtZSA9PT0gXCJoZWFydFwiID8gbmFtZSA6IGAke25hbWUucmVwbGFjZShcImdweHRweDpcIiwgXCJcIil9c2A7XG4gICAgICAgICAgICBpZiAoIWV4dGVuZGVkVmFsdWVzW3BsdXJhbF0pIHtcbiAgICAgICAgICAgICAgICBleHRlbmRlZFZhbHVlc1twbHVyYWxdID0gQXJyYXkocHRzLmxlbmd0aCkuZmlsbChudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGV4dGVuZGVkVmFsdWVzW3BsdXJhbF1baV0gPSB2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGxpbmUubGVuZ3RoIDwgMilcbiAgICAgICAgcmV0dXJuOyAvLyBJbnZhbGlkIGxpbmUgaW4gR2VvSlNPTlxuICAgIHJldHVybiB7XG4gICAgICAgIGxpbmU6IGxpbmUsXG4gICAgICAgIHRpbWVzOiB0aW1lcyxcbiAgICAgICAgZXh0ZW5kZWRWYWx1ZXM6IGV4dGVuZGVkVmFsdWVzLFxuICAgIH07XG59XG4vKipcbiAqIEV4dHJhY3QgYSBMaW5lU3RyaW5nIGdlb21ldHJ5IGZyb20gYSBydGVcbiAqIGVsZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGdldFJvdXRlKG5zLCBub2RlKSB7XG4gICAgY29uc3QgbGluZSA9IGdldFBvaW50cyQxKG5vZGUsIFwicnRlcHRcIik7XG4gICAgaWYgKCFsaW5lKVxuICAgICAgICByZXR1cm47XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogXCJGZWF0dXJlXCIsXG4gICAgICAgIHByb3BlcnRpZXM6IE9iamVjdC5hc3NpZ24oeyBfZ3B4VHlwZTogXCJydGVcIiB9LCBleHRyYWN0UHJvcGVydGllcyhucywgbm9kZSksIGdldExpbmVTdHlsZShnZXQxKG5vZGUsIFwiZXh0ZW5zaW9uc1wiKSkpLFxuICAgICAgICBnZW9tZXRyeToge1xuICAgICAgICAgICAgdHlwZTogXCJMaW5lU3RyaW5nXCIsXG4gICAgICAgICAgICBjb29yZGluYXRlczogbGluZS5saW5lLFxuICAgICAgICB9LFxuICAgIH07XG59XG5mdW5jdGlvbiBnZXRUcmFjayhucywgbm9kZSkge1xuICAgIGNvbnN0IHNlZ21lbnRzID0gJChub2RlLCBcInRya3NlZ1wiKTtcbiAgICBjb25zdCB0cmFjayA9IFtdO1xuICAgIGNvbnN0IHRpbWVzID0gW107XG4gICAgY29uc3QgZXh0cmFjdGVkTGluZXMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpIHtcbiAgICAgICAgY29uc3QgbGluZSA9IGdldFBvaW50cyQxKHNlZ21lbnQsIFwidHJrcHRcIik7XG4gICAgICAgIGlmIChsaW5lKSB7XG4gICAgICAgICAgICBleHRyYWN0ZWRMaW5lcy5wdXNoKGxpbmUpO1xuICAgICAgICAgICAgaWYgKGxpbmUudGltZXM/Lmxlbmd0aClcbiAgICAgICAgICAgICAgICB0aW1lcy5wdXNoKGxpbmUudGltZXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChleHRyYWN0
1023ZWRMaW5lcy5sZW5ndGggPT09IDApXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGNvbnN0IG11bHRpID0gZXh0cmFjdGVkTGluZXMubGVuZ3RoID4gMTtcbiAgICBjb25zdCBwcm9wZXJ0aWVzID0gT2JqZWN0LmFzc2lnbih7IF9ncHhUeXBlOiBcInRya1wiIH0sIGV4dHJhY3RQcm9wZXJ0aWVzKG5zLCBub2RlKSwgZ2V0TGluZVN0eWxlKGdldDEobm9kZSwgXCJleHRlbnNpb25zXCIpKSwgdGltZXMubGVuZ3RoXG4gICAgICAgID8ge1xuICAgICAgICAgICAgY29vcmRpbmF0ZVByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICB0aW1lczogbXVsdGkgPyB0aW1lcyA6IHRpbWVzWzBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfVxuICAgICAgICA6IHt9KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4dHJhY3RlZExpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBleHRyYWN0ZWRMaW5lc1tpXTtcbiAgICAgICAgdHJhY2sucHVzaChsaW5lLmxpbmUpO1xuICAgICAgICBpZiAoIXByb3BlcnRpZXMuY29vcmRpbmF0ZVByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHByb3BlcnRpZXMuY29vcmRpbmF0ZVByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9wcyA9IHByb3BlcnRpZXMuY29vcmRpbmF0ZVByb3BlcnRpZXM7XG4gICAgICAgIC8vIEdlbmVyYWxseSBleHRlbmRlZFZhbHVlcyB3aWxsIGJlIHRoaW5ncyBsaWtlIGhlYXJ0XG4gICAgICAgIC8vIHJhdGUsIGFuZCB0aGlzIGlzIGFuIGFycmF5IGxpa2UgeyBoZWFydDogWzEwMCwgMTAxLi4uXSB9XG4gICAgICAgIGZvciAoY29uc3QgW25hbWUsIHZhbF0gb2YgT2JqZWN0LmVud
1023HJpZXMobGluZS5leHRlbmRlZFZhbHVlcykpIHtcbiAgICAgICAgICAgIGlmIChtdWx0aSkge1xuICAgICAgICAgICAgICAgIGlmICghcHJvcHNbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcHNbbmFtZV0gPSBleHRyYWN0ZWRMaW5lcy5tYXAoKGxpbmUpID0+IG5ldyBBcnJheShsaW5lLmxpbmUubGVuZ3RoKS5maWxsKG51bGwpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcHJvcHNbbmFtZV1baV0gPSB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcm9wc1tuYW1lXSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcIkZlYXR1cmVcIixcbiAgICAgICAgcHJvcGVydGllczogcHJvcGVydGllcyxcbiAgICAgICAgZ2VvbWV0cnk6IG11bHRpXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcIk11bHRpTGluZVN0cmluZ1wiLFxuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiB0cmFjayxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwiTGluZVN0cmluZ1wiLFxuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiB0cmFja1swXSxcbiAgICAgICAgICAgIH0sXG4gICAgfTtcbn1cbi8qKlxuICogRXh0cmFjdCBhIHBvaW50LCBpZiBwb3NzaWJsZSwgZnJvbSBhIGdpdmVuIG5vZGUsXG4gKiB3aGljaCBpcyB1c3VhbGx5IGEgd3B0IG9yIHRya3B0XG4gKi9cbmZ1bmN0aW9uIGdldFBvaW50KG5zLCBub2RlKSB7XG4gICAgY29uc3QgcHJvcGVydGllcyA9IE9iamVjdC5hc3NpZ24oZXh0cmFjdFByb3BlcnRpZXMobnMsIG5vZGUpLCBnZXRNdWx0aShub2RlLCBbXCJzeW1cIl0pKTtcbiAgICBjb25zdCBwYWlyID0gY29vcmRQYWlyJDEobm9kZSk7XG4gICAgaWYgKCFwYWlyKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcIkZlYXR1cmVcIixcbiAgICAgICAgcHJvcGVydGllcyxcbiAgICAgICAgZ2VvbWV0cnk6IHtcbiAgICAgICAgICAgIHR5cGU6IFwiUG9pbnRcIixcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBwYWlyLmNvb3JkaW5hdGVzLFxuICAgICAgICB9LFxuICAgIH07XG59XG4vKipcbiAqIENvbnZlcnQgR1BYIHRvIEdlb0pTT04gaW5jcmVtZW50YWxseSwgcmV0dXJuaW5nXG4gKiBhIFtHZW5lcmF0b3JdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvR3VpZGUvSXRlcmF0b3JzX2FuZF9HZW5lcmF0b3JzKVxuICogdGhhdCB5aWVsZHMgb3V0cHV0IGZlYXR1cmUgYnkgZmVhdHVyZS5cbiAqL1xuZnVuY3Rpb24qIGdweEdlbihub2RlKSB7XG4gICAgY29uc3QgbiA9IG5vZGU7XG4gICAgY29uc3QgR1BYWCA9IFwiZ3B4eFwiO1xuICAgIGNvbnN0IEdQWFhfVVJJID0gXCJodHRwOi8vd3d3Lmdhcm1pbi5jb20veG1sc2NoZW1hcy9HcHhFeHRlbnNpb25zL3YzXCI7XG4gICAgLy8gTmFtZXNwYWNlc1xuICAgIGNvbnN0IG5zID0gW1tHUFhYLCBHUFhYX1VSSV1dO1xuICAgIGNvbnN0IGF0dHJzID0gbi5nZXRFbGVtZW50c0J5VGFnTmFtZShcImdweFwiKVswXT8uYXR0cmlidXRlcztcbiAgICBpZiAoYXR0cnMpIHtcbiAgICAgICAgZm9yIChjb25zdCBhdHRyIG9mIEFycmF5LmZyb20oYXR0cnMpKSB7XG4gICAgICAgICAgICBpZiAoYXR0ci5uYW1lPy5zdGFydHNXaXRoKFwieG1sbnM6XCIpICYmIGF0dHIudmFsdWUgIT09IEdQWFhfVVJJKSB7XG4gICAgICAgICAgICAgICAgbnMucHVzaChbYXR0ci5uYW1lLCBhdHRyLnZhbHVlXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCB0cmFjayBvZiAkKG4sIFwidHJrXCIpKSB7XG4gICAgICAgIGNvbnN0IGZlYXR1cmUgPSBnZXRUcmFjayhucywgdHJhY2spO1xuICAgICAgICBpZiAoZmVhdHVyZSlcbiAgICAgICAgICAgIHlpZWxkIGZlYXR1cmU7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgcm91dGUgb2YgJChuLCBcInJ0ZVwiKSkge1xuICAgICAgICBjb25zdCBmZWF0dXJlID0gZ2V0Um91dGUobnMsIHJvdXRlKTtcbiAgICAgICAgaWYgKGZlYXR1cmUpXG4gICAgICAgICAgICB5aWVsZCBmZWF0dXJlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHdheXBvaW50IG9mICQobiwgXCJ3cHRcIikpIHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBnZXRQb2ludChucywgd2F5cG9pbnQpO1xuICAgICAgICBpZiAocG9pbnQpXG4gICAgICAgICAgICB5aWVsZCBwb2ludDtcbiAgICB9XG59XG4vKipcbiAqXG4gKiBDb252ZXJ0IGEgR1BYIGRvY3VtZW50IHRvIEdlb0pTT04uIFRoZSBmaXJzdCBhcmd1bWVudCwgYGRvY2AsIG11c3QgYmUgYSBHUFhcbiAqIGRvY3VtZW50IGFzIGFuIFhNTCBET00gLSBub3QgYXMgYSBzdHJpbmcuIFlvdSBjYW4gZ2V0IHRoaXMgdXNpbmcgalF1ZXJ5J3MgZGVmYXVsdFxuICogYC5hamF4YCBmdW5jdGlvbiBvciB1c2luZyBhIGJhcmUgWE1MSHR0cFJlcXVlc3Qgd2l0aCB0aGUgYC5yZXNwb25zZWAgcHJvcGVydHlcbiAqIGhvbGRpbmcgYW4gWE1MIERPTS5cbiAqXG4gKiBUaGUgb3V0cHV0IGlzIGEgSmF2YVNjcmlwdCBvYmplY3Qgb2YgR2VvSlNPTiBkYXRhLCBzYW1lIGFzIGAua21sYCBvdXRwdXRzLCB3aXRoIHRoZVxuICogYWRkaXRpb24gb2YgYSBgX2dweFR5cGVgIHByb3BlcnR5IG9uIGVhY2ggYExpbmVTdHJpbmdgIGZlYXR1cmUgdGhhdCBpbmRpY2F0ZXMgd2hldGhlclxuICogdGhlIGZlYXR1cmUgd2FzIGVuY29kZWQgYXMgYSByb3V0ZSAoYHJ0ZWApIG9yIHRyYWNrIChgdHJrYCkgaW4gdGhlIEdQWCBkb2N1bWVudC5cbiAqL1xuZnVuY3Rpb24gZ3B4KG5vZGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcIkZlYXR1cmVDb2xsZWN0aW9uXCIsXG4gICAgICAgIGZlYXR1cmVzOiBBcnJheS5mcm9tKGdweEdlbihub2RlKSksXG4gICAgfTtcbn1cblxuY29uc3QgRVhURU5TSU9OU19OUyA9IFwiaHR0cDovL3d3dy5nYXJtaW4uY29tL3htbHNjaGVtYXMvQWN0aXZpdHlFeHRlbnNpb24vdjJcIjtcbmNvbnN0IFRSQUNLUE9JTlRfQVRUUklCVVRFUyA9IFtcbiAgICBbXCJoZWFydFJhdGVcIiwgXCJo
1023ZWFydFJhdGVzXCJdLFxuICAgIFtcIkNhZGVuY2VcIiwgXCJjYWRlbmNlc1wiXSxcbiAgICAvLyBFeHRlbmRlZCBUcmFja3BvaW50IGF0dHJpYnV0ZXNcbiAgICBbXCJTcGVlZFwiLCBcInNwZWVkc1wiXSxcbiAgICBbXCJXYXR0c1wiLCBcIndhdHRzXCJdLFxuXTtcbmNvbnN0IExBUF9BVFRSSUJVVEVTID0gW1xuICAgIFtcIlRvdGFsVGltZVNlY29uZHNcIiwgXCJ0b3RhbFRpbWVTZWNvbmRzXCJdLFxuICAgIFtcIkRpc3RhbmNlTWV0ZXJzXCIsIFwiZGlzdGFuY2VNZXRlcnNcIl0sXG4gICAgW1wiTWF4aW11bVNwZWVkXCIsIFwibWF4U3BlZWRcIl0sXG4gICAgW1wiQXZlcmFnZUhlYXJ0UmF0ZUJwbVwiLCBcImF2Z0hlYXJ0UmF0ZVwiXSxcbiAgICBbXCJNYXhpbXVtSGVhcnRSYXRlQnBtXCIsIFwibWF4SGVhcnRSYXRlXCJdLFxuICAgIC8vIEV4dGVuZGVkIExhcCBhdHRyaWJ1dGVzXG4gICAgW1wiQXZnU3BlZWRcIiwgXCJhdmdTcGVlZFwiXSxcbiAgICBbXCJBdmdXYXR0c1wiLCBcImF2Z1dhdHRzXCJdLFxuICAgIFtcIk1heFdhdHRzXCIsIFwibWF4V2F0dHNcIl0sXG5dO1xuZnVuY3Rpb24gZ2V0UHJvcGVydGllcyhub2RlLCBhdHRyaWJ1dGVOYW1lcykge1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IFt0YWcsIGFsaWFzXSBvZiBhdHRyaWJ1dGVOYW1lcykge1xuICAgICAgICBsZXQgZWxlbSA9IGdldDEobm9kZSwgdGFnKTtcbiAgICAgICAgaWYgKCFlbGVtKSB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IG5vZGUuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhFWFRFTlNJT05TX05TLCB0YWcpO1xuICAgICAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGVsZW0gPSBlbGVtZW50c1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2YWwgPSBOdW1iZXIucGFyc2VGbG9hdChub2RlVmFsKGVsZW0pKTtcbiAgICAgICAgaWYgKCFOdW1iZXIuaXNOYU4odmFsKSkge1xuICAgICAgICAgICAgcHJvcGVydGllcy5wdXNoKFthbGlhcywgdmFsXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHByb3BlcnRpZXM7XG59XG5mdW5jdGlvbiBjb29yZFBhaXIobm9kZSkge1xuICAgIGNvbnN0IGxsID0gW251bTEobm9kZSwgXCJMb25naXR1ZGVEZWdyZWVzXCIpLCBudW0xKG5vZGUsIFwiTGF0aXR1ZGVEZWdyZWVzXCIpXTtcbiAgICBpZiAobGxbMF0gPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICBOdW1iZXIuaXNOYU4obGxbMF0pIHx8XG4gICAgICAgIGxsWzFdID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgTnVtYmVyLmlzTmFOKGxsWzFdKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgaGVhcnRSYXRlID0gZ2V0MShub2RlLCBcIkhlYXJ0UmF0ZUJwbVwiKTtcbiAgICBjb25zdCB0aW1lID0gbm9kZVZhbChnZXQxKG5vZGUsIFwiVGltZVwiKSk7XG4gICAgZ2V0MShub2RlLCBcIkFsdGl0dWRlTWV0ZXJzXCIsIChhbHQpID0+IHtcbiAgICAgICAgY29uc3QgYSA9IE51bWJlci5wYXJzZUZsb2F0KG5vZGVWYWwoYWx0KSk7XG4gICAgICAgIGlmICghTnVtYmVyLmlzTmFOKGEpKSB7XG4gICAgICAgICAgICBsbC5wdXNoKGEpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29vcmRpbmF0ZXM6IGxsLFxuICAgICAgICB0aW1lOiB0aW1lIHx8IG51bGwsXG4gICAgICAgIGhlYXJ0UmF0ZTogaGVhcnRSYXRlID8gTnVtYmVyLnBhcnNlRmxvYXQobm9kZVZhbChoZWFydFJhdGUpKSA6IG51bGwsXG4gICAgICAgIGV4dGVuc2lvbnM6IGdldFByb3BlcnRpZXMobm9kZSwgVFJBQ0tQT0lOVF9BVFRSSUJVVEVTKSxcbiAgICB9O1xufVxuZnVuY3Rpb24gZ2V0UG9pbnRzKG5vZGUpIHtcbiAgICBjb25zdCBwdHMgPSAkKG5vZGUsIFwiVHJhY2twb2ludFwiKTtcbiAgICBjb25zdCBsaW5lID0gW107XG4gICAgY29uc3QgdGltZXMgPSBbXTtcbiAgICBjb25zdCBoZWFydFJhdGVzID0gW107XG4gICAgaWYgKHB0cy5sZW5ndGggPCAyKVxuICAgICAgICByZXR1cm4gbnVsbDsgLy8gSW52YWxpZCBsaW5lIGluIEdlb0pTT05cbiAgICBjb25zdCBleHRlbmRlZFByb3BlcnRpZXMgPSB7fTtcbiAgICBjb25zdCByZXN1bHQgPSB7IGV4dGVuZGVkUHJvcGVydGllcyB9O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGMgPSBjb29yZFBhaXIocHRzW2ldKTtcbiAgICAgICAgaWYgKGMgPT09IG51bGwpXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgbGluZS5wdXNoKGMuY29vcmRpbmF0ZXMpO1xuICAgICAgICBjb25zdCB7IHRpbWUsIGhlYXJ0UmF0ZSwgZXh0ZW5zaW9ucyB9ID0gYztcbiAgICAgICAgaWYgKHRpbWUpXG4gICAgICAgICAgICB0aW1lcy5wdXNoKHRpbWUpO1xuICAgICAgICBpZiAoaGVhcnRSYXRlKVxuICAgICAgICAgICAgaGVhcnRSYXRlcy5wdXNoKGhlYXJ0UmF0ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW2FsaWFzLCB2YWx1ZV0gb2YgZXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgaWYgKCFleHRlbmRlZFByb3BlcnRpZXNbYWxpYXNdKSB7XG4gICAgICAgICAgICAgICAgZXh0ZW5kZWRQcm9wZXJ0aWVzW2FsaWFzXSA9IEFycmF5KHB0cy5sZW5ndGgpLmZpbGwobnVsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBleHRlbmRlZFByb3BlcnRpZXNbYWxpYXNdW2ldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGxpbmUubGVuZ3RoIDwgMilcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ocmVzdWx0LCB7XG4gICAgICAgIGxpbmU6IGxpbmUsXG4gICAgICAgIHRpbWVzOiB0aW1lcyxcbiAgICAgICAgaGVhcnRSYXRlczogaGVhcnRSYXRlcyxcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGdldExhcChub2RlKSB7XG4gICAgY29uc3Qgc2VnbWVudHMgPSAkKG5vZGUsIFwiVHJhY2tcIik7XG4gICAgY29uc3QgdHJhY2sgPSBbXTtcbiAgICBjb25zdCB0aW1lcyA9IFtdO1xuICAgIGNvbnN0IGhlYXJ0UmF0ZXMgPSBbXTtcbiAgICBjb25zdCBhbGxFeHRlbmRlZFByb3BlcnRpZXMgPSBbXTtcbiAgICBsZXQgbGluZTtcbiAgICBjb25zdCBwcm9wZXJ0aWVzID0gT2JqZWN0LmFzc2lnbihPYmplY3QuZnJvbUVudHJpZXMoZ2V0UHJvcGVydGllcyhub2RlLCBMQVBfQVRUUklCVVRFUykpLCBnZXQobm9kZSwgXCJOYW1lXCIsIChuYW1lRWxlbWVudCkgPT4ge1xuICAgICAgICByZXR1cm4geyBuYW1lOiBub2RlVmFsKG5hbWVFbGVtZW50KSB9O1xuICAgIH0pKTtcbiAgICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpIHtcbiAgICAgICAgbGluZSA9IGdldFBvaW50cyhzZWdtZW50KTtcbiAgICAgICAgaWYgKGxpbmUpIHtcbiAgICAgICAgICAgI
1023HRyYWNrLnB1c2gobGluZS5saW5lKTtcbiAgICAgICAgICAgIGlmIChsaW5lLnRpbWVzLmxlbmd0aClcbiAgICAgICAgICAgICAgICB0aW1lcy5wdXNoKGxpbmUudGltZXMpO1xuICAgICAgICAgICAgaWYgKGxpbmUuaGVhcnRSYXRlcy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgaGVhcnRSYXRlcy5wdXNoKGxpbmUuaGVhcnRSYXRlcyk7XG4gICAgICAgICAgICBhbGxFeHRlbmRlZFByb3BlcnRpZXMucHVzaChsaW5lLmV4dGVuZGVkUHJvcGVydGllcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbGxFeHRlbmRlZFByb3BlcnRpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZXh0ZW5kZWRQcm9wZXJ0aWVzID0gYWxsRXh0ZW5kZWRQcm9wZXJ0aWVzW2ldO1xuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIGV4dGVuZGVkUHJvcGVydGllcykge1xuICAgICAgICAgICAgaWYgKHNlZ21lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIGlmIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXNbcHJvcGVydHldID0gbGluZS5leHRlbmRlZFByb3BlcnRpZXNbcHJvcGVydHldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghcHJvcGVydGllc1twcm9wZXJ0eV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllc1twcm9wZXJ0eV0gPSB0cmFjay5tYXAoKHRyYWNrKSA9PiBBcnJheSh0cmFjay5sZW5ndGgpLmZpbGwobnVsbCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzW3Byb3BlcnR5XVtpXSA9IGV4dGVuZGVkUHJvcGVydGllc1twcm9wZXJ0eV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRyYWNrLmxlbmd0aCA9PT0gMClcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgaWYgKHRpbWVzLmxlbmd0aCB8fCBoZWFydFJhdGVzLmxlbmd0aCkge1xuICAgICAgICBwcm9wZXJ0aWVzLmNvb3JkaW5hdGVQcm9wZXJ0aWVzID0gT2JqZWN0LmFzc2lnbih0aW1lcy5sZW5ndGhcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIHRpbWVzOiB0cmFjay5sZW5ndGggPT09IDEgPyB0aW1lc1swXSA6IHRpbWVzLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7fSwgaGVhcnRSYXRlcy5sZW5ndGhcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGhlYXJ0OiB0cmFjay5sZW5ndGggPT09IDEgPyBoZWFydFJhdGVzWzBdIDogaGVhcnRSYXRlcyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge30pO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcIkZlYXR1cmVcIixcbiAgICAgICAgcHJvcGVydGllczogcHJvcGVydGllcyxcbiAgICAgICAgZ2VvbWV0cnk6IHRyYWNrLmxlbmd0aCA9PT0gMVxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJMaW5lU3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgY29vcmRpbmF0ZXM6IHRyYWNrWzBdLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJNdWx0aUxpbmVTdHJpbmdcIixcbiAgICAgICAgICAgICAgICBjb29yZGluYXRlczogdHJhY2ssXG4gICAgICAgICAgICB9LFxuICAgIH07XG59XG4vKipcbiAqIEluY3JlbWVudGFsbHkgY29udmVydCBhIFRDWCBkb2N1bWVudCB0byBHZW9KU09OLiBUaGVcbiAqIGZpcnN0IGFyZ3VtZW50LCBgZG9jYCwgbXVzdCBiZSBhIFRDWFxuICogZG9jdW1lbnQgYXMgYW4gWE1MIERPTSAtIG5vdCBhcyBhIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24qIHRjeEdlbihub2RlKSB7XG4gICAgZm9yIChjb25zdCBsYXAgb2YgJChub2RlLCBcIkxhcFwiKSkge1xuICAgICAgICBjb25zdCBmZWF0dXJlID0gZ2V0TGFwKGxhcCk7XG4gICAgICAgIGlmIChmZWF0dXJlKVxuICAgICAgICAgICAgeWllbGQgZmVhdHVyZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBjb3Vyc2Ugb2YgJChub2RlLCBcIkNvdXJzZXNcIikpIHtcbiAgICAgICAgY29uc3QgZmVhdHVyZSA9IGdldExhcChjb3Vyc2UpO1xuICAgICAgICBpZiAoZmVhdHVyZSlcbiAgICAgICAgICAgIHlpZWxkIGZlYXR1cmU7XG4gICAgfVxufVxuLyoqXG4gKiBDb252ZXJ0IGEgVENYIGRvY3VtZW50IHRvIEdlb0pTT04uIFRoZSBmaXJzdCBhcmd1bWVudCwgYGRvY2AsIG11c3QgYmUgYSBUQ1hcbiAqIGRvY3VtZW50IGFzIGFuIFhNTCBET00gLSBub3QgYXMgYSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIHRjeChub2RlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogXCJGZWF0dXJlQ29sbGVjdGlvblwiLFxuICAgICAgICBmZWF0dXJlczogQXJyYXkuZnJvbSh0Y3hHZW4obm9kZSkpLFxuICAgIH07XG59XG5cbmZ1bmN0aW9uIGZpeENvbG9yKHYsIHByZWZpeCkge1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7fTtcbiAgICBjb25zdCBjb2xvclByb3AgPSBwcmVmaXggPT09IFwic3Ryb2tlXCIgfHwgcHJlZml4ID09PSBcImZpbGxcIiA/IHByZWZpeCA6IGAke3ByZWZpeH0tY29sb3JgO1xuICAgIGlmICh2WzBdID09PSBcIiNcIikge1xuICAgICAgICB2ID0gdi5zdWJzdHJpbmcoMSk7XG4gICAgfVxuICAgIGlmICh2Lmxlbmd0aCA9PT0gNiB8fCB2Lmxlbmd0aCA9PT0gMykge1xuICAgICAgICBwcm9wZXJ0aWVzW2NvbG9yUHJvcF0gPSBgIyR7dn1gO1xuICAgIH1cbiAgICBlbHNlIGlmICh2Lmxlbmd0aCA9PT0gOCkge1xuICAgICAgICBwcm9wZXJ0aWVzW2Ake3ByZWZpeH0tb3BhY2l0eWBdID1cbiAgICAgICAgICAgIE51bWJlci5wYXJzZUludCh2LnN1YnN0cmluZygwLCAyKSwgMTYpIC8gMjU1O1xuICAgICAgICBwcm9wZXJ0aWVzW2NvbG9yUHJvcF0gPVxuICAgICAgICAgICAgYCMke3Yuc3Vic3RyaW5nKDYsIDgpfSR7di5zdWJzdHJpbmcoNCwgNil9JHt2LnN1YnN0cmluZygyLCA0KX1gO1xuICAgIH1cbiAgICByZXR1cm4gcHJvcGVydGllcztcbn1cblxuZnVuY3Rpb24gbnVtZXJpY1Byb3BlcnR5KG5vZGUsIHNvdXJjZSwgdGFyZ2V0KSB7XG4gICAgY29uc3QgcHJvcGVydGllcyA9IHt9O1xuICAgIG51bTEobm9kZSwgc291cmNlLCAodmFsKSA9PiB7XG4gICAgICAgI
1023HByb3BlcnRpZXNbdGFyZ2V0XSA9IHZhbDtcbiAgICB9KTtcbiAgICByZXR1cm4gcHJvcGVydGllcztcbn1cbmZ1bmN0aW9uIGdldENvbG9yKG5vZGUsIG91dHB1dCkge1xuICAgIHJldHVybiBnZXQobm9kZSwgXCJjb2xvclwiLCAoZWxlbSkgPT4gZml4Q29sb3Iobm9kZVZhbChlbGVtKSwgb3V0cHV0KSk7XG59XG5mdW5jdGlvbiBleHRyYWN0SWNvbkhyZWYobm9kZSkge1xuICAgIHJldHVybiBnZXQobm9kZSwgXCJJY29uXCIsIChpY29uLCBwcm9wZXJ0aWVzKSA9PiB7XG4gICAgICAgIHZhbDEoaWNvbiwgXCJocmVmXCIsIChocmVmKSA9PiB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzLmljb24gPSBocmVmO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHByb3BlcnRpZXM7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBleHRyYWN0SWNvbihub2RlKSB7XG4gICAgcmV0dXJuIGdldChub2RlLCBcIkljb25TdHlsZVwiLCAoaWNvblN0eWxlKSA9PiB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGdldENvbG9yKGljb25TdHlsZSwgXCJpY29uXCIpLCBudW1lcmljUHJvcGVydHkoaWNvblN0eWxlLCBcInNjYWxlXCIsIFwiaWNvbi1zY2FsZVwiKSwgbnVtZXJpY1Byb3BlcnR5KGljb25TdHlsZSwgXCJoZWFkaW5nXCIsIFwiaWNvbi1oZWFkaW5nXCIpLCBnZXQoaWNvblN0eWxlLCBcImhvdFNwb3RcIiwgKGhvdHNwb3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxlZnQgPSBOdW1iZXIucGFyc2VGbG9hdChob3RzcG90LmdldEF0dHJpYnV0ZShcInhcIikgfHwgXCJcIik7XG4gICAgICAgICAgICBjb25zdCB0b3AgPSBOdW1iZXIucGFyc2VGbG9hdChob3RzcG90LmdldEF0dHJpYnV0ZShcInlcIikgfHwgXCJcIik7XG4gICAgICAgICAgICBjb25zdCB4dW5pdHMgPSBob3RzcG90LmdldEF0dHJpYnV0ZShcInh1bml0c1wiKSB8fCBcIlwiO1xuICAgICAgICAgICAgY29uc3QgeXVuaXRzID0gaG90c3BvdC5nZXRBdHRyaWJ1dGUoXCJ5dW5pdHNcIikgfHwgXCJcIjtcbiAgICAgICAgICAgIGlmICghTnVtYmVyLmlzTmFOKGxlZnQpICYmICFOdW1iZXIuaXNOYU4odG9wKSlcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBcImljb24tb2Zmc2V0XCI6IFtsZWZ0LCB0b3BdLFxuICAgICAgICAgICAgICAgICAgICBcImljb24tb2Zmc2V0LXVuaXRzXCI6IFt4dW5pdHMsIHl1bml0c10sXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfSksIGV4dHJhY3RJY29uSHJlZihpY29uU3R5bGUpKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGV4dHJhY3RMYWJlbChub2RlKSB7XG4gICAgcmV0dXJuIGdldChub2RlLCBcIkxhYmVsU3R5bGVcIiwgKGxhYmVsU3R5bGUpID0+IHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oZ2V0Q29sb3IobGFiZWxTdHlsZSwgXCJsYWJlbFwiKSwgbnVtZXJpY1Byb3BlcnR5KGxhYmVsU3R5bGUsIFwic2NhbGVcIiwgXCJsYWJlbC1zY2FsZVwiKSk7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBleHRyYWN0TGluZShub2RlKSB7XG4gICAgcmV0dXJuIGdldChub2RlLCBcIkxpbmVTdHlsZVwiLCAobGluZVN0eWxlKSA9PiB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGdldENvbG9yKGxpbmVTdHlsZSwgXCJzdHJva2VcIiksIG51bWVyaWNQcm9wZXJ0eShsaW5lU3R5bGUsIFwid2lkdGhcIiwgXCJzdHJva2Utd2lkdGhcIikpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZXh0cmFjdFBvbHkobm9kZSkge1xuICAgIHJldHVybiBnZXQobm9kZSwgXCJQb2x5U3R5bGVcIiwgKHBvbHlTdHlsZSwgcHJvcGVydGllcykgPT4ge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihwcm9wZXJ0aWVzLCBnZXQocG9seVN0eWxlLCBcImNvbG9yXCIsIChlbGVtKSA9PiBmaXhDb2xvcihub2RlVmFsKGVsZW0pLCBcImZpbGxcIikpLCB2YWwxKHBvbHlTdHlsZSwgXCJmaWxsXCIsIChmaWxsKSA9PiB7XG4gICAgICAgICAgICBpZiAoZmlsbCA9PT0gXCIwXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgXCJmaWxsLW9wYWNpdHlcIjogMCB9O1xuICAgICAgICB9KSwgdmFsMShwb2x5U3R5bGUsIFwib3V0bGluZVwiLCAob3V0bGluZSkgPT4ge1xuICAgICAgICAgICAgaWYgKG91dGxpbmUgPT09IFwiMFwiKVxuICAgICAgICAgICAgICAgIHJldHVybiB7IFwic3Ryb2tlLW9wYWNpdHlcIjogMCB9O1xuICAgICAgICB9KSk7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBleHRyYWN0U3R5bGUobm9kZSkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBleHRyYWN0UG9seShub2RlKSwgZXh0cmFjdExpbmUobm9kZSksIGV4dHJhY3RMYWJlbChub2RlKSwgZXh0cmFjdEljb24obm9kZSkpO1xufVxuXG5jb25zdCByZW1vdmVTcGFjZSA9IC9cXHMqL2c7XG5jb25zdCB0cmltU3BhY2UgPSAvXlxccyp8XFxzKiQvZztcbmNvbnN0IHNwbGl0U3BhY2UgPSAvXFxzKy87XG4vKipcbiAqIEdldCBvbmUgY29vcmRpbmF0ZSBmcm9tIGEgY29vcmRpbmF0ZSBhcnJheSwgaWYgYW55XG4gKi9cbmZ1bmN0aW9uIGNvb3JkMSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZVxuICAgICAgICAucmVwbGFjZShyZW1vdmVTcGFjZSwgXCJcIilcbiAgICAgICAgLnNwbGl0KFwiLFwiKVxuICAgICAgICAubWFwKE51bWJlci5wYXJzZUZsb2F0KVxuICAgICAgICAuZmlsdGVyKChudW0pID0+ICFOdW1iZXIuaXNOYU4obnVtKSlcbiAgICAgICAgLnNsaWNlKDAsIDMpO1xufVxuLyoqXG4gKiBHZXQgYWxsIGNvb3JkaW5hdGVzIGZyb20gYSBjb29yZGluYXRlIGFycmF5IGFzIFtbXSxbXV1cbiAqL1xuZnVuY3Rpb24gY29vcmQodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgLnJlcGxhY2UodHJpbVNwYWNlLCBcIlwiKVxuICAgICAgICAuc3BsaXQoc3BsaXRTcGFjZSlcbiAgICAgICAgLm1hcChjb29yZDEpXG4gICAgICAgIC5maWx0ZXIoKGNvb3JkKSA9PiB7XG4gICAgICAgIHJldHVybiBjb29yZC5sZW5ndGggPj0gMjtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGd4Q29vcmRzKG5vZGUpIHtcbiAgICBsZXQgZWxlbXMgPSAkKG5vZGUsIFwiY29vcmRcIik7XG4gICAgaWYgKGVsZW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBlbGVtcyA9ICRucyhub2RlLCBcImNvb3JkXCIsIFwiKlwiKTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSBlbGVtcy5tYXAoKGVsZW0pID0+IHtcbiAgICAgICAgcmV0dXJuIG5vZGVWYWwoZWxlbSkuc3BsaXQoXCIgXCIpLm1hcChOdW1iZXIucGFyc2VGbG9hdCk7XG4gICAgfSk7XG4gICAgaWYgKGNvb3JkaW5hdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2VvbWV0cnk6IGNvb3JkaW5hdGVzLmxlbmd0aCA+IDJcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgI
1023HR5cGU6IFwiTGluZVN0cmluZ1wiLFxuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJQb2ludFwiLFxuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBjb29yZGluYXRlc1swXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIHRpbWVzOiAkKG5vZGUsIFwid2hlblwiKS5tYXAoKGVsZW0pID0+IG5vZGVWYWwoZWxlbSkpLFxuICAgIH07XG59XG5mdW5jdGlvbiBmaXhSaW5nKHJpbmcpIHtcbiAgICBpZiAocmluZy5sZW5ndGggPT09IDApXG4gICAgICAgIHJldHVybiByaW5nO1xuICAgIGNvbnN0IGZpcnN0ID0gcmluZ1swXTtcbiAgICBjb25zdCBsYXN0ID0gcmluZ1tyaW5nLmxlbmd0aCAtIDFdO1xuICAgIGxldCBlcXVhbCA9IHRydWU7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNYXRoLm1heChmaXJzdC5sZW5ndGgsIGxhc3QubGVuZ3RoKTsgaSsrKSB7XG4gICAgICAgIGlmIChmaXJzdFtpXSAhPT0gbGFzdFtpXSkge1xuICAgICAgICAgICAgZXF1YWwgPSBmYWxzZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICghZXF1YWwpIHtcbiAgICAgICAgcmV0dXJuIHJpbmcuY29uY2F0KFtyaW5nWzBdXSk7XG4gICAgfVxuICAgIHJldHVybiByaW5nO1xufVxuZnVuY3Rpb24gZ2V0Q29vcmRpbmF0ZXMobm9kZSkge1xuICAgIHJldHVybiBub2RlVmFsKGdldDEobm9kZSwgXCJjb29yZGluYXRlc1wiKSk7XG59XG5mdW5jdGlvbiBnZXRHZW9tZXRyeShub2RlKSB7XG4gICAgbGV0IGdlb21ldHJpZXMgPSBbXTtcbiAgICBsZXQgY29vcmRUaW1lcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkID0gbm9kZS5jaGlsZE5vZGVzLml0ZW0oaSk7XG4gICAgICAgIGlmIChpc0VsZW1lbnQoY2hpbGQpKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGNoaWxkLnRhZ05hbWUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiTXVsdGlHZW9tZXRyeVwiOlxuICAgICAgICAgICAgICAgIGNhc2UgXCJNdWx0aVRyYWNrXCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcImd4Ok11bHRpVHJhY2tcIjoge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZEdlb21ldHJpZXMgPSBnZXRHZW9tZXRyeShjaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgIGdlb21ldHJpZXMgPSBnZW9tZXRyaWVzLmNvbmNhdChjaGlsZEdlb21ldHJpZXMuZ2VvbWV0cmllcyk7XG4gICAgICAgICAgICAgICAgICAgIGNvb3JkVGltZXMgPSBjb29yZFRpbWVzLmNvbmNhdChjaGlsZEdlb21ldHJpZXMuY29vcmRUaW1lcyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIFwiUG9pbnRcIjoge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb29yZGluYXRlcyA9IGNvb3JkMShnZXRDb29yZGluYXRlcyhjaGlsZCkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29vcmRpbmF0ZXMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdlb21ldHJpZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJQb2ludFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgXCJMaW5lYXJSaW5nXCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcIkxpbmVTdHJpbmdcIjoge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb29yZGluYXRlcyA9IGNvb3JkKGdldENvb3JkaW5hdGVzKGNoaWxkKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29yZGluYXRlcy5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cmllcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIkxpbmVTdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIFwiUG9seWdvblwiOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvb3JkcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGxpbmVhclJpbmcgb2YgJChjaGlsZCwgXCJMaW5lYXJSaW5nXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByaW5nID0gZml4UmluZyhjb29yZChnZXRDb29yZGluYXRlcyhsaW5lYXJSaW5nKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJpbmcubGVuZ3RoID49IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZHMucHVzaChyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoY29vcmRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cmllcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIlBvbHlnb25cIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlczogY29vcmRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgXCJUcmFja1wiOlxuICAgICAgICAgICAgICAgIGNhc2UgXCJneDpUcmFja1wiOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGd4ID0gZ3hDb29yZHMoY2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWd4KVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgdGltZXMsIGdlb21ldHJ5IH0gPSBneDtcbiAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cmllcy5wdXNoKGdlb21ldHJ5KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVzLmxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkVGltZXMucHVzaCh0aW1lcyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgI
1023H1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBnZW9tZXRyaWVzLFxuICAgICAgICBjb29yZFRpbWVzLFxuICAgIH07XG59XG5cbmNvbnN0IHRvTnVtYmVyID0gKHgpID0+IE51bWJlcih4KTtcbmNvbnN0IHR5cGVDb252ZXJ0ZXJzID0ge1xuICAgIHN0cmluZzogKHgpID0+IHgsXG4gICAgaW50OiB0b051bWJlcixcbiAgICB1aW50OiB0b051bWJlcixcbiAgICBzaG9ydDogdG9OdW1iZXIsXG4gICAgdXNob3J0OiB0b051bWJlcixcbiAgICBmbG9hdDogdG9OdW1iZXIsXG4gICAgZG91YmxlOiB0b051bWJlcixcbiAgICBib29sOiAoeCkgPT4gQm9vbGVhbih4KSxcbn07XG5mdW5jdGlvbiBleHRyYWN0RXh0ZW5kZWREYXRhKG5vZGUsIHNjaGVtYSkge1xuICAgIHJldHVybiBnZXQobm9kZSwgXCJFeHRlbmRlZERhdGFcIiwgKGV4dGVuZGVkRGF0YSwgcHJvcGVydGllcykgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGRhdGEgb2YgJChleHRlbmRlZERhdGEsIFwiRGF0YVwiKSkge1xuICAgICAgICAgICAgcHJvcGVydGllc1tkYXRhLmdldEF0dHJpYnV0ZShcIm5hbWVcIikgfHwgXCJcIl0gPSBub2RlVmFsKGdldDEoZGF0YSwgXCJ2YWx1ZVwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBzaW1wbGVEYXRhIG9mICQoZXh0ZW5kZWREYXRhLCBcIlNpbXBsZURhdGFcIikpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBzaW1wbGVEYXRhLmdldEF0dHJpYnV0ZShcIm5hbWVcIikgfHwgXCJcIjtcbiAgICAgICAgICAgIGNvbnN0IHR5cGVDb252ZXJ0ZXIgPSBzY2hlbWFbbmFtZV0gfHwgdHlwZUNvbnZlcnRlcnMuc3RyaW5nO1xuICAgICAgICAgICAgcHJvcGVydGllc1tuYW1lXSA9IHR5cGVDb252ZXJ0ZXIobm9kZVZhbChzaW1wbGVEYXRhKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb3BlcnRpZXM7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBnZXRNYXliZUhUTUxEZXNjcmlwdGlvbihub2RlKSB7XG4gICAgY29uc3QgZGVzY3JpcHRpb25Ob2RlID0gZ2V0MShub2RlLCBcImRlc2NyaXB0aW9uXCIpO1xuICAgIGZvciAoY29uc3QgYyBvZiBBcnJheS5mcm9tKGRlc2NyaXB0aW9uTm9kZT8uY2hpbGROb2RlcyB8fCBbXSkpIHtcbiAgICAgICAgaWYgKGMubm9kZVR5cGUgPT09IDQpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgXCJAdHlwZVwiOiBcImh0bWxcIixcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IG5vZGVWYWwoYyksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHt9O1xufVxuZnVuY3Rpb24gZXh0cmFjdFRpbWVTcGFuKG5vZGUpIHtcbiAgICByZXR1cm4gZ2V0KG5vZGUsIFwiVGltZVNwYW5cIiwgKHRpbWVTcGFuKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0aW1lc3Bhbjoge1xuICAgICAgICAgICAgICAgIGJlZ2luOiBub2RlVmFsKGdldDEodGltZVNwYW4sIFwiYmVnaW5cIikpLFxuICAgICAgICAgICAgICAgIGVuZDogbm9kZVZhbChnZXQxKHRpbWVTcGFuLCBcImVuZFwiKSksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZXh0cmFjdFRpbWVTdGFtcChub2RlKSB7XG4gICAgcmV0dXJuIGdldChub2RlLCBcIlRpbWVTdGFtcFwiLCAodGltZVN0YW1wKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHRpbWVzdGFtcDogbm9kZVZhbChnZXQxKHRpbWVTdGFtcCwgXCJ3aGVuXCIpKSB9O1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZXh0cmFjdENhc2NhZGVkU3R5bGUobm9kZSwgc3R5bGVNYXApIHtcbiAgICByZXR1cm4gdmFsMShub2RlLCBcInN0eWxlVXJsXCIsIChzdHlsZVVybCkgPT4ge1xuICAgICAgICBzdHlsZVVybCA9IG5vcm1hbGl6ZUlkKHN0eWxlVXJsKTtcbiAgICAgICAgaWYgKHN0eWxlTWFwW3N0eWxlVXJsXSkge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oeyBzdHlsZVVybCB9LCBzdHlsZU1hcFtzdHlsZVVybF0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZvciBiYWNrd2FyZC1jb21wYXRpYmlsaXR5LiBTaG91bGQgd2Ugc3RpbGwgaW5jbHVkZVxuICAgICAgICAvLyBzdHlsZVVybCBldmVuIGlmIGl0J3Mgbm90IHJlc29sdmVkP1xuICAgICAgICByZXR1cm4geyBzdHlsZVVybCB9O1xuICAgIH0pO1xufVxudmFyIEFsdGl0dWRlTW9kZTtcbihmdW5jdGlvbiAoQWx0aXR1ZGVNb2RlKSB7XG4gICAgQWx0aXR1ZGVNb2RlW1wiQUJTT0xVVEVcIl0gPSBcImFic29sdXRlXCI7XG4gICAgQWx0aXR1ZGVNb2RlW1wiUkVMQVRJVkVfVE9fR1JPVU5EXCJdID0gXCJyZWxhdGl2ZVRvR3JvdW5kXCI7XG4gICAgQWx0aXR1ZGVNb2RlW1wiQ0xBTVBfVE9fR1JPVU5EXCJdID0gXCJjbGFtcFRvR3JvdW5kXCI7XG4gICAgQWx0aXR1ZGVNb2RlW1wiQ0xBTVBfVE9fU0VBRkxPT1JcIl0gPSBcImNsYW1wVG9TZWFGbG9vclwiO1xuICAgIEFsdGl0dWRlTW9kZVtcIlJFTEFUSVZFX1RPX1NFQUZMT09SXCJdID0gXCJyZWxhdGl2ZVRvU2VhRmxvb3JcIjtcbn0pKEFsdGl0dWRlTW9kZSB8fCAoQWx0aXR1ZGVNb2RlID0ge30pKTtcbmZ1bmN0aW9uIHByb2Nlc3NBbHRpdHVkZU1vZGUobW9kZSkge1xuICAgIHN3aXRjaCAobW9kZT8udGV4dENvbnRlbnQpIHtcbiAgICAgICAgY2FzZSBBbHRpdHVkZU1vZGUuQUJTT0xVVEU6XG4gICAgICAgICAgICByZXR1cm4gQWx0aXR1ZGVNb2RlLkFCU09MVVRFO1xuICAgICAgICBjYXNlIEFsdGl0dWRlTW9kZS5DTEFNUF9UT19HUk9VTkQ6XG4gICAgICAgICAgICByZXR1cm4gQWx0aXR1ZGVNb2RlLkNMQU1QX1RPX0dST1VORDtcbiAgICAgICAgY2FzZSBBbHRpdHVkZU1vZGUuQ0xBTVBfVE9fU0VBRkxPT1I6XG4gICAgICAgICAgICByZXR1cm4gQWx0aXR1ZGVNb2RlLkNMQU1QX1RPX1NFQUZMT09SO1xuICAgICAgICBjYXNlIEFsdGl0dWRlTW9kZS5SRUxBVElWRV9UT19HUk9VTkQ6XG4gICAgICAgICAgICByZXR1cm4gQWx0aXR1ZGVNb2RlLlJFTEFUSVZFX1RPX0dST1VORDtcbiAgICAgICAgY2FzZSBBbHRpdHVkZU1vZGUuUkVMQVRJVkVfVE9fU0VBRkxPT1I6XG4gICAgICAgICAgICByZXR1cm4gQWx0aXR1ZGVNb2RlLlJFTEFUSVZFX1RPX1NFQUZMT09SO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gZ2V0R3JvdW5kT3ZlcmxheUJveChub2RlKSB7XG4gICAgY29uc3QgbGF0TG9uUXVhZCA9IGdldDEobm9kZSwgXCJneDpMYXRMb25RdWFkXCIpO1xuICAgIGlmIChsYXRMb25RdWFkKSB7XG4gICAgICAgIGNvbnN0IHJpbmcgPSBmaXhSaW5nKGNvb3JkKGdldENvb3JkaW5hdGVzKG5vZGUpKSk7XG4gICAgICAgI
1023HJldHVybiB7XG4gICAgICAgICAgICBnZW9tZXRyeToge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwiUG9seWdvblwiLFxuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBbcmluZ10sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gZ2V0TGF0TG9uQm94KG5vZGUpO1xufVxuY29uc3QgREVHUkVFU19UT19SQURJQU5TID0gTWF0aC5QSSAvIDE4MDtcbmZ1bmN0aW9uIHJvdGF0ZUJveChiYm94LCBjb29yZGluYXRlcywgcm90YXRpb24pIHtcbiAgICBjb25zdCBjZW50ZXIgPSBbKGJib3hbMF0gKyBiYm94WzJdKSAvIDIsIChiYm94WzFdICsgYmJveFszXSkgLyAyXTtcbiAgICByZXR1cm4gW1xuICAgICAgICBjb29yZGluYXRlc1swXS5tYXAoKGNvb3JkaW5hdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGR5ID0gY29vcmRpbmF0ZVsxXSAtIGNlbnRlclsxXTtcbiAgICAgICAgICAgIGNvbnN0IGR4ID0gY29vcmRpbmF0ZVswXSAtIGNlbnRlclswXTtcbiAgICAgICAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5zcXJ0KGR5ICoqIDIgKyBkeCAqKiAyKTtcbiAgICAgICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5hdGFuMihkeSwgZHgpICsgcm90YXRpb24gKiBERUdSRUVTX1RPX1JBRElBTlM7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIGNlbnRlclswXSArIE1hdGguY29zKGFuZ2xlKSAqIGRpc3RhbmNlLFxuICAgICAgICAgICAgICAgIGNlbnRlclsxXSArIE1hdGguc2luKGFuZ2xlKSAqIGRpc3RhbmNlLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgfSksXG4gICAgXTtcbn1cbmZ1bmN0aW9uIGdldExhdExvbkJveChub2RlKSB7XG4gICAgY29uc3QgbGF0TG9uQm94ID0gZ2V0MShub2RlLCBcIkxhdExvbkJveFwiKTtcbiAgICBpZiAobGF0TG9uQm94KSB7XG4gICAgICAgIGNvbnN0IG5vcnRoID0gbnVtMShsYXRMb25Cb3gsIFwibm9ydGhcIik7XG4gICAgICAgIGNvbnN0IHdlc3QgPSBudW0xKGxhdExvbkJveCwgXCJ3ZXN0XCIpO1xuICAgICAgICBjb25zdCBlYXN0ID0gbnVtMShsYXRMb25Cb3gsIFwiZWFzdFwiKTtcbiAgICAgICAgY29uc3Qgc291dGggPSBudW0xKGxhdExvbkJveCwgXCJzb3V0aFwiKTtcbiAgICAgICAgY29uc3Qgcm90YXRpb24gPSBudW0xKGxhdExvbkJveCwgXCJyb3RhdGlvblwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBub3J0aCA9PT0gXCJudW1iZXJcIiAmJlxuICAgICAgICAgICAgdHlwZW9mIHNvdXRoID09PSBcIm51bWJlclwiICYmXG4gICAgICAgICAgICB0eXBlb2Ygd2VzdCA9PT0gXCJudW1iZXJcIiAmJlxuICAgICAgICAgICAgdHlwZW9mIGVhc3QgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGJib3ggPSBbd2VzdCwgc291dGgsIGVhc3QsIG5vcnRoXTtcbiAgICAgICAgICAgIGxldCBjb29yZGluYXRlcyA9IFtcbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgIFt3ZXN0LCBub3J0aF0sIC8vIHRvcCBsZWZ0XG4gICAgICAgICAgICAgICAgICAgIFtlYXN0LCBub3J0aF0sIC8vIHRvcCByaWdodFxuICAgICAgICAgICAgICAgICAgICBbZWFzdCwgc291dGhdLCAvLyB0b3AgcmlnaHRcbiAgICAgICAgICAgICAgICAgICAgW3dlc3QsIHNvdXRoXSwgLy8gYm90dG9tIGxlZnRcbiAgICAgICAgICAgICAgICAgICAgW3dlc3QsIG5vcnRoXSwgLy8gdG9wIGxlZnQgKGFnYWluKVxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiByb3RhdGlvbiA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzID0gcm90YXRlQm94KGJib3gsIGNvb3JkaW5hdGVzLCByb3RhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGJib3gsXG4gICAgICAgICAgICAgICAgZ2VvbWV0cnk6IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJQb2x5Z29uXCIsXG4gICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZ2V0R3JvdW5kT3ZlcmxheShub2RlLCBzdHlsZU1hcCwgc2NoZW1hLCBvcHRpb25zKSB7XG4gICAgY29uc3QgYm94ID0gZ2V0R3JvdW5kT3ZlcmxheUJveChub2RlKTtcbiAgICBjb25zdCBnZW9tZXRyeSA9IGJveD8uZ2VvbWV0cnkgfHwgbnVsbDtcbiAgICBpZiAoIWdlb21ldHJ5ICYmIG9wdGlvbnMuc2tpcE51bGxHZW9tZXRyeSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgZmVhdHVyZSA9IHtcbiAgICAgICAgdHlwZTogXCJGZWF0dXJlXCIsXG4gICAgICAgIGdlb21ldHJ5LFxuICAgICAgICBwcm9wZXJ0aWVzOiBPYmplY3QuYXNzaWduKFxuICAgICAgICAvKipcbiAgICAgICAgICogUmVsYXRlZCB0b1xuICAgICAgICAgKiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS90bWN3LzAzN2ExY2I2NjYwZDc0YTM5MmU5ZGE3NDQ2NTQwZjQ2XG4gICAgICAgICAqL1xuICAgICAgICB7IFwiQGdlb21ldHJ5LXR5cGVcIjogXCJncm91bmRvdmVybGF5XCIgfSwgZ2V0TXVsdGkobm9kZSwgW1xuICAgICAgICAgICAgXCJuYW1lXCIsXG4gICAgICAgICAgICBcImFkZHJlc3NcIixcbiAgICAgICAgICAgIFwidmlzaWJpbGl0eVwiLFxuICAgICAgICAgICAgXCJvcGVuXCIsXG4gICAgICAgICAgICBcInBob25lTnVtYmVyXCIsXG4gICAgICAgICAgICBcImRlc2NyaXB0aW9uXCIsXG4gICAgICAgIF0pLCBnZXRNYXliZUhUTUxEZXNjcmlwdGlvbihub2RlKSwgZXh0cmFjdENhc2NhZGVkU3R5bGUobm9kZSwgc3R5bGVNYXApLCBleHRyYWN0U3R5bGUobm9kZSksIGV4dHJhY3RJY29uSHJlZihub2RlKSwgZXh0cmFjdEV4dGVuZGVkRGF0YShub2RlLCBzY2hlbWEpLCBleHRyYWN0VGltZVNwYW4obm9kZSksIGV4dHJhY3RUaW1lU3RhbXAobm9kZSkpLFxuICAgIH07XG4gICAgaWYgKGJveD8uYmJveCkge1xuICAgICAgICBmZWF0dXJlLmJib3ggPSBib3guYmJveDtcbiAgICB9XG4gICAgaWYgKGZlYXR1cmUucHJvcGVydGllcz8udmlzaWJpbGl0eSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZlYXR1cmUucHJvcGVydGllcy52aXNpYmlsaXR5ID0gZmVhdHVyZS5wcm9wZXJ0aWVzLnZpc2liaWxpdHkgIT09IFwiMFwiO1xuICAgIH1cbiAgICBjb25zdCBpZCA9IG5vZGUuZ2V0QXR0cmlidXRlKFwiaWRcIik7XG4gICAgaWYgKGlkICE9PSBudWxsICYmIGlkICE9PSBcIlwiKVxuICAgICAgICBmZWF0dXJlLmlkID0gaWQ7XG4gICAgcmV0dXJuIGZlYXR1cmU7XG59XG5cbmZ1bmN0aW9uIGdldE5ldHdvcmtMaW5rUmVnaW9uKG5vZGUpIHtcbiAgICBjb25zdCByZWdpb24gPSBnZXQxKG5vZGUsIFwiUmVnaW9uXCIpO1xuICAgIGlmIChyZWdpb24pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvb3JkaW5hdGVCb3g6IGdldExhdExvbkFsdEJveChyZWdpb24pLFxuICAgICAgICAgICAgbG9kOiBnZXRMb2Qobm9kZSksXG4gICAgICAgI
1023H07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZ2V0TG9kKG5vZGUpIHtcbiAgICBjb25zdCBsb2QgPSBnZXQxKG5vZGUsIFwiTG9kXCIpO1xuICAgIGlmIChsb2QpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIG51bTEobG9kLCBcIm1pbkxvZFBpeGVsc1wiKSA/PyAtMSxcbiAgICAgICAgICAgIG51bTEobG9kLCBcIm1heExvZFBpeGVsc1wiKSA/PyAtMSxcbiAgICAgICAgICAgIG51bTEobG9kLCBcIm1pbkZhZGVFeHRlbnRcIikgPz8gbnVsbCxcbiAgICAgICAgICAgIG51bTEobG9kLCBcIm1heEZhZGVFeHRlbnRcIikgPz8gbnVsbCxcbiAgICAgICAgXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBnZXRMYXRMb25BbHRCb3gobm9kZSkge1xuICAgIGNvbnN0IGxhdExvbkFsdEJveCA9IGdldDEobm9kZSwgXCJMYXRMb25BbHRCb3hcIik7XG4gICAgaWYgKGxhdExvbkFsdEJveCkge1xuICAgICAgICBjb25zdCBub3J0aCA9IG51bTEobGF0TG9uQWx0Qm94LCBcIm5vcnRoXCIpO1xuICAgICAgICBjb25zdCB3ZXN0ID0gbnVtMShsYXRMb25BbHRCb3gsIFwid2VzdFwiKTtcbiAgICAgICAgY29uc3QgZWFzdCA9IG51bTEobGF0TG9uQWx0Qm94LCBcImVhc3RcIik7XG4gICAgICAgIGNvbnN0IHNvdXRoID0gbnVtMShsYXRMb25BbHRCb3gsIFwic291dGhcIik7XG4gICAgICAgIGNvbnN0IGFsdGl0dWRlTW9kZSA9IHByb2Nlc3NBbHRpdHVkZU1vZGUoZ2V0MShsYXRMb25BbHRCb3gsIFwiYWx0aXR1ZGVNb2RlXCIpIHx8XG4gICAgICAgICAgICBnZXQxKGxhdExvbkFsdEJveCwgXCJneDphbHRpdHVkZU1vZGVcIikpO1xuICAgICAgICBpZiAoYWx0aXR1ZGVNb2RlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiRW5jb3VudGVyZWQgYW4gdW5zdXBwb3J0ZWQgZmVhdHVyZSBvZiBLTUwgZm9yIHRvZ2VvanNvbjogcGxlYXNlIGNvbnRhY3QgZGV2ZWxvcGVycyBmb3Igc3VwcG9ydCBvZiBhbHRpdHVkZSBtb2RlLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG5vcnRoID09PSBcIm51bWJlclwiICYmXG4gICAgICAgICAgICB0eXBlb2Ygc291dGggPT09IFwibnVtYmVyXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiB3ZXN0ID09PSBcIm51bWJlclwiICYmXG4gICAgICAgICAgICB0eXBlb2YgZWFzdCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgY29uc3QgYmJveCA9IFt3ZXN0LCBzb3V0aCwgZWFzdCwgbm9ydGhdO1xuICAgICAgICAgICAgY29uc3QgY29vcmRpbmF0ZXMgPSBbXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICBbd2VzdCwgbm9ydGhdLCAvLyB0b3AgbGVmdFxuICAgICAgICAgICAgICAgICAgICBbZWFzdCwgbm9ydGhdLCAvLyB0b3AgcmlnaHRcbiAgICAgICAgICAgICAgICAgICAgW2Vhc3QsIHNvdXRoXSwgLy8gdG9wIHJpZ2h0XG4gICAgICAgICAgICAgICAgICAgIFt3ZXN0LCBzb3V0aF0sIC8vIGJvdHRvbSBsZWZ0XG4gICAgICAgICAgICAgICAgICAgIFt3ZXN0LCBub3J0aF0sIC8vIHRvcCBsZWZ0IChhZ2FpbilcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYmJveCxcbiAgICAgICAgICAgICAgICBnZW9tZXRyeToge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIlBvbHlnb25cIixcbiAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBnZXRMaW5rT2JqZWN0KG5vZGUpIHtcbiAgICAvKlxuICAgICAgPExpbmsgaWQ9XCJJRFwiPlxuICAgICAgICA8IS0tIHNwZWNpZmljIHRvIExpbmsgLS0+XG4gICAgICAgIDxocmVmPi4uLjwvaHJlZj4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBzdHJpbmcgLS0+XG4gICAgICAgIDxyZWZyZXNoTW9kZT5vbkNoYW5nZTwvcmVmcmVzaE1vZGU+XG4gICAgICAgICAgPCEtLSByZWZyZXNoTW9kZUVudW06IG9uQ2hhbmdlLCBvbkludGVydmFsLCBvciBvbkV4cGlyZSAtLT5cbiAgICAgICAgPHJlZnJlc2hJbnRlcnZhbD40PC9yZWZyZXNoSW50ZXJ2YWw+ICA8IS0tIGZsb2F0IC0tPlxuICAgICAgICA8dmlld1JlZnJlc2hNb2RlPm5ldmVyPC92aWV3UmVmcmVzaE1vZGU+XG4gICAgICAgICAgPCEtLSB2aWV3UmVmcmVzaE1vZGVFbnVtOiBuZXZlciwgb25TdG9wLCBvblJlcXVlc3QsIG9uUmVnaW9uIC0tPlxuICAgICAgICA8dmlld1JlZnJlc2hUaW1lPjQ8L3ZpZXdSZWZyZXNoVGltZT4gIDwhLS0gZmxvYXQgLS0+XG4gICAgICAgIDx2aWV3Qm91bmRTY2FsZT4xPC92aWV3Qm91bmRTY2FsZT4gICAgPCEtLSBmbG9hdCAtLT5cbiAgICAgICAgPHZpZXdGb3JtYXQ+QkJPWD1bYmJveFdlc3RdLFtiYm94U291dGhdLFtiYm94RWFzdF0sW2Jib3hOb3J0aF08L3ZpZXdGb3JtYXQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBzdHJpbmcgLS0+XG4gICAgICAgIDxodHRwUXVlcnk+Li4uPC9odHRwUXVlcnk+ICAgICAgICAgICAgPCEtLSBzdHJpbmcgLS0+XG4gICAgICA8L0xpbms+XG4gICAgKi9cbiAgICBjb25zdCBsaW5rT2JqID0gZ2V0MShub2RlLCBcIkxpbmtcIik7XG4gICAgaWYgKGxpbmtPYmopIHtcbiAgICAgICAgcmV0dXJuIGdldE11bHRpKGxpbmtPYmosIFtcbiAgICAgICAgICAgIFwiaHJlZlwiLFxuICAgICAgICAgICAgXCJyZWZyZXNoTW9kZVwiLFxuICAgICAgICAgICAgXCJyZWZyZXNoSW50ZXJ2YWxcIixcbiAgICAgICAgICAgIFwidmlld1JlZnJlc2hNb2RlXCIsXG4gICAgICAgICAgICBcInZpZXdSZWZyZXNoVGltZVwiLFxuICAgICAgICAgICAgXCJ2aWV3Qm91bmRTY2FsZVwiLFxuICAgICAgICAgICAgXCJ2aWV3Rm9ybWF0XCIsXG4gICAgICAgICAgICBcImh0dHBRdWVyeVwiLFxuICAgICAgICBdKTtcbiAgICB9XG4gICAgcmV0dXJuIHt9O1xufVxuZnVuY3Rpb24gZ2V0TmV0d29ya0xpbmsobm9kZSwgc3R5bGVNYXAsIHNjaGVtYSwgb3B0aW9ucykge1xuICAgIGNvbnN0IGJveCA9IGdldE5ldHdvcmtMaW5rUmVnaW9uKG5vZGUpO1xuICAgIGNvbnN0IGdlb21ldHJ5ID0gYm94Py5jb29yZGluYX
1023RlQm94Py5nZW9tZXRyeSB8fCBudWxsO1xuICAgIGlmICghZ2VvbWV0cnkgJiYgb3B0aW9ucy5za2lwTnVsbEdlb21ldHJ5KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBmZWF0dXJlID0ge1xuICAgICAgICB0eXBlOiBcIkZlYXR1cmVcIixcbiAgICAgICAgZ2VvbWV0cnksXG4gICAgICAgIHByb3BlcnRpZXM6IE9iamVjdC5hc3NpZ24oXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZWxhdGVkIHRvXG4gICAgICAgICAqIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL3RtY3cvMDM3YTFjYjY2NjBkNzRhMzkyZTlkYTc0NDY1NDBmNDZcbiAgICAgICAgICovXG4gICAgICAgIHsgXCJAZ2VvbWV0cnktdHlwZVwiOiBcIm5ldHdvcmtsaW5rXCIgfSwgZ2V0TXVsdGkobm9kZSwgW1xuICAgICAgICAgICAgXCJuYW1lXCIsXG4gICAgICAgICAgICBcImFkZHJlc3NcIixcbiAgICAgICAgICAgIFwidmlzaWJpbGl0eVwiLFxuICAgICAgICAgICAgXCJvcGVuXCIsXG4gICAgICAgICAgICBcInBob25lTnVtYmVyXCIsXG4gICAgICAgICAgICBcInN0eWxlVXJsXCIsXG4gICAgICAgICAgICBcInJlZnJlc2hWaXNpYmlsaXR5XCIsXG4gICAgICAgICAgICBcImZseVRvVmlld1wiLFxuICAgICAgICAgICAgXCJkZXNjcmlwdGlvblwiLFxuICAgICAgICBdKSwgZ2V0TWF5YmVIVE1MRGVzY3JpcHRpb24obm9kZSksIGV4dHJhY3RDYXNjYWRlZFN0eWxlKG5vZGUsIHN0eWxlTWFwKSwgZXh0cmFjdFN0eWxlKG5vZGUpLCBleHRyYWN0SWNvbkhyZWYobm9kZSksIGV4dHJhY3RFeHRlbmRlZERhdGEobm9kZSwgc2NoZW1hKSwgZXh0cmFjdFRpbWVTcGFuKG5vZGUpLCBleHRyYWN0VGltZVN0YW1wKG5vZGUpLCBnZXRMaW5rT2JqZWN0KG5vZGUpLCBib3g/LmxvZCA/IHsgbG9kOiBib3gubG9kIH0gOiB7fSksXG4gICAgfTtcbiAgICBpZiAoYm94Py5jb29yZGluYXRlQm94Py5iYm94KSB7XG4gICAgICAgIGZlYXR1cmUuYmJveCA9IGJveC5jb29yZGluYXRlQm94LmJib3g7XG4gICAgfVxuICAgIGlmIChmZWF0dXJlLnByb3BlcnRpZXM/LnZpc2liaWxpdHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBmZWF0dXJlLnByb3BlcnRpZXMudmlzaWJpbGl0eSA9IGZlYXR1cmUucHJvcGVydGllcy52aXNpYmlsaXR5ICE9PSBcIjBcIjtcbiAgICB9XG4gICAgY29uc3QgaWQgPSBub2RlLmdldEF0dHJpYnV0ZShcImlkXCIpO1xuICAgIGlmIChpZCAhPT0gbnVsbCAmJiBpZCAhPT0gXCJcIilcbiAgICAgICAgZmVhdHVyZS5pZCA9IGlkO1xuICAgIHJldHVybiBmZWF0dXJlO1xufVxuXG5mdW5jdGlvbiBnZW9tZXRyeUxpc3RUb0dlb21ldHJ5KGdlb21ldHJpZXMpIHtcbiAgICByZXR1cm4gZ2VvbWV0cmllcy5sZW5ndGggPT09IDBcbiAgICAgICAgPyBudWxsXG4gICAgICAgIDogZ2VvbWV0cmllcy5sZW5ndGggPT09IDFcbiAgICAgICAgICAgID8gZ2VvbWV0cmllc1swXVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJHZW9tZXRyeUNvbGxlY3Rpb25cIixcbiAgICAgICAgICAgICAgICBnZW9tZXRyaWVzLFxuICAgICAgICAgICAgfTtcbn1cbmZ1bmN0aW9uIGdldFBsYWNlbWFyayhub2RlLCBzdHlsZU1hcCwgc2NoZW1hLCBvcHRpb25zKSB7XG4gICAgY29uc3QgeyBjb29yZFRpbWVzLCBnZW9tZXRyaWVzIH0gPSBnZXRHZW9tZXRyeShub2RlKTtcbiAgICBjb25zdCBnZW9tZXRyeSA9IGdlb21ldHJ5TGlzdFRvR2VvbWV0cnkoZ2VvbWV0cmllcyk7XG4gICAgaWYgKCFnZW9tZXRyeSAmJiBvcHRpb25zLnNraXBOdWxsR2VvbWV0cnkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IGZlYXR1cmUgPSB7XG4gICAgICAgIHR5cGU6IFwiRmVhdHVyZVwiLFxuICAgICAgICBnZW9tZXRyeSxcbiAgICAgICAgcHJvcGVydGllczogT2JqZWN0LmFzc2lnbihnZXRNdWx0aShub2RlLCBbXG4gICAgICAgICAgICBcIm5hbWVcIixcbiAgICAgICAgICAgIFwiYWRkcmVzc1wiLFxuICAgICAgICAgICAgXCJ2aXNpYmlsaXR5XCIsXG4gICAgICAgICAgICBcIm9wZW5cIixcbiAgICAgICAgICAgIFwicGhvbmVOdW1iZXJcIixcbiAgICAgICAgICAgIFwiZGVzY3JpcHRpb25cIixcbiAgICAgICAgXSksIGdldE1heWJlSFRNTERlc2NyaXB0aW9uKG5vZGUpLCBleHRyYWN0Q2FzY2FkZWRTdHlsZShub2RlLCBzdHlsZU1hcCksIGV4dHJhY3RTdHlsZShub2RlKSwgZXh0cmFjdEV4dGVuZGVkRGF0YShub2RlLCBzY2hlbWEpLCBleHRyYWN0VGltZVNwYW4obm9kZSksIGV4dHJhY3RUaW1lU3RhbXAobm9kZSksIGNvb3JkVGltZXMubGVuZ3RoXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBjb29yZGluYXRlUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICB0aW1lczogY29vcmRUaW1lcy5sZW5ndGggPT09IDEgPyBjb29yZFRpbWVzWzBdIDogY29vcmRUaW1lcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7fSksXG4gICAgfTtcbiAgICBpZiAoZmVhdHVyZS5wcm9wZXJ0aWVzPy52aXNpYmlsaXR5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZmVhdHVyZS5wcm9wZXJ0aWVzLnZpc2liaWxpdHkgPSBmZWF0dXJlLnByb3BlcnRpZXMudmlzaWJpbGl0eSAhPT0gXCIwXCI7XG4gICAgfVxuICAgIGNvbnN0IGlkID0gbm9kZS5nZXRBdHRyaWJ1dGUoXCJpZFwiKTtcbiAgICBpZiAoaWQgIT09IG51bGwgJiYgaWQgIT09IFwiXCIpXG4gICAgICAgIGZlYXR1cmUuaWQgPSBpZDtcbiAgICByZXR1cm4gZmVhdHVyZTtcbn1cblxuZnVuY3Rpb24gZ2V0U3R5bGVJZChzdHlsZSkge1xuICAgIGxldCBpZCA9IHN0eWxlLmdldEF0dHJpYnV0ZShcImlkXCIpO1xuICAgIGNvbnN0IHBhcmVudE5vZGUgPSBzdHlsZS5wYXJlbnROb2RlO1xuICAgIGlmICghaWQgJiZcbiAgICAgICAgaXNFbGVtZW50KHBhcmVudE5vZGUpICYmXG4gICAgICAgIHBhcmVudE5vZGUubG9jYWxOYW1lID09PSBcIkNhc2NhZGluZ1N0eWxlXCIpIHtcbiAgICAgICAgaWQgPSBwYXJlbnROb2RlLmdldEF0dHJpYnV0ZShcImttbDppZFwiKSB8fCBwYXJlbnROb2RlLmdldEF0dHJpYnV0ZShcImlkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gbm9ybWFsaXplSWQoaWQgfHwgXCJcIik7XG59XG5mdW5jdGlvbiBidWlsZFN0eWxlTWFwKG5vZGUpIHtcbiAgICBjb25zdCBzdHlsZU1hcCA9IHt9O1xuICAgIGZvciAoY29uc3Qgc3R5bGUgb2YgJChub2RlLCBcIlN0eWxlXCIpKSB7XG4gICAgICAgI
1023HN0eWxlTWFwW2dldFN0eWxlSWQoc3R5bGUpXSA9IGV4dHJhY3RTdHlsZShzdHlsZSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgbWFwIG9mICQobm9kZSwgXCJTdHlsZU1hcFwiKSkge1xuICAgICAgICBjb25zdCBpZCA9IG5vcm1hbGl6ZUlkKG1hcC5nZXRBdHRyaWJ1dGUoXCJpZFwiKSB8fCBcIlwiKTtcbiAgICAgICAgdmFsMShtYXAsIFwic3R5bGVVcmxcIiwgKHN0eWxlVXJsKSA9PiB7XG4gICAgICAgICAgICBzdHlsZVVybCA9IG5vcm1hbGl6ZUlkKHN0eWxlVXJsKTtcbiAgICAgICAgICAgIGlmIChzdHlsZU1hcFtzdHlsZVVybF0pIHtcbiAgICAgICAgICAgICAgICBzdHlsZU1hcFtpZF0gPSBzdHlsZU1hcFtzdHlsZVVybF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc3R5bGVNYXA7XG59XG5mdW5jdGlvbiBidWlsZFNjaGVtYShub2RlKSB7XG4gICAgY29uc3Qgc2NoZW1hID0ge307XG4gICAgZm9yIChjb25zdCBmaWVsZCBvZiAkKG5vZGUsIFwiU2ltcGxlRmllbGRcIikpIHtcbiAgICAgICAgc2NoZW1hW2ZpZWxkLmdldEF0dHJpYnV0ZShcIm5hbWVcIikgfHwgXCJcIl0gPVxuICAgICAgICAgICAgdHlwZUNvbnZlcnRlcnNbZmllbGQuZ2V0QXR0cmlidXRlKFwidHlwZVwiKSB8fCBcIlwiXSB8fCB0eXBlQ29udmVydGVycy5zdHJpbmc7XG4gICAgfVxuICAgIHJldHVybiBzY2hlbWE7XG59XG5jb25zdCBGT0xERVJfUFJPUFMgPSBbXG4gICAgXCJuYW1lXCIsXG4gICAgXCJ2aXNpYmlsaXR5XCIsXG4gICAgXCJvcGVuXCIsXG4gICAgXCJhZGRyZXNzXCIsXG4gICAgXCJkZXNjcmlwdGlvblwiLFxuICAgIFwicGhvbmVOdW1iZXJcIixcbiAgICBcInZpc2liaWxpdHlcIixcbl07XG5mdW5jdGlvbiBnZXRGb2xkZXIobm9kZSkge1xuICAgIGNvbnN0IG1ldGEgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIEFycmF5LmZyb20obm9kZS5jaGlsZE5vZGVzKSkge1xuICAgICAgICBpZiAoaXNFbGVtZW50KGNoaWxkKSAmJiBGT0xERVJfUFJPUFMuaW5jbHVkZXMoY2hpbGQudGFnTmFtZSkpIHtcbiAgICAgICAgICAgIG1ldGFbY2hpbGQudGFnTmFtZV0gPSBub2RlVmFsKGNoaWxkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcImZvbGRlclwiLFxuICAgICAgICBtZXRhLFxuICAgICAgICBjaGlsZHJlbjogW10sXG4gICAgfTtcbn1cbi8qKlxuICogWWllbGQgYSBuZXN0ZWQgdHJlZSB3aXRoIEtNTCBmb2xkZXIgc3RydWN0dXJlXG4gKlxuICogVGhpcyBnZW5lcmF0ZXMgYSB0cmVlIHdpdGggdGhlIGdpdmVuIHN0cnVjdHVyZTpcbiAqXG4gKiBgYGBqc1xuICoge1xuICogICBcInR5cGVcIjogXCJyb290XCIsXG4gKiAgIFwiY2hpbGRyZW5cIjogW1xuICogICAgIHtcbiAqICAgICAgIFwidHlwZVwiOiBcImZvbGRlclwiLFxuICogICAgICAgXCJtZXRhXCI6IHtcbiAqICAgICAgICAgXCJuYW1lXCI6IFwiVGVzdFwiXG4gKiAgICAgICB9LFxuICogICAgICAgXCJjaGlsZHJlblwiOiBbXG4gKiAgICAgICAgICAvLyAuLi5mZWF0dXJlcyBhbmQgZm9sZGVyc1xuICogICAgICAgXVxuICogICAgIH1cbiAqICAgICAvLyAuLi5mZWF0dXJlc1xuICogICBdXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMgR3JvdW5kT3ZlcmxheVxuICpcbiAqIEdyb3VuZE92ZXJsYXkgZWxlbWVudHMgYXJlIGNvbnZlcnRlZCBpbnRvXG4gKiBgRmVhdHVyZWAgb2JqZWN0cyB3aXRoIGBQb2x5Z29uYCBnZW9tZXRyaWVzLFxuICogYSBwcm9wZXJ0eSBsaWtlOlxuICpcbiAqIGBgYGpzb25cbiAqIHtcbiAqICAgXCJAZ2VvbWV0cnktdHlwZVwiOiBcImdyb3VuZG92ZXJsYXlcIlxuICogfVxuICogYGBgXG4gKlxuICogQW5kIHRoZSBncm91bmQgb3ZlcmxheSdzIGltYWdlIFVSTCBpbiB0aGUgYGhyZWZgXG4gKiBwcm9wZXJ0eS4gR3JvdW5kIG92ZXJsYXlzIHdpbGwgbmVlZCB0byBiZSBkaXNwbGF5ZWRcbiAqIHdpdGggYSBzZXBhcmF0ZSBtZXRob2QgdG8gb3RoZXIgZmVhdHVyZXMsIGRlcGVuZGluZ1xuICogb24gd2hpY2ggbWFwIGZyYW1ld29yayB5b3UncmUgdXNpbmcuXG4gKi9cbmZ1bmN0aW9uIGttbFdpdGhGb2xkZXJzKG5vZGUsIG9wdGlvbnMgPSB7XG4gICAgc2tpcE51bGxHZW9tZXRyeTogZmFsc2UsXG59KSB7XG4gICAgY29uc3QgbiA9IG5vZGU7XG4gICAgY29uc3Qgc3R5bGVNYXAgPSBidWlsZFN0eWxlTWFwKG4pO1xuICAgIGNvbnN0IHNjaGVtYSA9IGJ1aWxkU2NoZW1hKG4pO1xuICAgIGNvbnN0IHRyZWUgPSB7IHR5cGU6IFwicm9vdFwiLCBjaGlsZHJlbjogW10gfTtcbiAgICBmdW5jdGlvbiB0cmF2ZXJzZShub2RlLCBwb2ludGVyLCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChpc0VsZW1lbnQobm9kZSkpIHtcbiAgICAgICAgICAgIHN3aXRjaCAobm9kZS50YWdOYW1lKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcIkdyb3VuZE92ZXJsYXlcIjoge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwbGFjZW1hcmsgPSBnZXRHcm91bmRPdmVybGF5KG5vZGUsIHN0eWxlTWFwLCBzY2hlbWEsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGxhY2VtYXJrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb2ludGVyLmNoaWxkcmVuLnB1c2gocGxhY2VtYXJrKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSBcIlBsYWNlbWFya1wiOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYWNlbWFyayA9IGdldFBsYWNlbWFyayhub2RlLCBzdHlsZU1hcCwgc2NoZW1hLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBsYWNlbWFyaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRlci5jaGlsZHJlbi5wdXNoKHBsYWNlbWFyayk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgXCJGb2xkZXJcIjoge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgI
1023HBvaW50ZXIuY2hpbGRyZW4ucHVzaChmb2xkZXIpO1xuICAgICAgICAgICAgICAgICAgICBwb2ludGVyID0gZm9sZGVyO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSBcIk5ldHdvcmtMaW5rXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV0d29ya0xpbmsgPSBnZXROZXR3b3JrTGluayhub2RlLCBzdHlsZU1hcCwgc2NoZW1hLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5ldHdvcmtMaW5rKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb2ludGVyLmNoaWxkcmVuLnB1c2gobmV0d29ya0xpbmspO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZS5jaGlsZE5vZGVzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRyYXZlcnNlKG5vZGUuY2hpbGROb2Rlc1tpXSwgcG9pbnRlciwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgdHJhdmVyc2UobiwgdHJlZSwgb3B0aW9ucyk7XG4gICAgcmV0dXJuIHRyZWU7XG59XG4vKipcbiAqIENvbnZlcnQgS01MIHRvIEdlb0pTT04gaW5jcmVtZW50YWxseSwgcmV0dXJuaW5nXG4gKiBhIFtHZW5lcmF0b3JdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvR3VpZGUvSXRlcmF0b3JzX2FuZF9HZW5lcmF0b3JzKVxuICogdGhhdCB5aWVsZHMgb3V0cHV0IGZlYXR1cmUgYnkgZmVhdHVyZS5cbiAqL1xuZnVuY3Rpb24qIGttbEdlbihub2RlLCBvcHRpb25zID0ge1xuICAgIHNraXBOdWxsR2VvbWV0cnk6IGZhbHNlLFxufSkge1xuICAgIGNvbnN0IG4gPSBub2RlO1xuICAgIGNvbnN0IHN0eWxlTWFwID0gYnVpbGRTdHlsZU1hcChuKTtcbiAgICBjb25zdCBzY2hlbWEgPSBidWlsZFNjaGVtYShuKTtcbiAgICBmb3IgKGNvbnN0IHBsYWNlbWFyayBvZiAkKG4sIFwiUGxhY2VtYXJrXCIpKSB7XG4gICAgICAgIGNvbnN0IGZlYXR1cmUgPSBnZXRQbGFjZW1hcmsocGxhY2VtYXJrLCBzdHlsZU1hcCwgc2NoZW1hLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKGZlYXR1cmUpXG4gICAgICAgICAgICB5aWVsZCBmZWF0dXJlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGdyb3VuZE92ZXJsYXkgb2YgJChuLCBcIkdyb3VuZE92ZXJsYXlcIikpIHtcbiAgICAgICAgY29uc3QgZmVhdHVyZSA9IGdldEdyb3VuZE92ZXJsYXkoZ3JvdW5kT3ZlcmxheSwgc3R5bGVNYXAsIHNjaGVtYSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChmZWF0dXJlKVxuICAgICAgICAgICAgeWllbGQgZmVhdHVyZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBuZXR3b3JrTGluayBvZiAkKG4sIFwiTmV0d29ya0xpbmtcIikpIHtcbiAgICAgICAgY29uc3QgZmVhdHVyZSA9IGdldE5ldHdvcmtMaW5rKG5ldHdvcmtMaW5rLCBzdHlsZU1hcCwgc2NoZW1hLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKGZlYXR1cmUpXG4gICAgICAgICAgICB5aWVsZCBmZWF0dXJlO1xuICAgIH1cbn1cbi8qKlxuICogQ29udmVydCBhIEtNTCBkb2N1bWVudCB0byBHZW9KU09OLiBUaGUgZmlyc3QgYXJndW1lbnQsIGBkb2NgLCBtdXN0IGJlIGEgS01MXG4gKiBkb2N1bWVudCBhcyBhbiBYTUwgRE9NIC0gbm90IGFzIGEgc3RyaW5nLiBZb3UgY2FuIGdldCB0aGlzIHVzaW5nIGpRdWVyeSdzIGRlZmF1bHRcbiAqIGAuYWpheGAgZnVuY3Rpb24gb3IgdXNpbmcgYSBiYXJlIFhNTEh0dHBSZXF1
1023ZXN0IHdpdGggdGhlIGAucmVzcG9uc2VgIHByb3BlcnR5XG4gKiBob2xkaW5nIGFuIFhNTCBET00uXG4gKlxuICogVGhlIG91dHB1dCBpcyBhIEphdmFTY3JpcHQgb2JqZWN0IG9mIEdlb0pTT04gZGF0YS4gWW91IGNhbiBjb252ZXJ0IGl0IHRvIGEgc3RyaW5nXG4gKiB3aXRoIFtKU09OLnN0cmluZ2lmeV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvSlNPTi9zdHJpbmdpZnkpXG4gKiBvciB1c2UgaXQgZGlyZWN0bHkgaW4gbGlicmFyaWVzLlxuICovXG5mdW5jdGlvbiBrbWwobm9kZSwgb3B0aW9ucyA9IHtcbiAgICBza2lwTnVsbEdlb21ldHJ5OiBmYWxzZSxcbn0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcIkZlYXR1cmVDb2xsZWN0aW9uXCIsXG4gICAgICAgIGZlYXR1cmVzOiBBcnJheS5mcm9tKGttbEdlbihub2RlLCBvcHRpb25zKSksXG4gICAgfTtcbn1cblxuZXhwb3J0IHsgZ3B4LCBncHhHZW4sIGttbCwga21sR2VuLCBrbWxXaXRoRm9sZGVycywgdGN4LCB0Y3hHZW4gfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRvZ2VvanNvbi5lcy5tanMubWFwXG4iXSwibWFwcGluZ3MiOiI7QUFBQSxTQUFTLEVBQUUsU0FBUyxTQUFTO0NBQ3pCLE9BQU8sTUFBTSxLQUFLLFFBQVEscUJBQXFCLE9BQU8sQ0FBQztBQUMzRDtBQUNBLFNBQVMsWUFBWSxJQUFJO0NBQ3JCLE9BQU8sR0FBRyxPQUFPLE1BQU0sS0FBSyxJQUFJO0FBQ3BDO0FBQ0EsU0FBUyxJQUFJLFNBQVMsU0FBUyxJQUFJO0NBQy9CLE9BQU8sTUFBTSxLQUFLLFFBQVEsdUJBQXVCLElBQUksT0FBTyxDQUFDO0FBQ2pFOzs7O0FBSUEsU0FBUyxRQUFRLE1BQU07Q0FDbkIsTUFBTSxVQUFVO0NBQ2hCLE9BQU8s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BQU07SUFDNUIsVUFBVTtJQUNWO0dBQ0o7R0FDQSxLQUFLLGVBQWU7SUFDaEIsTUFBTSxjQUFjLGVBQWUsTUFBTSxVQUFVLFFBQVEsT0FBTztJQUNsRSxJQUFJLGFBQ0EsUUFBUSxTQUFTLEtBQUssV0FBVztJQUVyQztHQUNKO0VBQ0o7RUFFSixJQUFJLEtBQUssWUFDTCxLQUFLLElBQUksSUFBSSxHQUFHLElBQUksS0FBSyxXQUFXLFFBQVEsS0FDeEMsU0FBUyxLQUFLLFdBQVcsSUFBSSxTQUFTLE9BQU87Q0FHekQ7Q0FDQSxTQUFTLEdBQUcsTUFBTSxPQUFPO0NBQ3pCLE9BQU87QUFDWDs7Ozs7O0FBTUEsVUFBVSxPQUFPLE1BQU0sVUFBVSxFQUM3QixrQkFBa0IsTUFDdEIsR0FBRztDQUNDLE1BQU0sSUFBSTtDQUNWLE1BQU0sV0FBVyxjQUFjLENBQUM7Q0FDaEMsTUFBTSxTQUFTLFlBQVksQ0FBQztDQUM1QixLQUFLLE1BQU0sYUFBYSxFQUFFLEdBQUcsV0FBVyxHQUFHO0VBQ3ZDLE1BQU0sVUFBVSxhQUFhLFdBQVcsVUFBVSxRQUFRLE9BQU87RUFDakUsSUFBSSxTQUNBLE1BQU07Q0FDZDtDQUNBLEtBQUssTUFBTSxpQkFBaUIsRUFBRSxHQU
1023FHLGVBQWUsR0FBRztFQUMvQyxNQUFNLFVBQVUsaUJBQWlCLGVBQWUsVUFBVSxRQUFRLE9BQU87RUFDekUsSUFBSSxTQUNBLE1BQU07Q0FDZDtDQUNBLEtBQUssTUFBTSxlQUFlLEVBQUUsR0FBRyxhQUFhLEdBQUc7RUFDM0MsTUFBTSxVQUFVLGVBQWUsYUFBYSxVQUFVLFFBQVEsT0FBTztFQUNyRSxJQUFJLFNBQ0EsTUFBTTtDQUNkO0FBQ0o7Ozs7Ozs7Ozs7O0FBV0EsU0FBUyxJQUFJLE1BQU0sVUFBVSxFQUN6QixrQkFBa0IsTUFDdEIsR0FBRztDQUNDLE9BQU87RUFDSCxNQUFNO0VBQ04sVUFBVSxNQUFNLEtBQUssT0FBTyxNQUFNLE9BQU8sQ0FBQztDQUM5QztBQUNKIiwieF9nb29nbGVfaWdub3JlTGlzdCI6WzBdfQ==

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.