@kepler.gl/deckgl-layers 3.3.0-alpha.5 → 3.3.0-alpha.7

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 (189) 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 +341 -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 +574 -0
  12. package/dist/cjs/globe/globe-stars-layer.js +99 -0
  13. package/dist/cjs/globe/globe-stars-layer.spec.js +42 -0
  14. package/dist/cjs/globe/globe-view.js +404 -0
  15. package/dist/{globe → cjs/globe}/index.js +19 -1
  16. package/dist/cjs/globe/mvt-label-layer.js +190 -0
  17. package/dist/cjs/grid-layer/enhanced-cpu-grid-layer.js +116 -0
  18. package/dist/cjs/hexagon-layer/enhanced-hexagon-layer.js +134 -0
  19. package/dist/{index.js → cjs/index.js} +1 -1
  20. package/dist/cjs/layer-utils/aggregation-utils.js +181 -0
  21. package/dist/cjs/layer-utils/cluster-utils.js +93 -0
  22. package/dist/cjs/layer-utils/cpu-aggregator.js +798 -0
  23. package/dist/cjs/layer-utils/globe-cell-utils.js +173 -0
  24. package/dist/cjs/layer-utils/shader-utils.js +38 -0
  25. package/dist/cjs/line-layer/line-layer.js +95 -0
  26. package/dist/cjs/raster/images.js +271 -0
  27. package/dist/cjs/raster/pipeline-validation-patch.js +101 -0
  28. package/dist/cjs/raster/raster-layer/raster-layer-shaders.js +163 -0
  29. package/dist/cjs/raster/raster-layer/raster-layer-webgl1.fs.js +10 -0
  30. package/dist/cjs/raster/raster-layer/raster-layer-webgl1.vs.js +10 -0
  31. package/dist/cjs/raster/raster-layer/raster-layer-webgl2.fs.js +10 -0
  32. package/dist/cjs/raster/raster-layer/raster-layer-webgl2.vs.js +10 -0
  33. package/dist/cjs/raster/raster-layer/raster-layer.js +287 -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 +335 -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 +566 -0
  74. package/dist/esm/globe/globe-stars-layer.js +92 -0
  75. package/dist/esm/globe/globe-stars-layer.spec.js +40 -0
  76. package/dist/esm/globe/globe-view.js +398 -0
  77. package/dist/esm/globe/index.js +26 -0
  78. package/dist/esm/globe/mvt-label-layer.js +187 -0
  79. package/dist/esm/grid-layer/enhanced-cpu-grid-layer.js +112 -0
  80. package/dist/esm/hexagon-layer/enhanced-hexagon-layer.js +130 -0
  81. package/dist/esm/index.js +22 -0
  82. package/dist/esm/layer-utils/aggregation-utils.js +172 -0
  83. package/dist/esm/layer-utils/cluster-utils.js +86 -0
  84. package/dist/esm/layer-utils/cpu-aggregator.js +788 -0
  85. package/dist/esm/layer-utils/globe-cell-utils.js +167 -0
  86. package/dist/esm/layer-utils/shader-utils.js +32 -0
  87. package/dist/esm/line-layer/line-layer.js +91 -0
  88. package/dist/esm/raster/images.js +267 -0
  89. package/dist/esm/raster/pipeline-validation-patch.js +94 -0
  90. package/dist/esm/raster/raster-layer/raster-layer-shaders.js +153 -0
  91. package/dist/esm/raster/raster-layer/raster-layer-webgl1.fs.js +5 -0
  92. package/dist/esm/raster/raster-layer/raster-layer-webgl1.vs.js +5 -0
  93. package/dist/esm/raster/raster-layer/raster-layer-webgl2.fs.js +5 -0
  94. package/dist/esm/raster/raster-layer/raster-layer-webgl2.vs.js +5 -0
  95. package/dist/esm/raster/raster-layer/raster-layer.js +283 -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 +22 -1
  126. package/dist/globe/globe-stars-layer.d.ts +5 -0
  127. package/dist/globe/globe-stars-layer.spec.d.ts +1 -0
  128. package/dist/globe/index.d.ts +2 -2
  129. package/dist/wms/wms-layer.d.ts +8 -0
  130. package/package.json +19 -10
  131. package/dist/3d-building-layer/3d-building-layer.js +0 -66
  132. package/dist/3d-building-layer/3d-building-utils.js +0 -166
  133. package/dist/3d-building-layer/types.js +0 -6
  134. package/dist/cluster-layer/cluster-layer.js +0 -292
  135. package/dist/column-layer/enhanced-column-layer.js +0 -160
  136. package/dist/deckgl-extensions/filter-shader-module.js +0 -26
  137. package/dist/globe/atmosphere-layer.js +0 -220
  138. package/dist/globe/enhanced-multi-icon-layer.js +0 -63
  139. package/dist/globe/globe-depth-disk-layer.js +0 -145
  140. package/dist/globe/globe-layers.js +0 -569
  141. package/dist/globe/globe-stars-layer.js +0 -69
  142. package/dist/globe/globe-view.js +0 -404
  143. package/dist/globe/mvt-label-layer.js +0 -190
  144. package/dist/grid-layer/enhanced-cpu-grid-layer.js +0 -116
  145. package/dist/hexagon-layer/enhanced-hexagon-layer.js +0 -134
  146. package/dist/layer-utils/aggregation-utils.js +0 -181
  147. package/dist/layer-utils/cluster-utils.js +0 -93
  148. package/dist/layer-utils/cpu-aggregator.js +0 -798
  149. package/dist/layer-utils/globe-cell-utils.js +0 -173
  150. package/dist/layer-utils/shader-utils.js +0 -38
  151. package/dist/line-layer/line-layer.js +0 -95
  152. package/dist/raster/images.js +0 -271
  153. package/dist/raster/pipeline-validation-patch.js +0 -101
  154. package/dist/raster/raster-layer/raster-layer-shaders.js +0 -163
  155. package/dist/raster/raster-layer/raster-layer-webgl1.fs.js +0 -10
  156. package/dist/raster/raster-layer/raster-layer-webgl1.vs.js +0 -10
  157. package/dist/raster/raster-layer/raster-layer-webgl2.fs.js +0 -10
  158. package/dist/raster/raster-layer/raster-layer-webgl2.vs.js +0 -10
  159. package/dist/raster/raster-layer/raster-layer.js +0 -287
  160. package/dist/raster/raster-mesh-layer/matrix.d.ts +0 -4
  161. package/dist/raster/raster-mesh-layer/matrix.js +0 -18
  162. package/dist/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +0 -38
  163. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +0 -10
  164. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +0 -10
  165. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +0 -10
  166. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +0 -10
  167. package/dist/raster/raster-mesh-layer/raster-mesh-layer.js +0 -321
  168. package/dist/raster/raster-processing-uniforms.js +0 -124
  169. package/dist/raster/types.js +0 -6
  170. package/dist/raster/util.js +0 -139
  171. package/dist/raster/webgl/color/colormap.js +0 -45
  172. package/dist/raster/webgl/color/filter.js +0 -58
  173. package/dist/raster/webgl/color/gamma-contrast.js +0 -68
  174. package/dist/raster/webgl/color/linear-rescale.js +0 -35
  175. package/dist/raster/webgl/color/saturation.js +0 -42
  176. package/dist/raster/webgl/color/sigmoidal-contrast.js +0 -68
  177. package/dist/raster/webgl/pansharpen/pansharpen-brovey.js +0 -46
  178. package/dist/raster/webgl/spectral-indices/evi.js +0 -26
  179. package/dist/raster/webgl/spectral-indices/msavi.js +0 -25
  180. package/dist/raster/webgl/spectral-indices/normalized-difference.js +0 -19
  181. package/dist/raster/webgl/spectral-indices/savi.js +0 -21
  182. package/dist/raster/webgl/texture/combine-bands.js +0 -65
  183. package/dist/raster/webgl/texture/mask.js +0 -50
  184. package/dist/raster/webgl/texture/reorder-bands.js +0 -72
  185. package/dist/raster/webgl/texture/rgba-image.js +0 -34
  186. package/dist/raster/webgl/types.js +0 -6
  187. package/dist/svg-icon-layer/scatterplot-icon-layer.js +0 -88
  188. package/dist/svg-icon-layer/svg-icon-layer.js +0 -104
  189. package/dist/wms/wms-layer.js +0 -594
@@ -0,0 +1,335 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
3
+ import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
4
+ import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
5
+ import _get from "@babel/runtime/helpers/esm/get";
6
+ import _inherits from "@babel/runtime/helpers/esm/inherits";
7
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
8
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
11
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
12
+ function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; }
13
+ // SPDX-License-Identifier: MIT
14
+ // Copyright contributors to the kepler.gl project
15
+
16
+ // Shaders ported from iTowns, based on Sean O'Neil's approach in GPU Gems 2
17
+ // SEE: https://github.com/iTowns/itowns/blob/master/src/Core/Prefab/Globe/Atmosphere.js
18
+ // SEE: https://developer.nvidia.com/gpugems/gpugems2/part-ii-shading-lighting-and-shadows/chapter-16-accurate-atmospheric-scattering
19
+
20
+ import { COORDINATE_SYSTEM } from '@deck.gl/core';
21
+ import { SimpleMeshLayer } from '@deck.gl/mesh-layers';
22
+ import { SphereGeometry } from '@luma.gl/engine';
23
+ import { Vector3 } from '@math.gl/core';
24
+ import { getSunPosition } from '@math.gl/sun';
25
+ import { DEFAULT_GLOBE_CONFIG } from '@kepler.gl/constants';
26
+ var toRadians = function toRadians(degrees) {
27
+ return degrees * Math.PI / 180;
28
+ };
29
+ var angleToVec = function angleToVec(angle) {
30
+ return [Math.sin(angle), Math.cos(angle), 0];
31
+ };
32
+ var angleToSunPos = function angleToSunPos(angle) {
33
+ return new Vector3(angleToVec(angle)).normalize();
34
+ };
35
+ var GLOBE_MESH_INNER = new SphereGeometry({
36
+ radius: 6.4e6,
37
+ nlat: 100,
38
+ nlong: 100
39
+ });
40
+ var GLOBE_MESH_OUTER = new SphereGeometry({
41
+ radius: 6.7e6,
42
+ nlat: 100,
43
+ nlong: 100
44
+ });
45
+
46
+ // ~14% larger than the globe surface mesh — yields a thick soft aura (~0.1–0.15R).
47
+ var GLOBE_MESH_HUGE_HALO = new SphereGeometry({
48
+ radius: 7.3e6,
49
+ nlat: 100,
50
+ nlong: 100
51
+ });
52
+ var lon = 0,
53
+ lat = 90;
54
+ var sunPosNow = getSunPosition(Date.now(), lat, lon);
55
+ var v3SunPosNow = angleToSunPos(sunPosNow.azimuth + Math.PI);
56
+ var NUM_SAMPLE_RAYS = 3;
57
+
58
+ /**
59
+ * Zoom range over which the atmosphere effect fades out.
60
+ * Below ATMOSPHERE_FADE_ZOOM_START the effect is fully visible.
61
+ * Above ATMOSPHERE_FADE_ZOOM_END the effect is completely hidden.
62
+ */
63
+ var ATMOSPHERE_FADE_ZOOM_START = 3.5;
64
+ var ATMOSPHERE_FADE_ZOOM_END = 6;
65
+
66
+ /**
67
+ * Convert a mapState zoom level to a [0, 1] atmosphere opacity multiplier.
68
+ * Returns 1 (fully visible) below ATMOSPHERE_FADE_ZOOM_START, smoothly
69
+ * interpolates to 0 between the two thresholds, and returns 0 above
70
+ * ATMOSPHERE_FADE_ZOOM_END.
71
+ */
72
+ export function atmosphereZoomFade(zoom) {
73
+ if (zoom <= ATMOSPHERE_FADE_ZOOM_START) return 1;
74
+ if (zoom >= ATMOSPHERE_FADE_ZOOM_END) return 0;
75
+ var t = (zoom - ATMOSPHERE_FADE_ZOOM_START) / (ATMOSPHERE_FADE_ZOOM_END - ATMOSPHERE_FADE_ZOOM_START);
76
+ // Smooth-step for a perceptually gentle transition.
77
+ return 1 - t * t * (3 - 2 * t);
78
+ }
79
+ var ATMOSPHERE_UNIFORMS = {
80
+ v3SunPos: v3SunPosNow,
81
+ exposure: 2,
82
+ fSamples: 3,
83
+ g: -0.65,
84
+ fKrESun: 0.00025 * 20,
85
+ fKmESun: 0.0001 * 20,
86
+ fKr4PI: 0.00025 * 4 * Math.PI,
87
+ fKm4PI: 0.0001 * 4 * Math.PI,
88
+ fScaleDepth: 0.25,
89
+ fInnerRadius: 258,
90
+ fOuterRadius: 265,
91
+ fTerminatorAttenuateFactor: 0.8,
92
+ fTerminatorOpacityFactor: 1
93
+ };
94
+ export var AtmosphereLayerRealistic = /*#__PURE__*/function (_SimpleMeshLayer) {
95
+ function AtmosphereLayerRealistic() {
96
+ _classCallCheck(this, AtmosphereLayerRealistic);
97
+ return _callSuper(this, AtmosphereLayerRealistic, arguments);
98
+ }
99
+ _inherits(AtmosphereLayerRealistic, _SimpleMeshLayer);
100
+ return _createClass(AtmosphereLayerRealistic, [{
101
+ key: "draw",
102
+ value: function draw(_ref) {
103
+ var uniforms = _ref.uniforms;
104
+ var _this$props = this.props,
105
+ config = _this$props.config,
106
+ zoomFade = _this$props.zoomFade;
107
+ var model = this.state.model;
108
+ if (model) {
109
+ model.props.uniforms = _objectSpread(_objectSpread(_objectSpread({}, model.props.uniforms), ATMOSPHERE_UNIFORMS), {}, {
110
+ fTerminatorOpacityFactor: config.terminator ? config.terminatorOpacity : 0,
111
+ v3SunPos: config.azimuth ? angleToSunPos(toRadians(config.azimuthAngle)) : v3SunPosNow,
112
+ fAtmosphereZoomFade: zoomFade
113
+ });
114
+ }
115
+ _superPropGet(AtmosphereLayerRealistic, "draw", this, 3)([{
116
+ uniforms: uniforms
117
+ }]);
118
+ }
119
+ }, {
120
+ key: "getShaders",
121
+ value: function getShaders() {
122
+ return _objectSpread(_objectSpread({}, _superPropGet(AtmosphereLayerRealistic, "getShaders", this, 3)([])), {}, {
123
+ inject: {
124
+ 'fs:#decl': "\n uniform vec3 v3SunPos;\n\n uniform float g;\n uniform float exposure;\n\n uniform float fSamples;\n\n uniform float fInnerRadius;\n uniform float fOuterRadius;\n uniform float fKrESun;\n uniform float fKmESun;\n uniform float fKr4PI;\n uniform float fKm4PI;\n uniform float fScaleDepth;\n\n uniform float fTerminatorAttenuateFactor;\n uniform float fTerminatorOpacityFactor;\n uniform float fAtmosphereZoomFade;\n\n const int nSamples = ".concat(NUM_SAMPLE_RAYS, ";\n\n float scale(float fCos) {\n float x = 1.0 - fCos;\n return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.8 + x*5.25))));\n }\n "),
125
+ 'fs:#main-end': "\n vec3 v3CameraPos = cameraPosition;\n vec3 v3Pos = position_commonspace.xyz;\n\n float g2 = g * g;\n\n vec3 v3InvWavelength = vec3(1.0 / pow(0.650, 4.0), 1.0 / pow(0.570, 4.0), 1.0 / pow(0.475, 4.0));\n\n float fInnerRadius2 = fInnerRadius * fInnerRadius;\n float fOuterRadius2 = fOuterRadius * fOuterRadius;\n float fScale = 1.0 / (fOuterRadius - fInnerRadius);\n float fScaleOverScaleDepth = 1.0 / (fOuterRadius - fInnerRadius) / fScaleDepth;\n\n float cameraHeight2 = length(v3CameraPos) * length(v3CameraPos);\n\n vec3 v3Ray = v3Pos - v3CameraPos;\n float fFar = length(v3Ray);\n v3Ray /= fFar;\n\n float B = 2.0 * dot(v3CameraPos, v3Ray);\n float C = cameraHeight2 - fOuterRadius2;\n float fDet = max(0.0, B*B - 4.0 * C);\n float fNear = 0.5 * (-B - sqrt(fDet));\n\n vec3 v3Start = v3CameraPos + v3Ray * fNear;\n fFar -= fNear;\n\n float fDepth = exp((fInnerRadius - fOuterRadius) / fScaleDepth);\n float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);\n float fLightAngle = dot(v3SunPos, v3Pos) / length(v3Pos);\n float fCameraScale = scale(fCameraAngle);\n float fLightScale = scale(fLightAngle);\n float fCameraOffset = fDepth*fCameraScale;\n float fTemp = (fLightScale + fCameraScale);\n\n float fSampleLength = fFar / fSamples;\n float fScaledLength = fSampleLength * fScale;\n vec3 v3SampleRay = v3Ray * fSampleLength;\n vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;\n\n vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);\n vec3 v3Attenuate = vec3(0.0, 0.0, 0.0);\n for(int i=0; i<nSamples; i++)\n {\n float fHeight = length(v3SamplePoint);\n float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));\n float fScatter = fDepth*fTemp - fCameraOffset;\n v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));\n v3FrontColor += v3Attenuate * (fDepth * fScaledLength);\n v3SamplePoint += v3SampleRay;\n }\n\n vec3 c0 = v3Attenuate;\n vec3 c1 = v3FrontColor * (v3InvWavelength * fKrESun + fKmESun);\n\n fragColor = vec4(c1, 1.0 - c0 * fTerminatorAttenuateFactor);\n fragColor.a *= fTerminatorOpacityFactor;\n\n // Keep the day hemisphere completely unshaded \u2014 the attenuation-based\n // alpha above is non-zero even at noon, which slightly darkens the lit\n // side. Gate it with a day/night mask so darkening only appears across\n // the terminator and onto the night side.\n // fLightAngle = dot(sunDir, surfaceNormal): +1 at the subsolar point\n // (noon), 0 at the terminator, -1 at midnight. smoothstep maps the day\n // side (>= 0.2) to 0 (no darkening), ramps through the terminator, and\n // reaches full darkening on the night side (<= -0.2).\n float fNightMask = smoothstep(0.2, -0.2, fLightAngle);\n fragColor.a *= fNightMask;\n\n // Fade out the entire day/night shading effect as the user zooms in.\n // At zoom levels above ATMOSPHERE_FADE_ZOOM_END the effect is invisible,\n // so it doesn't obscure map detail at street/city scale.\n fragColor.a *= fAtmosphereZoomFade;\n ",
126
+ 'fs:DECKGL_FILTER_COLOR': ""
127
+ }
128
+ });
129
+ }
130
+ }]);
131
+ }(SimpleMeshLayer);
132
+ _defineProperty(AtmosphereLayerRealistic, "layerName", 'AtmosphereLayerRealistic');
133
+ export var AtmosphereSkyLayerRealistic = /*#__PURE__*/function (_SimpleMeshLayer2) {
134
+ function AtmosphereSkyLayerRealistic() {
135
+ _classCallCheck(this, AtmosphereSkyLayerRealistic);
136
+ return _callSuper(this, AtmosphereSkyLayerRealistic, arguments);
137
+ }
138
+ _inherits(AtmosphereSkyLayerRealistic, _SimpleMeshLayer2);
139
+ return _createClass(AtmosphereSkyLayerRealistic, [{
140
+ key: "draw",
141
+ value: function draw(_ref2) {
142
+ var uniforms = _ref2.uniforms;
143
+ var _this$props2 = this.props,
144
+ config = _this$props2.config,
145
+ zoomFade = _this$props2.zoomFade;
146
+ var model = this.state.model;
147
+ if (model) {
148
+ model.props.uniforms = _objectSpread(_objectSpread(_objectSpread({}, model.props.uniforms), ATMOSPHERE_UNIFORMS), {}, {
149
+ v3SunPos: config.azimuth ? angleToSunPos(toRadians(config.azimuthAngle)) : v3SunPosNow,
150
+ fAtmosphereZoomFade: zoomFade
151
+ });
152
+ }
153
+ _superPropGet(AtmosphereSkyLayerRealistic, "draw", this, 3)([{
154
+ uniforms: uniforms
155
+ }]);
156
+ }
157
+ }, {
158
+ key: "getShaders",
159
+ value: function getShaders() {
160
+ return _objectSpread(_objectSpread({}, _superPropGet(AtmosphereSkyLayerRealistic, "getShaders", this, 3)([])), {}, {
161
+ inject: {
162
+ 'fs:#decl': "\n uniform vec3 v3SunPos;\n\n uniform float g;\n uniform float exposure;\n\n uniform float fSamples;\n\n uniform float fInnerRadius;\n uniform float fOuterRadius;\n uniform float fKrESun;\n uniform float fKmESun;\n uniform float fKr4PI;\n uniform float fKm4PI;\n uniform float fScaleDepth;\n uniform float fAtmosphereZoomFade;\n\n const int nSamples = ".concat(NUM_SAMPLE_RAYS, ";\n\n float scale(float fCos) {\n float x = 1.0 - fCos;\n return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.8 + x*5.25))));\n }\n\n float getMiePhase(float fCos, float fCos2, float g, float g2) {\n return 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(1.0 + g2 - 2.0 * g * fCos, 1.5);\n }\n\n float getRayleighPhase(float fCos2) {\n return 0.75 + 0.75 * fCos2;\n }\n "),
163
+ 'fs:#main-end': "\n vec3 v3CameraPos = cameraPosition;\n vec3 v3Pos = position_commonspace.xyz;\n\n float g2 = g * g;\n\n vec3 v3InvWavelength = vec3(1.0 / pow(0.650, 4.0), 1.0 / pow(0.570, 4.0), 1.0 / pow(0.475, 4.0));\n\n float fInnerRadius2 = fInnerRadius * fInnerRadius;\n float fOuterRadius2 = fOuterRadius * fOuterRadius;\n float fScale = 1.0 / (fOuterRadius - fInnerRadius);\n float fScaleOverScaleDepth = 1.0 / (fOuterRadius - fInnerRadius) / fScaleDepth;\n\n float cameraHeight2 = length(v3CameraPos) * length(v3CameraPos);\n\n vec3 v3Ray = v3Pos - v3CameraPos;\n float fFar = length(v3Ray);\n v3Ray /= fFar;\n\n float B = 2.0 * dot(v3CameraPos, v3Ray);\n float C = cameraHeight2 - fOuterRadius2;\n float fDet = max(0.0, B*B - 4.0 * C);\n float fNear = 0.5 * (-B - sqrt(fDet));\n\n vec3 v3Start = v3CameraPos + v3Ray * fNear;\n fFar -= fNear;\n float fStartAngle = dot(v3Ray, v3Start) / fOuterRadius;\n float fStartDepth = exp(-1.0 / fScaleDepth);\n float fStartOffset = fStartDepth * scale(fStartAngle);\n\n float fSampleLength = fFar / fSamples;\n float fScaledLength = fSampleLength * fScale;\n vec3 v3SampleRay = v3Ray * fSampleLength;\n vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;\n\n vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);\n for(int i=0; i<nSamples; i++)\n {\n float fHeight = length(v3SamplePoint);\n float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));\n float fLightAngle = dot(v3SunPos, v3SamplePoint) / fHeight;\n float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;\n float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));\n vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));\n\n v3FrontColor += v3Attenuate * (fDepth * fScaledLength);\n v3SamplePoint += v3SampleRay;\n }\n\n vec3 c0 = v3FrontColor * (v3InvWavelength * fKrESun);\n vec3 c1 = v3FrontColor * fKmESun;\n\n vec3 v3Direction = v3CameraPos - v3Pos;\n\n float fCos = dot(v3SunPos, v3Direction) / length(v3Direction);\n float fCos2 = fCos * fCos;\n\n vec3 skyColor = getRayleighPhase(fCos2) * c0 + getMiePhase(fCos, fCos2, g, g2) * c1;\n\n fragColor = vec4(skyColor, 1.0);\n fragColor.a = fragColor.b;\n\n // Fade the sky halo out as the user zooms in past continent scale.\n fragColor.a *= fAtmosphereZoomFade;\n ",
164
+ 'fs:DECKGL_FILTER_COLOR': ""
165
+ }
166
+ });
167
+ }
168
+ }]);
169
+ }(SimpleMeshLayer);
170
+ _defineProperty(AtmosphereSkyLayerRealistic, "layerName", 'AtmosphereSkyLayerRealistic');
171
+ var ATMOSPHERE_PARAMETERS = {
172
+ depthTest: false,
173
+ blendFunc: [0x0302, 0x0303, 1, 0x0303],
174
+ // SRC_ALPHA, ONE_MINUS_SRC_ALPHA, ONE, ONE_MINUS_SRC_ALPHA
175
+ blendEquation: [0x8006, 0x8006] // FUNC_ADD
176
+ };
177
+ var ATMOSPHERE_SKY_PARAMETERS = {
178
+ cullFace: 0x0404,
179
+ // GL.FRONT
180
+ depthMask: false,
181
+ blendFunc: [0x0302, 0x0303, 1, 0x0303],
182
+ blendEquation: [0x8006, 0x8006]
183
+ };
184
+
185
+ /**
186
+ * Soft, sun-independent glow. Radii are in deck.gl common space
187
+ * (GLOBE_COMMON_RADIUS = 256; atmosphere uses ~258 as a slight fudge).
188
+ * Outer ≈ 14% larger than inner at radius multiplier = 1 (matches the base mesh).
189
+ */
190
+ var HUGE_HALO_INNER_RADIUS = 258;
191
+ var HUGE_HALO_BASE_OUTER_RADIUS = 294;
192
+ var HUGE_HALO_BASE_SHELL = HUGE_HALO_BASE_OUTER_RADIUS - HUGE_HALO_INNER_RADIUS;
193
+ /** Matches the Halo Radius slider max; higher values can produce a black-disc artifact. */
194
+ var HUGE_HALO_RADIUS_MAX = 3.5;
195
+ var HUGE_HALO_UNIFORMS = {
196
+ fInnerRadius: HUGE_HALO_INNER_RADIUS,
197
+ // Soft cyan matching the reference huge-halo look.
198
+ v3HaloColor: [0.45, 0.72, 1.0],
199
+ fHaloIntensity: 1.0
200
+ };
201
+ var HUGE_HALO_PARAMETERS = {
202
+ cullFace: 0x0404,
203
+ // GL.FRONT
204
+ depthMask: false,
205
+ // Large shells often enclose the camera; disable depth so the ring still draws.
206
+ depthTest: false,
207
+ blendFunc: [0x0302, 0x0303, 1, 0x0303],
208
+ // SRC_ALPHA, ONE_MINUS_SRC_ALPHA
209
+ blendEquation: [0x8006, 0x8006]
210
+ };
211
+ function resolveHugeHaloRadius(config) {
212
+ var multiplier = Number.isFinite(config.hugeHaloRadius) ? config.hugeHaloRadius : DEFAULT_GLOBE_CONFIG.hugeHaloRadius;
213
+ // Scale shell thickness; keep outer above the planet surface.
214
+ return HUGE_HALO_INNER_RADIUS + HUGE_HALO_BASE_SHELL * Math.max(Math.min(multiplier, HUGE_HALO_RADIUS_MAX), 0.05);
215
+ }
216
+ function resolveHugeHaloOpacity(config) {
217
+ var opacity = Number.isFinite(config.hugeHaloOpacity) ? config.hugeHaloOpacity : DEFAULT_GLOBE_CONFIG.hugeHaloOpacity;
218
+ return Math.max(0, Math.min(1, opacity));
219
+ }
220
+
221
+ /**
222
+ * View-independent atmosphere: a large uniform emissive aura around the globe.
223
+ * Unlike AtmosphereSkyLayerRealistic, this ignores sun direction and uses a
224
+ * linear radial falloff through a thick shell (max at the surface → 0 at outer radius).
225
+ */
226
+ export var AtmosphereHugeHaloLayer = /*#__PURE__*/function (_SimpleMeshLayer3) {
227
+ function AtmosphereHugeHaloLayer() {
228
+ _classCallCheck(this, AtmosphereHugeHaloLayer);
229
+ return _callSuper(this, AtmosphereHugeHaloLayer, arguments);
230
+ }
231
+ _inherits(AtmosphereHugeHaloLayer, _SimpleMeshLayer3);
232
+ return _createClass(AtmosphereHugeHaloLayer, [{
233
+ key: "draw",
234
+ value: function draw(_ref3) {
235
+ var uniforms = _ref3.uniforms;
236
+ var _this$props3 = this.props,
237
+ config = _this$props3.config,
238
+ zoomFade = _this$props3.zoomFade;
239
+ var model = this.state.model;
240
+ if (model) {
241
+ model.props.uniforms = _objectSpread(_objectSpread(_objectSpread({}, model.props.uniforms), HUGE_HALO_UNIFORMS), {}, {
242
+ fHaloOpacity: resolveHugeHaloOpacity(config),
243
+ fAtmosphereZoomFade: zoomFade
244
+ });
245
+ }
246
+ _superPropGet(AtmosphereHugeHaloLayer, "draw", this, 3)([{
247
+ uniforms: uniforms
248
+ }]);
249
+ }
250
+ }, {
251
+ key: "getShaders",
252
+ value: function getShaders() {
253
+ return _objectSpread(_objectSpread({}, _superPropGet(AtmosphereHugeHaloLayer, "getShaders", this, 3)([])), {}, {
254
+ inject: {
255
+ 'fs:#decl': "\n uniform float fInnerRadius;\n uniform vec3 v3HaloColor;\n uniform float fHaloIntensity;\n uniform float fHaloOpacity;\n uniform float fAtmosphereZoomFade;\n ",
256
+ 'fs:#main-end': "\n vec3 v3CameraPos = cameraPosition;\n vec3 v3Pos = position_commonspace.xyz;\n // Outer radius from the actual mesh vertex so sizeScale stays in sync.\n float fOuterRadius = length(v3Pos);\n vec3 v3Ray = normalize(v3Pos - v3CameraPos);\n\n // Impact parameter of the view ray (perpendicular distance from globe\n // center to the ray). Stable when the camera is inside the outer shell,\n // unlike near/far sphere-intersection math which breaks in that case\n // and produced a black disc at high radius multipliers.\n float fDMin = length(cross(v3CameraPos, v3Ray));\n\n // Linear falloff in the annulus only: max at the surface, zero at outer.\n float fShell = max(fOuterRadius - fInnerRadius, 0.0001);\n float fGlow = 0.0;\n if (fDMin >= fInnerRadius && fDMin < fOuterRadius) {\n float t = (fDMin - fInnerRadius) / fShell;\n fGlow = 1.0 - t;\n }\n\n fGlow *= fHaloIntensity;\n\n // Straight alpha (not premultiplied) for SRC_ALPHA blending.\n fragColor = vec4(v3HaloColor, fGlow * fHaloOpacity);\n fragColor.a *= fAtmosphereZoomFade;\n ",
257
+ 'fs:DECKGL_FILTER_COLOR': ""
258
+ }
259
+ });
260
+ }
261
+ }]);
262
+ }(SimpleMeshLayer);
263
+ _defineProperty(AtmosphereHugeHaloLayer, "layerName", 'AtmosphereHugeHaloLayer');
264
+ export var getGlobeAtmosphereLayer = function getGlobeAtmosphereLayer(_ref4) {
265
+ var config = _ref4.config,
266
+ zoom = _ref4.zoom;
267
+ var zoomFade = atmosphereZoomFade(zoom !== null && zoom !== void 0 ? zoom : 0);
268
+ return new AtmosphereLayerRealistic({
269
+ id: 'atmosphere',
270
+ data: [[0, 0, 0]],
271
+ config: config,
272
+ zoomFade: zoomFade,
273
+ coordinateOrigin: [0, 0, 0],
274
+ coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
275
+ getPosition: function (d) {
276
+ return d;
277
+ },
278
+ getColor: [0, 0, 0],
279
+ mesh: GLOBE_MESH_INNER,
280
+ parameters: ATMOSPHERE_PARAMETERS
281
+ });
282
+ };
283
+
284
+ /** Realistic sun-lit scattering sky halo (thin limb glow). */
285
+ export var getGlobeAtmosphereSkyLayer = function getGlobeAtmosphereSkyLayer(_ref5) {
286
+ var config = _ref5.config,
287
+ zoom = _ref5.zoom;
288
+ var zoomFade = atmosphereZoomFade(zoom !== null && zoom !== void 0 ? zoom : 0);
289
+ return new AtmosphereSkyLayerRealistic({
290
+ id: 'atmosphere-sky',
291
+ data: [[0, 0, 0]],
292
+ config: config,
293
+ zoomFade: zoomFade,
294
+ coordinateOrigin: [0, 0, 0],
295
+ coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
296
+ getPosition: function (d) {
297
+ return d;
298
+ },
299
+ getColor: [0, 0, 0],
300
+ mesh: GLOBE_MESH_OUTER,
301
+ parameters: ATMOSPHERE_SKY_PARAMETERS
302
+ });
303
+ };
304
+
305
+ /**
306
+ * Large uniform glow drawn in addition to the realistic sky halo when
307
+ * `config.hugeHalo` is enabled. Returns null when disabled.
308
+ */
309
+ export var getGlobeHugeHaloLayer = function getGlobeHugeHaloLayer(_ref6) {
310
+ var config = _ref6.config,
311
+ zoom = _ref6.zoom;
312
+ if (!config.hugeHalo) {
313
+ return null;
314
+ }
315
+ var zoomFade = atmosphereZoomFade(zoom !== null && zoom !== void 0 ? zoom : 0);
316
+ var outerRadius = resolveHugeHaloRadius(config);
317
+ // Keep mesh extent in sync with the desired outer radius (base mesh = default outer).
318
+ var sizeScale = outerRadius / HUGE_HALO_BASE_OUTER_RADIUS;
319
+ return new AtmosphereHugeHaloLayer({
320
+ id: 'atmosphere-huge-halo',
321
+ data: [[0, 0, 0]],
322
+ config: config,
323
+ zoomFade: zoomFade,
324
+ coordinateOrigin: [0, 0, 0],
325
+ coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
326
+ getPosition: function (d) {
327
+ return d;
328
+ },
329
+ getColor: [0, 0, 0],
330
+ mesh: GLOBE_MESH_HUGE_HALO,
331
+ sizeScale: sizeScale,
332
+ parameters: HUGE_HALO_PARAMETERS
333
+ });
334
+ };
335
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDT09SRElOQVRFX1NZU1RFTSIsIlNpbXBsZU1lc2hMYXllciIsIlNwaGVyZUdlb21ldHJ5IiwiVmVjdG9yMyIsImdldFN1blBvc2l0aW9uIiwiREVGQVVMVF9HTE9CRV9DT05GSUciLCJ0b1JhZGlhbnMiLCJkZWdyZWVzIiwiTWF0aCIsIlBJIiwiYW5nbGVUb1ZlYyIsImFuZ2xlIiwic2luIiwiY29zIiwiYW5nbGVUb1N1blBvcyIsIm5vcm1hbGl6ZSIsIkdMT0JFX01FU0hfSU5ORVIiLCJyYWRpdXMiLCJubGF0IiwibmxvbmciLCJHTE9CRV9NRVNIX09VVEVSIiwiR0xPQkVfTUVTSF9IVUdFX0hBTE8iLCJsb24iLCJsYXQiLCJzdW5Qb3NOb3ciLCJEYXRlIiwibm93IiwidjNTdW5Qb3NOb3ciLCJhemltdXRoIiwiTlVNX1NBTVBMRV9SQVlTIiwiQVRNT1NQSEVSRV9GQURFX1pPT01fU1RBUlQiLCJBVE1PU1BIRVJFX0ZBREVfWk9PTV9FTkQiLCJhdG1vc3BoZXJlWm9vbUZhZGUiLCJ6b29tIiwidCIsIkFUTU9TUEhFUkVfVU5JRk9STVMiLCJ2M1N1blBvcyIsImV4cG9zdXJlIiwiZlNhbXBsZXMiLCJnIiwiZktyRVN1biIsImZLbUVTdW4iLCJmS3I0UEkiLCJmS200UEkiLCJmU2NhbGVEZXB0aCIsImZJbm5lclJhZGl1cyIsImZPdXRlclJhZGl1cyIsImZUZXJtaW5hdG9yQXR0ZW51YXRlRmFjdG9yIiwiZlRlcm1pbmF0b3JPcGFjaXR5RmFjdG9yIiwiQXRtb3NwaGVyZUxheWVyUmVhbGlzdGljIiwiX1NpbXBsZU1lc2hMYXllciIsIl9jbGFzc0NhbGxDaGVjayIsIl9jYWxsU3VwZXIiLCJhcmd1bWVudHMiLCJfaW5oZXJpdHMiLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsImRyYXciLCJfcmVmIiwidW5pZm9ybXMiLCJfdGhpcyRwcm9wcyIsInByb3BzIiwiY29uZmlnIiwiem9vbUZhZGUiLCJtb2RlbCIsInN0YXRlIiwiX29iamVjdFNwcmVhZCIsInRlcm1pbmF0b3IiLCJ0ZXJtaW5hdG9yT3BhY2l0eSIsImF6aW11dGhBbmdsZSIsImZBdG1vc3BoZXJlWm9vbUZhZGUiLCJfc3VwZXJQcm9wR2V0IiwiZ2V0U2hhZGVycyIsImluamVjdCIsImNvbmNhdCIsIl9kZWZpbmVQcm9wZXJ0eSIsIkF0bW9zcGhlcmVTa3lMYXllclJlYWxpc3RpYyIsIl9TaW1wbGVNZXNoTGF5ZXIyIiwiX3JlZjIiLCJfdGhpcyRwcm9wczIiLCJBVE1PU1BIRVJFX1BBUkFNRVRFUlMiLCJkZXB0aFRlc3QiLCJibGVuZEZ1bmMiLCJibGVuZEVxdWF0aW9uIiwiQVRNT1NQSEVSRV9TS1lfUEFSQU1FVEVSUyIsImN1bGxGYWNlIiwiZGVwdGhNYXNrIiwiSFVHRV9IQUxPX0lOTkVSX1JBRElVUyIsIkhVR0VfSEFMT19CQVNFX09VVEVSX1JBRElVUyIsIkhVR0VfSEFMT19CQVNFX1NIRUxMIiwiSFVHRV9IQUxPX1JBRElVU19NQVgiLCJIVUdFX0hBTE9fVU5JRk9STVMiLCJ2M0hhbG9Db2xvciIsImZIYWxvSW50ZW5zaXR5IiwiSFVHRV9IQUxPX1BBUkFNRVRFUlMiLCJyZXNvbHZlSHVnZUhhbG9SYWRpdXMiLCJtdWx0aXBsaWVyIiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJodWdlSGFsb1JhZGl1cyIsIm1heCIsIm1pbiIsInJlc29sdmVIdWdlSGFsb09wYWNpdHkiLCJvcGFjaXR5IiwiaHVnZUhhbG9PcGFjaXR5IiwiQXRtb3NwaGVyZUh1Z2VIYWxvTGF5ZXIiLCJfU2ltcGxlTWVzaExheWVyMyIsIl9yZWYzIiwiX3RoaXMkcHJvcHMzIiwiZkhhbG9PcGFjaXR5IiwiZ2V0R2xvYmVBdG1vc3BoZXJlTGF5ZXIiLCJfcmVmNCIsImlkIiwiZGF0YSIsImNvb3JkaW5hdGVPcmlnaW4iLCJjb29yZGluYXRlU3lzdGVtIiwiQ0FSVEVTSUFOIiwiZ2V0UG9zaXRpb24iLCJkIiwiZ2V0Q29sb3IiLCJtZXNoIiwicGFyYW1ldGVycyIsImdldEdsb2JlQXRtb3NwaGVyZVNreUxheWVyIiwiX3JlZjUiLCJnZXRHbG9iZUh1Z2VIYWxvTGF5ZXIiLCJfcmVmNiIsImh1Z2VIYWxvIiwib3V0ZXJSYWRpdXMiLCJzaXplU2NhbGUiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZ2xvYmUvYXRtb3NwaGVyZS1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG4vLyBTaGFkZXJzIHBvcnRlZCBmcm9tIGlUb3ducywgYmFzZWQgb24gU2VhbiBPJ05laWwncyBhcHByb2FjaCBpbiBHUFUgR2VtcyAyXG4vLyBTRUU6IGh0dHBzOi8vZ2l0aHViLmNvbS9pVG93bnMvaXRvd25zL2Jsb2IvbWFzdGVyL3NyYy9Db3JlL1ByZWZhYi9HbG9iZS9BdG1vc3BoZXJlLmpzXG4vLyBTRUU6IGh0dHBzOi8vZGV2ZWxvcGVyLm52aWRpYS5jb20vZ3B1Z2Vtcy9ncHVnZW1zMi9wYXJ0LWlpLXNoYWRpbmctbGlnaHRpbmctYW5kLXNoYWRvd3MvY2hhcHRlci0xNi1hY2N1cmF0ZS1hdG1vc3BoZXJpYy1zY2F0dGVyaW5nXG5cbmltcG9ydCB7Q09PUkRJTkFURV9TWVNURU19IGZyb20gJ0BkZWNrLmdsL2NvcmUnO1xuaW1wb3J0IHtTaW1wbGVNZXNoTGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL21lc2gtbGF5ZXJzJztcbmltcG9ydCB7U3BoZXJlR2VvbWV0cnl9IGZyb20gJ0BsdW1hLmdsL2VuZ2luZSc7XG5pbXBvcnQge1ZlY3RvcjN9IGZyb20gJ0BtYXRoLmdsL2NvcmUnO1xuaW1wb3J0IHtnZXRTdW5Qb3NpdGlvbn0gZnJvbSAnQG1hdGguZ2wvc3VuJztcblxuaW1wb3J0IHtERUZBVUxUX0dMT0JFX0NPTkZJRywgdHlwZSBHbG9iZUNvbmZpZ30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuXG5jb25zdCB0b1JhZGlhbnMgPSAoZGVncmVlczogbnVtYmVyKTogbnVtYmVyID0+IChkZWdyZWVzICogTWF0aC5QSSkgLyAxODA7XG5cbmNvbnN0IGFuZ2xlVG9WZWMgPSAoYW5nbGU6IG51bWJlcik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9PiB7XG4gIHJldHVybiBbTWF0aC5zaW4oYW5nbGUpLCBNYXRoLmNvcyhhbmdsZSksIDBdO1xufTtcblxuY29uc3QgYW5nbGVUb1N1blBvcyA9IChhbmdsZTogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICByZXR1cm4gbmV3IFZlY3RvcjMoYW5nbGVUb1ZlYyhhbmdsZSkpLm5vcm1hbGl6ZSgpIGFzIHVua25vd24gYXMgbnVtYmVyW107XG59O1xuXG5jb25zdCBHTE9CRV9NRVNIX0lOTkVSID0gbmV3IFNwaGVyZUdlb21ldHJ5KHtcbiAgcmFkaXVzOiA2LjRlNixcbiAgbmxhdDogMTAwLFxuICBubG9uZzogMTAwXG59KTtcblxuY29uc3QgR0xPQkVfTUVTSF9PVVRFUiA9IG5ldyBTcGhlcmVHZW9tZXRyeSh7XG4gIHJhZGl1czogNi43ZTYsXG4gIG5sYXQ6IDEwMCxcbiAgbmxvbmc6IDEwMFxufSk7XG5cbi8vIH4xNCUgbGFyZ2VyIHRoYW4gdGhlIGdsb2JlIHN1cmZhY2UgbWVzaCDigJQgeWllbGRzIGEgdGhpY2sgc29mdCBhdXJhICh+MC4x4oCTMC4xNVIpLlxuY29uc3QgR0xPQkVfTUVTSF9IVUdFX0hBTE8gPSBuZXcgU3BoZXJlR2VvbWV0cnkoe1xuICByYWRpdXM6IDcuM2U2LFxuICBubGF0OiAxMDAsXG4gIG5sb25nOiAxMDBcbn0pO1xuXG5jb25zdCBbbG9uLCBsYXRdID0gWzAsIDkwXTtcbmNvbnN0IHN1blBvc05vdyA9IGdldFN1blBvc2l0aW9uKERhdGUubm93KCksIGxhdCwgbG9uKTtcbmNvbnN0IHYzU3VuUG9zTm93ID0gYW5nbGVUb1N1blBvcyhzdW5Qb3NOb3cuYXppbXV0aCArIE1hdGguUEkpO1xuXG5jb25zdCBOVU1fU0FNUExFX1JBWVMgPSAzO1xuXG4vKipcbiAqIFpvb20gcmFuZ2Ugb3ZlciB3aGljaCB0aGUgYXRtb3NwaGVyZSBlZmZlY3QgZmFkZXMgb3V0LlxuICogQmVsb3cgQVRNT1NQSEVSRV9GQURFX1pPT01fU1RBUlQgdGhlIGVmZmVjdCBpcyBmdWxseSB2aXNpYmxlLlxuICogQWJvdmUgQVRNT1NQSEVSRV9GQURFX1pPT01fRU5EIHRoZSBlZmZlY3QgaXMgY29tcGxldGVseSBoaWRkZW4uXG4gKi9cbmNvbnN0IEFUTU9TUEhFUkVfRkFERV9aT09NX1NUQVJUID0gMy41O1xuY29uc3QgQVRNT1NQSEVSRV9GQURFX1pPT01fRU5EID0gNjtcblxuLyoqXG4gKiBDb252ZXJ0IGEgbWFwU3RhdGUgem9vbSBsZXZlbCB0byBhIFswLCAxXSBhdG1vc3BoZXJlIG9wYWNpdHkgbXVsdGlwbGllci5cbiAqIFJldHVybnMgMSAoZnVsbHkgdmlzaWJsZSkgYmVsb3cgQVRNT1NQSEVSRV9GQURFX1pPT01fU1RBUlQsIHNtb290aGx5XG4gKiBpbnRlcnBvbGF0ZXMgdG8gMCBiZXR3ZWVuIHRoZSB0d28gdGhyZXNob2xkcywgYW5kIHJldHVybnMgMCBhYm92ZVxuICogQVRNT1NQSEVSRV9GQURFX1pPT01fRU5ELlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXRtb3NwaGVyZVpvb21GYWRlKHpvb206IG51bWJlcik6IG51bWJlciB7XG4gIGlmICh6b29tIDw9IEFUTU9TUEhFUkVfRkFERV9aT09NX1NUQVJUKSByZXR1cm4gMTtcbiAgaWYgKHpvb20gPj0gQVRNT1NQSEVSRV9GQURFX1pPT01fRU5EKSByZXR1cm4gMDtcbiAgY29uc3QgdCA9ICh6b29tIC0gQVRNT1NQSEVSRV9GQURFX1pPT01fU1RBUlQpIC8gKEFUTU9TUEhFUkVfRkFERV9aT09NX0VORCAtIEFUTU9TUEhFUkVfRkFERV9aT09NX1NUQVJUKTtcbiAgLy8gU21vb3RoLXN0ZXAgZm9yIGEgcGVyY2VwdHVhbGx5IGdlbnRsZSB0cmFuc2l0aW9uLlxuICByZXR1cm4gMSAtIHQgKiB0ICogKDMgLSAyICogdCk7XG59XG5cbmNvbnN0IEFUTU9TUEhFUkVfVU5JRk9STVMgPSB7XG4gIHYzU3VuUG9zOiB2M1N1blBvc05vdyxcbiAgZXhwb3N1cmU6IDIsXG4gIGZTYW1wbGVzOiAzLFxuICBnOiAtMC42NSxcbiAgZktyRVN1bjogMC4wMDAyNSAqIDIwLFxuICBmS21FU3VuOiAwLjAwMDEgKiAyMCxcbiAgZktyNFBJOiAwLjAwMDI1ICogNCAqIE1hdGguUEksXG4gIGZLbTRQSTogMC4wMDAxICogNCAqIE1hdGguUEksXG4gIGZTY2FsZURlcHRoOiAwLjI1LFxuICBmSW5uZXJSYWRpdXM6IDI1OCxcbiAgZk91dGVyUmFkaXVzOiAyNjUsXG4gIGZUZXJtaW5hdG9yQXR0ZW51YXRlRmFjdG9yOiAwLjgsXG4gIGZUZXJtaW5hdG9yT3BhY2l0eUZhY3RvcjogMVxufTtcblxudHlwZSBBdG1vc3BoZXJlTGF5ZXJQcm9wcyA9IHtcbiAgY29uZmlnOiBHbG9iZUNvbmZpZztcbiAgLyoqIFByZS1jb21wdXRlZCBbMCwgMV0gem9vbS1mYWRlIG11bHRpcGxpZXI7IDEgPSBmdWxseSB2aXNpYmxlLCAwID0gaGlkZGVuLiAqL1xuICB6b29tRmFkZTogbnVtYmVyO1xufTtcblxuZXhwb3J0IGNsYXNzIEF0bW9zcGhlcmVMYXllclJlYWxpc3RpYyBleHRlbmRzIFNpbXBsZU1lc2hMYXllcjxhbnksIEF0bW9zcGhlcmVMYXllclByb3BzPiB7XG4gIHN0YXRpYyBsYXllck5hbWUgPSAnQXRtb3NwaGVyZUxheWVyUmVhbGlzdGljJztcblxuICBkcmF3KHt1bmlmb3Jtc306IHt1bmlmb3Jtczogb2JqZWN0fSk6IHZvaWQge1xuICAgIGNvbnN0IHtjb25maWcsIHpvb21GYWRlfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLnN0YXRlLm1vZGVsO1xuICAgIGlmIChtb2RlbCkge1xuICAgICAgKG1vZGVsIGFzIGFueSkucHJvcHMudW5pZm9ybXMgPSB7XG4gICAgICAgIC4uLihtb2RlbCBhcyBhbnkpLnByb3BzLnVuaWZvcm1zLFxuICAgICAgICAuLi5BVE1PU1BIRVJFX1VOSUZPUk1TLFxuICAgICAgICBmVGVybWluYXRvck9wYWNpdHlGYWN0b3I6IGNvbmZpZy50ZXJtaW5hdG9yID8gY29uZmlnLnRlcm1pbmF0b3JPcGFjaXR5IDogMCxcbiAgICAgICAgdjNTdW5Qb3M6IGNvbmZpZy5hemltdXRoID8gYW5nbGVUb1N1blBvcyh0b1JhZGlhbnMoY29uZmlnLmF6aW11dGhBbmdsZSkpIDogdjNTdW5Qb3NOb3csXG4gICAgICAgIGZBdG1vc3BoZXJlWm9vbUZhZGU6IHpvb21GYWRlXG4gICAgICB9O1xuICAgIH1cbiAgICBzdXBlci5kcmF3KHt1bmlmb3Jtc30pO1xuICB9XG5cbiAgZ2V0U2hhZGVycygpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdXBlci5nZXRTaGFkZXJzKCksXG4gICAgICBpbmplY3Q6IHtcbiAgICAgICAgJ2ZzOiNkZWNsJzogYFxuICAgICAgICAgIHVuaWZvcm0gdmVjMyB2M1N1blBvcztcblxuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZztcbiAgICAgICAgICB1bmlmb3JtIGZsb2F0IGV4cG9zdXJlO1xuXG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmU2FtcGxlcztcblxuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZklubmVyUmFkaXVzO1xuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZk91dGVyUmFkaXVzO1xuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZktyRVN1bjtcbiAgICAgICAgICB1bmlmb3JtIGZsb2F0IGZLbUVTdW47XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmS3I0UEk7XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmS200UEk7XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmU2NhbGVEZXB0aDtcblxuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZlRlcm1pbmF0b3JBdHRlbnVhdGVGYWN0b3I7XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmVGVybWluYXRvck9wYWNpdHlGYWN0b3I7XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmQXRtb3NwaGVyZVpvb21GYWRlO1xuXG4gICAgICAgICAgY29uc3QgaW50IG5TYW1wbGVzID0gJHtOVU1fU0FNUExFX1JBWVN9O1xuXG4gICAgICAgICAgZmxvYXQgc2NhbGUoZmxvYXQgZkNvcykge1xuICAgICAgICAgICAgZmxvYXQgeCA9IDEuMCAtIGZDb3M7XG4gICAgICAgICAgICByZXR1cm4gZlNjYWxlRGVwdGggKiBleHAoLTAuMDAyODcgKyB4KigwLjQ1OSArIHgqKDMuODMgKyB4KigtNi44ICsgeCo1LjI1KSkpKTtcbiAgICAgICAgICB9XG4gICAgICAgIGAsXG4gICAgICAgICdmczojbWFpbi1lbmQnOiBgXG4gICAgICAgICAgdmVjMyB2M0NhbWVyYVBvcyA9IGNhbWVyYVBvc2l0aW9uO1xuICAgICAgICAgIHZlYzMgdjNQb3MgPSBwb3NpdGlvbl9jb21tb25zcGFjZS54eXo7XG5cbiAgICAgICAgICBmbG9hdCBnMiA9IGcgKiBnO1xuXG4gICAgICAgICAgdmVjMyB2M0ludldhdmVsZW5ndGggPSB2ZWMzKDEuMCAvIHBvdygwLjY1MCwgNC4wKSwgMS4wIC8gcG93KDAuNTcwLCA0LjApLCAxLjAgLyBwb3coMC40NzUsIDQuMCkpO1xuXG4gICAgICAgICAgZmxvYXQgZklubmVyUmFkaXVzMiA9IGZJbm5lclJhZGl1cyAqIGZJbm5lclJhZGl1cztcbiAgICAgICAgICBmbG9hdCBmT3V0ZXJSYWRpdXMyID0gZk91dGVyUmFkaXVzICogZk91dGVyUmFkaXVzO1xuICAgICAgICAgIGZsb2F0IGZTY2FsZSA9IDEuMCAvIChmT3V0ZXJSYWRpdXMgLSBmSW5uZXJSYWRpdXMpO1xuICAgICAgICAgIGZsb2F0IGZTY2FsZU92ZXJTY2FsZURlcHRoID0gMS4wIC8gKGZPdXRlclJhZGl1cyAtIGZJbm5lclJhZGl1cykgLyBmU2NhbGVEZXB0aDtcblxuICAgICAgICAgIGZsb2F0IGNhbWVyYUhlaWdodDIgPSBsZW5ndGgodjNDYW1lcmFQb3MpICogbGVuZ3RoKHYzQ2FtZXJhUG9zKTtcblxuICAgICAgICAgIHZlYzMgdjNSYXkgPSB2M1BvcyAtIHYzQ2FtZXJhUG9zO1xuICAgICAgICAgIGZsb2F0IGZGYXIgPSBsZW5ndGgodjNSYXkpO1xuICAgICAgICAgIHYzUmF5IC89IGZGYXI7XG5cbiAgICAgICAgICBmbG9hdCBCID0gMi4wICogZG90KHYzQ2FtZXJhUG9zLCB2M1JheSk7XG4gICAgICAgICAgZmxvYXQgQyA9IGNhbWVyYUhlaWdodDIgLSBmT3V0ZXJSYWRpdXMyO1xuICAgICAgICAgIGZsb2F0IGZEZXQgPSBtYXgoMC4wLCBCKkIgLSA0LjAgKiBDKTtcbiAgICAgICAgICBmbG9hdCBmTmVhciA9IDAuNSAqICgtQiAtIHNxcnQoZkRldCkpO1xuXG4gICAgICAgICAgdmVjMyB2M1N0YXJ0ID0gdjNDYW1lcmFQb3MgKyB2M1JheSAqIGZOZWFyO1xuICAgICAgICAgIGZGYXIgLT0gZk5lYXI7XG5cbiAgICAgICAgICBmbG9hdCBmRGVwdGggPSBleHAoKGZJbm5lclJhZGl1cyAtIGZPdXRlclJhZGl1cykgLyBmU2NhbGVEZXB0aCk7XG4gICAgICAgICAgZmxvYXQgZkNhbWVyYUFuZ2xlID0gZG90KC12M1JheSwgdjNQb3MpIC8gbGVuZ3RoKHYzUG9zKTtcbiAgICAgICAgICBmbG9hdCBmTGlnaHRBbmdsZSA9IGRvdCh2M1N1blBvcywgdjNQb3MpIC8gbGVuZ3RoKHYzUG9zKTtcbiAgICAgICAgICBmbG9hdCBmQ2FtZXJhU2NhbGUgPSBzY2FsZShmQ2FtZXJhQW5nbGUpO1xuICAgICAgICAgIGZsb2F0IGZMaWdodFNjYWxlID0gc2NhbGUoZkxpZ2h0QW5nbGUpO1xuICAgICAgICAgIGZsb2F0IGZDYW1lcmFPZmZzZXQgPSBmRGVwdGgqZkNhbWVyYVNjYWxlO1xuICAgICAgICAgIGZsb2F0IGZUZW1wID0gKGZMaWdodFNjYWxlICsgZkNhbWVyYVNjYWxlKTtcblxuICAgICAgICAgIGZsb2F0IGZTYW1wbGVMZW5ndGggPSBmRmFyIC8gZlNhbXBsZXM7XG4gICAgICAgICAgZmxvYXQgZlNjYWxlZExlbmd0aCA9IGZTYW1wbGVMZW5ndGggKiBmU2NhbGU7XG4gICAgICAgICAgdmVjMyB2M1NhbXBsZVJheSA9IHYzUmF5ICogZlNhbXBsZUxlbmd0aDtcbiAgICAgICAgICB2ZWMzIHYzU2FtcGxlUG9pbnQgPSB2M1N0YXJ0ICsgdjNTYW1wbGVSYXkgKiAwLjU7XG5cbiAgICAgICAgICB2ZWMzIHYzRnJvbnRDb2xvciA9IHZlYzMoMC4wLCAwLjAsIDAuMCk7XG4gICAgICAgICAgdmVjMyB2M0F0dGVudWF0ZSA9IHZlYzMoMC4wLCAwLjAsIDAuMCk7XG4gICAgICAgICAgZm9yKGludCBpPTA7IGk8blNhbXBsZXM7IGkrKylcbiAgICAgICAgICB7XG4gICAgICAgICAgICAgIGZsb2F0IGZIZWlnaHQgPSBsZW5ndGgodjNTYW1wbGVQb2ludCk7XG4gICAgICAgICAgICAgIGZsb2F0IGZEZXB0aCA9IGV4cChmU2NhbGVPdmVyU2NhbGVEZXB0aCAqIChmSW5uZXJSYWRpdXMgLSBmSGVpZ2h0KSk7XG4gICAgICAgICAgICAgIGZsb2F0IGZTY2F0dGVyID0gZkRlcHRoKmZUZW1wIC0gZkNhbWVyYU9mZnNldDtcbiAgICAgICAgICAgICAgdjNBdHRlbnVhdGUgPSBleHAoLWZTY2F0dGVyICogKHYzSW52V2F2ZWxlbmd0aCAqIGZLcjRQSSArIGZLbTRQSSkpO1xuICAgICAgICAgICAgICB2M0Zyb250Q29sb3IgKz0gdjNBdHRlbnVhdGUgKiAoZkRlcHRoICogZlNjYWxlZExlbmd0aCk7XG4gICAgICAgICAgICAgIHYzU2FtcGxlUG9pbnQgKz0gdjNTYW1wbGVSYXk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmVjMyBjMCA9IHYzQXR0ZW51YXRlO1xuICAgICAgICAgIHZlYzMgYzEgPSB2M0Zyb250Q29sb3IgKiAodjNJbnZXYXZlbGVuZ3RoICogZktyRVN1biArIGZLbUVTdW4pO1xuXG4gICAgICAgICAgZnJhZ0NvbG9yID0gdmVjNChjMSwgMS4wIC0gYzAgKiBmVGVybWluYXRvckF0dGVudWF0ZUZhY3Rvcik7XG4gICAgICAgICAgZnJhZ0NvbG9yLmEgKj0gZlRlcm1pbmF0b3JPcGFjaXR5RmFjdG9yO1xuXG4gICAgICAgICAgLy8gS2VlcCB0aGUgZGF5IGhlbWlzcGhlcmUgY29tcGxldGVseSB1bnNoYWRlZCDigJQgdGhlIGF0dGVudWF0aW9uLWJhc2VkXG4gICAgICAgICAgLy8gYWxwaGEgYWJvdmUgaXMgbm9uLXplcm8gZXZlbiBhdCBub29uLCB3aGljaCBzbGlnaHRseSBkYXJrZW5zIHRoZSBsaXRcbiAgICAgICAgICAvLyBzaWRlLiBHYXRlIGl0IHdpdGggYSBkYXkvbmlnaHQgbWFzayBzbyBkYXJrZW5pbmcgb25seSBhcHBlYXJzIGFjcm9zc1xuICAgICAgICAgIC8vIHRoZSB0ZXJtaW5hdG9yIGFuZCBvbnRvIHRoZSBuaWdodCBzaWRlLlxuICAgICAgICAgIC8vIGZMaWdodEFuZ2xlID0gZG90KHN1bkRpciwgc3VyZmFjZU5vcm1hbCk6ICsxIGF0IHRoZSBzdWJzb2xhciBwb2ludFxuICAgICAgICAgIC8vIChub29uKSwgMCBhdCB0aGUgdGVybWluYXRvciwgLTEgYXQgbWlkbmlnaHQuIHNtb290aHN0ZXAgbWFwcyB0aGUgZGF5XG4gICAgICAgICAgLy8gc2lkZSAoPj0gMC4yKSB0byAwIChubyBkYXJrZW5pbmcpLCByYW1wcyB0aHJvdWdoIHRoZSB0ZXJtaW5hdG9yLCBhbmRcbiAgICAgICAgICAvLyByZWFjaGVzIGZ1bGwgZGFya2VuaW5nIG9uIHRoZSBuaWdodCBzaWRlICg8PSAtMC4yKS5cbiAgICAgICAgICBmbG9hdCBmTmlnaHRNYXNrID0gc21vb3Roc3RlcCgwLjIsIC0wLjIsIGZMaWdodEFuZ2xlKTtcbiAgICAgICAgICBmcmFnQ29sb3IuYSAqPSBmTmlnaHRNYXNrO1xuXG4gICAgICAgICAgLy8gRmFkZSBvdXQgdGhlIGVudGlyZSBkYXkvbmlnaHQgc2hhZGluZyBlZmZlY3QgYXMgdGhlIHVzZXIgem9vbXMgaW4uXG4gICAgICAgICAgLy8gQXQgem9vbSBsZXZlbHMgYWJvdmUgQVRNT1NQSEVSRV9GQURFX1pPT01fRU5EIHRoZSBlZmZlY3QgaXMgaW52aXNpYmxlLFxuICAgICAgICAgIC8vIHNvIGl0IGRvZXNuJ3Qgb2JzY3VyZSBtYXAgZGV0YWlsIGF0IHN0cmVldC9jaXR5IHNjYWxlLlxuICAgICAgICAgIGZyYWdDb2xvci5hICo9IGZBdG1vc3BoZXJlWm9vbUZhZGU7XG4gICAgICAgIGAsXG4gICAgICAgICdmczpERUNLR0xfRklMVEVSX0NPTE9SJzogYGBcbiAgICAgIH1cbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBdG1vc3BoZXJlU2t5TGF5ZXJSZWFsaXN0aWMgZXh0ZW5kcyBTaW1wbGVNZXNoTGF5ZXI8YW55LCBBdG1vc3BoZXJlTGF5ZXJQcm9wcz4ge1xuICBzdGF0aWMgbGF5ZXJOYW1lID0gJ0F0bW9zcGhlcmVTa3lMYXllclJlYWxpc3RpYyc7XG5cbiAgZHJhdyh7dW5pZm9ybXN9OiB7dW5pZm9ybXM6IG9iamVjdH0pOiB2b2lkIHtcbiAgICBjb25zdCB7Y29uZmlnLCB6b29tRmFkZX0gPSB0aGlzLnByb3BzO1xuICAgIGNvbnN0IG1vZGVsID0gdGhpcy5zdGF0ZS5tb2RlbDtcbiAgICBpZiAobW9kZWwpIHtcbiAgICAgIChtb2RlbCBhcyBhbnkpLnByb3BzLnVuaWZvcm1zID0ge1xuICAgICAgICAuLi4obW9kZWwgYXMgYW55KS5wcm9wcy51bmlmb3JtcyxcbiAgICAgICAgLi4uQVRNT1NQSEVSRV9VTklGT1JNUyxcbiAgICAgICAgdjNTdW5Qb3M6IGNvbmZpZy5hemltdXRoID8gYW5nbGVUb1N1blBvcyh0b1JhZGlhbnMoY29uZmlnLmF6aW11dGhBbmdsZSkpIDogdjNTdW5Qb3NOb3csXG4gICAgICAgIGZBdG1vc3BoZXJlWm9vbUZhZGU6IHpvb21GYWRlXG4gICAgICB9O1xuICAgIH1cbiAgICBzdXBlci5kcmF3KHt1bmlmb3Jtc30pO1xuICB9XG5cbiAgZ2V0U2hhZGVycygpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdXBlci5nZXRTaGFkZXJzKCksXG4gICAgICBpbmplY3Q6IHtcbiAgICAgICAgJ2ZzOiNkZWNsJzogYFxuICAgICAgICAgIHVuaWZvcm0gdmVjMyB2M1N1blBvcztcblxuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZztcbiAgICAgICAgICB1bmlmb3JtIGZsb2F0IGV4cG9zdXJlO1xuXG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmU2FtcGxlcztcblxuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZklubmVyUmFkaXVzO1xuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZk91dGVyUmFkaXVzO1xuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZktyRVN1bjtcbiAgICAgICAgICB1bmlmb3JtIGZsb2F0IGZLbUVTdW47XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmS3I0UEk7XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmS200UEk7XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmU2NhbGVEZXB0aDtcbiAgICAgICAgICB1bmlmb3JtIGZsb2F0IGZBdG1vc3BoZXJlWm9vbUZhZGU7XG5cbiAgICAgICAgICBjb25zdCBpbnQgblNhbXBsZXMgPSAke05VTV9TQU1QTEVfUkFZU307XG5cbiAgICAgICAgICBmbG9hdCBzY2FsZShmbG9hdCBmQ29zKSB7XG4gICAgICAgICAgICBmbG9hdCB4ID0gMS4wIC0gZkNvcztcbiAgICAgICAgICAgIHJldHVybiBmU2NhbGVEZXB0aCAqIGV4cCgtMC4wMDI4NyArIHgqKDAuNDU5ICsgeCooMy44MyArIHgqKC02LjggKyB4KjUuMjUpKSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZsb2F0IGdldE1pZVBoYXNlKGZsb2F0IGZDb3MsIGZsb2F0IGZDb3MyLCBmbG9hdCBnLCBmbG9hdCBnMikge1xuICAgICAgICAgICAgcmV0dXJuIDEuNSAqICgoMS4wIC0gZzIpIC8gKDIuMCArIGcyKSkgKiAoMS4wICsgZkNvczIpIC8gcG93KDEuMCArIGcyIC0gMi4wICogZyAqIGZDb3MsIDEuNSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZmxvYXQgZ2V0UmF5bGVpZ2hQaGFzZShmbG9hdCBmQ29zMikge1xuICAgICAgICAgICAgcmV0dXJuIDAuNzUgKyAwLjc1ICogZkNvczI7XG4gICAgICAgICAgfVxuICAgICAgICBgLFxuICAgICAgICAnZnM6I21haW4tZW5kJzogYFxuICAgICAgICAgIHZlYzMgdjNDYW1lcmFQb3MgPSBjYW1lcmFQb3NpdGlvbjtcbiAgICAgICAgICB2ZWMzIHYzUG9zID0gcG9zaXRpb25fY29tbW9uc3BhY2UueHl6O1xuXG4gICAgICAgICAgZmxvYXQgZzIgPSBnICogZztcblxuICAgICAgICAgIHZlYzMgdjNJbnZXYXZlbGVuZ3RoID0gdmVjMygxLjAgLyBwb3coMC42NTAsIDQuMCksIDEuMCAvIHBvdygwLjU3MCwgNC4wKSwgMS4wIC8gcG93KDAuNDc1LCA0LjApKTtcblxuICAgICAgICAgIGZsb2F0IGZJbm5lclJhZGl1czIgPSBmSW5uZXJSYWRpdXMgKiBmSW5uZXJSYWRpdXM7XG4gICAgICAgICAgZmxvYXQgZk91dGVyUmFkaXVzMiA9IGZPdXRlclJhZGl1cyAqIGZPdXRlclJhZGl1cztcbiAgICAgICAgICBmbG9hdCBmU2NhbGUgPSAxLjAgLyAoZk91dGVyUmFkaXVzIC0gZklubmVyUmFkaXVzKTtcbiAgICAgICAgICBmbG9hdCBmU2NhbGVPdmVyU2NhbGVEZXB0aCA9IDEuMCAvIChmT3V0ZXJSYWRpdXMgLSBmSW5uZXJSYWRpdXMpIC8gZlNjYWxlRGVwdGg7XG5cbiAgICAgICAgICBmbG9hdCBjYW1lcmFIZWlnaHQyID0gbGVuZ3RoKHYzQ2FtZXJhUG9zKSAqIGxlbmd0aCh2M0NhbWVyYVBvcyk7XG5cbiAgICAgICAgICB2ZWMzIHYzUmF5ID0gdjNQb3MgLSB2M0NhbWVyYVBvcztcbiAgICAgICAgICBmbG9hdCBmRmFyID0gbGVuZ3RoKHYzUmF5KTtcbiAgICAgICAgICB2M1JheSAvPSBmRmFyO1xuXG4gICAgICAgICAgZmxvYXQgQiA9IDIuMCAqIGRvdCh2M0NhbWVyYVBvcywgdjNSYXkpO1xuICAgICAgICAgIGZsb2F0IEMgPSBjYW1lcmFIZWlnaHQyIC0gZk91dGVyUmFkaXVzMjtcbiAgICAgICAgICBmbG9hdCBmRGV0ID0gbWF4KDAuMCwgQipCIC0gNC4wICogQyk7XG4gICAgICAgICAgZmxvYXQgZk5lYXIgPSAwLjUgKiAoLUIgLSBzcXJ0KGZEZXQpKTtcblxuICAgICAgICAgIHZlYzMgdjNTdGFydCA9IHYzQ2FtZXJhUG9zICsgdjNSYXkgKiBmTmVhcjtcbiAgICAgICAgICBmRmFyIC09IGZOZWFyO1xuICAgICAgICAgIGZsb2F0IGZTdGFydEFuZ2xlID0gZG90KHYzUmF5LCB2M1N0YXJ0KSAvIGZPdXRlclJhZGl1cztcbiAgICAgICAgICBmbG9hdCBmU3RhcnREZXB0aCA9IGV4cCgtMS4wIC8gZlNjYWxlRGVwdGgpO1xuICAgICAgICAgIGZsb2F0IGZTdGFydE9mZnNldCA9IGZTdGFydERlcHRoICogc2NhbGUoZlN0YXJ0QW5nbGUpO1xuXG4gICAgICAgICAgZmxvYXQgZlNhbXBsZUxlbmd0aCA9IGZGYXIgLyBmU2FtcGxlcztcbiAgICAgICAgICBmbG9hdCBmU2NhbGVkTGVuZ3RoID0gZlNhbXBsZUxlbmd0aCAqIGZTY2FsZTtcbiAgICAgICAgICB2ZWMzIHYzU2FtcGxlUmF5ID0gdjNSYXkgKiBmU2FtcGxlTGVuZ3RoO1xuICAgICAgICAgIHZlYzMgdjNTYW1wbGVQb2ludCA9IHYzU3RhcnQgKyB2M1NhbXBsZVJheSAqIDAuNTtcblxuICAgICAgICAgIHZlYzMgdjNGcm9udENvbG9yID0gdmVjMygwLjAsIDAuMCwgMC4wKTtcbiAgICAgICAgICBmb3IoaW50IGk9MDsgaTxuU2FtcGxlczsgaSsrKVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGZsb2F0IGZIZWlnaHQgPSBsZW5ndGgodjNTYW1wbGVQb2ludCk7XG4gICAgICAgICAgICBmbG9hdCBmRGVwdGggPSBleHAoZlNjYWxlT3ZlclNjYWxlRGVwdGggKiAoZklubmVyUmFkaXVzIC0gZkhlaWdodCkpO1xuICAgICAgICAgICAgZmxvYXQgZkxpZ2h0QW5nbGUgPSBkb3QodjNTdW5Qb3MsIHYzU2FtcGxlUG9pbnQpIC8gZkhlaWdodDtcbiAgICAgICAgICAgIGZsb2F0IGZDYW1lcmFBbmdsZSA9IGRvdCh2M1JheSwgdjNTYW1wbGVQb2ludCkgLyBmSGVpZ2h0O1xuICAgICAgICAgICAgZmxvYXQgZlNjYXR0ZXIgPSAoZlN0YXJ0T2Zmc2V0ICsgZkRlcHRoICogKHNjYWxlKGZMaWdodEFuZ2xlKSAtIHNjYWxlKGZDYW1lcmFBbmdsZSkpKTtcbiAgICAgICAgICAgIHZlYzMgdjNBdHRlbnVhdGUgPSBleHAoLWZTY2F0dGVyICogKHYzSW52V2F2ZWxlbmd0aCAqIGZLcjRQSSArIGZLbTRQSSkpO1xuXG4gICAgICAgICAgICB2M0Zyb250Q29sb3IgKz0gdjNBdHRlbnVhdGUgKiAoZkRlcHRoICogZlNjYWxlZExlbmd0aCk7XG4gICAgICAgICAgICB2M1NhbXBsZVBvaW50ICs9IHYzU2FtcGxlUmF5O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZlYzMgYzAgPSB2M0Zyb250Q29sb3IgKiAodjNJbnZXYXZlbGVuZ3RoICogZktyRVN1bik7XG4gICAgICAgICAgdmVjMyBjMSA9IHYzRnJvbnRDb2xvciAqIGZLbUVTdW47XG5cbiAgICAgICAgICB2ZWMzIHYzRGlyZWN0aW9uID0gdjNDYW1lcmFQb3MgLSB2M1BvcztcblxuICAgICAgICAgIGZsb2F0IGZDb3MgPSBkb3QodjNTdW5Qb3MsIHYzRGlyZWN0aW9uKSAvIGxlbmd0aCh2M0RpcmVjdGlvbik7XG4gICAgICAgICAgZmxvYXQgZkNvczIgPSBmQ29zICogZkNvcztcblxuICAgICAgICAgIHZlYzMgc2t5Q29sb3IgPSBnZXRSYXlsZWlnaFBoYXNlKGZDb3MyKSAqIGMwICsgZ2V0TWllUGhhc2UoZkNvcywgZkNvczIsIGcsIGcyKSAqIGMxO1xuXG4gICAgICAgICAgZnJhZ0NvbG9yID0gdmVjNChza3lDb2xvciwgMS4wKTtcbiAgICAgICAgICBmcmFnQ29sb3IuYSA9IGZyYWdDb2xvci5iO1xuXG4gICAgICAgICAgLy8gRmFkZSB0aGUgc2t5IGhhbG8gb3V0IGFzIHRoZSB1c2VyIHpvb21zIGluIHBhc3QgY29udGluZW50IHNjYWxlLlxuICAgICAgICAgIGZyYWdDb2xvci5hICo9IGZBdG1vc3BoZXJlWm9vbUZhZGU7XG4gICAgICAgIGAsXG4gICAgICAgICdmczpERUNLR0xfRklMVEVSX0NPTE9SJzogYGBcbiAgICAgIH1cbiAgICB9O1xuICB9XG59XG5cbmNvbnN0IEFUTU9TUEhFUkVfUEFSQU1FVEVSUyA9IHtcbiAgZGVwdGhUZXN0OiBmYWxzZSxcbiAgYmxlbmRGdW5jOiBbMHgwMzAyLCAweDAzMDMsIDEsIDB4MDMwM10sIC8vIFNSQ19BTFBIQSwgT05FX01JTlVTX1NSQ19BTFBIQSwgT05FLCBPTkVfTUlOVVNfU1JDX0FMUEhBXG4gIGJsZW5kRXF1YXRpb246IFsweDgwMDYsIDB4ODAwNl0gLy8gRlVOQ19BRERcbn07XG5cbmNvbnN0IEFUTU9TUEhFUkVfU0tZX1BBUkFNRVRFUlMgPSB7XG4gIGN1bGxGYWNlOiAweDA0MDQsIC8vIEdMLkZST05UXG4gIGRlcHRoTWFzazogZmFsc2UsXG4gIGJsZW5kRnVuYzogWzB4MDMwMiwgMHgwMzAzLCAxLCAweDAzMDNdLFxuICBibGVuZEVxdWF0aW9uOiBbMHg4MDA2LCAweDgwMDZdXG59O1xuXG4vKipcbiAqIFNvZnQsIHN1bi1pbmRlcGVuZGVudCBnbG93LiBSYWRpaSBhcmUgaW4gZGVjay5nbCBjb21tb24gc3BhY2VcbiAqIChHTE9CRV9DT01NT05fUkFESVVTID0gMjU2OyBhdG1vc3BoZXJlIHVzZXMgfjI1OCBhcyBhIHNsaWdodCBmdWRnZSkuXG4gKiBPdXRlciDiiYggMTQlIGxhcmdlciB0aGFuIGlubmVyIGF0IHJhZGl1cyBtdWx0aXBsaWVyID0gMSAobWF0Y2hlcyB0aGUgYmFzZSBtZXNoKS5cbiAqL1xuY29uc3QgSFVHRV9IQUxPX0lOTkVSX1JBRElVUyA9IDI1ODtcbmNvbnN0IEhVR0VfSEFMT19CQVNFX09VVEVSX1JBRElVUyA9IDI5NDtcbmNvbnN0IEhVR0VfSEFMT19CQVNFX1NIRUxMID0gSFVHRV9IQUxPX0JBU0VfT1VURVJfUkFESVVTIC0gSFVHRV9IQUxPX0lOTkVSX1JBRElVUztcbi8qKiBNYXRjaGVzIHRoZSBIYWxvIFJhZGl1cyBzbGlkZXIgbWF4OyBoaWdoZXIgdmFsdWVzIGNhbiBwcm9kdWNlIGEgYmxhY2stZGlzYyBhcnRpZmFjdC4gKi9cbmNvbnN0IEhVR0VfSEFMT19SQURJVVNfTUFYID0gMy41O1xuXG5jb25zdCBIVUdFX0hBTE9fVU5JRk9STVMgPSB7XG4gIGZJbm5lclJhZGl1czogSFVHRV9IQUxPX0lOTkVSX1JBRElVUyxcbiAgLy8gU29mdCBjeWFuIG1hdGNoaW5nIHRoZSByZWZlcmVuY2UgaHVnZS1oYWxvIGxvb2suXG4gIHYzSGFsb0NvbG9yOiBbMC40NSwgMC43MiwgMS4wXSxcbiAgZkhhbG9JbnRlbnNpdHk6IDEuMFxufTtcblxuY29uc3QgSFVHRV9IQUxPX1BBUkFNRVRFUlMgPSB7XG4gIGN1bGxGYWNlOiAweDA0MDQsIC8vIEdMLkZST05UXG4gIGRlcHRoTWFzazogZmFsc2UsXG4gIC8vIExhcmdlIHNoZWxscyBvZnRlbiBlbmNsb3NlIHRoZSBjYW1lcmE7IGRpc2FibGUgZGVwdGggc28gdGhlIHJpbmcgc3RpbGwgZHJhd3MuXG4gIGRlcHRoVGVzdDogZmFsc2UsXG4gIGJsZW5kRnVuYzogWzB4MDMwMiwgMHgwMzAzLCAxLCAweDAzMDNdLCAvLyBTUkNfQUxQSEEsIE9ORV9NSU5VU19TUkNfQUxQSEFcbiAgYmxlbmRFcXVhdGlvbjogWzB4ODAwNiwgMHg4MDA2XVxufTtcblxuZnVuY3Rpb24gcmVzb2x2ZUh1Z2VIYWxvUmFkaXVzKGNvbmZpZzogR2xvYmVDb25maWcpOiBudW1iZXIge1xuICBjb25zdCBtdWx0aXBsaWVyID0gTnVtYmVyLmlzRmluaXRlKGNvbmZpZy5odWdlSGFsb1JhZGl1cylcbiAgICA/IChjb25maWcuaHVnZUhhbG9SYWRpdXMgYXMgbnVtYmVyKVxuICAgIDogREVGQVVMVF9HTE9CRV9DT05GSUcuaHVnZUhhbG9SYWRpdXM7XG4gIC8vIFNjYWxlIHNoZWxsIHRoaWNrbmVzczsga2VlcCBvdXRlciBhYm92ZSB0aGUgcGxhbmV0IHN1cmZhY2UuXG4gIHJldHVybiAoXG4gICAgSFVHRV9IQUxPX0lOTkVSX1JBRElVUyArXG4gICAgSFVHRV9IQUxPX0JBU0VfU0hFTEwgKiBNYXRoLm1heChNYXRoLm1pbihtdWx0aXBsaWVyLCBIVUdFX0hBTE9fUkFESVVTX01BWCksIDAuMDUpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVIdWdlSGFsb09wYWNpdHkoY29uZmlnOiBHbG9iZUNvbmZpZyk6IG51bWJlciB7XG4gIGNvbnN0IG9wYWNpdHkgPSBOdW1iZXIuaXNGaW5pdGUoY29uZmlnLmh1Z2VIYWxvT3BhY2l0eSlcbiAgICA/IChjb25maWcuaHVnZUhhbG9PcGFjaXR5IGFzIG51bWJlcilcbiAgICA6IERFRkFVTFRfR0xPQkVfQ09ORklHLmh1Z2VIYWxvT3BhY2l0eTtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWluKDEsIG9wYWNpdHkpKTtcbn1cblxuLyoqXG4gKiBWaWV3LWluZGVwZW5kZW50IGF0bW9zcGhlcmU6IGEgbGFyZ2UgdW5pZm9ybSBlbWlzc2l2ZSBhdXJhIGFyb3VuZCB0aGUgZ2xvYmUuXG4gKiBVbmxpa2UgQXRtb3NwaGVyZVNreUxheWVyUmVhbGlzdGljLCB0aGlzIGlnbm9yZXMgc3VuIGRpcmVjdGlvbiBhbmQgdXNlcyBhXG4gKiBsaW5lYXIgcmFkaWFsIGZhbGxvZmYgdGhyb3VnaCBhIHRoaWNrIHNoZWxsIChtYXggYXQgdGhlIHN1cmZhY2Ug4oaSIDAgYXQgb3V0ZXIgcmFkaXVzKS5cbiAqL1xuZXhwb3J0IGNsYXNzIEF0bW9zcGhlcmVIdWdlSGFsb0xheWVyIGV4dGVuZHMgU2ltcGxlTWVzaExheWVyPGFueSwgQXRtb3NwaGVyZUxheWVyUHJvcHM+IHtcbiAgc3RhdGljIGxheWVyTmFtZSA9ICdBdG1vc3BoZXJlSHVnZUhhbG9MYXllcic7XG5cbiAgZHJhdyh7dW5pZm9ybXN9OiB7dW5pZm9ybXM6IG9iamVjdH0pOiB2b2lkIHtcbiAgICBjb25zdCB7Y29uZmlnLCB6b29tRmFkZX0gPSB0aGlzLnByb3BzO1xuICAgIGNvbnN0IG1vZGVsID0gdGhpcy5zdGF0ZS5tb2RlbDtcbiAgICBpZiAobW9kZWwpIHtcbiAgICAgIChtb2RlbCBhcyBhbnkpLnByb3BzLnVuaWZvcm1zID0ge1xuICAgICAgICAuLi4obW9kZWwgYXMgYW55KS5wcm9wcy51bmlmb3JtcyxcbiAgICAgICAgLi4uSFVHRV9IQUxPX1VOSUZPUk1TLFxuICAgICAgICBmSGFsb09wYWNpdHk6IHJlc29sdmVIdWdlSGFsb09wYWNpdHkoY29uZmlnKSxcbiAgICAgICAgZkF0bW9zcGhlcmVab29tRmFkZTogem9vbUZhZGVcbiAgICAgIH07XG4gICAgfVxuICAgIHN1cGVyLmRyYXcoe3VuaWZvcm1zfSk7XG4gIH1cblxuICBnZXRTaGFkZXJzKCk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnN1cGVyLmdldFNoYWRlcnMoKSxcbiAgICAgIGluamVjdDoge1xuICAgICAgICAnZnM6I2RlY2wnOiBgXG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmSW5uZXJSYWRpdXM7XG4gICAgICAgICAgdW5pZm9ybSB2ZWMzIHYzSGFsb0NvbG9yO1xuICAgICAgICAgIHVuaWZvcm0gZmxvYXQgZkhhbG9JbnRlbnNpdHk7XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmSGFsb09wYWNpdHk7XG4gICAgICAgICAgdW5pZm9ybSBmbG9hdCBmQXRtb3NwaGVyZVpvb21GYWRlO1xuICAgICAgICBgLFxuICAgICAgICAnZnM6I21haW4tZW5kJzogYFxuICAgICAgICAgIHZlYzMgdjNDYW1lcmFQb3MgPSBjYW1lcmFQb3NpdGlvbjtcbiAgICAgICAgICB2ZWMzIHYzUG9zID0gcG9zaXRpb25fY29tbW9uc3BhY2UueHl6O1xuICAgICAgICAgIC8vIE91dGVyIHJhZGl1cyBmcm9tIHRoZSBhY3R1YWwgbWVzaCB2ZXJ0ZXggc28gc2l6ZVNjYWxlIHN0YXlzIGluIHN5bmMuXG4gICAgICAgICAgZmxvYXQgZk91dGVyUmFkaXVzID0gbGVuZ3RoKHYzUG9zKTtcbiAgICAgICAgICB2ZWMzIHYzUmF5ID0gbm9ybWFsaXplKHYzUG9zIC0gdjNDYW1lcmFQb3MpO1xuXG4gICAgICAgICAgLy8gSW1wYWN0IHBhcmFtZXRlciBvZiB0aGUgdmlldyByYXkgKHBlcnBlbmRpY3VsYXIgZGlzdGFuY2UgZnJvbSBnbG9iZVxuICAgICAgICAgIC8vIGNlbnRlciB0byB0aGUgcmF5KS4gU3RhYmxlIHdoZW4gdGhlIGNhbWVyYSBpcyBpbnNpZGUgdGhlIG91dGVyIHNoZWxsLFxuICAgICAgICAgIC8vIHVubGlrZSBuZWFyL2ZhciBzcGhlcmUtaW50ZXJzZWN0aW9uIG1hdGggd2hpY2ggYnJlYWtzIGluIHRoYXQgY2FzZVxuICAgICAgICAgIC8vIGFuZCBwcm9kdWNlZCBhIGJsYWNrIGRpc2MgYXQgaGlnaCByYWRpdXMgbXVsdGlwbGllcnMuXG4gICAgICAgICAgZmxvYXQgZkRNaW4gPSBsZW5ndGgoY3Jvc3ModjNDYW1lcmFQb3MsIHYzUmF5KSk7XG5cbiAgICAgICAgICAvLyBMaW5lYXIgZmFsbG9mZiBpbiB0aGUgYW5udWx1cyBvbmx5OiBtYXggYXQgdGhlIHN1cmZhY2UsIHplcm8gYXQgb3V0ZXIuXG4gICAgICAgICAgZmxvYXQgZlNoZWxsID0gbWF4KGZPdXRlclJhZGl1cyAtIGZJbm5lclJhZGl1cywgMC4wMDAxKTtcbiAgICAgICAgICBmbG9hdCBmR2xvdyA9IDAuMDtcbiAgICAgICAgICBpZiAoZkRNaW4gPj0gZklubmVyUmFkaXVzICYmIGZETWluIDwgZk91dGVyUmFkaXVzKSB7XG4gICAgICAgICAgICBmbG9hdCB0ID0gKGZETWluIC0gZklubmVyUmFkaXVzKSAvIGZTaGVsbDtcbiAgICAgICAgICAgIGZHbG93ID0gMS4wIC0gdDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmR2xvdyAqPSBmSGFsb0ludGVuc2l0eTtcblxuICAgICAgICAgIC8vIFN0cmFpZ2h0IGFscGhhIChub3QgcHJlbXVsdGlwbGllZCkgZm9yIFNSQ19BTFBIQSBibGVuZGluZy5cbiAgICAgICAgICBmcmFnQ29sb3IgPSB2ZWM0KHYzSGFsb0NvbG9yLCBmR2xvdyAqIGZIYWxvT3BhY2l0eSk7XG4gICAgICAgICAgZnJhZ0NvbG9yLmEgKj0gZkF0bW9zcGhlcmVab29tRmFkZTtcbiAgICAgICAgYCxcbiAgICAgICAgJ2ZzOkRFQ0tHTF9GSUxURVJfQ09MT1InOiBgYFxuICAgICAgfVxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGdldEdsb2JlQXRtb3NwaGVyZUxheWVyID0gKHtjb25maWcsIHpvb219OiB7Y29uZmlnOiBHbG9iZUNvbmZpZzsgem9vbT86IG51bWJlcn0pID0+IHtcbiAgY29uc3Qgem9vbUZhZGUgPSBhdG1vc3BoZXJlWm9vbUZhZGUoem9vbSA/PyAwKTtcbiAgcmV0dXJuIG5ldyBBdG1vc3BoZXJlTGF5ZXJSZWFsaXN0aWMoe1xuICAgIGlkOiAnYXRtb3NwaGVyZScsXG4gICAgZGF0YTogW1swLCAwLCAwXV0sXG4gICAgY29uZmlnLFxuICAgIHpvb21GYWRlLFxuICAgIGNvb3JkaW5hdGVPcmlnaW46IFswLCAwLCAwXSxcbiAgICBjb29yZGluYXRlU3lzdGVtOiBDT09SRElOQVRFX1NZU1RFTS5DQVJURVNJQU4sXG4gICAgZ2V0UG9zaXRpb246ICgoZDogbnVtYmVyW10pID0+IGQpIGFzIGFueSxcbiAgICBnZXRDb2xvcjogWzAsIDAsIDBdLFxuICAgIG1lc2g6IEdMT0JFX01FU0hfSU5ORVIsXG4gICAgcGFyYW1ldGVyczogQVRNT1NQSEVSRV9QQVJBTUVURVJTXG4gIH0pO1xufTtcblxuLyoqIFJlYWxpc3RpYyBzdW4tbGl0IHNjYXR0ZXJpbmcgc2t5IGhhbG8gKHRoaW4gbGltYiBnbG93KS4gKi9cbmV4cG9ydCBjb25zdCBnZXRHbG9iZUF0bW9zcGhlcmVTa3lMYXllciA9ICh7Y29uZmlnLCB6b29tfToge2NvbmZpZzogR2xvYmVDb25maWc7IHpvb20/OiBudW1iZXJ9KSA9PiB7XG4gIGNvbnN0IHpvb21GYWRlID0gYXRtb3NwaGVyZVpvb21GYWRlKHpvb20gPz8gMCk7XG4gIHJldHVybiBuZXcgQXRtb3NwaGVyZVNreUxheWVyUmVhbGlzdGljKHtcbiAgICBpZDogJ2F0bW9zcGhlcmUtc2t5JyxcbiAgICBkYXRhOiBbWzAsIDAsIDBdXSxcbiAgICBjb25maWcsXG4gICAgem9vbUZhZGUsXG4gICAgY29vcmRpbmF0ZU9yaWdpbjogWzAsIDAsIDBdLFxuICAgIGNvb3JkaW5hdGVTeXN0ZW06IENPT1JESU5BVEVfU1lTVEVNLkNBUlRFU0lBTixcbiAgICBnZXRQb3NpdGlvbjogKChkOiBudW1iZXJbXSkgPT4gZCkgYXMgYW55LFxuICAgIGdldENvbG9yOiBbMCwgMCwgMF0sXG4gICAgbWVzaDogR0xPQkVfTUVTSF9PVVRFUixcbiAgICBwYXJhbWV0ZXJzOiBBVE1PU1BIRVJFX1NLWV9QQVJBTUVURVJTXG4gIH0pO1xufTtcblxuLyoqXG4gKiBMYXJnZSB1bmlmb3JtIGdsb3cgZHJhd24gaW4gYWRkaXRpb24gdG8gdGhlIHJlYWxpc3RpYyBza3kgaGFsbyB3aGVuXG4gKiBgY29uZmlnLmh1Z2VIYWxvYCBpcyBlbmFibGVkLiBSZXR1cm5zIG51bGwgd2hlbiBkaXNhYmxlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEdsb2JlSHVnZUhhbG9MYXllciA9ICh7Y29uZmlnLCB6b29tfToge2NvbmZpZzogR2xvYmVDb25maWc7IHpvb20/OiBudW1iZXJ9KSA9PiB7XG4gIGlmICghY29uZmlnLmh1Z2VIYWxvKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3Qgem9vbUZhZGUgPSBhdG1vc3BoZXJlWm9vbUZhZGUoem9vbSA/PyAwKTtcbiAgY29uc3Qgb3V0ZXJSYWRpdXMgPSByZXNvbHZlSHVnZUhhbG9SYWRpdXMoY29uZmlnKTtcbiAgLy8gS2VlcCBtZXNoIGV4dGVudCBpbiBzeW5jIHdpdGggdGhlIGRlc2lyZWQgb3V0ZXIgcmFkaXVzIChiYXNlIG1lc2ggPSBkZWZhdWx0IG91dGVyKS5cbiAgY29uc3Qgc2l6ZVNjYWxlID0gb3V0ZXJSYWRpdXMgLyBIVUdFX0hBTE9fQkFTRV9PVVRFUl9SQURJVVM7XG4gIHJldHVybiBuZXcgQXRtb3NwaGVyZUh1Z2VIYWxvTGF5ZXIoe1xuICAgIGlkOiAnYXRtb3NwaGVyZS1odWdlLWhhbG8nLFxuICAgIGRhdGE6IFtbMCwgMCwgMF1dLFxuICAgIGNvbmZpZyxcbiAgICB6b29tRmFkZSxcbiAgICBjb29yZGluYXRlT3JpZ2luOiBbMCwgMCwgMF0sXG4gICAgY29vcmRpbmF0ZVN5c3RlbTogQ09PUkRJTkFURV9TWVNURU0uQ0FSVEVTSUFOLFxuICAgIGdldFBvc2l0aW9uOiAoKGQ6IG51bWJlcltdKSA9PiBkKSBhcyBhbnksXG4gICAgZ2V0Q29sb3I6IFswLCAwLCAwXSxcbiAgICBtZXNoOiBHTE9CRV9NRVNIX0hVR0VfSEFMTyxcbiAgICBzaXplU2NhbGUsXG4gICAgcGFyYW1ldGVyczogSFVHRV9IQUxPX1BBUkFNRVRFUlNcbiAgfSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxTQUFRQSxpQkFBaUIsUUFBTyxlQUFlO0FBQy9DLFNBQVFDLGVBQWUsUUFBTyxzQkFBc0I7QUFDcEQsU0FBUUMsY0FBYyxRQUFPLGlCQUFpQjtBQUM5QyxTQUFRQyxPQUFPLFFBQU8sZUFBZTtBQUNyQyxTQUFRQyxjQUFjLFFBQU8sY0FBYztBQUUzQyxTQUFRQyxvQkFBb0IsUUFBeUIsc0JBQXNCO0FBRTNFLElBQU1DLFNBQVMsR0FBRyxTQUFaQSxTQUFTQSxDQUFJQyxPQUFlO0VBQUEsT0FBY0EsT0FBTyxHQUFHQyxJQUFJLENBQUNDLEVBQUUsR0FBSSxHQUFHO0FBQUE7QUFFeEUsSUFBTUMsVUFBVSxHQUFHLFNBQWJBLFVBQVVBLENBQUlDLEtBQWEsRUFBK0I7RUFDOUQs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
@@ -0,0 +1,60 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
3
+ import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
4
+ import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
5
+ import _get from "@babel/runtime/helpers/esm/get";
6
+ import _inherits from "@babel/runtime/helpers/esm/inherits";
7
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
8
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
11
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
12
+ function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; }
13
+ // SPDX-License-Identifier: MIT
14
+ // Copyright contributors to the kepler.gl project
15
+
16
+ // @ts-ignore _MultiIconLayer is an experimental, underscore-prefixed deck.gl export whose named type binding isn't reliably resolvable through the package barrel under this project's module resolution. Access it off the namespace with a loose type.
17
+ import { _MultiIconLayer as MultiIconLayer } from '@deck.gl/layers';
18
+
19
+ // Back-face culling for globe-mode text labels.
20
+ //
21
+ // deck.gl's TextLayer uses a MultiIconLayer to render glyphs; on a globe, labels
22
+ // anchored on the far hemisphere would otherwise be drawn "through" the planet.
23
+ // This subclass injects a small GLSL
24
+ // snippet into the icon vertex shader that degenerates (collapses) glyph vertices
25
+ // whose anchor is facing away from the camera, so back-side labels disappear.
26
+ //
27
+ // The test uses the true sphere-horizon condition rather than a fixed dot-product
28
+ // cutoff. In deck.gl common space the globe is a sphere centered at the origin, so:
29
+ // - the label anchor position doubles as its outward surface normal, and
30
+ // - a surface point is visible from the camera exactly when the angle between its
31
+ // normal and the camera direction is within the horizon half-angle, i.e.
32
+ // dot(normalize(anchor), normalize(cameraPos)) > R / d
33
+ // where R is the sphere radius (= |anchor|) and d = |cameraPos| is the camera
34
+ // distance from the globe center.
35
+ // This is zoom-independent: the visible cap automatically shrinks as you zoom in and
36
+ // grows as you pull back, so labels don't pop in/out at the limb while zooming.
37
+ var BACKFACE_CULL_INJECT = /* glsl */"\n // Only cull on the globe; leave web-mercator / flat views untouched.\n if (project.projectionMode == PROJECTION_MODE_GLOBE) {\n vec3 anchorCommon = geometry.position.xyz;\n float radius = length(anchorCommon);\n float camDist = length(project.cameraPosition);\n // Guard against degenerate anchors / camera at the center.\n if (radius > 0.0 && camDist > radius) {\n float cosSurface = dot(anchorCommon / radius, project.cameraPosition / camDist);\n // Cosine of the horizon half-angle. Add a tiny margin so labels are hidden just\n // before they wrap exactly onto the limb (avoids glyphs smeared along the edge).\n float cosHorizon = radius / camDist + 0.02;\n if (cosSurface < cosHorizon) {\n // Push the vertex outside clip space so this glyph is discarded. The hook\n // exposes the clip-space position as `position`, not `gl_Position`.\n position = vec4(0.0, 0.0, 2.0, 1.0);\n }\n }\n }\n";
38
+ var EnhancedMultiIconLayer = /*#__PURE__*/function (_ref) {
39
+ function EnhancedMultiIconLayer() {
40
+ _classCallCheck(this, EnhancedMultiIconLayer);
41
+ return _callSuper(this, EnhancedMultiIconLayer, arguments);
42
+ }
43
+ _inherits(EnhancedMultiIconLayer, _ref);
44
+ return _createClass(EnhancedMultiIconLayer, [{
45
+ key: "getShaders",
46
+ value: function getShaders() {
47
+ var _shaders$inject;
48
+ var shaders = _superPropGet(EnhancedMultiIconLayer, "getShaders", this, 3)([]);
49
+ var existing = ((_shaders$inject = shaders.inject) === null || _shaders$inject === void 0 ? void 0 : _shaders$inject['vs:DECKGL_FILTER_GL_POSITION']) || '';
50
+ return _objectSpread(_objectSpread({}, shaders), {}, {
51
+ inject: _objectSpread(_objectSpread({}, shaders.inject || {}), {}, {
52
+ 'vs:DECKGL_FILTER_GL_POSITION': "".concat(existing, "\n").concat(BACKFACE_CULL_INJECT)
53
+ })
54
+ });
55
+ }
56
+ }]);
57
+ }(MultiIconLayer);
58
+ _defineProperty(EnhancedMultiIconLayer, "layerName", 'EnhancedMultiIconLayer');
59
+ export { EnhancedMultiIconLayer as default };
60
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfTXVsdGlJY29uTGF5ZXIiLCJNdWx0aUljb25MYXllciIsIkJBQ0tGQUNFX0NVTExfSU5KRUNUIiwiRW5oYW5jZWRNdWx0aUljb25MYXllciIsIl9yZWYiLCJfY2xhc3NDYWxsQ2hlY2siLCJfY2FsbFN1cGVyIiwiYXJndW1lbnRzIiwiX2luaGVyaXRzIiwiX2NyZWF0ZUNsYXNzIiwia2V5IiwidmFsdWUiLCJnZXRTaGFkZXJzIiwiX3NoYWRlcnMkaW5qZWN0Iiwic2hhZGVycyIsIl9zdXBlclByb3BHZXQiLCJleGlzdGluZyIsImluamVjdCIsIl9vYmplY3RTcHJlYWQiLCJjb25jYXQiLCJfZGVmaW5lUHJvcGVydHkiLCJkZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2dsb2JlL2VuaGFuY2VkLW11bHRpLWljb24tbGF5ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuLy8gQHRzLWlnbm9yZSBfTXVsdGlJY29uTGF5ZXIgaXMgYW4gZXhwZXJpbWVudGFsLCB1bmRlcnNjb3JlLXByZWZpeGVkIGRlY2suZ2wgZXhwb3J0IHdob3NlIG5hbWVkIHR5cGUgYmluZGluZyBpc24ndCByZWxpYWJseSByZXNvbHZhYmxlIHRocm91Z2ggdGhlIHBhY2thZ2UgYmFycmVsIHVuZGVyIHRoaXMgcHJvamVjdCdzIG1vZHVsZSByZXNvbHV0aW9uLiBBY2Nlc3MgaXQgb2ZmIHRoZSBuYW1lc3BhY2Ugd2l0aCBhIGxvb3NlIHR5cGUuXG5pbXBvcnQge19NdWx0aUljb25MYXllciBhcyBNdWx0aUljb25MYXllcn0gZnJvbSAnQGRlY2suZ2wvbGF5ZXJzJztcblxuLy8gQmFjay1mYWNlIGN1bGxpbmcgZm9yIGdsb2JlLW1vZGUgdGV4dCBsYWJlbHMuXG4vL1xuLy8gZGVjay5nbCdzIFRleHRMYXllciB1c2VzIGEgTXVsdGlJY29uTGF5ZXIgdG8gcmVuZGVyIGdseXBoczsgb24gYSBnbG9iZSwgbGFiZWxzXG4vLyBhbmNob3JlZCBvbiB0aGUgZmFyIGhlbWlzcGhlcmUgd291bGQgb3RoZXJ3aXNlIGJlIGRyYXduIFwidGhyb3VnaFwiIHRoZSBwbGFuZXQuXG4vLyBUaGlzIHN1YmNsYXNzIGluamVjdHMgYSBzbWFsbCBHTFNMXG4vLyBzbmlwcGV0IGludG8gdGhlIGljb24gdmVydGV4IHNoYWRlciB0aGF0IGRlZ2VuZXJhdGVzIChjb2xsYXBzZXMpIGdseXBoIHZlcnRpY2VzXG4vLyB3aG9zZSBhbmNob3IgaXMgZmFjaW5nIGF3YXkgZnJvbSB0aGUgY2FtZXJhLCBzbyBiYWNrLXNpZGUgbGFiZWxzIGRpc2FwcGVhci5cbi8vXG4vLyBUaGUgdGVzdCB1c2VzIHRoZSB0cnVlIHNwaGVyZS1ob3Jpem9uIGNvbmRpdGlvbiByYXRoZXIgdGhhbiBhIGZpeGVkIGRvdC1wcm9kdWN0XG4vLyBjdXRvZmYuIEluIGRlY2suZ2wgY29tbW9uIHNwYWNlIHRoZSBnbG9iZSBpcyBhIHNwaGVyZSBjZW50ZXJlZCBhdCB0aGUgb3JpZ2luLCBzbzpcbi8vICAgLSB0aGUgbGFiZWwgYW5jaG9yIHBvc2l0aW9uIGRvdWJsZXMgYXMgaXRzIG91dHdhcmQgc3VyZmFjZSBub3JtYWwsIGFuZFxuLy8gICAtIGEgc3VyZmFjZSBwb2ludCBpcyB2aXNpYmxlIGZyb20gdGhlIGNhbWVyYSBleGFjdGx5IHdoZW4gdGhlIGFuZ2xlIGJldHdlZW4gaXRzXG4vLyAgICAgbm9ybWFsIGFuZCB0aGUgY2FtZXJhIGRpcmVjdGlvbiBpcyB3aXRoaW4gdGhlIGhvcml6b24gaGFsZi1hbmdsZSwgaS5lLlxuLy8gICAgICAgICBkb3Qobm9ybWFsaXplKGFuY2hvciksIG5vcm1hbGl6ZShjYW1lcmFQb3MpKSA+IFIgLyBkXG4vLyAgICAgd2hlcmUgUiBpcyB0aGUgc3BoZXJlIHJhZGl1cyAoPSB8YW5jaG9yfCkgYW5kIGQgPSB8Y2FtZXJhUG9zfCBpcyB0aGUgY2FtZXJhXG4vLyAgICAgZGlzdGFuY2UgZnJvbSB0aGUgZ2xvYmUgY2VudGVyLlxuLy8gVGhpcyBpcyB6b29tLWluZGVwZW5kZW50OiB0aGUgdmlzaWJsZSBjYXAgYXV0b21hdGljYWxseSBzaHJpbmtzIGFzIHlvdSB6b29tIGluIGFuZFxuLy8gZ3Jvd3MgYXMgeW91IHB1bGwgYmFjaywgc28gbGFiZWxzIGRvbid0IHBvcCBpbi9vdXQgYXQgdGhlIGxpbWIgd2hpbGUgem9vbWluZy5cbmNvbnN0IEJBQ0tGQUNFX0NVTExfSU5KRUNUID0gLyogZ2xzbCAqLyBgXG4gIC8vIE9ubHkgY3VsbCBvbiB0aGUgZ2xvYmU7IGxlYXZlIHdlYi1tZXJjYXRvciAvIGZsYXQgdmlld3MgdW50b3VjaGVkLlxuICBpZiAocHJvamVjdC5wcm9qZWN0aW9uTW9kZSA9PSBQUk9KRUNUSU9OX01PREVfR0xPQkUpIHtcbiAgICB2ZWMzIGFuY2hvckNvbW1vbiA9IGdlb21ldHJ5LnBvc2l0aW9uLnh5ejtcbiAgICBmbG9hdCByYWRpdXMgPSBsZW5ndGgoYW5jaG9yQ29tbW9uKTtcbiAgICBmbG9hdCBjYW1EaXN0ID0gbGVuZ3RoKHByb2plY3QuY2FtZXJhUG9zaXRpb24pO1xuICAgIC8vIEd1YXJkIGFnYWluc3QgZGVnZW5lcmF0ZSBhbmNob3JzIC8gY2FtZXJhIGF0IHRoZSBjZW50ZXIuXG4gICAgaWYgKHJhZGl1cyA+IDAuMCAmJiBjYW1EaXN0ID4gcmFkaXVzKSB7XG4gICAgICBmbG9hdCBjb3NTdXJmYWNlID0gZG90KGFuY2hvckNvbW1vbiAvIHJhZGl1cywgcHJvamVjdC5jYW1lcmFQb3NpdGlvbiAvIGNhbURpc3QpO1xuICAgICAgLy8gQ29zaW5lIG9mIHRoZSBob3Jpem9uIGhhbGYtYW5nbGUuIEFkZCBhIHRpbnkgbWFyZ2luIHNvIGxhYmVscyBhcmUgaGlkZGVuIGp1c3RcbiAgICAgIC8vIGJlZm9yZSB0aGV5IHdyYXAgZXhhY3RseSBvbnRvIHRoZSBsaW1iIChhdm9pZHMgZ2x5cGhzIHNtZWFyZWQgYWxvbmcgdGhlIGVkZ2UpLlxuICAgICAgZmxvYXQgY29zSG9yaXpvbiA9IHJhZGl1cyAvIGNhbURpc3QgKyAwLjAyO1xuICAgICAgaWYgKGNvc1N1cmZhY2UgPCBjb3NIb3Jpem9uKSB7XG4gICAgICAgIC8vIFB1c2ggdGhlIHZlcnRleCBvdXRzaWRlIGNsaXAgc3BhY2Ugc28gdGhpcyBnbHlwaCBpcyBkaXNjYXJkZWQuIFRoZSBob29rXG4gICAgICAgIC8vIGV4cG9zZXMgdGhlIGNsaXAtc3BhY2UgcG9zaXRpb24gYXMgXFxgcG9zaXRpb25cXGAsIG5vdCBcXGBnbF9Qb3NpdGlvblxcYC5cbiAgICAgICAgcG9zaXRpb24gPSB2ZWM0KDAuMCwgMC4wLCAyLjAsIDEuMCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5gO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFbmhhbmNlZE11bHRpSWNvbkxheWVyIGV4dGVuZHMgKE11bHRpSWNvbkxheWVyIGFzIGFueSkge1xuICBzdGF0aWMgbGF5ZXJOYW1lID0gJ0VuaGFuY2VkTXVsdGlJY29uTGF5ZXInO1xuXG4gIGdldFNoYWRlcnMoKSB7XG4gICAgY29uc3Qgc2hhZGVycyA9IHN1cGVyLmdldFNoYWRlcnMoKTtcbiAgICBjb25zdCBleGlzdGluZyA9IHNoYWRlcnMuaW5qZWN0Py5bJ3ZzOkRFQ0tHTF9GSUxURVJfR0xfUE9TSVRJT04nXSB8fCAnJztcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2hhZGVycyxcbiAgICAgIGluamVjdDoge1xuICAgICAgICAuLi4oc2hhZGVycy5pbmplY3QgfHwge30pLFxuICAgICAgICAndnM6REVDS0dMX0ZJTFRFUl9HTF9QT1NJVElPTic6IGAke2V4aXN0aW5nfVxcbiR7QkFDS0ZBQ0VfQ1VMTF9JTkpFQ1R9YFxuICAgICAgfVxuICAgIH07XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTs7QUFFQTtBQUNBLFNBQVFBLGVBQWUsSUFBSUMsY0FBYyxRQUFPLGlCQUFpQjs7QUFFakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBTUMsb0JBQW9CLEdBQUcscTlCQW1CNUI7QUFBQyxJQUVtQkMsc0JBQXNCLDBCQUFBQyxJQUFBO0VBQUEsU0FBQUQsdUJBQUE7SUFBQUUsZUFBQSxPQUFBRixzQkFBQTtJQUFBLE9BQUFHLFVBQUEsT0FBQUgsc0JBQUEsRUFBQUksU0FBQTtFQUFBO0VBQUFDLFNBQUEsQ0FBQUwsc0JBQUEsRUFBQUMsSUFBQTtFQUFBLE9BQUFLLFlBQUEsQ0FBQU4sc0JBQUE7SUFBQU8sR0FBQTtJQUFBQyxLQUFBLEVBR3pDLFNBQUFDLFVBQVVBLENBQUEsRUFBRztNQUFBLElBQUFDLGVBQUE7TUFDWCxJQUFNQyxPQUFPLEdBQUFDLGFBQUEsQ0FBQVosc0JBQUEsNEJBQXFCO01BQ2xDLElBQU1hLFFBQVEsR0FBRyxFQUFBSCxlQUFBLEdBQUFDLE9BQU8sQ0FBQ0csTUFBTSxjQUFBSixlQUFBLHVCQUFkQSxlQUFBLENBQWlCLDhCQUE4QixDQUFDLEtBQUksRUFBRTtNQUN2RSxPQUFBSyxhQUFBLENBQUFBLGFBQUEsS0FDS0osT0FBTztRQUNWRyxNQUFNLEVBQUFDLGFBQUEsQ0FBQUEsYUFBQSxLQUNBSixPQUFPLENBQUNHLE1BQU0sSUFBSSxDQUFDLENBQUM7VUFDeEIsOEJBQThCLEtBQUFFLE1BQUEsQ0FBS0gsUUFBUSxRQUFBRyxNQUFBLENBQUtqQixvQkFBb0I7UUFBRTtNQUN2RTtJQUVMO0VBQUM7QUFBQSxFQWJrREQsY0FBYztBQUFBbUIsZUFBQSxDQUE5Q2pCLHNCQUFzQixlQUN0Qix3QkFBd0I7QUFBQSxTQUR4QkEsc0JBQXNCLElBQUFrQixPQUFBIiwiaWdub3JlTGlzdCI6W119