@kepler.gl/deckgl-layers 3.3.0-alpha.4 → 3.3.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/dist/cjs/3d-building-layer/3d-building-layer.js +66 -0
  2. package/dist/cjs/3d-building-layer/3d-building-utils.js +166 -0
  3. package/dist/cjs/3d-building-layer/types.js +6 -0
  4. package/dist/cjs/cluster-layer/cluster-layer.js +292 -0
  5. package/dist/cjs/column-layer/enhanced-column-layer.js +160 -0
  6. package/dist/{deckgl-extensions → cjs/deckgl-extensions}/filter-arrow-layer.js +1 -1
  7. package/dist/cjs/deckgl-extensions/filter-shader-module.js +26 -0
  8. package/dist/cjs/globe/atmosphere-layer.js +220 -0
  9. package/dist/cjs/globe/enhanced-multi-icon-layer.js +63 -0
  10. package/dist/cjs/globe/globe-depth-disk-layer.js +145 -0
  11. package/dist/cjs/globe/globe-layers.js +569 -0
  12. package/dist/cjs/globe/globe-stars-layer.js +69 -0
  13. package/dist/cjs/globe/globe-view.js +407 -0
  14. package/dist/{globe → cjs/globe}/index.js +1 -1
  15. package/dist/cjs/globe/mvt-label-layer.js +190 -0
  16. package/dist/cjs/grid-layer/enhanced-cpu-grid-layer.js +116 -0
  17. package/dist/cjs/hexagon-layer/enhanced-hexagon-layer.js +134 -0
  18. package/dist/{index.js → cjs/index.js} +1 -1
  19. package/dist/cjs/layer-utils/aggregation-utils.js +181 -0
  20. package/dist/cjs/layer-utils/cluster-utils.js +93 -0
  21. package/dist/cjs/layer-utils/cpu-aggregator.js +798 -0
  22. package/dist/cjs/layer-utils/globe-cell-utils.js +173 -0
  23. package/dist/cjs/layer-utils/shader-utils.js +38 -0
  24. package/dist/cjs/line-layer/line-layer.js +95 -0
  25. package/dist/cjs/raster/images.js +271 -0
  26. package/dist/cjs/raster/pipeline-validation-patch.js +101 -0
  27. package/dist/cjs/raster/raster-layer/raster-layer-shaders.js +163 -0
  28. package/dist/cjs/raster/raster-layer/raster-layer-webgl1.fs.js +10 -0
  29. package/dist/cjs/raster/raster-layer/raster-layer-webgl1.vs.js +10 -0
  30. package/dist/cjs/raster/raster-layer/raster-layer-webgl2.fs.js +10 -0
  31. package/dist/cjs/raster/raster-layer/raster-layer-webgl2.vs.js +10 -0
  32. package/dist/cjs/raster/raster-layer/raster-layer.js +287 -0
  33. package/dist/cjs/raster/raster-mesh-layer/matrix.js +18 -0
  34. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +38 -0
  35. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +10 -0
  36. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +10 -0
  37. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +10 -0
  38. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +10 -0
  39. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer.js +321 -0
  40. package/dist/cjs/raster/raster-processing-uniforms.js +124 -0
  41. package/dist/cjs/raster/types.js +6 -0
  42. package/dist/cjs/raster/util.js +139 -0
  43. package/dist/cjs/raster/webgl/color/colormap.js +45 -0
  44. package/dist/cjs/raster/webgl/color/filter.js +58 -0
  45. package/dist/cjs/raster/webgl/color/gamma-contrast.js +68 -0
  46. package/dist/cjs/raster/webgl/color/linear-rescale.js +35 -0
  47. package/dist/cjs/raster/webgl/color/saturation.js +42 -0
  48. package/dist/cjs/raster/webgl/color/sigmoidal-contrast.js +68 -0
  49. package/dist/{raster → cjs/raster}/webgl/index.js +1 -1
  50. package/dist/cjs/raster/webgl/pansharpen/pansharpen-brovey.js +46 -0
  51. package/dist/cjs/raster/webgl/spectral-indices/evi.js +26 -0
  52. package/dist/cjs/raster/webgl/spectral-indices/msavi.js +25 -0
  53. package/dist/cjs/raster/webgl/spectral-indices/normalized-difference.js +19 -0
  54. package/dist/cjs/raster/webgl/spectral-indices/savi.js +21 -0
  55. package/dist/cjs/raster/webgl/texture/combine-bands.js +65 -0
  56. package/dist/cjs/raster/webgl/texture/mask.js +50 -0
  57. package/dist/cjs/raster/webgl/texture/reorder-bands.js +72 -0
  58. package/dist/cjs/raster/webgl/texture/rgba-image.js +34 -0
  59. package/dist/cjs/raster/webgl/types.js +6 -0
  60. package/dist/cjs/svg-icon-layer/scatterplot-icon-layer.js +88 -0
  61. package/dist/cjs/svg-icon-layer/svg-icon-layer.js +104 -0
  62. package/dist/cjs/wms/wms-layer.js +624 -0
  63. package/dist/esm/3d-building-layer/3d-building-layer.js +62 -0
  64. package/dist/esm/3d-building-layer/3d-building-utils.js +157 -0
  65. package/dist/esm/3d-building-layer/types.js +3 -0
  66. package/dist/esm/cluster-layer/cluster-layer.js +286 -0
  67. package/dist/esm/column-layer/enhanced-column-layer.js +156 -0
  68. package/dist/esm/deckgl-extensions/filter-arrow-layer.js +64 -0
  69. package/dist/esm/deckgl-extensions/filter-shader-module.js +20 -0
  70. package/dist/esm/globe/atmosphere-layer.js +214 -0
  71. package/dist/esm/globe/enhanced-multi-icon-layer.js +60 -0
  72. package/dist/esm/globe/globe-depth-disk-layer.js +140 -0
  73. package/dist/esm/globe/globe-layers.js +561 -0
  74. package/dist/esm/globe/globe-stars-layer.js +63 -0
  75. package/dist/esm/globe/globe-view.js +401 -0
  76. package/dist/esm/globe/index.js +26 -0
  77. package/dist/esm/globe/mvt-label-layer.js +187 -0
  78. package/dist/esm/grid-layer/enhanced-cpu-grid-layer.js +112 -0
  79. package/dist/esm/hexagon-layer/enhanced-hexagon-layer.js +130 -0
  80. package/dist/esm/index.js +22 -0
  81. package/dist/esm/layer-utils/aggregation-utils.js +172 -0
  82. package/dist/esm/layer-utils/cluster-utils.js +86 -0
  83. package/dist/esm/layer-utils/cpu-aggregator.js +788 -0
  84. package/dist/esm/layer-utils/globe-cell-utils.js +167 -0
  85. package/dist/esm/layer-utils/shader-utils.js +32 -0
  86. package/dist/esm/line-layer/line-layer.js +91 -0
  87. package/dist/esm/raster/images.js +267 -0
  88. package/dist/esm/raster/pipeline-validation-patch.js +94 -0
  89. package/dist/esm/raster/raster-layer/raster-layer-shaders.js +153 -0
  90. package/dist/esm/raster/raster-layer/raster-layer-webgl1.fs.js +5 -0
  91. package/dist/esm/raster/raster-layer/raster-layer-webgl1.vs.js +5 -0
  92. package/dist/esm/raster/raster-layer/raster-layer-webgl2.fs.js +5 -0
  93. package/dist/esm/raster/raster-layer/raster-layer-webgl2.vs.js +5 -0
  94. package/dist/esm/raster/raster-layer/raster-layer.js +283 -0
  95. package/dist/esm/raster/raster-mesh-layer/matrix.js +12 -0
  96. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +30 -0
  97. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +5 -0
  98. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +5 -0
  99. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +5 -0
  100. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +5 -0
  101. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer.js +318 -0
  102. package/dist/esm/raster/raster-processing-uniforms.js +118 -0
  103. package/dist/esm/raster/types.js +3 -0
  104. package/dist/esm/raster/util.js +134 -0
  105. package/dist/esm/raster/webgl/color/colormap.js +39 -0
  106. package/dist/esm/raster/webgl/color/filter.js +52 -0
  107. package/dist/esm/raster/webgl/color/gamma-contrast.js +62 -0
  108. package/dist/esm/raster/webgl/color/linear-rescale.js +29 -0
  109. package/dist/esm/raster/webgl/color/saturation.js +36 -0
  110. package/dist/esm/raster/webgl/color/sigmoidal-contrast.js +62 -0
  111. package/dist/esm/raster/webgl/index.js +26 -0
  112. package/dist/esm/raster/webgl/pansharpen/pansharpen-brovey.js +40 -0
  113. package/dist/esm/raster/webgl/spectral-indices/evi.js +20 -0
  114. package/dist/esm/raster/webgl/spectral-indices/msavi.js +19 -0
  115. package/dist/esm/raster/webgl/spectral-indices/normalized-difference.js +13 -0
  116. package/dist/esm/raster/webgl/spectral-indices/savi.js +15 -0
  117. package/dist/esm/raster/webgl/texture/combine-bands.js +58 -0
  118. package/dist/esm/raster/webgl/texture/mask.js +44 -0
  119. package/dist/esm/raster/webgl/texture/reorder-bands.js +65 -0
  120. package/dist/esm/raster/webgl/texture/rgba-image.js +28 -0
  121. package/dist/esm/raster/webgl/types.js +3 -0
  122. package/dist/esm/svg-icon-layer/scatterplot-icon-layer.js +84 -0
  123. package/dist/esm/svg-icon-layer/svg-icon-layer.js +101 -0
  124. package/dist/esm/wms/wms-layer.js +619 -0
  125. package/dist/globe/atmosphere-layer.d.ts +13 -2
  126. package/dist/globe/globe-depth-disk-layer.d.ts +1 -0
  127. package/dist/globe/globe-layers.d.ts +8 -2
  128. package/dist/raster/images.d.ts +10 -1
  129. package/dist/raster/raster-layer/raster-layer.d.ts +4 -0
  130. package/dist/raster/raster-mesh-layer/raster-mesh-layer.d.ts +4 -0
  131. package/dist/wms/wms-layer.d.ts +8 -0
  132. package/package.json +18 -11
  133. package/dist/3d-building-layer/3d-building-layer.js +0 -66
  134. package/dist/3d-building-layer/3d-building-utils.js +0 -166
  135. package/dist/3d-building-layer/types.js +0 -6
  136. package/dist/cluster-layer/cluster-layer.js +0 -292
  137. package/dist/column-layer/enhanced-column-layer.js +0 -160
  138. package/dist/deckgl-extensions/filter-shader-module.js +0 -26
  139. package/dist/globe/atmosphere-layer.js +0 -184
  140. package/dist/globe/enhanced-multi-icon-layer.js +0 -63
  141. package/dist/globe/globe-depth-disk-layer.js +0 -145
  142. package/dist/globe/globe-layers.js +0 -565
  143. package/dist/globe/globe-stars-layer.js +0 -69
  144. package/dist/globe/globe-view.js +0 -316
  145. package/dist/globe/mvt-label-layer.js +0 -190
  146. package/dist/grid-layer/enhanced-cpu-grid-layer.js +0 -116
  147. package/dist/hexagon-layer/enhanced-hexagon-layer.js +0 -134
  148. package/dist/layer-utils/aggregation-utils.js +0 -181
  149. package/dist/layer-utils/cluster-utils.js +0 -93
  150. package/dist/layer-utils/cpu-aggregator.js +0 -798
  151. package/dist/layer-utils/globe-cell-utils.js +0 -173
  152. package/dist/layer-utils/shader-utils.js +0 -38
  153. package/dist/line-layer/line-layer.js +0 -95
  154. package/dist/raster/images.js +0 -259
  155. package/dist/raster/pipeline-validation-patch.js +0 -101
  156. package/dist/raster/raster-layer/raster-layer-shaders.js +0 -163
  157. package/dist/raster/raster-layer/raster-layer-webgl1.fs.js +0 -10
  158. package/dist/raster/raster-layer/raster-layer-webgl1.vs.js +0 -10
  159. package/dist/raster/raster-layer/raster-layer-webgl2.fs.js +0 -10
  160. package/dist/raster/raster-layer/raster-layer-webgl2.vs.js +0 -10
  161. package/dist/raster/raster-layer/raster-layer.js +0 -237
  162. package/dist/raster/raster-mesh-layer/matrix.js +0 -18
  163. package/dist/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +0 -38
  164. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +0 -10
  165. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +0 -10
  166. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +0 -10
  167. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +0 -10
  168. package/dist/raster/raster-mesh-layer/raster-mesh-layer.js +0 -271
  169. package/dist/raster/raster-processing-uniforms.js +0 -124
  170. package/dist/raster/types.js +0 -6
  171. package/dist/raster/util.js +0 -139
  172. package/dist/raster/webgl/color/colormap.js +0 -45
  173. package/dist/raster/webgl/color/filter.js +0 -58
  174. package/dist/raster/webgl/color/gamma-contrast.js +0 -68
  175. package/dist/raster/webgl/color/linear-rescale.js +0 -35
  176. package/dist/raster/webgl/color/saturation.js +0 -42
  177. package/dist/raster/webgl/color/sigmoidal-contrast.js +0 -68
  178. package/dist/raster/webgl/pansharpen/pansharpen-brovey.js +0 -46
  179. package/dist/raster/webgl/spectral-indices/evi.js +0 -26
  180. package/dist/raster/webgl/spectral-indices/msavi.js +0 -25
  181. package/dist/raster/webgl/spectral-indices/normalized-difference.js +0 -19
  182. package/dist/raster/webgl/spectral-indices/savi.js +0 -21
  183. package/dist/raster/webgl/texture/combine-bands.js +0 -65
  184. package/dist/raster/webgl/texture/mask.js +0 -50
  185. package/dist/raster/webgl/texture/reorder-bands.js +0 -72
  186. package/dist/raster/webgl/texture/rgba-image.js +0 -34
  187. package/dist/raster/webgl/types.js +0 -6
  188. package/dist/svg-icon-layer/scatterplot-icon-layer.js +0 -88
  189. package/dist/svg-icon-layer/svg-icon-layer.js +0 -104
  190. package/dist/wms/wms-layer.js +0 -594
@@ -0,0 +1,561 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright contributors to the kepler.gl project
3
+
4
+ import { COORDINATE_SYSTEM } from '@deck.gl/core';
5
+ import { SolidPolygonLayer, BitmapLayer } from '@deck.gl/layers';
6
+ import { TileLayer, MVTLayer } from '@deck.gl/geo-layers';
7
+ import { getGlobeAtmosphereLayer, getGlobeAtmosphereSkyLayer } from './atmosphere-layer';
8
+ import { getGlobeDepthDiskLayer } from './globe-depth-disk-layer';
9
+ import { MVTLabelLayer } from './mvt-label-layer';
10
+ var devicePixelRatio = Math.min(2, typeof window !== 'undefined' && window.devicePixelRatio || 1);
11
+ var BACKGROUND_PARAMETERS = {
12
+ depthTest: true,
13
+ cull: true,
14
+ depthMask: false
15
+ };
16
+ var BASEMAP_RASTER_PARAMETERS = {
17
+ depthMask: false
18
+ };
19
+ var BACKGROUND_DATA = [[[-180, 90], [0, 90], [180, 90], [180, -90], [0, -90], [-180, -90]]];
20
+ var BACKGROUND_NORTH_POLE_DATA = [[[-180, 90], [0, 90], [180, 90], [180, 85], [0, 85], [-180, 85]]];
21
+ export var DEFAULT_BASEMAP_COLOR = {
22
+ backgroundFillColor: [9, 16, 29],
23
+ basemapDefaultFillColor: [255, 255, 255],
24
+ basemapWaterFillColor: [17, 35, 48],
25
+ basemapDefaultLineColor: [40, 63, 93],
26
+ basemapAdminLineColor: [40, 63, 93],
27
+ basemapLabelColor: [114.75, 114.75, 114.75]
28
+ };
29
+ function getPaintColor(color) {
30
+ if (Array.isArray(color) && color[0] === 'interpolate') {
31
+ return color[4];
32
+ }
33
+ return color;
34
+ }
35
+ function colorStringToRGB(color) {
36
+ if (!color) return null;
37
+ if (typeof color !== 'string') return null;
38
+
39
+ // Handle hsl() format
40
+ var hslMatch = color.match(/hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/);
41
+ if (hslMatch) {
42
+ var h = parseInt(hslMatch[1], 10) / 360;
43
+ var s = parseInt(hslMatch[2], 10) / 100;
44
+ var l = parseInt(hslMatch[3], 10) / 100;
45
+ // HSL to RGB conversion
46
+ var r, g, b;
47
+ if (s === 0) {
48
+ r = g = b = l;
49
+ } else {
50
+ var hue2rgb = function hue2rgb(p, q, t) {
51
+ if (t < 0) t += 1;
52
+ if (t > 1) t -= 1;
53
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
54
+ if (t < 1 / 2) return q;
55
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
56
+ return p;
57
+ };
58
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
59
+ var p = 2 * l - q;
60
+ r = hue2rgb(p, q, h + 1 / 3);
61
+ g = hue2rgb(p, q, h);
62
+ b = hue2rgb(p, q, h - 1 / 3);
63
+ }
64
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
65
+ }
66
+
67
+ // Handle rgb() format
68
+ var rgbMatch = color.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
69
+ if (rgbMatch) {
70
+ return [parseInt(rgbMatch[1], 10), parseInt(rgbMatch[2], 10), parseInt(rgbMatch[3], 10)];
71
+ }
72
+
73
+ // Handle hex format
74
+ var hexMatch = color.match(/^#([0-9a-f]{6})$/i);
75
+ if (hexMatch) {
76
+ var hex = hexMatch[1];
77
+ return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16)];
78
+ }
79
+ return null;
80
+ }
81
+ function findFirstLayerByGroup(layers, layerGroups, groupSlug) {
82
+ var layerGroup = layerGroups.find(function (group) {
83
+ return group.slug === groupSlug;
84
+ });
85
+ if (!layerGroup) return null;
86
+ return layers.find(function (layer) {
87
+ return layerGroup.filter(layer);
88
+ });
89
+ }
90
+ function findBackgroundColor(style) {
91
+ var _found;
92
+ var found = style.layers.find(function (l) {
93
+ return l.id === 'background' || l.id === 'land';
94
+ });
95
+ found = found || style.layers.find(function (l) {
96
+ return l.type === 'background';
97
+ });
98
+ return colorStringToRGB(getPaintColor((_found = found) === null || _found === void 0 || (_found = _found.paint) === null || _found === void 0 ? void 0 : _found['background-color']));
99
+ }
100
+ function findWaterColor(style, layerGroups) {
101
+ var _found$paint;
102
+ var found = style.layers.find(function (l) {
103
+ return l.id === 'water';
104
+ }) || findFirstLayerByGroup(style.layers, layerGroups, 'water');
105
+ return colorStringToRGB(found === null || found === void 0 || (_found$paint = found.paint) === null || _found$paint === void 0 ? void 0 : _found$paint['fill-color']);
106
+ }
107
+ function findAdminColor(style, layerGroups) {
108
+ var _borderLayers$paint;
109
+ var borderLayers = style.layers.find(function (lyr) {
110
+ return lyr.id === 'admin-3-4-boundaries';
111
+ }) || findFirstLayerByGroup(style.layers, layerGroups, 'border');
112
+ return colorStringToRGB(borderLayers === null || borderLayers === void 0 || (_borderLayers$paint = borderLayers.paint) === null || _borderLayers$paint === void 0 ? void 0 : _borderLayers$paint['line-color']);
113
+ }
114
+ function findLabelColor(style, layerGroups) {
115
+ var _labelLayer;
116
+ var labelLayer = style.layers.find(function (lyr) {
117
+ return lyr.id === 'country-label-lg' && lyr.type === 'symbol';
118
+ });
119
+ labelLayer = labelLayer || style.layers.find(function (lyr) {
120
+ return lyr.id === 'country-label' && lyr.type === 'symbol';
121
+ });
122
+ labelLayer = labelLayer || findFirstLayerByGroup(style.layers, layerGroups, 'label');
123
+ return colorStringToRGB((_labelLayer = labelLayer) === null || _labelLayer === void 0 || (_labelLayer = _labelLayer.paint) === null || _labelLayer === void 0 ? void 0 : _labelLayer['text-color']);
124
+ }
125
+ export var getBasemapColors = function getBasemapColors(mapStyle) {
126
+ var _findBackgroundColor, _findWaterColor, _findAdminColor, _findLabelColor;
127
+ var _mapStyle$style = mapStyle.style,
128
+ styleJson = _mapStyle$style === void 0 ? {
129
+ layers: []
130
+ } : _mapStyle$style,
131
+ _mapStyle$layerGroups = mapStyle.layerGroups,
132
+ layerGroups = _mapStyle$layerGroups === void 0 ? [] : _mapStyle$layerGroups;
133
+ return {
134
+ backgroundFillColor: (_findBackgroundColor = findBackgroundColor(styleJson)) !== null && _findBackgroundColor !== void 0 ? _findBackgroundColor : DEFAULT_BASEMAP_COLOR.backgroundFillColor,
135
+ basemapWaterFillColor: (_findWaterColor = findWaterColor(styleJson, layerGroups)) !== null && _findWaterColor !== void 0 ? _findWaterColor : DEFAULT_BASEMAP_COLOR.basemapWaterFillColor,
136
+ basemapAdminLineColor: (_findAdminColor = findAdminColor(styleJson, layerGroups)) !== null && _findAdminColor !== void 0 ? _findAdminColor : DEFAULT_BASEMAP_COLOR.basemapAdminLineColor,
137
+ basemapLabelColor: (_findLabelColor = findLabelColor(styleJson, layerGroups)) !== null && _findLabelColor !== void 0 ? _findLabelColor : DEFAULT_BASEMAP_COLOR.basemapLabelColor
138
+ };
139
+ };
140
+
141
+ // Predefined color schemes for well-known basemap styles
142
+ var KNOWN_STYLE_COLORS = {
143
+ dark: {
144
+ backgroundFillColor: [15, 15, 15],
145
+ basemapWaterFillColor: [10, 20, 35],
146
+ basemapAdminLineColor: [60, 60, 80],
147
+ basemapLabelColor: [150, 150, 150]
148
+ },
149
+ 'dark-matter': {
150
+ backgroundFillColor: [18, 18, 18],
151
+ basemapWaterFillColor: [14, 19, 29],
152
+ basemapAdminLineColor: [50, 50, 60],
153
+ basemapLabelColor: [130, 130, 130]
154
+ },
155
+ light: {
156
+ backgroundFillColor: [235, 233, 228],
157
+ basemapWaterFillColor: [170, 211, 223],
158
+ basemapAdminLineColor: [180, 175, 170],
159
+ basemapLabelColor: [80, 80, 80]
160
+ },
161
+ positron: {
162
+ backgroundFillColor: [242, 239, 233],
163
+ basemapWaterFillColor: [174, 209, 220],
164
+ basemapAdminLineColor: [190, 185, 180],
165
+ basemapLabelColor: [90, 90, 90]
166
+ },
167
+ voyager: {
168
+ backgroundFillColor: [234, 229, 220],
169
+ basemapWaterFillColor: [170, 211, 223],
170
+ basemapAdminLineColor: [180, 170, 160],
171
+ basemapLabelColor: [70, 70, 70]
172
+ },
173
+ muted: {
174
+ backgroundFillColor: [225, 225, 218],
175
+ basemapWaterFillColor: [180, 210, 220],
176
+ basemapAdminLineColor: [170, 165, 160],
177
+ basemapLabelColor: [90, 90, 90]
178
+ },
179
+ muted_night: {
180
+ backgroundFillColor: [22, 26, 30],
181
+ basemapWaterFillColor: [15, 25, 40],
182
+ basemapAdminLineColor: [55, 60, 70],
183
+ basemapLabelColor: [140, 140, 140]
184
+ }
185
+ };
186
+
187
+ /**
188
+ * Get basemap colors either from the style JSON or from known style presets.
189
+ * Falls back to default dark colors if style is unknown and no JSON is available.
190
+ */
191
+ export var getBasemapColorsForStyle = function getBasemapColorsForStyle(styleType, mapStyle) {
192
+ var _mapStyle$style2;
193
+ // Try to extract from style JSON first
194
+ if (mapStyle !== null && mapStyle !== void 0 && (_mapStyle$style2 = mapStyle.style) !== null && _mapStyle$style2 !== void 0 && (_mapStyle$style2 = _mapStyle$style2.layers) !== null && _mapStyle$style2 !== void 0 && _mapStyle$style2.length) {
195
+ return getBasemapColors(mapStyle);
196
+ }
197
+ // Fall back to known style presets
198
+ if (KNOWN_STYLE_COLORS[styleType]) {
199
+ return KNOWN_STYLE_COLORS[styleType];
200
+ }
201
+ // Default dark colors
202
+ return {
203
+ backgroundFillColor: DEFAULT_BASEMAP_COLOR.backgroundFillColor,
204
+ basemapWaterFillColor: DEFAULT_BASEMAP_COLOR.basemapWaterFillColor,
205
+ basemapAdminLineColor: DEFAULT_BASEMAP_COLOR.basemapAdminLineColor,
206
+ basemapLabelColor: DEFAULT_BASEMAP_COLOR.basemapLabelColor
207
+ };
208
+ };
209
+
210
+ /**
211
+ * Clear color (background around the globe) for globe mode, in RGBA 0-255 as
212
+ * expected by deck.gl's View `clearColor` prop (deck.gl >= 9 no longer supports
213
+ * the global `parameters.clearColor`; it must be set per-view with `clear: true`).
214
+ */
215
+ export function getGlobeClearColor(backgroundColor) {
216
+ if (backgroundColor) {
217
+ return [backgroundColor[0], backgroundColor[1], backgroundColor[2], 255];
218
+ }
219
+ // Default matches the previous hardcoded clear color [0.015, 0.035, 0.065] in 0-1 space.
220
+ return [4, 9, 17, 255];
221
+ }
222
+ var INVISIBLE_COLOR = [0, 0, 0, 0];
223
+ var BASEMAP_MVT_PARAMETERS = {
224
+ // Occlude the far side of the globe via the DEPTH DISK (getGlobeDepthDiskLayer)
225
+ // rather than back-face culling. Globe mode sets a global `cull: true` for the
226
+ // opaque sphere surface, but back-face culling relies on stable triangle
227
+ // winding — and deck.gl 9's globe projection loses precision at high zoom
228
+ // (float32), flipping the winding of the small admin/water triangles so they
229
+ // get wrongly culled and the geometry vanishes past ~zoom 12 (you then see
230
+ // through to the far side / "different geometry"). Depth testing against the disk
231
+ // is a precision-robust occluder that works at any zoom, so:
232
+ // - cull: false → don't winding-cull the near-side geometry
233
+ // - depthTest: true → far-side geometry (behind the disk) fails depth, hidden
234
+ // - depthMask: false → don't write depth (avoid self z-fighting on the shell)
235
+ // Raster tiles are unaffected (their 4-corner quads keep stable winding), which
236
+ // is why satellite already zooms to max cleanly. Labels disable cull for the
237
+ // same reason (see mvt-label-layer.ts).
238
+ depthTest: true,
239
+ depthMask: false,
240
+ cull: false
241
+ };
242
+
243
+ // deck.gl 9's globe selects finer tiles than needed for a given view (its
244
+ // GlobeViewport scale is ~3x smaller than the equivalent mercator zoom), so bias
245
+ // vector tile selection coarser to keep the tile count — and thus performance —
246
+ // in check. This trades a little detail for far fewer tiles; make it less negative
247
+ // (toward 0) for sharper detail, or more negative for more perf.
248
+ // These are *base* offsets: globeLatitudeZoomCompensation is added on top at draw
249
+ // time, so the effective zoomOffset only equals these exact values at the equator.
250
+ // Satellite raster uses base 0 — it doesn't need the vector bias (a coarser raster
251
+ // tile just looks softer rather than dropping features).
252
+ var MAPBOX_GLOBE_VECTOR_ZOOM_OFFSET = -2;
253
+ var CARTO_GLOBE_VECTOR_ZOOM_OFFSET = -2;
254
+ var GLOBE_SATELLITE_ZOOM_OFFSET = 0;
255
+
256
+ // Whole-world tile extent (Web Mercator latitude limit). Required whenever a
257
+ // negative `zoomOffset` is used: deck's `getTileIndices` returns NO tiles when
258
+ // the target zoom drops below `minZoom` *unless* an `extent` is set (in which
259
+ // case it clamps to `minZoom` instead). Without this, zooming out or panning
260
+ // toward the poles (where deck 9's globe controller lowers the effective zoom)
261
+ // makes the whole globe basemap disappear.
262
+ var GLOBE_TILE_EXTENT = [-180, -85.051129, 180, 85.051129];
263
+
264
+ // Max *native* zoom of each vector tile source. Set this (not an arbitrarily
265
+ // high number) so deck overzooms — i.e. keeps rendering the deepest real tile
266
+ // when the view zooms past it — instead of requesting tiles that don't exist
267
+ // and 404 (which shows up as empty rectangles). The raw `.vector.pbf` /`.mvt`
268
+ // endpoints do NOT auto-overzoom the way Mapbox GL does.
269
+ // - mapbox-streets-v8 has data up to z16
270
+ // - CARTO carto.streets v1 has data up to z14
271
+ var MAPBOX_VECTOR_MAX_DATA_ZOOM = 16;
272
+ var CARTO_VECTOR_MAX_DATA_ZOOM = 14;
273
+
274
+ /**
275
+ * deck.gl 9's globe couples zoom to latitude via `zoomAdjust` (see
276
+ * globe-viewport.js): `scale = 2^(zoom - zoomAdjust(lat))`, and its controller
277
+ * *lowers* the stored `zoom` as you pan toward the poles to keep the globe's
278
+ * on-screen size constant. Tile LOD, however, is selected from the raw `zoom`,
279
+ * so rotating toward a pole silently drops the LOD and thins out labels.
280
+ * Replicated from `@deck.gl/core` globe-viewport.js `zoomAdjust`.
281
+ */
282
+ function zoomAdjust(latitude) {
283
+ return Math.log2(Math.PI * Math.cos(latitude * Math.PI / 180));
284
+ }
285
+
286
+ /**
287
+ * Latitude compensation to add to a globe tile layer's `zoomOffset`, so tile LOD
288
+ * tracks the *visual* (on-screen) scale instead of the latitude-adjusted mercator
289
+ * zoom. This cancels the pan-induced zoom drop, keeping tile detail/labels
290
+ * constant while rotating toward the poles.
291
+ */
292
+ function globeLatitudeZoomCompensation(latitude) {
293
+ if (latitude == null || !Number.isFinite(latitude)) {
294
+ return 0;
295
+ }
296
+ // Clamp away from the poles to avoid log2(0) = -Infinity at |lat| = 90.
297
+ var clamped = Math.max(-85, Math.min(85, latitude));
298
+ return zoomAdjust(0) - zoomAdjust(clamped);
299
+ }
300
+
301
+ /**
302
+ * Globe basemap tile provider.
303
+ *
304
+ * - `mapbox` uses Mapbox vector/raster tiles and requires an access token.
305
+ * - `carto` uses CARTO's free OpenMapTiles vector tiles + Esri World Imagery
306
+ * raster, and needs no token. Used as an automatic fallback when no Mapbox
307
+ * token is available (e.g. MapLibre / CARTO basemap setups), so the globe
308
+ * basemap still renders instead of showing a solid-color sphere.
309
+ */
310
+
311
+ /**
312
+ * Resolve which globe basemap tile provider to use.
313
+ *
314
+ * The globe should follow the *selected basemap style's* rendering library so
315
+ * it stays consistent with the flat 2D map: a MapLibre/CARTO style uses the
316
+ * free CARTO tiles (even when a Mapbox token is available), and a Mapbox style
317
+ * uses Mapbox tiles. A Mapbox style with no token falls back to CARTO so the
318
+ * globe still renders instead of showing a bare colored sphere.
319
+ *
320
+ * @param baseMapLibrary the selected style's library ('mapbox' | 'maplibre'),
321
+ * e.g. from `getBaseMapLibrary(currentStyle)`.
322
+ */
323
+ export var resolveGlobeBasemapProvider = function resolveGlobeBasemapProvider(baseMapLibrary, mapboxApiAccessToken) {
324
+ if (baseMapLibrary === 'maplibre') {
325
+ return 'carto';
326
+ }
327
+ if (baseMapLibrary === 'mapbox') {
328
+ return mapboxApiAccessToken ? 'mapbox' : 'carto';
329
+ }
330
+ // Unknown library: prefer Mapbox when a token exists, otherwise CARTO.
331
+ return mapboxApiAccessToken ? 'mapbox' : 'carto';
332
+ };
333
+
334
+ // CARTO free vector tiles (OpenMapTiles schema, no API key required).
335
+ var CARTO_VECTOR_TILE_URLS = ['https://tiles-a.basemaps.cartocdn.com/vectortiles/carto.streets/v1/{z}/{x}/{y}.mvt', 'https://tiles-b.basemaps.cartocdn.com/vectortiles/carto.streets/v1/{z}/{x}/{y}.mvt', 'https://tiles-c.basemaps.cartocdn.com/vectortiles/carto.streets/v1/{z}/{x}/{y}.mvt', 'https://tiles-d.basemaps.cartocdn.com/vectortiles/carto.streets/v1/{z}/{x}/{y}.mvt'];
336
+
337
+ // Free satellite raster fallback (Esri World Imagery, no API key required).
338
+ var ESRI_WORLD_IMAGERY_URL = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}';
339
+
340
+ /**
341
+ * Maps a raw MVT source-layer name to a normalized semantic layer kind, so the
342
+ * fill/line/label accessors work across both the Mapbox (`mapbox-streets-v8`)
343
+ * and CARTO/OpenMapTiles schemas.
344
+ *
345
+ * | semantic | mapbox | openmaptiles |
346
+ * | -------- | ------------- | ------------ |
347
+ * | water | `water` | `water` |
348
+ * | admin | `admin` | `boundary` |
349
+ * | label | `place_label` | `place` |
350
+ */
351
+
352
+ function getBasemapLayerKind(layerName) {
353
+ switch (layerName) {
354
+ case 'water':
355
+ return 'water';
356
+ case 'admin':
357
+ case 'boundary':
358
+ return 'admin';
359
+ case 'place_label':
360
+ case 'place':
361
+ return 'label';
362
+ default:
363
+ return 'other';
364
+ }
365
+ }
366
+ var MAPBOX_ATTRIBUTION = {
367
+ label: '© Mapbox',
368
+ href: 'https://www.mapbox.com/about/maps/'
369
+ };
370
+ var OSM_ATTRIBUTION = {
371
+ label: '© OpenStreetMap',
372
+ href: 'https://www.openstreetmap.org/copyright'
373
+ };
374
+ var CARTO_ATTRIBUTION = {
375
+ label: '© CARTO',
376
+ href: 'https://carto.com/attributions'
377
+ };
378
+ var ESRI_ATTRIBUTION = {
379
+ label: 'Powered by Esri',
380
+ href: 'https://www.esri.com/'
381
+ };
382
+
383
+ /**
384
+ * Resolve the tile-source attribution entries for the globe basemap. deck.gl
385
+ * renders the globe basemap tiles itself (not the base Maplibre/Mapbox map), so
386
+ * the base map's attribution machinery never sees them. This lets the UI credit
387
+ * the actual tile provider(s) in globe mode.
388
+ */
389
+ export var getGlobeBasemapAttributions = function getGlobeBasemapAttributions(_ref) {
390
+ var _globe$config;
391
+ var globe = _ref.globe,
392
+ mapboxApiAccessToken = _ref.mapboxApiAccessToken,
393
+ mapStyleType = _ref.mapStyleType,
394
+ basemapProvider = _ref.basemapProvider;
395
+ if (!(globe !== null && globe !== void 0 && globe.enabled) || !((_globe$config = globe.config) !== null && _globe$config !== void 0 && _globe$config.basemap)) {
396
+ return [];
397
+ }
398
+ var provider = basemapProvider !== null && basemapProvider !== void 0 ? basemapProvider : resolveGlobeBasemapProvider(undefined, mapboxApiAccessToken);
399
+ if (provider === 'mapbox') {
400
+ return mapboxApiAccessToken ? [MAPBOX_ATTRIBUTION, OSM_ATTRIBUTION] : [];
401
+ }
402
+ var isSatellite = mapStyleType === 'satellite' || mapStyleType === 'satellite-street';
403
+ // CARTO vector tiles are OpenStreetMap-derived; Esri imagery is credited separately.
404
+ return isSatellite ? [ESRI_ATTRIBUTION, CARTO_ATTRIBUTION, OSM_ATTRIBUTION] : [CARTO_ATTRIBUTION, OSM_ATTRIBUTION];
405
+ };
406
+
407
+ // eslint-disable-next-line complexity
408
+ export var getGlobeBaseLayers = function getGlobeBaseLayers(_ref2) {
409
+ var mapboxApiAccessToken = _ref2.mapboxApiAccessToken,
410
+ globe = _ref2.globe,
411
+ mapStyleType = _ref2.mapStyleType,
412
+ basemapProvider = _ref2.basemapProvider,
413
+ latitude = _ref2.latitude,
414
+ zoom = _ref2.zoom;
415
+ var config = globe.config;
416
+ var isSatellite = mapStyleType === 'satellite';
417
+ var isSatelliteStreet = mapStyleType === 'satellite-street';
418
+ var latZoomCompensation = globeLatitudeZoomCompensation(latitude);
419
+
420
+ // Fall back to the free CARTO tiles whenever no Mapbox token is available so
421
+ // the globe basemap still renders (matches kepler's default token-free
422
+ // MapLibre/CARTO basemaps). Callers should pass an explicit `basemapProvider`
423
+ // (derived from the selected style) so the globe follows the 2D basemap.
424
+ var provider = basemapProvider !== null && basemapProvider !== void 0 ? basemapProvider : resolveGlobeBasemapProvider(undefined, mapboxApiAccessToken);
425
+ var useCarto = provider === 'carto';
426
+ var hasTileAccess = useCarto || Boolean(mapboxApiAccessToken);
427
+ return [config.atmosphere ? getGlobeAtmosphereSkyLayer({
428
+ config: config,
429
+ zoom: zoom
430
+ }) : null,
431
+ // Depth-only cross-section disk: writes depth at the globe's silhouette so
432
+ // far-side geometry (arcs/lines) is occluded by the planet.
433
+ getGlobeDepthDiskLayer({
434
+ fillColor: config.surfaceColor
435
+ }),
436
+ // Background surface polygon
437
+ (!config.basemap || !isSatellite && !isSatelliteStreet) && new SolidPolygonLayer({
438
+ id: 'globe-background',
439
+ data: BACKGROUND_DATA,
440
+ getPolygon: function (d) {
441
+ return d;
442
+ },
443
+ filled: true,
444
+ getFillColor: config.surfaceColor,
445
+ parameters: BACKGROUND_PARAMETERS
446
+ }),
447
+ // Fill hole at north pole
448
+ config.basemap && new SolidPolygonLayer({
449
+ id: 'globe-background-north-pole',
450
+ data: BACKGROUND_NORTH_POLE_DATA,
451
+ getPolygon: function (d) {
452
+ return d;
453
+ },
454
+ filled: true,
455
+ getFillColor: config.water ? config.waterColor : config.surfaceColor,
456
+ parameters: BACKGROUND_PARAMETERS
457
+ }),
458
+ // Satellite tiles
459
+ config.basemap && (isSatellite || isSatelliteStreet) && hasTileAccess && new TileLayer({
460
+ id: "globe-satellite-tiles-".concat(provider),
461
+ data: useCarto ? [ESRI_WORLD_IMAGERY_URL] : ["https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}@2x.png?access_token=".concat(mapboxApiAccessToken)],
462
+ minZoom: 0,
463
+ maxZoom: useCarto ? 18 : 19,
464
+ zoomOffset: GLOBE_SATELLITE_ZOOM_OFFSET + latZoomCompensation,
465
+ extent: GLOBE_TILE_EXTENT,
466
+ // Esri tiles are 256px; Mapbox @2x tiles are 512px.
467
+ tileSize: useCarto ? 256 : 512 / devicePixelRatio,
468
+ renderSubLayers: function renderSubLayers(props) {
469
+ var _props$tile$bbox = props.tile.bbox,
470
+ west = _props$tile$bbox.west,
471
+ south = _props$tile$bbox.south,
472
+ east = _props$tile$bbox.east,
473
+ north = _props$tile$bbox.north;
474
+ return [new BitmapLayer(props, {
475
+ _imageCoordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
476
+ data: undefined,
477
+ image: props.data,
478
+ bounds: [west, south, east, north]
479
+ })];
480
+ },
481
+ parameters: BASEMAP_RASTER_PARAMETERS
482
+ }),
483
+ // Vector basemap (MVT labels/admin/water)
484
+ config.basemap && !isSatellite && hasTileAccess && new MVTLayer({
485
+ // force the layer to update when the style/label/provider config changes
486
+ id: "globe-basemap-mvt-layer-".concat(provider, "-").concat(mapStyleType),
487
+ data: useCarto ? CARTO_VECTOR_TILE_URLS : "https://a.tiles.mapbox.com/v4/mapbox.mapbox-streets-v8/{z}/{x}/{y}.vector.pbf?access_token=".concat(mapboxApiAccessToken),
488
+ minZoom: 0,
489
+ // Overzoom past the source's native max instead of 404-ing on tiles that
490
+ // don't exist (which renders as empty rectangles at high zoom).
491
+ maxZoom: useCarto ? CARTO_VECTOR_MAX_DATA_ZOOM : MAPBOX_VECTOR_MAX_DATA_ZOOM,
492
+ zoomOffset: (useCarto ? CARTO_GLOBE_VECTOR_ZOOM_OFFSET : MAPBOX_GLOBE_VECTOR_ZOOM_OFFSET) + latZoomCompensation,
493
+ extent: GLOBE_TILE_EXTENT,
494
+ binary: false,
495
+ parameters: BASEMAP_MVT_PARAMETERS,
496
+ loadOptions: useCarto ? {
497
+ // OpenMapTiles schema: `boundary` = admin lines, `place` = labels.
498
+ mvt: {
499
+ layers: isSatelliteStreet ? ['place', 'boundary'] : ['place', 'boundary', 'water', 'transportation']
500
+ }
501
+ } : {
502
+ mvt: {
503
+ layers: isSatelliteStreet ? ['place_label', 'admin'] : ['place_label', 'admin', 'water', 'road']
504
+ }
505
+ },
506
+ // Render admin/water via GeoJsonLayer and place labels via TextLayer.
507
+ config: config,
508
+ renderSubLayers: function renderSubLayers(props) {
509
+ return new MVTLabelLayer(props);
510
+ },
511
+ getFillColor: function getFillColor(f) {
512
+ switch (getBasemapLayerKind(f.properties.layerName)) {
513
+ case 'water':
514
+ return config.water ? config.waterColor : INVISIBLE_COLOR;
515
+ default:
516
+ return config.surfaceColor;
517
+ }
518
+ },
519
+ getLineColor: function getLineColor(f) {
520
+ switch (getBasemapLayerKind(f.properties.layerName)) {
521
+ case 'admin':
522
+ return config.adminLines ? config.adminLinesColor : INVISIBLE_COLOR;
523
+ default:
524
+ return config.surfaceColor;
525
+ }
526
+ },
527
+ getLineWidth: function getLineWidth(f) {
528
+ switch (getBasemapLayerKind(f.properties.layerName)) {
529
+ case 'admin':
530
+ switch (f.properties.admin_level) {
531
+ case 0:
532
+ case 2:
533
+ return 1;
534
+ default:
535
+ return 0.75;
536
+ }
537
+ default:
538
+ return 0;
539
+ }
540
+ },
541
+ updateTriggers: {
542
+ getFillColor: [config.waterColor, config.surfaceColor, config.water],
543
+ getLineColor: [config.adminLinesColor, config.surfaceColor, config.adminLines]
544
+ },
545
+ lineWidthUnits: 'pixels',
546
+ lineWidthMinPixels: 0,
547
+ lineWidthMaxPixels: 20,
548
+ getPointRadius: 0,
549
+ pointRadiusMinPixels: 0
550
+ })].filter(Boolean);
551
+ };
552
+ export var getGlobeTopLayers = function getGlobeTopLayers(_ref3) {
553
+ var globe = _ref3.globe,
554
+ zoom = _ref3.zoom;
555
+ var config = globe.config;
556
+ return [config.atmosphere ? getGlobeAtmosphereLayer({
557
+ config: config,
558
+ zoom: zoom
559
+ }) : null].filter(Boolean);
560
+ };
561
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDT09SRElOQVRFX1NZU1RFTSIsIlNvbGlkUG9seWdvbkxheWVyIiwiQml0bWFwTGF5ZXIiLCJUaWxlTGF5ZXIiLCJNVlRMYXllciIsImdldEdsb2JlQXRtb3NwaGVyZUxheWVyIiwiZ2V0R2xvYmVBdG1vc3BoZXJlU2t5TGF5ZXIiLCJnZXRHbG9iZURlcHRoRGlza0xheWVyIiwiTVZUTGFiZWxMYXllciIsImRldmljZVBpeGVsUmF0aW8iLCJNYXRoIiwibWluIiwid2luZG93IiwiQkFDS0dST1VORF9QQVJBTUVURVJTIiwiZGVwdGhUZXN0IiwiY3VsbCIsImRlcHRoTWFzayIsIkJBU0VNQVBfUkFTVEVSX1BBUkFNRVRFUlMiLCJCQUNLR1JPVU5EX0RBVEEiLCJCQUNLR1JPVU5EX05PUlRIX1BPTEVfREFUQSIsIkRFRkFVTFRfQkFTRU1BUF9DT0xPUiIsImJhY2tncm91bmRGaWxsQ29sb3IiLCJiYXNlbWFwRGVmYXVsdEZpbGxDb2xvciIsImJhc2VtYXBXYXRlckZpbGxDb2xvciIsImJhc2VtYXBEZWZhdWx0TGluZUNvbG9yIiwiYmFzZW1hcEFkbWluTGluZUNvbG9yIiwiYmFzZW1hcExhYmVsQ29sb3IiLCJnZXRQYWludENvbG9yIiwiY29sb3IiLCJBcnJheSIsImlzQXJyYXkiLCJjb2xvclN0cmluZ1RvUkdCIiwiaHNsTWF0Y2giLCJtYXRjaCIsImgiLCJwYXJzZUludCIsInMiLCJsIiwiciIsImciLCJiIiwiaHVlMnJnYiIsInAiLCJxIiwidCIsInJvdW5kIiwicmdiTWF0Y2giLCJoZXhNYXRjaCIsImhleCIsInNsaWNlIiwiZmluZEZpcnN0TGF5ZXJCeUdyb3VwIiwibGF5ZXJzIiwibGF5ZXJHcm91cHMiLCJncm91cFNsdWciLCJsYXllckdyb3VwIiwiZmluZCIsImdyb3VwIiwic2x1ZyIsImxheWVyIiwiZmlsdGVyIiwiZmluZEJhY2tncm91bmRDb2xvciIsInN0eWxlIiwiX2ZvdW5kIiwiZm91bmQiLCJpZCIsInR5cGUiLCJwYWludCIsImZpbmRXYXRlckNvbG9yIiwiX2ZvdW5kJHBhaW50IiwiZmluZEFkbWluQ29sb3IiLCJfYm9yZGVyTGF5ZXJzJHBhaW50IiwiYm9yZGVyTGF5ZXJzIiwibHlyIiwiZmluZExhYmVsQ29sb3IiLCJfbGFiZWxMYXllciIsImxhYmVsTGF5ZXIiLCJnZXRCYXNlbWFwQ29sb3JzIiwibWFwU3R5bGUiLCJfZmluZEJhY2tncm91bmRDb2xvciIsIl9maW5kV2F0ZXJDb2xvciIsIl9maW5kQWRtaW5Db2xvciIsIl9maW5kTGFiZWxDb2xvciIsIl9tYXBTdHlsZSRzdHlsZSIsInN0eWxlSnNvbiIsIl9tYXBTdHlsZSRsYXllckdyb3VwcyIsIktOT1dOX1NUWUxFX0NPTE9SUyIsImRhcmsiLCJsaWdodCIsInBvc2l0cm9uIiwidm95YWdlciIsIm11dGVkIiwibXV0ZWRfbmlnaHQiLCJnZXRCYXNlbWFwQ29sb3JzRm9yU3R5bGUiLCJzdHlsZVR5cGUiLCJfbWFwU3R5bGUkc3R5bGUyIiwibGVuZ3RoIiwiZ2V0R2xvYmVDbGVhckNvbG9yIiwiYmFja2dyb3VuZENvbG9yIiwiSU5WSVNJQkxFX0NPTE9SIiwiQkFTRU1BUF9NVlRfUEFSQU1FVEVSUyIsIk1BUEJPWF9HTE9CRV9WRUNUT1JfWk9PTV9PRkZTRVQiLCJDQVJUT19HTE9CRV9WRUNUT1JfWk9PTV9PRkZTRVQiLCJHTE9CRV9TQVRFTExJVEVfWk9PTV9PRkZTRVQiLCJHTE9CRV9USUxFX0VYVEVOVCIsIk1BUEJPWF9WRUNUT1JfTUFYX0RBVEFfWk9PTSIsIkNBUlRPX1ZFQ1RPUl9NQVhfREFUQV9aT09NIiwiem9vbUFkanVzdCIsImxhdGl0dWRlIiwibG9nMiIsIlBJIiwiY29zIiwiZ2xvYmVMYXRpdHVkZVpvb21Db21wZW5zYXRpb24iLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImNsYW1wZWQiLCJtYXgiLCJyZXNvbHZlR2xvYmVCYXNlbWFwUHJvdmlkZXIiLCJiYXNlTWFwTGlicmFyeSIsIm1hcGJveEFwaUFjY2Vzc1Rva2VuIiwiQ0FSVE9fVkVDVE9SX1RJTEVfVVJMUyIsIkVTUklfV09STERfSU1BR0VSWV9VUkwiLCJnZXRCYXNlbWFwTGF5ZXJLaW5kIiwibGF5ZXJOYW1lIiwiTUFQQk9YX0FUVFJJQlVUSU9OIiwibGFiZWwiLCJocmVmIiwiT1NNX0FUVFJJQlVUSU9OIiwiQ0FSVE9fQVRUUklCVVRJT04iLCJFU1JJX0FUVFJJQlVUSU9OIiwiZ2V0R2xvYmVCYXNlbWFwQXR0cmlidXRpb25zIiwiX3JlZiIsIl9nbG9iZSRjb25maWciLCJnbG9iZSIsIm1hcFN0eWxlVHlwZSIsImJhc2VtYXBQcm92aWRlciIsImVuYWJsZWQiLCJjb25maWciLCJiYXNlbWFwIiwicHJvdmlkZXIiLCJ1bmRlZmluZWQiLCJpc1NhdGVsbGl0ZSIsImdldEdsb2JlQmFzZUxheWVycyIsIl9yZWYyIiwiem9vbSIsImlzU2F0ZWxsaXRlU3RyZWV0IiwibGF0Wm9vbUNvbXBlbnNhdGlvbiIsInVzZUNhcnRvIiwiaGFzVGlsZUFjY2VzcyIsIkJvb2xlYW4iLCJhdG1vc3BoZXJlIiwiZmlsbENvbG9yIiwic3VyZmFjZUNvbG9yIiwiZGF0YSIsImdldFBvbHlnb24iLCJkIiwiZmlsbGVkIiwiZ2V0RmlsbENvbG9yIiwicGFyYW1ldGVycyIsIndhdGVyIiwid2F0ZXJDb2xvciIsImNvbmNhdCIsIm1pblpvb20iLCJtYXhab29tIiwiem9vbU9mZnNldCIsImV4dGVudCIsInRpbGVTaXplIiwicmVuZGVyU3ViTGF5ZXJzIiwicHJvcHMiLCJfcHJvcHMkdGlsZSRiYm94IiwidGlsZSIsImJib3giLCJ3ZXN0Iiwic291dGgiLCJlYXN0Iiwibm9ydGgiLCJfaW1hZ2VDb29yZGluYXRlU3lzdGVtIiwiQ0FSVEVTSUFOIiwiaW1hZ2UiLCJib3VuZHMiLCJiaW5hcnkiLCJsb2FkT3B0aW9ucyIsIm12dCIsImYiLCJwcm9wZXJ0aWVzIiwiZ2V0TGluZUNvbG9yIiwiYWRtaW5MaW5lcyIsImFkbWluTGluZXNDb2xvciIsImdldExpbmVXaWR0aCIsImFkbWluX2xldmVsIiwidXBkYXRlVHJpZ2dlcnMiLCJsaW5lV2lkdGhVbml0cyIsImxpbmVXaWR0aE1pblBpeGVscyIsImxpbmVXaWR0aE1heFBpeGVscyIsImdldFBvaW50UmFkaXVzIiwicG9pbnRSYWRpdXNNaW5QaXhlbHMiLCJnZXRHbG9iZVRvcExheWVycyIsIl9yZWYzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2dsb2JlL2dsb2JlLWxheWVycy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge0NPT1JESU5BVEVfU1lTVEVNLCBMYXllcn0gZnJvbSAnQGRlY2suZ2wvY29yZSc7XG5pbXBvcnQge1NvbGlkUG9seWdvbkxheWVyLCBCaXRtYXBMYXllcn0gZnJvbSAnQGRlY2suZ2wvbGF5ZXJzJztcbmltcG9ydCB7VGlsZUxheWVyLCBNVlRMYXllcn0gZnJvbSAnQGRlY2suZ2wvZ2VvLWxheWVycyc7XG5cbmltcG9ydCB0eXBlIHtHbG9iZX0gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUge1JHQkNvbG9yfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcblxuaW1wb3J0IHtnZXRHbG9iZUF0bW9zcGhlcmVMYXllciwgZ2V0R2xvYmVBdG1vc3BoZXJlU2t5TGF5ZXJ9IGZyb20gJy4vYXRtb3NwaGVyZS1sYXllcic7XG5pbXBvcnQge2dldEdsb2JlRGVwdGhEaXNrTGF5ZXJ9IGZyb20gJy4vZ2xvYmUtZGVwdGgtZGlzay1sYXllcic7XG5pbXBvcnQge01WVExhYmVsTGF5ZXJ9IGZyb20gJy4vbXZ0LWxhYmVsLWxheWVyJztcblxudHlwZSBMYXllckdyb3VwID0ge3NsdWc6IHN0cmluZzsgZmlsdGVyOiAobGF5ZXI6IGFueSkgPT4gYm9vbGVhbn07XG5cbmNvbnN0IGRldmljZVBpeGVsUmF0aW8gPSBNYXRoLm1pbihcbiAgMixcbiAgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKSB8fCAxXG4pO1xuXG5jb25zdCBCQUNLR1JPVU5EX1BBUkFNRVRFUlMgPSB7XG4gIGRlcHRoVGVzdDogdHJ1ZSxcbiAgY3VsbDogdHJ1ZSxcbiAgZGVwdGhNYXNrOiBmYWxzZVxufTtcblxuY29uc3QgQkFTRU1BUF9SQVNURVJfUEFSQU1FVEVSUyA9IHtcbiAgZGVwdGhNYXNrOiBmYWxzZVxufTtcblxuY29uc3QgQkFDS0dST1VORF9EQVRBID0gW1xuICBbXG4gICAgWy0xODAsIDkwXSxcbiAgICBbMCwgOTBdLFxuICAgIFsxODAsIDkwXSxcbiAgICBbMTgwLCAtOTBdLFxuICAgIFswLCAtOTBdLFxuICAgIFstMTgwLCAtOTBdXG4gIF1cbl07XG5cbmNvbnN0IEJBQ0tHUk9VTkRfTk9SVEhfUE9MRV9EQVRBID0gW1xuICBbXG4gICAgWy0xODAsIDkwXSxcbiAgICBbMCwgOTBdLFxuICAgIFsxODAsIDkwXSxcbiAgICBbMTgwLCA4NV0sXG4gICAgWzAsIDg1XSxcbiAgICBbLTE4MCwgODVdXG4gIF1cbl07XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0JBU0VNQVBfQ09MT1IgPSB7XG4gIGJhY2tncm91bmRGaWxsQ29sb3I6IFs5LCAxNiwgMjldIGFzIFJHQkNvbG9yLFxuICBiYXNlbWFwRGVmYXVsdEZpbGxDb2xvcjogWzI1NSwgMjU1LCAyNTVdIGFzIFJHQkNvbG9yLFxuICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6IFsxNywgMzUsIDQ4XSBhcyBSR0JDb2xvcixcbiAgYmFzZW1hcERlZmF1bHRMaW5lQ29sb3I6IFs0MCwgNjMsIDkzXSBhcyBSR0JDb2xvcixcbiAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBbNDAsIDYzLCA5M10gYXMgUkdCQ29sb3IsXG4gIGJhc2VtYXBMYWJlbENvbG9yOiBbMTE0Ljc1LCAxMTQuNzUsIDExNC43NV0gYXMgUkdCQ29sb3Jcbn07XG5cbmZ1bmN0aW9uIGdldFBhaW50Q29sb3IoY29sb3I6IGFueSk6IHN0cmluZyB8IG51bGwge1xuICBpZiAoQXJyYXkuaXNBcnJheShjb2xvcikgJiYgY29sb3JbMF0gPT09ICdpbnRlcnBvbGF0ZScpIHtcbiAgICByZXR1cm4gY29sb3JbNF07XG4gIH1cbiAgcmV0dXJuIGNvbG9yO1xufVxuXG5mdW5jdGlvbiBjb2xvclN0cmluZ1RvUkdCKGNvbG9yOiBzdHJpbmcgfCBudWxsKTogUkdCQ29sb3IgfCBudWxsIHtcbiAgaWYgKCFjb2xvcikgcmV0dXJuIG51bGw7XG4gIGlmICh0eXBlb2YgY29sb3IgIT09ICdzdHJpbmcnKSByZXR1cm4gbnVsbDtcblxuICAvLyBIYW5kbGUgaHNsKCkgZm9ybWF0XG4gIGNvbnN0IGhzbE1hdGNoID0gY29sb3IubWF0Y2goL2hzbFxcKFxccyooXFxkKylcXHMqLFxccyooXFxkKyklXFxzKixcXHMqKFxcZCspJVxccypcXCkvKTtcbiAgaWYgKGhzbE1hdGNoKSB7XG4gICAgY29uc3QgaCA9IHBhcnNlSW50KGhzbE1hdGNoWzFdLCAxMCkgLyAzNjA7XG4gICAgY29uc3QgcyA9IHBhcnNlSW50KGhzbE1hdGNoWzJdLCAxMCkgLyAxMDA7XG4gICAgY29uc3QgbCA9IHBhcnNlSW50KGhzbE1hdGNoWzNdLCAxMCkgLyAxMDA7XG4gICAgLy8gSFNMIHRvIFJHQiBjb252ZXJzaW9uXG4gICAgbGV0IHI6IG51bWJlciwgZzogbnVtYmVyLCBiOiBudW1iZXI7XG4gICAgaWYgKHMgPT09IDApIHtcbiAgICAgIHIgPSBnID0gYiA9IGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGh1ZTJyZ2IgPSAocDogbnVtYmVyLCBxOiBudW1iZXIsIHQ6IG51bWJlcikgPT4ge1xuICAgICAgICBpZiAodCA8IDApIHQgKz0gMTtcbiAgICAgICAgaWYgKHQgPiAxKSB0IC09IDE7XG4gICAgICAgIGlmICh0IDwgMSAvIDYpIHJldHVybiBwICsgKHEgLSBwKSAqIDYgKiB0O1xuICAgICAgICBpZiAodCA8IDEgLyAyKSByZXR1cm4gcTtcbiAgICAgICAgaWYgKHQgPCAyIC8gMykgcmV0dXJuIHAgKyAocSAtIHApICogKDIgLyAzIC0gdCkgKiA2O1xuICAgICAgICByZXR1cm4gcDtcbiAgICAgIH07XG4gICAgICBjb25zdCBxID0gbCA8IDAuNSA/IGwgKiAoMSArIHMpIDogbCArIHMgLSBsICogcztcbiAgICAgIGNvbnN0IHAgPSAyICogbCAtIHE7XG4gICAgICByID0gaHVlMnJnYihwLCBxLCBoICsgMSAvIDMpO1xuICAgICAgZyA9IGh1ZTJyZ2IocCwgcSwgaCk7XG4gICAgICBiID0gaHVlMnJnYihwLCBxLCBoIC0gMSAvIDMpO1xuICAgIH1cbiAgICByZXR1cm4gW01hdGgucm91bmQociAqIDI1NSksIE1hdGgucm91bmQoZyAqIDI1NSksIE1hdGgucm91bmQoYiAqIDI1NSldIGFzIFJHQkNvbG9yO1xuICB9XG5cbiAgLy8gSGFuZGxlIHJnYigpIGZvcm1hdFxuICBjb25zdCByZ2JNYXRjaCA9IGNvbG9yLm1hdGNoKC9yZ2JcXChcXHMqKFxcZCspXFxzKixcXHMqKFxcZCspXFxzKixcXHMqKFxcZCspXFxzKlxcKS8pO1xuICBpZiAocmdiTWF0Y2gpIHtcbiAgICByZXR1cm4gW1xuICAgICAgcGFyc2VJbnQocmdiTWF0Y2hbMV0sIDEwKSxcbiAgICAgIHBhcnNlSW50KHJnYk1hdGNoWzJdLCAxMCksXG4gICAgICBwYXJzZUludChyZ2JNYXRjaFszXSwgMTApXG4gICAgXSBhcyBSR0JDb2xvcjtcbiAgfVxuXG4gIC8vIEhhbmRsZSBoZXggZm9ybWF0XG4gIGNvbnN0IGhleE1hdGNoID0gY29sb3IubWF0Y2goL14jKFswLTlhLWZdezZ9KSQvaSk7XG4gIGlmIChoZXhNYXRjaCkge1xuICAgIGNvbnN0IGhleCA9IGhleE1hdGNoWzFdO1xuICAgIHJldHVybiBbXG4gICAgICBwYXJzZUludChoZXguc2xpY2UoMCwgMiksIDE2KSxcbiAgICAgIHBhcnNlSW50KGhleC5zbGljZSgyLCA0KSwgMTYpLFxuICAgICAgcGFyc2VJbnQoaGV4LnNsaWNlKDQsIDYpLCAxNilcbiAgICBdIGFzIFJHQkNvbG9yO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGZpbmRGaXJzdExheWVyQnlHcm91cChsYXllcnM6IGFueVtdLCBsYXllckdyb3VwczogTGF5ZXJHcm91cFtdLCBncm91cFNsdWc6IHN0cmluZykge1xuICBjb25zdCBsYXllckdyb3VwID0gbGF5ZXJHcm91cHMuZmluZChncm91cCA9PiBncm91cC5zbHVnID09PSBncm91cFNsdWcpO1xuICBpZiAoIWxheWVyR3JvdXApIHJldHVybiBudWxsO1xuICByZXR1cm4gbGF5ZXJzLmZpbmQobGF5ZXIgPT4gbGF5ZXJHcm91cC5maWx0ZXIobGF5ZXIpKTtcbn1cblxuZnVuY3Rpb24gZmluZEJhY2tncm91bmRDb2xvcihzdHlsZTogYW55KTogUkdCQ29sb3IgfCBudWxsIHtcbiAgbGV0IGZvdW5kID0gc3R5bGUubGF5ZXJzLmZpbmQoKGw6IGFueSkgPT4gbC5pZCA9PT0gJ2JhY2tncm91bmQnIHx8IGwuaWQgPT09ICdsYW5kJyk7XG4gIGZvdW5kID0gZm91bmQgfHwgc3R5bGUubGF5ZXJzLmZpbmQoKGw6IGFueSkgPT4gbC50eXBlID09PSAnYmFja2dyb3VuZCcpO1xuICByZXR1cm4gY29sb3JTdHJpbmdUb1JHQihnZXRQYWludENvbG9yKGZvdW5kPy5wYWludD8uWydiYWNrZ3JvdW5kLWNvbG9yJ10pKTtcbn1cblxuZnVuY3Rpb24gZmluZFdhdGVyQ29sb3Ioc3R5bGU6IGFueSwgbGF5ZXJHcm91cHM6IExheWVyR3JvdXBbXSk6IFJHQkNvbG9yIHwgbnVsbCB7XG4gIGNvbnN0IGZvdW5kID1cbiAgICBzdHlsZS5sYXllcnMuZmluZCgobDogYW55KSA9PiBsLmlkID09PSAnd2F0ZXInKSB8fFxuICAgIGZpbmRGaXJzdExheWVyQnlHcm91cChzdHlsZS5sYXllcnMsIGxheWVyR3JvdXBzLCAnd2F0ZXInKTtcbiAgcmV0dXJuIGNvbG9yU3RyaW5nVG9SR0IoZm91bmQ/LnBhaW50Py5bJ2ZpbGwtY29sb3InXSk7XG59XG5cbmZ1bmN0aW9uIGZpbmRBZG1pbkNvbG9yKHN0eWxlOiBhbnksIGxheWVyR3JvdXBzOiBMYXllckdyb3VwW10pOiBSR0JDb2xvciB8IG51bGwge1xuICBjb25zdCBib3JkZXJMYXllcnMgPVxuICAgIHN0eWxlLmxheWVycy5maW5kKChseXI6IGFueSkgPT4gbHlyLmlkID09PSAnYWRtaW4tMy00LWJvdW5kYXJpZXMnKSB8fFxuICAgIGZpbmRGaXJzdExheWVyQnlHcm91cChzdHlsZS5sYXllcnMsIGxheWVyR3JvdXBzLCAnYm9yZGVyJyk7XG4gIHJldHVybiBjb2xvclN0cmluZ1RvUkdCKGJvcmRlckxheWVycz8ucGFpbnQ/LlsnbGluZS1jb2xvciddKTtcbn1cblxuZnVuY3Rpb24gZmluZExhYmVsQ29sb3Ioc3R5bGU6IGFueSwgbGF5ZXJHcm91cHM6IExheWVyR3JvdXBbXSk6IFJHQkNvbG9yIHwgbnVsbCB7XG4gIGxldCBsYWJlbExheWVyID0gc3R5bGUubGF5ZXJzLmZpbmQoXG4gICAgKGx5cjogYW55KSA9PiBseXIuaWQgPT09ICdjb3VudHJ5LWxhYmVsLWxnJyAmJiBseXIudHlwZSA9PT0gJ3N5bWJvbCdcbiAgKTtcbiAgbGFiZWxMYXllciA9XG4gICAgbGFiZWxMYXllciB8fFxuICAgIHN0eWxlLmxheWVycy5maW5kKChseXI6IGFueSkgPT4gbHlyLmlkID09PSAnY291bnRyeS1sYWJlbCcgJiYgbHlyLnR5cGUgPT09ICdzeW1ib2wnKTtcbiAgbGFiZWxMYXllciA9IGxhYmVsTGF5ZXIgfHwgZmluZEZpcnN0TGF5ZXJCeUdyb3VwKHN0eWxlLmxheWVycywgbGF5ZXJHcm91cHMsICdsYWJlbCcpO1xuICByZXR1cm4gY29sb3JTdHJpbmdUb1JHQihsYWJlbExheWVyPy5wYWludD8uWyd0ZXh0LWNvbG9yJ10pO1xufVxuXG5leHBvcnQgY29uc3QgZ2V0QmFzZW1hcENvbG9ycyA9IChcbiAgbWFwU3R5bGU6IFBhcnRpYWw8e3N0eWxlOiBhbnk7IGxheWVyR3JvdXBzOiBMYXllckdyb3VwW119PlxuKToge1xuICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBSR0JDb2xvcjtcbiAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOiBSR0JDb2xvcjtcbiAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBSR0JDb2xvcjtcbiAgYmFzZW1hcExhYmVsQ29sb3I6IFJHQkNvbG9yO1xufSA9PiB7XG4gIGNvbnN0IHtzdHlsZTogc3R5bGVKc29uID0ge2xheWVyczogW119LCBsYXllckdyb3VwcyA9IFtdfSA9IG1hcFN0eWxlO1xuXG4gIHJldHVybiB7XG4gICAgYmFja2dyb3VuZEZpbGxDb2xvcjpcbiAgICAgIGZpbmRCYWNrZ3JvdW5kQ29sb3Ioc3R5bGVKc29uKSA/PyBERUZBVUxUX0JBU0VNQVBfQ09MT1IuYmFja2dyb3VuZEZpbGxDb2xvcixcbiAgICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6XG4gICAgICBmaW5kV2F0ZXJDb2xvcihzdHlsZUpzb24sIGxheWVyR3JvdXBzKSA/PyBERUZBVUxUX0JBU0VNQVBfQ09MT1IuYmFzZW1hcFdhdGVyRmlsbENvbG9yLFxuICAgIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjpcbiAgICAgIGZpbmRBZG1pbkNvbG9yKHN0eWxlSnNvbiwgbGF5ZXJHcm91cHMpID8/IERFRkFVTFRfQkFTRU1BUF9DT0xPUi5iYXNlbWFwQWRtaW5MaW5lQ29sb3IsXG4gICAgYmFzZW1hcExhYmVsQ29sb3I6XG4gICAgICBmaW5kTGFiZWxDb2xvcihzdHlsZUpzb24sIGxheWVyR3JvdXBzKSA/PyBERUZBVUxUX0JBU0VNQVBfQ09MT1IuYmFzZW1hcExhYmVsQ29sb3JcbiAgfTtcbn07XG5cbi8vIFByZWRlZmluZWQgY29sb3Igc2NoZW1lcyBmb3Igd2VsbC1rbm93biBiYXNlbWFwIHN0eWxlc1xuY29uc3QgS05PV05fU1RZTEVfQ09MT1JTOiBSZWNvcmQ8XG4gIHN0cmluZyxcbiAge1xuICAgIGJhY2tncm91bmRGaWxsQ29sb3I6IFJHQkNvbG9yO1xuICAgIGJhc2VtYXBXYXRlckZpbGxDb2xvcjogUkdCQ29sb3I7XG4gICAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBSR0JDb2xvcjtcbiAgICBiYXNlbWFwTGFiZWxDb2xvcjogUkdCQ29sb3I7XG4gIH1cbj4gPSB7XG4gIGRhcms6IHtcbiAgICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBbMTUsIDE1LCAxNV0sXG4gICAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOiBbMTAsIDIwLCAzNV0sXG4gICAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBbNjAsIDYwLCA4MF0sXG4gICAgYmFzZW1hcExhYmVsQ29sb3I6IFsxNTAsIDE1MCwgMTUwXVxuICB9LFxuICAnZGFyay1tYXR0ZXInOiB7XG4gICAgYmFja2dyb3VuZEZpbGxDb2xvcjogWzE4LCAxOCwgMThdLFxuICAgIGJhc2VtYXBXYXRlckZpbGxDb2xvcjogWzE0LCAxOSwgMjldLFxuICAgIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogWzUwLCA1MCwgNjBdLFxuICAgIGJhc2VtYXBMYWJlbENvbG9yOiBbMTMwLCAxMzAsIDEzMF1cbiAgfSxcbiAgbGlnaHQ6IHtcbiAgICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBbMjM1LCAyMzMsIDIyOF0sXG4gICAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOiBbMTcwLCAyMTEsIDIyM10sXG4gICAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBbMTgwLCAxNzUsIDE3MF0sXG4gICAgYmFzZW1hcExhYmVsQ29sb3I6IFs4MCwgODAsIDgwXVxuICB9LFxuICBwb3NpdHJvbjoge1xuICAgIGJhY2tncm91bmRGaWxsQ29sb3I6IFsyNDIsIDIzOSwgMjMzXSxcbiAgICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6IFsxNzQsIDIwOSwgMjIwXSxcbiAgICBiYXNlbWFwQWRtaW5MaW5lQ29sb3I6IFsxOTAsIDE4NSwgMTgwXSxcbiAgICBiYXNlbWFwTGFiZWxDb2xvcjogWzkwLCA5MCwgOTBdXG4gIH0sXG4gIHZveWFnZXI6IHtcbiAgICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBbMjM0LCAyMjksIDIyMF0sXG4gICAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOiBbMTcwLCAyMTEsIDIyM10sXG4gICAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBbMTgwLCAxNzAsIDE2MF0sXG4gICAgYmFzZW1hcExhYmVsQ29sb3I6IFs3MCwgNzAsIDcwXVxuICB9LFxuICBtdXRlZDoge1xuICAgIGJhY2tncm91bmRGaWxsQ29sb3I6IFsyMjUsIDIyNSwgMjE4XSxcbiAgICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6IFsxODAsIDIxMCwgMjIwXSxcbiAgICBiYXNlbWFwQWRtaW5MaW5lQ29sb3I6IFsxNzAsIDE2NSwgMTYwXSxcbiAgICBiYXNlbWFwTGFiZWxDb2xvcjogWzkwLCA5MCwgOTBdXG4gIH0sXG4gIG11dGVkX25pZ2h0OiB7XG4gICAgYmFja2dyb3VuZEZpbGxDb2xvcjogWzIyLCAyNiwgMzBdLFxuICAgIGJhc2VtYXBXYXRlckZpbGxDb2xvcjogWzE1LCAyNSwgNDBdLFxuICAgIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogWzU1LCA2MCwgNzBdLFxuICAgIGJhc2VtYXBMYWJlbENvbG9yOiBbMTQwLCAxNDAsIDE0MF1cbiAgfVxufTtcblxuLyoqXG4gKiBHZXQgYmFzZW1hcCBjb2xvcnMgZWl0aGVyIGZyb20gdGhlIHN0eWxlIEpTT04gb3IgZnJvbSBrbm93biBzdHlsZSBwcmVzZXRzLlxuICogRmFsbHMgYmFjayB0byBkZWZhdWx0IGRhcmsgY29sb3JzIGlmIHN0eWxlIGlzIHVua25vd24gYW5kIG5vIEpTT04gaXMgYXZhaWxhYmxlLlxuICovXG5leHBvcnQgY29uc3QgZ2V0QmFzZW1hcENvbG9yc0ZvclN0eWxlID0gKFxuICBzdHlsZVR5cGU6IHN0cmluZyxcbiAgbWFwU3R5bGU/OiBQYXJ0aWFsPHtzdHlsZTogYW55OyBsYXllckdyb3VwczogTGF5ZXJHcm91cFtdfT5cbik6IHtcbiAgYmFja2dyb3VuZEZpbGxDb2xvcjogUkdCQ29sb3I7XG4gIGJhc2VtYXBXYXRlckZpbGxDb2xvcjogUkdCQ29sb3I7XG4gIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogUkdCQ29sb3I7XG4gIGJhc2VtYXBMYWJlbENvbG9yOiBSR0JDb2xvcjtcbn0gPT4ge1xuICAvLyBUcnkgdG8gZXh0cmFjdCBmcm9tIHN0eWxlIEpTT04gZmlyc3RcbiAgaWYgKG1hcFN0eWxlPy5zdHlsZT8ubGF5ZXJzPy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZ2V0QmFzZW1hcENvbG9ycyhtYXBTdHlsZSk7XG4gIH1cbiAgLy8gRmFsbCBiYWNrIHRvIGtub3duIHN0eWxlIHByZXNldHNcbiAgaWYgKEtOT1dOX1NUWUxFX0NPTE9SU1tzdHlsZVR5cGVdKSB7XG4gICAgcmV0dXJuIEtOT1dOX1NUWUxFX0NPTE9SU1tzdHlsZVR5cGVdO1xuICB9XG4gIC8vIERlZmF1bHQgZGFyayBjb2xvcnNcbiAgcmV0dXJuIHtcbiAgICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBERUZBVUxUX0JBU0VNQVBfQ09MT1IuYmFja2dyb3VuZEZpbGxDb2xvcixcbiAgICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6IERFRkFVTFRfQkFTRU1BUF9DT0xPUi5iYXNlbWFwV2F0ZXJGaWxsQ29sb3IsXG4gICAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBERUZBVUxUX0JBU0VNQVBfQ09MT1IuYmFzZW1hcEFkbWluTGluZUNvbG9yLFxuICAgIGJhc2VtYXBMYWJlbENvbG9yOiBERUZBVUxUX0JBU0VNQVBfQ09MT1IuYmFzZW1hcExhYmVsQ29sb3JcbiAgfTtcbn07XG5cbi8qKlxuICogQ2xlYXIgY29sb3IgKGJhY2tncm91bmQgYXJvdW5kIHRoZSBnbG9iZSkgZm9yIGdsb2JlIG1vZGUsIGluIFJHQkEgMC0yNTUgYXNcbiAqIGV4cGVjdGVkIGJ5IGRlY2suZ2wncyBWaWV3IGBjbGVhckNvbG9yYCBwcm9wIChkZWNrLmdsID49IDkgbm8gbG9uZ2VyIHN1cHBvcnRzXG4gKiB0aGUgZ2xvYmFsIGBwYXJhbWV0ZXJzLmNsZWFyQ29sb3JgOyBpdCBtdXN0IGJlIHNldCBwZXItdmlldyB3aXRoIGBjbGVhcjogdHJ1ZWApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0R2xvYmVDbGVhckNvbG9yKFxuICBiYWNrZ3JvdW5kQ29sb3I/OiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfCBudW1iZXJbXVxuKTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICBpZiAoYmFja2dyb3VuZENvbG9yKSB7XG4gICAgcmV0dXJuIFtiYWNrZ3JvdW5kQ29sb3JbMF0sIGJhY2tncm91bmRDb2xvclsxXSwgYmFja2dyb3VuZENvbG9yWzJdLCAyNTVdO1xuICB9XG4gIC8vIERlZmF1bHQgbWF0Y2hlcyB0aGUgcHJldmlvdXMgaGFyZGNvZGVkIGNsZWFyIGNvbG9yIFswLjAxNSwgMC4wMzUsIDAuMDY1XSBpbiAwLTEgc3BhY2UuXG4gIHJldHVybiBbNCwgOSwgMTcsIDI1NV07XG59XG5cbmNvbnN0IElOVklTSUJMRV9DT0xPUjogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMCwgMCwgMCwgMF07XG5cbmNvbnN0IEJBU0VNQVBfTVZUX1BBUkFNRVRFUlMgPSB7XG4gIC8vIE9jY2x1ZGUgdGhlIGZhciBzaWRlIG9mIHRoZSBnbG9iZSB2aWEgdGhlIERFUFRIIERJU0sgKGdldEdsb2JlRGVwdGhEaXNrTGF5ZXIpXG4gIC8vIHJhdGhlciB0aGFuIGJhY2stZmFjZSBjdWxsaW5nLiBHbG9iZSBtb2RlIHNldHMgYSBnbG9iYWwgYGN1bGw6IHRydWVgIGZvciB0aGVcbiAgLy8gb3BhcXVlIHNwaGVyZSBzdXJmYWNlLCBidXQgYmFjay1mYWNlIGN1bGxpbmcgcmVsaWVzIG9uIHN0YWJsZSB0cmlhbmdsZVxuICAvLyB3aW5kaW5nIOKAlCBhbmQgZGVjay5nbCA5J3MgZ2xvYmUgcHJvamVjdGlvbiBsb3NlcyBwcmVjaXNpb24gYXQgaGlnaCB6b29tXG4gIC8vIChmbG9hdDMyKSwgZmxpcHBpbmcgdGhlIHdpbmRpbmcgb2YgdGhlIHNtYWxsIGFkbWluL3dhdGVyIHRyaWFuZ2xlcyBzbyB0aGV5XG4gIC8vIGdldCB3cm9uZ2x5IGN1bGxlZCBhbmQgdGhlIGdlb21ldHJ5IHZhbmlzaGVzIHBhc3Qgfnpvb20gMTIgKHlvdSB0aGVuIHNlZVxuICAvLyB0aHJvdWdoIHRvIHRoZSBmYXIgc2lkZSAvIFwiZGlmZmVyZW50IGdlb21ldHJ5XCIpLiBEZXB0aCB0ZXN0aW5nIGFnYWluc3QgdGhlIGRpc2tcbiAgLy8gaXMgYSBwcmVjaXNpb24tcm9idXN0IG9jY2x1ZGVyIHRoYXQgd29ya3MgYXQgYW55IHpvb20sIHNvOlxuICAvLyAgIC0gY3VsbDogZmFsc2UgICAgIOKGkiBkb24ndCB3aW5kaW5nLWN1bGwgdGhlIG5lYXItc2lkZSBnZW9tZXRyeVxuICAvLyAgIC0gZGVwdGhUZXN0OiB0cnVlIOKGkiBmYXItc2lkZSBnZW9tZXRyeSAoYmVoaW5kIHRoZSBkaXNrKSBmYWlscyBkZXB0aCwgaGlkZGVuXG4gIC8vICAgLSBkZXB0aE1hc2s6IGZhbHNlIOKGkiBkb24ndCB3cml0ZSBkZXB0aCAoYXZvaWQgc2VsZiB6LWZpZ2h0aW5nIG9uIHRoZSBzaGVsbClcbiAgLy8gUmFzdGVyIHRpbGVzIGFyZSB1bmFmZmVjdGVkICh0aGVpciA0LWNvcm5lciBxdWFkcyBrZWVwIHN0YWJsZSB3aW5kaW5nKSwgd2hpY2hcbiAgLy8gaXMgd2h5IHNhdGVsbGl0ZSBhbHJlYWR5IHpvb21zIHRvIG1heCBjbGVhbmx5LiBMYWJlbHMgZGlzYWJsZSBjdWxsIGZvciB0aGVcbiAgLy8gc2FtZSByZWFzb24gKHNlZSBtdnQtbGFiZWwtbGF5ZXIudHMpLlxuICBkZXB0aFRlc3Q6IHRydWUsXG4gIGRlcHRoTWFzazogZmFsc2UsXG4gIGN1bGw6IGZhbHNlXG59O1xuXG4vLyBkZWNrLmdsIDkncyBnbG9iZSBzZWxlY3RzIGZpbmVyIHRpbGVzIHRoYW4gbmVlZGVkIGZvciBhIGdpdmVuIHZpZXcgKGl0c1xuLy8gR2xvYmVWaWV3cG9ydCBzY2FsZSBpcyB+M3ggc21hbGxlciB0aGFuIHRoZSBlcXVpdmFsZW50IG1lcmNhdG9yIHpvb20pLCBzbyBiaWFzXG4vLyB2ZWN0b3IgdGlsZSBzZWxlY3Rpb24gY29hcnNlciB0byBrZWVwIHRoZSB0aWxlIGNvdW50IOKAlCBhbmQgdGh1cyBwZXJmb3JtYW5jZSDigJRcbi8vIGluIGNoZWNrLiBUaGlzIHRyYWRlcyBhIGxpdHRsZSBkZXRhaWwgZm9yIGZhciBmZXdlciB0aWxlczsgbWFrZSBpdCBsZXNzIG5lZ2F0aXZlXG4vLyAodG93YXJkIDApIGZvciBzaGFycGVyIGRldGFpbCwgb3IgbW9yZSBuZWdhdGl2ZSBmb3IgbW9yZSBwZXJmLlxuLy8gVGhlc2UgYXJlICpiYXNlKiBvZmZzZXRzOiBnbG9iZUxhdGl0dWRlWm9vbUNvbXBlbnNhdGlvbiBpcyBhZGRlZCBvbiB0b3AgYXQgZHJhd1xuLy8gdGltZSwgc28gdGhlIGVmZmVjdGl2ZSB6b29tT2Zmc2V0IG9ubHkgZXF1YWxzIHRoZXNlIGV4YWN0IHZhbHVlcyBhdCB0aGUgZXF1YXRvci5cbi8vIFNhdGVsbGl0ZSByYXN0ZXIgdXNlcyBiYXNlIDAg4oCUIGl0IGRvZXNuJ3QgbmVlZCB0aGUgdmVjdG9yIGJpYXMgKGEgY29hcnNlciByYXN0ZXJcbi8vIHRpbGUganVzdCBsb29rcyBzb2Z0ZXIgcmF0aGVyIHRoYW4gZHJvcHBpbmcgZmVhdHVyZXMpLlxuY29uc3QgTUFQQk9YX0dMT0JFX1ZFQ1RPUl9aT09NX09GRlNFVCA9IC0yO1xuY29uc3QgQ0FSVE9fR0xPQkVfVkVDVE9SX1pPT01fT0ZGU0VUID0gLTI7XG5jb25zdCBHTE9CRV9TQVRFTExJVEVfWk9PTV9PRkZTRVQgPSAwO1xuXG4vLyBXaG9sZS13b3JsZCB0aWxlIGV4dGVudCAoV2ViIE1lcmNhdG9yIGxhdGl0dWRlIGxpbWl0KS4gUmVxdWlyZWQgd2hlbmV2ZXIgYVxuLy8gbmVnYXRpdmUgYHpvb21PZmZzZXRgIGlzIHVzZWQ6IGRlY2sncyBgZ2V0VGlsZUluZGljZXNgIHJldHVybnMgTk8gdGlsZXMgd2hlblxuLy8gdGhlIHRhcmdldCB6b29tIGRyb3BzIGJlbG93IGBtaW5ab29tYCAqdW5sZXNzKiBhbiBgZXh0ZW50YCBpcyBzZXQgKGluIHdoaWNoXG4vLyBjYXNlIGl0IGNsYW1wcyB0byBgbWluWm9vbWAgaW5zdGVhZCkuIFdpdGhvdXQgdGhpcywgem9vbWluZyBvdXQgb3IgcGFubmluZ1xuLy8gdG93YXJkIHRoZSBwb2xlcyAod2hlcmUgZGVjayA5J3MgZ2xvYmUgY29udHJvbGxlciBsb3dlcnMgdGhlIGVmZmVjdGl2ZSB6b29tKVxuLy8gbWFrZXMgdGhlIHdob2xlIGdsb2JlIGJhc2VtYXAgZGlzYXBwZWFyLlxuY29uc3QgR0xPQkVfVElMRV9FWFRFTlQ6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gW1xuICAtMTgwLCAtODUuMDUxMTI5LCAxODAsIDg1LjA1MTEyOVxuXTtcblxuLy8gTWF4ICpuYXRpdmUqIHpvb20gb2YgZWFjaCB2ZWN0b3IgdGlsZSBzb3VyY2UuIFNldCB0aGlzIChub3QgYW4gYXJiaXRyYXJpbHlcbi8vIGhpZ2ggbnVtYmVyKSBzbyBkZWNrIG92ZXJ6b29tcyDigJQgaS5lLiBrZWVwcyByZW5kZXJpbmcgdGhlIGRlZXBlc3QgcmVhbCB0aWxlXG4vLyB3aGVuIHRoZSB2aWV3IHpvb21zIHBhc3QgaXQg4oCUIGluc3RlYWQgb2YgcmVxdWVzdGluZyB0aWxlcyB0aGF0IGRvbid0IGV4aXN0XG4vLyBhbmQgNDA0ICh3aGljaCBzaG93cyB1cCBhcyBlbXB0eSByZWN0YW5nbGVzKS4gVGhlIHJhdyBgLnZlY3Rvci5wYmZgIC9gLm12dGBcbi8vIGVuZHBvaW50cyBkbyBOT1QgYXV0by1vdmVyem9vbSB0aGUgd2F5IE1hcGJveCBHTCBkb2VzLlxuLy8gICAtIG1hcGJveC1zdHJlZXRzLXY4IGhhcyBkYXRhIHVwIHRvIHoxNlxuLy8gICAtIENBUlRPIGNhcnRvLnN0cmVldHMgdjEgaGFzIGRhdGEgdXAgdG8gejE0XG5jb25zdCBNQVBCT1hfVkVDVE9SX01BWF9EQVRBX1pPT00gPSAxNjtcbmNvbnN0IENBUlRPX1ZFQ1RPUl9NQVhfREFUQV9aT09NID0gMTQ7XG5cbi8qKlxuICogZGVjay5nbCA5J3MgZ2xvYmUgY291cGxlcyB6b29tIHRvIGxhdGl0dWRlIHZpYSBgem9vbUFkanVzdGAgKHNlZVxuICogZ2xvYmUtdmlld3BvcnQuanMpOiBgc2NhbGUgPSAyXih6b29tIC0gem9vbUFkanVzdChsYXQpKWAsIGFuZCBpdHMgY29udHJvbGxlclxuICogKmxvd2VycyogdGhlIHN0b3JlZCBgem9vbWAgYXMgeW91IHBhbiB0b3dhcmQgdGhlIHBvbGVzIHRvIGtlZXAgdGhlIGdsb2JlJ3NcbiAqIG9uLXNjcmVlbiBzaXplIGNvbnN0YW50LiBUaWxlIExPRCwgaG93ZXZlciwgaXMgc2VsZWN0ZWQgZnJvbSB0aGUgcmF3IGB6b29tYCxcbiAqIHNvIHJvdGF0aW5nIHRvd2FyZCBhIHBvbGUgc2lsZW50bHkgZHJvcHMgdGhlIExPRCBhbmQgdGhpbnMgb3V0IGxhYmVscy5cbiAqIFJlcGxpY2F0ZWQgZnJvbSBgQGRlY2suZ2wvY29yZWAgZ2xvYmUtdmlld3BvcnQuanMgYHpvb21BZGp1c3RgLlxuICovXG5mdW5jdGlvbiB6b29tQWRqdXN0KGxhdGl0dWRlOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5sb2cyKE1hdGguUEkgKiBNYXRoLmNvcygobGF0aXR1ZGUgKiBNYXRoLlBJKSAvIDE4MCkpO1xufVxuXG4vKipcbiAqIExhdGl0dWRlIGNvbXBlbnNhdGlvbiB0byBhZGQgdG8gYSBnbG9iZSB0aWxlIGxheWVyJ3MgYHpvb21PZmZzZXRgLCBzbyB0aWxlIExPRFxuICogdHJhY2tzIHRoZSAqdmlzdWFsKiAob24tc2NyZWVuKSBzY2FsZSBpbnN0ZWFkIG9mIHRoZSBsYXRpdHVkZS1hZGp1c3RlZCBtZXJjYXRvclxuICogem9vbS4gVGhpcyBjYW5jZWxzIHRoZSBwYW4taW5kdWNlZCB6b29tIGRyb3AsIGtlZXBpbmcgdGlsZSBkZXRhaWwvbGFiZWxzXG4gKiBjb25zdGFudCB3aGlsZSByb3RhdGluZyB0b3dhcmQgdGhlIHBvbGVzLlxuICovXG5mdW5jdGlvbiBnbG9iZUxhdGl0dWRlWm9vbUNvbXBlbnNhdGlvbihsYXRpdHVkZT86IG51bWJlcik6IG51bWJlciB7XG4gIGlmIChsYXRpdHVkZSA9PSBudWxsIHx8ICFOdW1iZXIuaXNGaW5pdGUobGF0aXR1ZGUpKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgLy8gQ2xhbXAgYXdheSBmcm9tIHRoZSBwb2xlcyB0byBhdm9pZCBsb2cyKDApID0gLUluZmluaXR5IGF0IHxsYXR8ID0gOTAuXG4gIGNvbnN0IGNsYW1wZWQgPSBNYXRoLm1heCgtODUsIE1hdGgubWluKDg1LCBsYXRpdHVkZSkpO1xuICByZXR1cm4gem9vbUFkanVzdCgwKSAtIHpvb21BZGp1c3QoY2xhbXBlZCk7XG59XG5cbi8qKlxuICogR2xvYmUgYmFzZW1hcCB0aWxlIHByb3ZpZGVyLlxuICpcbiAqIC0gYG1hcGJveGAgdXNlcyBNYXBib3ggdmVjdG9yL3Jhc3RlciB0aWxlcyBhbmQgcmVxdWlyZXMgYW4gYWNjZXNzIHRva2VuLlxuICogLSBgY2FydG9gIHVzZXMgQ0FSVE8ncyBmcmVlIE9wZW5NYXBUaWxlcyB2ZWN0b3IgdGlsZXMgKyBFc3JpIFdvcmxkIEltYWdlcnlcbiAqICAgcmFzdGVyLCBhbmQgbmVlZHMgbm8gdG9rZW4uIFVzZWQgYXMgYW4gYXV0b21hdGljIGZhbGxiYWNrIHdoZW4gbm8gTWFwYm94XG4gKiAgIHRva2VuIGlzIGF2YWlsYWJsZSAoZS5nLiBNYXBMaWJyZSAvIENBUlRPIGJhc2VtYXAgc2V0dXBzKSwgc28gdGhlIGdsb2JlXG4gKiAgIGJhc2VtYXAgc3RpbGwgcmVuZGVycyBpbnN0ZWFkIG9mIHNob3dpbmcgYSBzb2xpZC1jb2xvciBzcGhlcmUuXG4gKi9cbmV4cG9ydCB0eXBlIEdsb2JlQmFzZW1hcFByb3ZpZGVyID0gJ21hcGJveCcgfCAnY2FydG8nO1xuXG4vKipcbiAqIFJlc29sdmUgd2hpY2ggZ2xvYmUgYmFzZW1hcCB0aWxlIHByb3ZpZGVyIHRvIHVzZS5cbiAqXG4gKiBUaGUgZ2xvYmUgc2hvdWxkIGZvbGxvdyB0aGUgKnNlbGVjdGVkIGJhc2VtYXAgc3R5bGUncyogcmVuZGVyaW5nIGxpYnJhcnkgc29cbiAqIGl0IHN0YXlzIGNvbnNpc3RlbnQgd2l0aCB0aGUgZmxhdCAyRCBtYXA6IGEgTWFwTGlicmUvQ0FSVE8gc3R5bGUgdXNlcyB0aGVcbiAqIGZyZWUgQ0FSVE8gdGlsZXMgKGV2ZW4gd2hlbiBhIE1hcGJveCB0b2tlbiBpcyBhdmFpbGFibGUpLCBhbmQgYSBNYXBib3ggc3R5bGVcbiAqIHVzZXMgTWFwYm94IHRpbGVzLiBBIE1hcGJveCBzdHlsZSB3aXRoIG5vIHRva2VuIGZhbGxzIGJhY2sgdG8gQ0FSVE8gc28gdGhlXG4gKiBnbG9iZSBzdGlsbCByZW5kZXJzIGluc3RlYWQgb2Ygc2hvd2luZyBhIGJhcmUgY29sb3JlZCBzcGhlcmUuXG4gKlxuICogQHBhcmFtIGJhc2VNYXBMaWJyYXJ5IHRoZSBzZWxlY3RlZCBzdHlsZSdzIGxpYnJhcnkgKCdtYXBib3gnIHwgJ21hcGxpYnJlJyksXG4gKiAgIGUuZy4gZnJvbSBgZ2V0QmFzZU1hcExpYnJhcnkoY3VycmVudFN0eWxlKWAuXG4gKi9cbmV4cG9ydCBjb25zdCByZXNvbHZlR2xvYmVCYXNlbWFwUHJvdmlkZXIgPSAoXG4gIGJhc2VNYXBMaWJyYXJ5OiAnbWFwYm94JyB8ICdtYXBsaWJyZScgfCB1bmRlZmluZWQsXG4gIG1hcGJveEFwaUFjY2Vzc1Rva2VuPzogc3RyaW5nXG4pOiBHbG9iZUJhc2VtYXBQcm92aWRlciA9PiB7XG4gIGlmIChiYXNlTWFwTGlicmFyeSA9PT0gJ21hcGxpYnJlJykge1xuICAgIHJldHVybiAnY2FydG8nO1xuICB9XG4gIGlmIChiYXNlTWFwTGlicmFyeSA9PT0gJ21hcGJveCcpIHtcbiAgICByZXR1cm4gbWFwYm94QXBpQWNjZXNzVG9rZW4gPyAnbWFwYm94JyA6ICdjYXJ0byc7XG4gIH1cbiAgLy8gVW5rbm93biBsaWJyYXJ5OiBwcmVmZXIgTWFwYm94IHdoZW4gYSB0b2tlbiBleGlzdHMsIG90aGVyd2lzZSBDQVJUTy5cbiAgcmV0dXJuIG1hcGJveEFwaUFjY2Vzc1Rva2VuID8gJ21hcGJveCcgOiAnY2FydG8nO1xufTtcblxuLy8gQ0FSVE8gZnJlZSB2ZWN0b3IgdGlsZXMgKE9wZW5NYXBUaWxlcyBzY2hlbWEsIG5vIEFQSSBrZXkgcmVxdWlyZWQpLlxuY29uc3QgQ0FSVE9fVkVDVE9SX1RJTEVfVVJMUyA9IFtcbiAgJ2h0dHBzOi8vdGlsZXMtYS5iYXNlbWFwcy5jYXJ0b2Nkbi5jb20vdmVjdG9ydGlsZXMvY2FydG8uc3RyZWV0cy92MS97en0ve3h9L3t5fS5tdnQnLFxuICAnaHR0cHM6Ly90aWxlcy1iLmJhc2VtYXBzLmNhcnRvY2RuLmNvbS92ZWN0b3J0aWxlcy9jYXJ0by5zdHJlZXRzL3YxL3t6fS97eH0ve3l9Lm12dCcsXG4gICdodHRwczovL3RpbGVzLWMuYmFzZW1hcHMuY2FydG9jZG4uY29tL3ZlY3RvcnRpbGVzL2NhcnRvLnN0cmVldHMvdjEve3p9L3t4fS97eX0ubXZ0JyxcbiAgJ2h0dHBzOi8vdGlsZXMtZC5iYXNlbWFwcy5jYXJ0b2Nkbi5jb20vdmVjdG9ydGlsZXMvY2FydG8uc3RyZWV0cy92MS97en0ve3h9L3t5fS5tdnQnXG5dO1xuXG4vLyBGcmVlIHNhdGVsbGl0ZSByYXN0ZXIgZmFsbGJhY2sgKEVzcmkgV29ybGQgSW1hZ2VyeSwgbm8gQVBJIGtleSByZXF1aXJlZCkuXG5jb25zdCBFU1JJX1dPUkxEX0lNQUdFUllfVVJMID1cbiAgJ2h0dHBzOi8vc2VydmVyLmFyY2dpc29ubGluZS5jb20vQXJjR0lTL3Jlc3Qvc2VydmljZXMvV29ybGRfSW1hZ2VyeS9NYXBTZXJ2ZXIvdGlsZS97en0ve3l9L3t4fSc7XG5cbi8qKlxuICogTWFwcyBhIHJhdyBNVlQgc291cmNlLWxheWVyIG5hbWUgdG8gYSBub3JtYWxpemVkIHNlbWFudGljIGxheWVyIGtpbmQsIHNvIHRoZVxuICogZmlsbC9saW5lL2xhYmVsIGFjY2Vzc29ycyB3b3JrIGFjcm9zcyBib3RoIHRoZSBNYXBib3ggKGBtYXBib3gtc3RyZWV0cy12OGApXG4gKiBhbmQgQ0FSVE8vT3Blbk1hcFRpbGVzIHNjaGVtYXMuXG4gKlxuICogfCBzZW1hbnRpYyB8IG1hcGJveCAgICAgICAgfCBvcGVubWFwdGlsZXMgfFxuICogfCAtLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0gfFxuICogfCB3YXRlciAgICB8IGB3YXRlcmAgICAgICAgfCBgd2F0ZXJgICAgICAgfFxuICogfCBhZG1pbiAgICB8IGBhZG1pbmAgICAgICAgfCBgYm91bmRhcnlgICAgfFxuICogfCBsYWJlbCAgICB8IGBwbGFjZV9sYWJlbGAgfCBgcGxhY2VgICAgICAgfFxuICovXG50eXBlIEJhc2VtYXBMYXllcktpbmQgPSAnd2F0ZXInIHwgJ2FkbWluJyB8ICdsYWJlbCcgfCAnb3RoZXInO1xuXG5mdW5jdGlvbiBnZXRCYXNlbWFwTGF5ZXJLaW5kKGxheWVyTmFtZT86IHN0cmluZyk6IEJhc2VtYXBMYXllcktpbmQge1xuICBzd2l0Y2ggKGxheWVyTmFtZSkge1xuICAgIGNhc2UgJ3dhdGVyJzpcbiAgICAgIHJldHVybiAnd2F0ZXInO1xuICAgIGNhc2UgJ2FkbWluJzpcbiAgICBjYXNlICdib3VuZGFyeSc6XG4gICAgICByZXR1cm4gJ2FkbWluJztcbiAgICBjYXNlICdwbGFjZV9sYWJlbCc6XG4gICAgY2FzZSAncGxhY2UnOlxuICAgICAgcmV0dXJuICdsYWJlbCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnb3RoZXInO1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIEdsb2JlQXR0cmlidXRpb24gPSB7bGFiZWw6IHN0cmluZzsgaHJlZjogc3RyaW5nfTtcblxuY29uc3QgTUFQQk9YX0FUVFJJQlVUSU9OOiBHbG9iZUF0dHJpYnV0aW9uID0ge1xuICBsYWJlbDogJ8KpIE1hcGJveCcsXG4gIGhyZWY6ICdodHRwczovL3d3dy5tYXBib3guY29tL2Fib3V0L21hcHMvJ1xufTtcbmNvbnN0IE9TTV9BVFRSSUJVVElPTjogR2xvYmVBdHRyaWJ1dGlvbiA9IHtcbiAgbGFiZWw6ICfCqSBPcGVuU3RyZWV0TWFwJyxcbiAgaHJlZjogJ2h0dHBzOi8vd3d3Lm9wZW5zdHJlZXRtYXAub3JnL2NvcHlyaWdodCdcbn07XG5jb25zdCBDQVJUT19BVFRSSUJVVElPTjogR2xvYmVBdHRyaWJ1dGlvbiA9IHtcbiAgbGFiZWw6ICfCqSBDQVJUTycsXG4gIGhyZWY6ICdodHRwczovL2NhcnRvLmNvbS9hdHRyaWJ1dGlvbnMnXG59O1xuY29uc3QgRVNSSV9BVFRSSUJVVElPTjogR2xvYmVBdHRyaWJ1dGlvbiA9IHtcbiAgbGFiZWw6ICdQb3dlcmVkIGJ5IEVzcmknLFxuICBocmVmOiAnaHR0cHM6Ly93d3cuZXNyaS5jb20vJ1xufTtcblxuLyoqXG4gKiBSZXNvbHZlIHRoZSB0aWxlLXNvdXJjZSBhdHRyaWJ1dGlvbiBlbnRyaWVzIGZvciB0aGUgZ2xvYmUgYmFzZW1hcC4gZGVjay5nbFxuICogcmVuZGVycyB0aGUgZ2xvYmUgYmFzZW1hcCB0aWxlcyBpdHNlbGYgKG5vdCB0aGUgYmFzZSBNYXBsaWJyZS9NYXBib3ggbWFwKSwgc29cbiAqIHRoZSBiYXNlIG1hcCdzIGF0dHJpYnV0aW9uIG1hY2hpbmVyeSBuZXZlciBzZWVzIHRoZW0uIFRoaXMgbGV0cyB0aGUgVUkgY3JlZGl0XG4gKiB0aGUgYWN0dWFsIHRpbGUgcHJvdmlkZXIocykgaW4gZ2xvYmUgbW9kZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEdsb2JlQmFzZW1hcEF0dHJpYnV0aW9ucyA9ICh7XG4gIGdsb2JlLFxuICBtYXBib3hBcGlBY2Nlc3NUb2tlbixcbiAgbWFwU3R5bGVUeXBlLFxuICBiYXNlbWFwUHJvdmlkZXJcbn06IHtcbiAgZ2xvYmU/OiBHbG9iZTtcbiAgbWFwYm94QXBpQWNjZXNzVG9rZW4/OiBzdHJpbmc7XG4gIG1hcFN0eWxlVHlwZT86IHN0cmluZztcbiAgYmFzZW1hcFByb3ZpZGVyPzogR2xvYmVCYXNlbWFwUHJvdmlkZXI7XG59KTogR2xvYmVBdHRyaWJ1dGlvbltdID0+IHtcbiAgaWYgKCFnbG9iZT8uZW5hYmxlZCB8fCAhZ2xvYmUuY29uZmlnPy5iYXNlbWFwKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgcHJvdmlkZXI6IEdsb2JlQmFzZW1hcFByb3ZpZGVyID1cbiAgICBiYXNlbWFwUHJvdmlkZXIgPz8gcmVzb2x2ZUdsb2JlQmFzZW1hcFByb3ZpZGVyKHVuZGVmaW5lZCwgbWFwYm94QXBpQWNjZXNzVG9rZW4pO1xuXG4gIGlmIChwcm92aWRlciA9PT0gJ21hcGJveCcpIHtcbiAgICByZXR1cm4gbWFwYm94QXBpQWNjZXNzVG9rZW4gPyBbTUFQQk9YX0FUVFJJQlVUSU9OLCBPU01fQVRUUklCVVRJT05dIDogW107XG4gIH1cblxuICBjb25zdCBpc1NhdGVsbGl0ZSA9IG1hcFN0eWxlVHlwZSA9PT0gJ3NhdGVsbGl0ZScgfHwgbWFwU3R5bGVUeXBlID09PSAnc2F0ZWxsaXRlLXN0cmVldCc7XG4gIC8vIENBUlRPIHZlY3RvciB0aWxlcyBhcmUgT3BlblN0cmVldE1hcC1kZXJpdmVkOyBFc3JpIGltYWdlcnkgaXMgY3JlZGl0ZWQgc2VwYXJhdGVseS5cbiAgcmV0dXJuIGlzU2F0ZWxsaXRlXG4gICAgPyBbRVNSSV9BVFRSSUJVVElPTiwgQ0FSVE9fQVRUUklCVVRJT04sIE9TTV9BVFRSSUJVVElPTl1cbiAgICA6IFtDQVJUT19BVFRSSUJVVElPTiwgT1NNX0FUVFJJQlVUSU9OXTtcbn07XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG5leHBvcnQgY29uc3QgZ2V0R2xvYmVCYXNlTGF5ZXJzID0gKHtcbiAgbWFwYm94QXBpQWNjZXNzVG9rZW4sXG4gIGdsb2JlLFxuICBtYXBTdHlsZVR5cGUsXG4gIGJhc2VtYXBQcm92aWRlcixcbiAgbGF0aXR1ZGUsXG4gIHpvb21cbn06IHtcbiAgbWFwYm94QXBpQWNjZXNzVG9rZW46IHN0cmluZztcbiAgZ2xvYmU6IEdsb2JlO1xuICBtYXBTdHlsZVR5cGU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBXaGljaCB0aWxlIHByb3ZpZGVyIHRvIHVzZSBmb3IgdGhlIGdsb2JlIGJhc2VtYXAuIERlZmF1bHRzIHRvIGBtYXBib3hgIHdoZW5cbiAgICogYSB0b2tlbiBpcyBwcmVzZW50LCBvdGhlcndpc2UgZmFsbHMgYmFjayB0byB0aGUgdG9rZW4tZnJlZSBgY2FydG9gIHRpbGVzLlxuICAgKi9cbiAgYmFzZW1hcFByb3ZpZGVyPzogR2xvYmVCYXNlbWFwUHJvdmlkZXI7XG4gIC8qKlxuICAgKiBDdXJyZW50IGNhbWVyYSBjZW50ZXIgbGF0aXR1ZGUuIFVzZWQgdG8ga2VlcCB0aWxlIExPRCBjb25zdGFudCB3aGlsZSByb3RhdGluZ1xuICAgKiB0b3dhcmQgdGhlIHBvbGVzIChkZWNrLmdsIDkgbG93ZXJzIHRoZSBlZmZlY3RpdmUgem9vbSBuZWFyIHRoZSBwb2xlcykuIFdoZW5cbiAgICogb21pdHRlZCwgbm8gbGF0aXR1ZGUgY29tcGVuc2F0aW9uIGlzIGFwcGxpZWQgKGVxdWF0b3IgYmVoYXZpb3IpLlxuICAgKi9cbiAgbGF0aXR1ZGU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDdXJyZW50IG1hcCB6b29tIGxldmVsLiBVc2VkIHRvIGZhZGUgdGhlIGF0bW9zcGhlcmUgZWZmZWN0cyBvdXQgd2hlbiB0aGUgdXNlclxuICAgKiB6b29tcyBpbiBwYXN0IGEgY2VydGFpbiB0aHJlc2hvbGQgKG1pcnJvcnMgR29vZ2xlIE1hcHMgZ2xvYmUgYmVoYXZpb3VyKS5cbiAgICovXG4gIHpvb20/OiBudW1iZXI7XG59KTogTGF5ZXJbXSA9PiB7XG4gIGNvbnN0IHtjb25maWd9ID0gZ2xvYmU7XG5cbiAgY29uc3QgaXNTYXRlbGxpdGUgPSBtYXBTdHlsZVR5cGUgPT09ICdzYXRlbGxpdGUnO1xuICBjb25zdCBpc1NhdGVsbGl0ZVN0cmVldCA9IG1hcFN0eWxlVHlwZSA9PT0gJ3NhdGVsbGl0ZS1zdHJlZXQnO1xuXG4gIGNvbnN0IGxhdFpvb21Db21wZW5zYXRpb24gPSBnbG9iZUxhdGl0dWRlWm9vbUNvbXBlbnNhdGlvbihsYXRpdHVkZSk7XG5cbiAgLy8gRmFsbCBiYWNrIHRvIHRoZSBmcmVlIENBUlRPIHRpbGVzIHdoZW5ldmVyIG5vIE1hcGJveCB0b2tlbiBpcyBhdmFpbGFibGUgc29cbiAgLy8gdGhlIGdsb2JlIGJhc2VtYXAgc3RpbGwgcmVuZGVycyAobWF0Y2hlcyBrZXBsZXIncyBkZWZhdWx0IHRva2VuLWZyZWVcbiAgLy8gTWFwTGlicmUvQ0FSVE8gYmFzZW1hcHMpLiBDYWxsZXJzIHNob3VsZCBwYXNzIGFuIGV4cGxpY2l0IGBiYXNlbWFwUHJvdmlkZXJgXG4gIC8vIChkZXJpdmVkIGZyb20gdGhlIHNlbGVjdGVkIHN0eWxlKSBzbyB0aGUgZ2xvYmUgZm9sbG93cyB0aGUgMkQgYmFzZW1hcC5cbiAgY29uc3QgcHJvdmlkZXI6IEdsb2JlQmFzZW1hcFByb3ZpZGVyID1cbiAgICBiYXNlbWFwUHJvdmlkZXIgPz8gcmVzb2x2ZUdsb2JlQmFzZW1hcFByb3ZpZGVyKHVuZGVmaW5lZCwgbWFwYm94QXBpQWNjZXNzVG9rZW4pO1xuICBjb25zdCB1c2VDYXJ0byA9IHByb3ZpZGVyID09PSAnY2FydG8nO1xuICBjb25zdCBoYXNUaWxlQWNjZXNzID0gdXNlQ2FydG8gfHwgQm9vbGVhbihtYXBib3hBcGlBY2Nlc3NUb2tlbik7XG5cbiAgcmV0dXJuIFtcbiAgICBjb25maWcuYXRtb3NwaGVyZSA/IGdldEdsb2JlQXRtb3NwaGVyZVNreUxheWVyKHtjb25maWcsIHpvb219KSA6IG51bGwsXG5cbiAgICAvLyBEZXB0aC1vbmx5IGNyb3NzLXNlY3Rpb24gZGlzazogd3JpdGVzIGRlcHRoIGF0IHRoZSBnbG9iZSdzIHNpbGhvdWV0dGUgc29cbiAgICAvLyBmYXItc2lkZSBnZW9tZXRyeSAoYXJjcy9saW5lcykgaXMgb2NjbHVkZWQgYnkgdGhlIHBsYW5ldC5cbiAgICBnZXRHbG9iZURlcHRoRGlza0xheWVyKHtmaWxsQ29sb3I6IGNvbmZpZy5zdXJmYWNlQ29sb3J9KSxcblxuICAgIC8vIEJhY2tncm91bmQgc3VyZmFjZSBwb2x5Z29uXG4gICAgKCFjb25maWcuYmFzZW1hcCB8fCAoIWlzU2F0ZWxsaXRlICYmICFpc1NhdGVsbGl0ZVN0cmVldCkpICYmXG4gICAgICBuZXcgU29saWRQb2x5Z29uTGF5ZXIoe1xuICAgICAgICBpZDogJ2dsb2JlLWJhY2tncm91bmQnLFxuICAgICAgICBkYXRhOiBCQUNLR1JPVU5EX0RBVEEsXG4gICAgICAgIGdldFBvbHlnb246ICgoZDogbnVtYmVyW11bXSkgPT4gZCkgYXMgYW55LFxuICAgICAgICBmaWxsZWQ6IHRydWUsXG4gICAgICAgIGdldEZpbGxDb2xvcjogY29uZmlnLnN1cmZhY2VDb2xvciBhcyBhbnksXG4gICAgICAgIHBhcmFtZXRlcnM6IEJBQ0tHUk9VTkRfUEFSQU1FVEVSU1xuICAgICAgfSksXG5cbiAgICAvLyBGaWxsIGhvbGUgYXQgbm9ydGggcG9sZVxuICAgIGNvbmZpZy5iYXNlbWFwICYmXG4gICAgICBuZXcgU29saWRQb2x5Z29uTGF5ZXIoe1xuICAgICAgICBpZDogJ2dsb2JlLWJhY2tncm91bmQtbm9ydGgtcG9sZScsXG4gICAgICAgIGRhdGE6IEJBQ0tHUk9VTkRfTk9SVEhfUE9MRV9EQVRBLFxuICAgICAgICBnZXRQb2x5Z29uOiAoKGQ6IG51bWJlcltdW10pID0+IGQpIGFzIGFueSxcbiAgICAgICAgZmlsbGVkOiB0cnVlLFxuICAgICAgICBnZXRGaWxsQ29sb3I6IChjb25maWcud2F0ZXIgPyBjb25maWcud2F0ZXJDb2xvciA6IGNvbmZpZy5zdXJmYWNlQ29sb3IpIGFzIGFueSxcbiAgICAgICAgcGFyYW1ldGVyczogQkFDS0dST1VORF9QQVJBTUVURVJTXG4gICAgICB9KSxcblxuICAgIC8vIFNhdGVsbGl0ZSB0aWxlc1xuICAgIGNvbmZpZy5iYXNlbWFwICYmXG4gICAgICAoaXNTYXRlbGxpdGUgfHwgaXNTYXRlbGxpdGVTdHJlZXQpICYmXG4gICAgICBoYXNUaWxlQWNjZXNzICYmXG4gICAgICBuZXcgVGlsZUxheWVyKHtcbiAgICAgICAgaWQ6IGBnbG9iZS1zYXRlbGxpdGUtdGlsZXMtJHtwcm92aWRlcn1gLFxuICAgICAgICBkYXRhOiB1c2VDYXJ0b1xuICAgICAgICAgID8gW0VTUklfV09STERfSU1BR0VSWV9VUkxdXG4gICAgICAgICAgOiBbXG4gICAgICAgICAgICAgIGBodHRwczovL2FwaS5tYXBib3guY29tL3Y0L21hcGJveC5zYXRlbGxpdGUve3p9L3t4fS97eX1AMngucG5nP2FjY2Vzc190b2tlbj0ke21hcGJveEFwaUFjY2Vzc1Rva2VufWBcbiAgICAgICAgICAgIF0sXG4gICAgICAgIG1pblpvb206IDAsXG4gICAgICAgIG1heFpvb206IHVzZUNhcnRvID8gMTggOiAxOSxcbiAgICAgICAgem9vbU9mZnNldDogR0xPQkVfU0FURUxMSVRFX1pPT01fT0ZGU0VUICsgbGF0Wm9vbUNvbXBlbnNhdGlvbixcbiAgICAgICAgZXh0ZW50OiBHTE9CRV9USUxFX0VYVEVOVCxcbiAgICAgICAgLy8gRXNyaSB0aWxlcyBhcmUgMjU2cHg7IE1hcGJveCBAMnggdGlsZXMgYXJlIDUxMnB4LlxuICAgICAgICB0aWxlU2l6ZTogdXNlQ2FydG8gPyAyNTYgOiA1MTIgLyBkZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgICByZW5kZXJTdWJMYXllcnM6IChwcm9wczogYW55KSA9PiB7XG4gICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgYmJveDoge3dlc3QsIHNvdXRoLCBlYXN0LCBub3J0aH1cbiAgICAgICAgICB9ID0gcHJvcHMudGlsZTtcblxuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBuZXcgQml0bWFwTGF5ZXIocHJvcHMsIHtcbiAgICAgICAgICAgICAgX2ltYWdlQ29vcmRpbmF0ZVN5c3RlbTogQ09PUkRJTkFURV9TWVNURU0uQ0FSVEVTSUFOLFxuICAgICAgICAgICAgICBkYXRhOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGltYWdlOiBwcm9wcy5kYXRhLFxuICAgICAgICAgICAgICBib3VuZHM6IFt3ZXN0LCBzb3V0aCwgZWFzdCwgbm9ydGhdXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIF07XG4gICAgICAgIH0sXG4gICAgICAgIHBhcmFtZXRlcnM6IEJBU0VNQVBfUkFTVEVSX1BBUkFNRVRFUlNcbiAgICAgIH0pLFxuXG4gICAgLy8gVmVjdG9yIGJhc2VtYXAgKE1WVCBsYWJlbHMvYWRtaW4vd2F0ZXIpXG4gICAgY29uZmlnLmJhc2VtYXAgJiZcbiAgICAgICFpc1NhdGVsbGl0ZSAmJlxuICAgICAgaGFzVGlsZUFjY2VzcyAmJlxuICAgICAgbmV3IE1WVExheWVyKHtcbiAgICAgICAgLy8gZm9yY2UgdGhlIGxheWVyIHRvIHVwZGF0ZSB3aGVuIHRoZSBzdHlsZS9sYWJlbC9wcm92aWRlciBjb25maWcgY2hhbmdlc1xuICAgICAgICBpZDogYGdsb2JlLWJhc2VtYXAtbXZ0LWxheWVyLSR7cHJvdmlkZXJ9LSR7bWFwU3R5bGVUeXBlfWAsXG4gICAgICAgIGRhdGE6IHVzZUNhcnRvXG4gICAgICAgICAgPyBDQVJUT19WRUNUT1JfVElMRV9VUkxTXG4gICAgICAgICAgOiBgaHR0cHM6Ly9hLnRpbGVzLm1hcGJveC5jb20vdjQvbWFwYm94Lm1hcGJveC1zdHJlZXRzLXY4L3t6fS97eH0ve3l9LnZlY3Rvci5wYmY/YWNjZXNzX3Rva2VuPSR7bWFwYm94QXBpQWNjZXNzVG9rZW59YCxcbiAgICAgICAgbWluWm9vbTogMCxcbiAgICAgICAgLy8gT3Zlcnpvb20gcGFzdCB0aGUgc291cmNlJ3MgbmF0aXZlIG1heCBpbnN0ZWFkIG9mIDQwNC1pbmcgb24gdGlsZXMgdGhhdFxuICAgICAgICAvLyBkb24ndCBleGlzdCAod2hpY2ggcmVuZGVycyBhcyBlbXB0eSByZWN0YW5nbGVzIGF0IGhpZ2ggem9vbSkuXG4gICAgICAgIG1heFpvb206IHVzZUNhcnRvID8gQ0FSVE9fVkVDVE9SX01BWF9EQVRBX1pPT00gOiBNQVBCT1hfVkVDVE9SX01BWF9EQVRBX1pPT00sXG4gICAgICAgIHpvb21PZmZzZXQ6XG4gICAgICAgICAgKHVzZUNhcnRvID8gQ0FSVE9fR0xPQkVfVkVDVE9SX1pPT01fT0ZGU0VUIDogTUFQQk9YX0dMT0JFX1ZFQ1RPUl9aT09NX09GRlNFVCkgK1xuICAgICAgICAgIGxhdFpvb21Db21wZW5zYXRpb24sXG4gICAgICAgIGV4dGVudDogR0xPQkVfVElMRV9FWFRFTlQsXG4gICAgICAgIGJpbmFyeTogZmFsc2UsXG4gICAgICAgIHBhcmFtZXRlcnM6IEJBU0VNQVBfTVZUX1BBUkFNRVRFUlMsXG4gICAgICAgIGxvYWRPcHRpb25zOiB1c2VDYXJ0b1xuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAvLyBPcGVuTWFwVGlsZXMgc2NoZW1hOiBgYm91bmRhcnlgID0gYWRtaW4gbGluZXMsIGBwbGFjZWAgPSBsYWJlbHMuXG4gICAgICAgICAgICAgIG12dDoge1xuICAgICAgICAgICAgICAgIGxheWVyczogaXNTYXRlbGxpdGVTdHJlZXRcbiAgICAgICAgICAgICAgICAgID8gWydwbGFjZScsICdib3VuZGFyeSddXG4gICAgICAgICAgICAgICAgICA6IFsncGxhY2UnLCAnYm91bmRhcnknLCAnd2F0ZXInLCAndHJhbnNwb3J0YXRpb24nXVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgOiB7XG4gICAgICAgICAgICAgIG12dDoge1xuICAgICAgICAgICAgICAgIGxheWVyczogaXNTYXRlbGxpdGVTdHJlZXRcbiAgICAgICAgICAgICAgICAgID8gWydwbGFjZV9sYWJlbCcsICdhZG1pbiddXG4gICAgICAgICAgICAgICAgICA6IFsncGxhY2VfbGFiZWwnLCAnYWRtaW4nLCAnd2F0ZXInLCAncm9hZCddXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIC8vIFJlbmRlciBhZG1pbi93YXRlciB2aWEgR2VvSnNvbkxheWVyIGFuZCBwbGFjZSBsYWJlbHMgdmlhIFRleHRMYXllci5cbiAgICAgICAgY29uZmlnLFxuICAgICAgICByZW5kZXJTdWJMYXllcnM6IChwcm9wczogYW55KSA9PiBuZXcgTVZUTGFiZWxMYXllcihwcm9wcyksXG4gICAgICAgIGdldEZpbGxDb2xvcjogKGY6IGFueSkgPT4ge1xuICAgICAgICAgIHN3aXRjaCAoZ2V0QmFzZW1hcExheWVyS2luZChmLnByb3BlcnRpZXMubGF5ZXJOYW1lKSkge1xuICAgICAgICAgICAgY2FzZSAnd2F0ZXInOlxuICAgICAgICAgICAgICByZXR1cm4gY29uZmlnLndhdGVyID8gY29uZmlnLndhdGVyQ29sb3IgOiBJTlZJU0lCTEVfQ09MT1I7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gY29uZmlnLnN1cmZhY2VDb2xvcjtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGdldExpbmVDb2xvcjogKGY6IGFueSkgPT4ge1xuICAgICAgICAgIHN3aXRjaCAoZ2V0QmFzZW1hcExheWVyS2luZChmLnByb3BlcnRpZXMubGF5ZXJOYW1lKSkge1xuICAgICAgICAgICAgY2FzZSAnYWRtaW4nOlxuICAgICAgICAgICAgICByZXR1cm4gY29uZmlnLmFkbWluTGluZXMgPyBjb25maWcuYWRtaW5MaW5lc0NvbG9yIDogSU5WSVNJQkxFX0NPTE9SO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZy5zdXJmYWNlQ29sb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBnZXRMaW5lV2lkdGg6IChmOiBhbnkpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGdldEJhc2VtYXBMYXllcktpbmQoZi5wcm9wZXJ0aWVzLmxheWVyTmFtZSkpIHtcbiAgICAgICAgICAgIGNhc2UgJ2FkbWluJzpcbiAgICAgICAgICAgICAgc3dpdGNoIChmLnByb3BlcnRpZXMuYWRtaW5fbGV2ZWwpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgIHJldHVybiAwLjc1O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHVwZGF0ZVRyaWdnZXJzOiB7XG4gICAgICAgICAgZ2V0RmlsbENvbG9yOiBbY29uZmlnLndhdGVyQ29sb3IsIGNvbmZpZy5zdXJmYWNlQ29sb3IsIGNvbmZpZy53YXRlcl0sXG4gICAgICAgICAgZ2V0TGluZUNvbG9yOiBbY29uZmlnLmFkbWluTGluZXNDb2xvciwgY29uZmlnLnN1cmZhY2VDb2xvciwgY29uZmlnLmFkbWluTGluZXNdXG4gICAgICAgIH0sXG4gICAgICAgIGxpbmVXaWR0aFVuaXRzOiAncGl4ZWxzJyxcbiAgICAgICAgbGluZVdpZHRoTWluUGl4ZWxzOiAwLFxuICAgICAgICBsaW5lV2lkdGhNYXhQaXhlbHM6IDIwLFxuICAgICAgICBnZXRQb2ludFJhZGl1czogMCxcbiAgICAgICAgcG9pbnRSYWRpdXNNaW5QaXhlbHM6IDBcbiAgICAgIH0gYXMgYW55KVxuICBdLmZpbHRlcihCb29sZWFuKSBhcyBMYXllcltdO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEdsb2JlVG9wTGF5ZXJzID0gKHtnbG9iZSwgem9vbX06IHtnbG9iZTogR2xvYmU7IHpvb20/OiBudW1iZXJ9KTogTGF5ZXJbXSA9PiB7XG4gIGNvbnN0IHtjb25maWd9ID0gZ2xvYmU7XG4gIHJldHVybiBbY29uZmlnLmF0bW9zcGhlcmUgPyBnZXRHbG9iZUF0bW9zcGhlcmVMYXllcih7Y29uZmlnLCB6b29tfSkgOiBudWxsXS5maWx0ZXIoQm9vbGVhbikgYXMgTGF5ZXJbXTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7O0FBRUEsU0FBUUEsaUJBQWlCLFFBQWMsZUFBZTtBQUN0RCxTQUFRQyxpQkFBaUIsRUFBRUMsV0FBVyxRQUFPLGlCQUFpQjtBQUM5RCxTQUFRQyxTQUFTLEVBQUVDLFFBQVEsUUFBTyxxQkFB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