UNPKG

25.3 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.Shader = undefined;
7
8var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
9
10var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
11
12var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
13
14var _core = require('../core');
15
16var _utils = require('../utils');
17
18var _scope = require('../scope');
19
20var _defines = require('./defines');
21
22var _glslInjectDefines = require('glsl-inject-defines');
23
24var _glslInjectDefines2 = _interopRequireDefault(_glslInjectDefines);
25
26function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
28function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
29
30function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
31
32function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
33
34var Shader = exports.Shader = function (_Component) {
35 _inherits(Shader, _Component);
36
37 _createClass(Shader, null, [{
38 key: 'defaults',
39 value: function defaults() {
40 return _extends({}, _core.ShaderLib.defaults(), { defines: {} });
41 }
42 }]);
43
44 function Shader(ctx) {
45 var initialState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
46
47 _classCallCheck(this, Shader);
48
49 (0, _utils.assignDefaults)(initialState, Shader.defaults());
50 var shaderName = initialState.shaderName;
51
52 var contextCache = {};
53 var shaderCache = {};
54 var shaderLib = new _core.ShaderLib(_extends({}, initialState));
55
56 var injectShaderDefines = _core.Component.compose(new _defines.ShaderDefines(ctx, _extends({}, initialState.defines)));
57
58 var injectContext = null;
59
60 var fragmentShaderUncompiled = null;
61 var vertexShaderUncompiled = null;
62 var fragmentShader = null;
63 var vertexShader = null;
64
65 var _this = _possibleConstructorReturn(this, (Shader.__proto__ || Object.getPrototypeOf(Shader)).call(this, ctx, initialState, update));
66
67 function update(state, block, previousState) {
68 injectShaderDefines(function (reglContext) {
69 var _state$forceCompile = state.forceCompile,
70 forceCompile = _state$forceCompile === undefined ? false : _state$forceCompile;
71 var defines = reglContext.defines;
72
73
74 if (Object.keys(defines).length) {
75 if (shaderLib.preprocessor.define(defines)) {
76 forceCompile = true;
77 }
78 }
79
80 if (forceCompile || shouldCompile(reglContext, state)) {
81 compile(reglContext, state);
82 }
83
84 setInjectContext(reglContext, state);
85
86 if ('function' == typeof injectContext) {
87 injectContext(state, block);
88 } else {
89 block(state);
90 }
91 });
92 }
93
94 function getShaderFromCache(reglContext, currentState, shader) {
95 shader = getViableShader(reglContext, currentState, shader);
96 return shaderCache[shaderLib.hash(shader)];
97 }
98
99 function setInjectContext(reglContext, currentState) {
100 var opts = {
101 context: {
102 fragmentShader: function (_fragmentShader) {
103 function fragmentShader(_x2) {
104 return _fragmentShader.apply(this, arguments);
105 }
106
107 fragmentShader.toString = function () {
108 return _fragmentShader.toString();
109 };
110
111 return fragmentShader;
112 }(function (_ref) {
113 var fs = _ref.fragmentShader;
114 return fragmentShader || fs;
115 }),
116 vertexShader: function (_vertexShader) {
117 function vertexShader(_x3) {
118 return _vertexShader.apply(this, arguments);
119 }
120
121 vertexShader.toString = function () {
122 return _vertexShader.toString();
123 };
124
125 return vertexShader;
126 }(function (_ref2) {
127 var vs = _ref2.vertexShader;
128 return vertexShader || vs;
129 })
130 }
131 };
132
133 var requestedFragmentShader = getShaderFromCache(reglContext, currentState, currentState.fragmentShader);
134
135 var requestedVertexShader = getShaderFromCache(reglContext, currentState, currentState.vertexShader);
136
137 if (requestedFragmentShader && requestedFragmentShader != fragmentShader) {
138 fragmentShader = requestedFragmentShader;
139 }
140
141 if (requestedVertexShader && requestedVertexShader != vertexShader) {
142 vertexShader = requestedVertexShader;
143 }
144
145 if ('string' == typeof vertexShader) {
146 opts.vert = vertexShader;
147 }
148 if ('string' == typeof fragmentShader) {
149 opts.frag = fragmentShader;
150 }
151
152 if ('string' == typeof opts.vert || 'string' == typeof opts.frag) {
153 var hash = [shaderLib.hash(opts.vert), shaderLib.hash(opts.frag)].filter(Boolean).join('');
154 if (null == contextCache[hash]) {
155 injectContext = ctx.regl(opts);
156 contextCache[hash] = injectContext;
157 injectContext.opts = opts;
158 } else {
159 injectContext = contextCache[hash];
160 }
161 }
162 }
163
164 function compile(reglContext, currentState) {
165 if (!isShaderCached(currentState.vertexShader)) {
166 compileVertexShader();
167 }
168
169 if (!isShaderCached(currentState.fragmentShader)) {
170 compileFragmentShader();
171 }
172
173 function compileShader(type, shader) {
174 var compiled = null;
175 var uncompiled = null;
176 if (isViableShader(shader)) {
177 uncompiled = getViableShader(reglContext, currentState, shader);
178 compiled = shaderLib.compile(shaderName + ' (' + type + ')', uncompiled);
179 compiled = shaderLib.preprocess(compiled);
180 return { compiled: compiled, uncompiled: uncompiled };
181 }
182 return null;
183 }
184
185 function isShaderCached(shader) {
186 return Boolean(getShaderFromCache(reglContext, currentState, shader));
187 }
188
189 function compileVertexShader() {
190 var result = compileShader('vertex', currentState.vertexShader);
191 if (result) {
192 vertexShader = result.compiled;
193 vertexShaderUncompiled = result.uncompiled;
194 shaderCache[shaderLib.hash(vertexShaderUncompiled)] = vertexShader;
195 }
196 }
197
198 function compileFragmentShader() {
199 var result = compileShader('fragment', currentState.fragmentShader);
200 if (result) {
201 fragmentShader = result.compiled;
202 fragmentShaderUncompiled = result.uncompiled;
203 shaderCache[shaderLib.hash(fragmentShaderUncompiled)] = fragmentShader;
204 }
205 }
206 }
207
208 function getViableShader(reglContext, currentState, shader) {
209 var defines = shaderLib.defines;
210
211 if ('string' == typeof shader) {
212 return (0, _glslInjectDefines2.default)(shader, defines);
213 } else if ('function' == typeof shader) {
214 return (0, _glslInjectDefines2.default)(shader(reglContext, currentState), defines);
215 }
216 }
217
218 function isViableShader(shader) {
219 return ['string', 'function'].indexOf(typeof shader === 'undefined' ? 'undefined' : _typeof(shader)) > -1;
220 }
221
222 function shouldCompile(reglContext, currentState) {
223 var needsCompile = false;
224 check('function' != typeof injectContext);
225 checkShader(vertexShaderUncompiled, currentState.vertexShader);
226 checkShader(fragmentShaderUncompiled, currentState.fragmentShader);
227 return needsCompile;
228
229 function check(cond) {
230 if (cond) {
231 needsCompile = true;
232 }
233 }
234
235 function checkShader(current, next) {
236 next = getViableShader(reglContext, currentState, next);
237 if (shaderCache[shaderLib.hash(next)]) {
238 return check(true);
239 } else if ('string' != typeof current && next) {
240 return check(true);
241 } else if ('string' == typeof next && current != next) {
242 return check(true);
243 }
244 }
245 }
246 return _this;
247 }
248
249 return Shader;
250}(_core.Component);
251//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zaGFkZXIvc2hhZGVyLmpzIl0sIm5hbWVzIjpbIlNoYWRlciIsImRlZmF1bHRzIiwiZGVmaW5lcyIsImN0eCIsImluaXRpYWxTdGF0ZSIsInNoYWRlck5hbWUiLCJjb250ZXh0Q2FjaGUiLCJzaGFkZXJDYWNoZSIsInNoYWRlckxpYiIsImluamVjdFNoYWRlckRlZmluZXMiLCJjb21wb3NlIiwiaW5qZWN0Q29udGV4dCIsImZyYWdtZW50U2hhZGVyVW5jb21waWxlZCIsInZlcnRleFNoYWRlclVuY29tcGlsZWQiLCJmcmFnbWVudFNoYWRlciIsInZlcnRleFNoYWRlciIsInVwZGF0ZSIsInN0YXRlIiwiYmxvY2siLCJwcmV2aW91c1N0YXRlIiwicmVnbENvbnRleHQiLCJmb3JjZUNvbXBpbGUiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwicHJlcHJvY2Vzc29yIiwiZGVmaW5lIiwic2hvdWxkQ29tcGlsZSIsImNvbXBpbGUiLCJzZXRJbmplY3RDb250ZXh0IiwiZ2V0U2hhZGVyRnJvbUNhY2hlIiwiY3VycmVudFN0YXRlIiwic2hhZGVyIiwiZ2V0VmlhYmxlU2hhZGVyIiwiaGFzaCIsIm9wdHMiLCJjb250ZXh0IiwiZnMiLCJ2cyIsInJlcXVlc3RlZEZyYWdtZW50U2hhZGVyIiwicmVxdWVzdGVkVmVydGV4U2hhZGVyIiwidmVydCIsImZyYWciLCJmaWx0ZXIiLCJCb29sZWFuIiwiam9pbiIsInJlZ2wiLCJpc1NoYWRlckNhY2hlZCIsImNvbXBpbGVWZXJ0ZXhTaGFkZXIiLCJjb21waWxlRnJhZ21lbnRTaGFkZXIiLCJjb21waWxlU2hhZGVyIiwidHlwZSIsImNvbXBpbGVkIiwidW5jb21waWxlZCIsImlzVmlhYmxlU2hhZGVyIiwicHJlcHJvY2VzcyIsInJlc3VsdCIsImluZGV4T2YiLCJuZWVkc0NvbXBpbGUiLCJjaGVjayIsImNoZWNrU2hhZGVyIiwiY29uZCIsImN1cnJlbnQiLCJuZXh0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7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QUE2QlcsWUFBN0IsRUFBMkNnQyxJQUEzQyxDQUFQO0FBQ0EsWUFBSXhELFlBQVlDLFVBQVUwQixJQUFWLENBQWU2QixJQUFmLENBQVosQ0FBSixFQUF1QztBQUNyQyxpQkFBT0osTUFBTSxJQUFOLENBQVA7QUFDRCxTQUZELE1BRU8sSUFBSSxZQUFZLE9BQU9HLE9BQW5CLElBQThCQyxJQUFsQyxFQUF3QztBQUM3QyxpQkFBT0osTUFBTSxJQUFOLENBQVA7QUFDRCxTQUZNLE1BRUEsSUFBSSxZQUFZLE9BQU9JLElBQW5CLElBQTJCRCxXQUFXQyxJQUExQyxFQUFnRDtBQUNyRCxpQkFBT0osTUFBTSxJQUFOLENBQVA7QUFDRDtBQUNGO0FBQ0Y7QUExS2lDO0FBMktuQyIsImZpbGUiOiJzaGFkZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIFNoYWRlckxpYiB9IGZyb20gJy4uL2NvcmUnXG5pbXBvcnQgeyBhc3NpZ25EZWZhdWx0cyB9IGZyb20gJy4uL3V0aWxzJ1xuaW1wb3J0IHsgU2NvcGVkQ29udGV4dCB9IGZyb20gJy4uL3Njb3BlJ1xuaW1wb3J0IHsgU2hhZGVyRGVmaW5lcyB9IGZyb20gJy4vZGVmaW5lcydcbmltcG9ydCBpbmplY3REZWZpbmVzIGZyb20gJ2dsc2wtaW5qZWN0LWRlZmluZXMnXG5cbmV4cG9ydCBjbGFzcyBTaGFkZXIgZXh0ZW5kcyBDb21wb25lbnQge1xuICBzdGF0aWMgZGVmYXVsdHMoKSB7IHJldHVybiB7IC4uLlNoYWRlckxpYi5kZWZhdWx0cygpLCBkZWZpbmVzOiB7fSB9IH1cbiAgY29uc3RydWN0b3IoY3R4LCBpbml0aWFsU3RhdGUgPSB7fSkge1xuICAgIGFzc2lnbkRlZmF1bHRzKGluaXRpYWxTdGF0ZSwgU2hhZGVyLmRlZmF1bHRzKCkpXG4gICAgY29uc3QgeyBzaGFkZXJOYW1lIH0gPSBpbml0aWFsU3RhdGVcbiAgICBjb25zdCBjb250ZXh0Q2FjaGUgPSB7fVxuICAgIGNvbnN0IHNoYWRlckNhY2hlID0ge31cbiAgICBjb25zdCBzaGFkZXJMaWIgPSBuZXcgU2hhZGVyTGliKHsgLi4uaW5pdGlhbFN0YXRlIH0pXG5cbiAgICBjb25zdCBpbmplY3RTaGFkZXJEZWZpbmVzID0gQ29tcG9uZW50LmNvbXBvc2UoXG4gICAgICBuZXcgU2hhZGVyRGVmaW5lcyhjdHgsIHsgLi4uaW5pdGlhbFN0YXRlLmRlZmluZXMgfSksXG4gICAgKVxuXG4gICAgbGV0IGluamVjdENvbnRleHQgPSBudWxsXG5cbiAgICBsZXQgZnJhZ21lbnRTaGFkZXJVbmNvbXBpbGVkID0gbnVsbFxuICAgIGxldCB2ZXJ0ZXhTaGFkZXJVbmNvbXBpbGVkID0gbnVsbFxuICAgIGxldCBmcmFnbWVudFNoYWRlciA9IG51bGxcbiAgICBsZXQgdmVydGV4U2hhZGVyID0gbnVsbFxuXG4gICAgc3VwZXIoY3R4LCBpbml0aWFsU3RhdGUsIHVwZGF0ZSlcbiAgICBmdW5jdGlvbiB1cGRhdGUoc3RhdGUsIGJsb2NrLCBwcmV2aW91c1N0YXRlKSB7XG4gICAgICBpbmplY3RTaGFkZXJEZWZpbmVzKChyZWdsQ29udGV4dCkgPT4ge1xuICAgICAgICBsZXQge2ZvcmNlQ29tcGlsZSA9IGZhbHNlfSA9IHN0YXRlXG4gICAgICAgIGNvbnN0IHtkZWZpbmVzfSA9IHJlZ2xDb250ZXh0XG5cbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGRlZmluZXMpLmxlbmd0aCkge1xuICAgICAgICAgIGlmIChzaGFkZXJMaWIucHJlcHJvY2Vzc29yLmRlZmluZShkZWZpbmVzKSkge1xuICAgICAgICAgICAgZm9yY2VDb21waWxlID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb3JjZUNvbXBpbGUgfHwgc2hvdWxkQ29tcGlsZShyZWdsQ29udGV4dCwgc3RhdGUpKSB7XG4gICAgICAgICAgY29tcGlsZShyZWdsQ29udGV4dCwgc3RhdGUpXG4gICAgICAgIH1cblxuICAgICAgICBzZXRJbmplY3RDb250ZXh0KHJlZ2xDb250ZXh0LCBzdGF0ZSlcblxuICAgICAgICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgaW5qZWN0Q29udGV4dCkge1xuICAgICAgICAgIGluamVjdENvbnRleHQoc3RhdGUsIGJsb2NrKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJsb2NrKHN0YXRlKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNoYWRlckZyb21DYWNoZShyZWdsQ29udGV4dCwgY3VycmVudFN0YXRlLCBzaGFkZXIpIHtcbiAgICAgIHNoYWRlciA9IGdldFZpYWJsZVNoYWRlcihyZWdsQ29udGV4dCwgY3VycmVudFN0YXRlLCBzaGFkZXIpXG4gICAgICByZXR1cm4gc2hhZGVyQ2FjaGVbc2hhZGVyTGliLmhhc2goc2hhZGVyKV1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRJbmplY3RDb250ZXh0KHJlZ2xDb250ZXh0LCBjdXJyZW50U3RhdGUpIHtcbiAgICAgIGNvbnN0IG9wdHMgPSB7XG4gICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICBmcmFnbWVudFNoYWRlcjogKHtmcmFnbWVudFNoYWRlcjogZnN9KSA9PiBmcmFnbWVudFNoYWRlciB8fCBmcyxcbiAgICAgICAgICB2ZXJ0ZXhTaGFkZXI6ICh7dmVydGV4U2hhZGVyOiB2cyB9KSA9PiB2ZXJ0ZXhTaGFkZXIgfHwgdnMsXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVxdWVzdGVkRnJhZ21lbnRTaGFkZXIgPSBnZXRTaGFkZXJGcm9tQ2FjaGUoXG4gICAgICAgIHJlZ2xDb250ZXh0LFxuICAgICAgICBjdXJyZW50U3RhdGUsXG4gICAgICAgIGN1cnJlbnRTdGF0ZS5mcmFnbWVudFNoYWRlcilcblxuICAgICAgY29uc3QgcmVxdWVzdGVkVmVydGV4U2hhZGVyID0gZ2V0U2hhZGVyRnJvbUNhY2hlKFxuICAgICAgICByZWdsQ29udGV4dCxcbiAgICAgICAgY3VycmVudFN0YXRlLFxuICAgICAgICBjdXJyZW50U3RhdGUudmVydGV4U2hhZGVyKVxuXG4gICAgICBpZiAocmVxdWVzdGVkRnJhZ21lbnRTaGFkZXIgJiYgcmVxdWVzdGVkRnJhZ21lbnRTaGFkZXIgIT0gZnJhZ21lbnRTaGFkZXIpIHtcbiAgICAgICAgZnJhZ21lbnRTaGFkZXIgPSByZXF1ZXN0ZWRGcmFnbWVudFNoYWRlclxuICAgICAgfVxuXG4gICAgICBpZiAocmVxdWVzdGVkVmVydGV4U2hhZGVyICYmIHJlcXVlc3RlZFZlcnRleFNoYWRlciAhPSB2ZXJ0ZXhTaGFkZXIpIHtcbiAgICAgICAgdmVydGV4U2hhZGVyID0gcmVxdWVzdGVkVmVydGV4U2hhZGVyXG4gICAgICB9XG5cbiAgICAgIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgdmVydGV4U2hhZGVyKSB7IG9wdHMudmVydCA9IHZlcnRleFNoYWRlciB9XG4gICAgICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIGZyYWdtZW50U2hhZGVyKSB7IG9wdHMuZnJhZyA9IGZyYWdtZW50U2hhZGVyIH1cblxuICAgICAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBvcHRzLnZlcnQgfHwgJ3N0cmluZycgPT0gdHlwZW9mIG9wdHMuZnJhZykge1xuICAgICAgICBjb25zdCBoYXNoID0gW3NoYWRlckxpYi5oYXNoKG9wdHMudmVydCksIHNoYWRlckxpYi5oYXNoKG9wdHMuZnJhZyldXG4gICAgICAgIC5maWx0ZXIoQm9vbGVhbikuam9pbignJylcbiAgICAgICAgaWYgKG51bGwgPT0gY29udGV4dENhY2hlW2hhc2hdKSB7XG4gICAgICAgICAgaW5qZWN0Q29udGV4dCA9IGN0eC5yZWdsKG9wdHMpXG4gICAgICAgICAgY29udGV4dENhY2hlW2hhc2hdID0gaW5qZWN0Q29udGV4dFxuICAgICAgICAgIGluamVjdENvbnRleHQub3B0cyA9IG9wdHNcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbmplY3RDb250ZXh0ID0gY29udGV4dENhY2hlW2hhc2hdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb21waWxlKHJlZ2xDb250ZXh0LCBjdXJyZW50U3RhdGUpIHtcbiAgICAgIGlmICghaXNTaGFkZXJDYWNoZWQoY3VycmVudFN0YXRlLnZlcnRleFNoYWRlcikpIHtcbiAgICAgICAgY29tcGlsZVZlcnRleFNoYWRlcigpXG4gICAgICB9XG5cbiAgICAgIGlmICghaXNTaGFkZXJDYWNoZWQoY3VycmVudFN0YXRlLmZyYWdtZW50U2hhZGVyKSkge1xuICAgICAgICBjb21waWxlRnJhZ21lbnRTaGFkZXIoKVxuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBjb21waWxlU2hhZGVyKHR5cGUsIHNoYWRlcikge1xuICAgICAgICBsZXQgY29tcGlsZWQgPSBudWxsXG4gICAgICAgIGxldCB1bmNvbXBpbGVkID0gbnVsbFxuICAgICAgICBpZiAoaXNWaWFibGVTaGFkZXIoc2hhZGVyKSkge1xuICAgICAgICAgIHVuY29tcGlsZWQgPSBnZXRWaWFibGVTaGFkZXIocmVnbENvbnRleHQsIGN1cnJlbnRTdGF0ZSwgc2hhZGVyKVxuICAgICAgICAgIGNvbXBpbGVkID0gc2hhZGVyTGliLmNvbXBpbGUoYCR7c2hhZGVyTmFtZX0gKCR7dHlwZX0pYCwgdW5jb21waWxlZClcbiAgICAgICAgICBjb21waWxlZCA9IHNoYWRlckxpYi5wcmVwcm9jZXNzKGNvbXBpbGVkKVxuICAgICAgICAgIHJldHVybiB7Y29tcGlsZWQsIHVuY29tcGlsZWR9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gaXNTaGFkZXJDYWNoZWQoc2hhZGVyKSB7XG4gICAgICAgIHJldHVybiBCb29sZWFuKGdldFNoYWRlckZyb21DYWNoZShyZWdsQ29udGV4dCwgY3VycmVudFN0YXRlLCBzaGFkZXIpKVxuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBjb21waWxlVmVydGV4U2hhZGVyKCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBjb21waWxlU2hhZGVyKCd2ZXJ0ZXgnLCBjdXJyZW50U3RhdGUudmVydGV4U2hhZGVyKVxuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgdmVydGV4U2hhZGVyID0gcmVzdWx0LmNvbXBpbGVkXG4gICAgICAgICAgdmVydGV4U2hhZGVyVW5jb21waWxlZCA9IHJlc3VsdC51bmNvbXBpbGVkXG4gICAgICAgICAgc2hhZGVyQ2FjaGVbc2hhZGVyTGliLmhhc2godmVydGV4U2hhZGVyVW5jb21waWxlZCldID0gdmVydGV4U2hhZGVyXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gY29tcGlsZUZyYWdtZW50U2hhZGVyKCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBjb21waWxlU2hhZGVyKCdmcmFnbWVudCcsIGN1cnJlbnRTdGF0ZS5mcmFnbWVudFNoYWRlcilcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIGZyYWdtZW50U2hhZGVyID0gcmVzdWx0LmNvbXBpbGVkXG4gICAgICAgICAgZnJhZ21lbnRTaGFkZXJVbmNvbXBpbGVkID0gcmVzdWx0LnVuY29tcGlsZWRcbiAgICAgICAgICBzaGFkZXJDYWNoZVtzaGFkZXJMaWIuaGFzaChmcmFnbWVudFNoYWRlclVuY29tcGlsZWQpXSA9IGZyYWdtZW50U2hhZGVyXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRWaWFibGVTaGFkZXIocmVnbENvbnRleHQsIGN1cnJlbnRTdGF0ZSwgc2hhZGVyKSB7XG4gICAgICBjb25zdCB7ZGVmaW5lc30gPSBzaGFkZXJMaWJcbiAgICAgIGlmICgnc3RyaW5nJyA9PSB0eXBlb2Ygc2hhZGVyKSB7XG4gICAgICAgIHJldHVybiBpbmplY3REZWZpbmVzKHNoYWRlciwgZGVmaW5lcylcbiAgICAgIH0gZWxzZSBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2Ygc2hhZGVyKSB7XG4gICAgICAgIHJldHVybiBpbmplY3REZWZpbmVzKHNoYWRlcihyZWdsQ29udGV4dCwgY3VycmVudFN0YXRlKSwgZGVmaW5lcylcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1ZpYWJsZVNoYWRlcihzaGFkZXIpIHtcbiAgICAgIHJldHVybiBbJ3N0cmluZycsICdmdW5jdGlvbiddLmluZGV4T2YodHlwZW9mIHNoYWRlcikgPiAtMVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNob3VsZENvbXBpbGUocmVnbENvbnRleHQsIGN1cnJlbnRTdGF0ZSkge1xuICAgICAgbGV0IG5lZWRzQ29tcGlsZSA9IGZhbHNlXG4gICAgICBjaGVjaygnZnVuY3Rpb24nICE9IHR5cGVvZiBpbmplY3RDb250ZXh0KVxuICAgICAgY2hlY2tTaGFkZXIodmVydGV4U2hhZGVyVW5jb21waWxlZCwgY3VycmVudFN0YXRlLnZlcnRleFNoYWRlcilcbiAgICAgIGNoZWNrU2hhZGVyKGZyYWdtZW50U2hhZGVyVW5jb21waWxlZCwgY3VycmVudFN0YXRlLmZyYWdtZW50U2hhZGVyKVxuICAgICAgcmV0dXJuIG5lZWRzQ29tcGlsZVxuXG4gICAgICBmdW5jdGlvbiBjaGVjayhjb25kKSB7XG4gICAgICAgIGlmIChjb25kKSB7IG5lZWRzQ29tcGlsZSA9IHRydWUgfVxuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBjaGVja1NoYWRlcihjdXJyZW50LCBuZXh0KSB7XG4gICAgICAgIGxldCBjb25kID0gZmFsc2VcbiAgICAgICAgbmV4dCA9IGdldFZpYWJsZVNoYWRlcihyZWdsQ29udGV4dCwgY3VycmVudFN0YXRlLCBuZXh0KVxuICAgICAgICBpZiAoc2hhZGVyQ2FjaGVbc2hhZGVyTGliLmhhc2gobmV4dCldKSB7XG4gICAgICAgICAgcmV0dXJuIGNoZWNrKHRydWUpXG4gICAgICAgIH0gZWxzZSBpZiAoJ3N0cmluZycgIT0gdHlwZW9mIGN1cnJlbnQgJiYgbmV4dCkge1xuICAgICAgICAgIHJldHVybiBjaGVjayh0cnVlKVxuICAgICAgICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBuZXh0ICYmIGN1cnJlbnQgIT0gbmV4dCkge1xuICAgICAgICAgIHJldHVybiBjaGVjayh0cnVlKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
\No newline at end of file