element-resize-detector
Advanced tools
Comparing version 0.2.5 to 0.2.8
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.elementResizeDetectorMaker = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
"use strict"; | ||
var utils = require("./utils"); | ||
module.exports = function batchUpdaterMaker(options) { | ||
options = options || {}; | ||
var reporter = options.reporter; | ||
var async = utils.getOption(options, "async", true); | ||
var autoUpdate = utils.getOption(options, "auto", true); | ||
if(autoUpdate && !async) { | ||
reporter.warn("Invalid options combination. auto=true and async=false is invalid. Setting async=true."); | ||
async = true; | ||
} | ||
if(!reporter) { | ||
throw new Error("Reporter required."); | ||
} | ||
var batchSize = 0; | ||
var batch = {}; | ||
var handler; | ||
function queueUpdate(element, updater) { | ||
if(autoUpdate && async && batchSize === 0) { | ||
updateBatchAsync(); | ||
} | ||
if(!batch[element]) { | ||
batch[element] = []; | ||
} | ||
batch[element].push(updater); | ||
batchSize++; | ||
} | ||
function forceUpdateBatch(updateAsync) { | ||
if(updateAsync === undefined) { | ||
updateAsync = async; | ||
} | ||
if(handler) { | ||
cancelFrame(handler); | ||
handler = null; | ||
} | ||
if(async) { | ||
updateBatchAsync(); | ||
} else { | ||
updateBatch(); | ||
} | ||
} | ||
function updateBatch() { | ||
for(var element in batch) { | ||
if(batch.hasOwnProperty(element)) { | ||
var updaters = batch[element]; | ||
for(var i = 0; i < updaters.length; i++) { | ||
var updater = updaters[i]; | ||
updater(); | ||
} | ||
} | ||
} | ||
clearBatch(); | ||
} | ||
function updateBatchAsync() { | ||
handler = requestFrame(function performUpdate() { | ||
updateBatch(); | ||
}); | ||
} | ||
function clearBatch() { | ||
batchSize = 0; | ||
batch = {}; | ||
} | ||
function cancelFrame(listener) { | ||
// var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout; | ||
var cancel = window.clearTimeout; | ||
return cancel(listener); | ||
} | ||
function requestFrame(callback) { | ||
// var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(fn) { return window.setTimeout(fn, 20); }; | ||
var raf = function(fn) { return window.setTimeout(fn, 0); }; | ||
return raf(callback); | ||
} | ||
return { | ||
update: queueUpdate, | ||
force: forceUpdateBatch | ||
}; | ||
}; | ||
},{"./utils":2}],2:[function(require,module,exports){ | ||
"use strict"; | ||
var utils = module.exports = {}; | ||
utils.getOption = getOption; | ||
function getOption(options, name, defaultValue) { | ||
var value = options[name]; | ||
if((value === undefined || value === null) && defaultValue !== undefined) { | ||
return defaultValue; | ||
} | ||
return value; | ||
} | ||
},{}],3:[function(require,module,exports){ | ||
"use strict"; | ||
var detector = module.exports = {}; | ||
@@ -38,3 +152,3 @@ | ||
},{}],2:[function(require,module,exports){ | ||
},{}],4:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -60,3 +174,3 @@ | ||
},{}],3:[function(require,module,exports){ | ||
},{}],5:[function(require,module,exports){ | ||
//Heavily inspired by http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/ | ||
@@ -72,2 +186,3 @@ | ||
var reporterMaker = require("./reporter"); | ||
var batchUpdater = require("batch-updater"); | ||
@@ -102,6 +217,2 @@ /** | ||
//Options to be used as default for the listenTo function. | ||
var globalOptions = {}; | ||
globalOptions.callOnAdd = !!getOption(options, "callOnAdd", true); | ||
//idHandler is currently not an option to the listenTo function, so it should not be added to globalOptions. | ||
@@ -125,2 +236,7 @@ var idHandler = options.idHandler; | ||
//Options to be used as default for the listenTo function. | ||
var globalOptions = {}; | ||
globalOptions.callOnAdd = !!getOption(options, "callOnAdd", true); | ||
globalOptions.batchUpdater = getOption(options, "batchUpdater", batchUpdater({ reporter: reporter })); | ||
var eventListenerHandler = listenerHandlerMaker(idHandler); | ||
@@ -172,27 +288,11 @@ var elementUtils = elementUtilsMaker(idHandler); | ||
var callOnAdd = getOption(options, "callOnAdd", globalOptions.callOnAdd); | ||
var callOnAdd = getOption(options, "callOnAdd", globalOptions.callOnAdd); | ||
var batchUpdater = getOption(options, "batchUpdater", globalOptions.batchUpdater); | ||
forEach(elements, function attachListenerToElement(element) { | ||
//The element may change size directly after the call to listenTo, which would be unable to detect it because | ||
//the async adding of the object. By checking the size before and after, the size change can still be detected | ||
//and the listener can be called accordingly. | ||
var preWidth = element.offsetWidth; | ||
var preHeight = element.offsetHeight; | ||
if(!elementUtils.isDetectable(element)) { | ||
//The element is not prepared to be detectable, so do prepare it and add a listener to it. | ||
return elementUtils.makeDetectable(reporter, element, function onElementDetectable(element) { | ||
return elementUtils.makeDetectable(batchUpdater, reporter, element, function onElementDetectable(element) { | ||
elementUtils.addListener(element, onResizeCallback); | ||
onElementReadyToAddListener(callOnAdd, element, listener); | ||
//Only here the uncaught resize may occur (since this code is async). | ||
//Check if the size is the same as when adding the listener. | ||
var postWidth = element.offsetWidth; | ||
var postHeight = element.offsetHeight; | ||
//If callOnAdd is true, then the listener will have been called either way, so no need to call the listener manually then. | ||
if(!callOnAdd && (preWidth !== postWidth || preHeight !== postHeight)) { | ||
//The element was changed while the object was being added. Call the listener. | ||
listener(element); | ||
} | ||
}); | ||
@@ -221,3 +321,3 @@ } | ||
},{"./collection-utils":2,"./element-utils":4,"./id-generator":5,"./id-handler":6,"./listener-handler":7,"./reporter":8}],4:[function(require,module,exports){ | ||
},{"./collection-utils":4,"./element-utils":6,"./id-generator":7,"./id-handler":8,"./listener-handler":9,"./reporter":10,"batch-updater":1}],6:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -275,3 +375,3 @@ | ||
*/ | ||
function makeDetectable(reporter, element, callback) { | ||
function makeDetectable(batchUpdater, reporter, element, callback) { | ||
function injectObject(id, element, callback) { | ||
@@ -298,4 +398,8 @@ var OBJECT_STYLE = "display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;"; | ||
//Mutating the object element here seems to fire another load event. | ||
//Mutating the inner document of the object element is fine though. | ||
var objectElement = this; | ||
//Create the style element to be added to the object. | ||
getDocument(this, function onObjectDocumentReady(objectDocument) { | ||
getDocument(objectElement, function onObjectDocumentReady(objectDocument) { | ||
var style = objectDocument.createElement("style"); | ||
@@ -309,5 +413,2 @@ style.innerHTML = "html, body { margin: 0; padding: 0 } div { -webkit-transition: opacity 0.01s; -ms-transition: opacity 0.01s; -o-transition: opacity 0.01s; transition: opacity 0.01s; opacity: 0; }"; | ||
//TODO: Is this needed here? | ||
//this.style.cssText = OBJECT_STYLE; | ||
//Notify that the element is ready to be listened to. | ||
@@ -320,49 +421,59 @@ callback(element); | ||
var style = getComputedStyle(element); | ||
if(style.position === "static") { | ||
element.style.position = "relative"; | ||
var position = style.position; | ||
var removeRelativeStyles = function(reporter, element, style, property) { | ||
function getNumericalValue(value) { | ||
return value.replace(/[^-\d\.]/g, ""); | ||
} | ||
function mutateDom() { | ||
if(position === "static") { | ||
element.style.position = "relative"; | ||
var value = style[property]; | ||
var removeRelativeStyles = function(reporter, element, style, property) { | ||
function getNumericalValue(value) { | ||
return value.replace(/[^-\d\.]/g, ""); | ||
} | ||
if(value !== "auto" && getNumericalValue(value) !== "0") { | ||
reporter.warn("An element that is positioned static has style." + property + "=" + value + " which is ignored due to the static positioning. The element will need to be positioned relative, so the style." + property + " will be set to 0. Element: ", element); | ||
element.style[property] = 0; | ||
} | ||
}; | ||
var value = style[property]; | ||
//Check so that there are no accidental styles that will make the element styled differently now that is is relative. | ||
//If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway). | ||
removeRelativeStyles(reporter, element, style, "top"); | ||
removeRelativeStyles(reporter, element, style, "right"); | ||
removeRelativeStyles(reporter, element, style, "bottom"); | ||
removeRelativeStyles(reporter, element, style, "left"); | ||
} | ||
if(value !== "auto" && getNumericalValue(value) !== "0") { | ||
reporter.warn("An element that is positioned static has style." + property + "=" + value + " which is ignored due to the static positioning. The element will need to be positioned relative, so the style." + property + " will be set to 0. Element: ", element); | ||
element.style[property] = 0; | ||
} | ||
}; | ||
//Add an object element as a child to the target element that will be listened to for resize events. | ||
var object = document.createElement("object"); | ||
object.type = "text/html"; | ||
object.style.cssText = OBJECT_STYLE; | ||
object.onload = onObjectLoad; | ||
object._erdObjectId = id; | ||
//Check so that there are no accidental styles that will make the element styled differently now that is is relative. | ||
//If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway). | ||
removeRelativeStyles(reporter, element, style, "top"); | ||
removeRelativeStyles(reporter, element, style, "right"); | ||
removeRelativeStyles(reporter, element, style, "bottom"); | ||
removeRelativeStyles(reporter, element, style, "left"); | ||
} | ||
//Safari: This must occur before adding the object to the DOM. | ||
//IE: Does not like that this happens before, even if it is also added after. | ||
if(!browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
//Add an object element as a child to the target element that will be listened to for resize events. | ||
var object = document.createElement("object"); | ||
object.style.cssText = OBJECT_STYLE; | ||
object.type = "text/html"; | ||
object.onload = onObjectLoad; | ||
object._erdObjectId = id; | ||
element.appendChild(object); | ||
//Safari: This must occur before adding the object to the DOM. | ||
//IE: Does not like that this happens before, even if it is also added after. | ||
if(!browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
//IE: This must occur after adding the object to the DOM. | ||
if(browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
element.appendChild(object); | ||
//IE: This must occur after adding the object to the DOM. | ||
if(browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
} | ||
if(batchUpdater) { | ||
batchUpdater.update(id, mutateDom); | ||
} else { | ||
mutateDom(); | ||
} | ||
} | ||
//Create an unique erd-target-id for the target element, so that event listeners can be identified to this element. | ||
var id = idHandler.set(element); | ||
//Obtain the id of the element (will be generated if not present), so that event listeners can be identified to this element. | ||
var id = idHandler.get(element); | ||
@@ -400,3 +511,3 @@ if(browserDetector.isIE(8)) { | ||
},{"./browser-detector":1,"./collection-utils":2}],5:[function(require,module,exports){ | ||
},{"./browser-detector":3,"./collection-utils":4}],7:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -421,3 +532,3 @@ | ||
},{}],6:[function(require,module,exports){ | ||
},{}],8:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -429,23 +540,18 @@ | ||
/** | ||
* Gets the resize detector id of the element. | ||
* Gets the resize detector id of the element. If the element does not have an id, one will be assigned to the element. | ||
* @public | ||
* @param {element} The target element to get the id of. | ||
* @param {element} element The target element to get the id of. | ||
* @param {boolean?} readonly An id will not be assigned to the element if the readonly parameter is true. Default is false. | ||
* @returns {string|number} The id of the element. | ||
*/ | ||
function getId(element) { | ||
function getId(element, readonly) { | ||
if(!readonly && !hasId(element)) { | ||
setId(element); | ||
} | ||
return element[ID_PROP_NAME]; | ||
} | ||
/** | ||
* Sets the resize detector id of the element. | ||
* @public | ||
* @param {element} The target element to set the id to. | ||
* @param {string?} An optional id to set to the element. If not specified, an id will be generated. All id's must be unique. | ||
* @returns {string|number} The id of the element. | ||
*/ | ||
function setId(element, id) { | ||
if(!id && id !== 0) { | ||
//Number should be generated. | ||
id = idGenerator.generate(); | ||
} | ||
function setId(element) { | ||
var id = idGenerator.generate(); | ||
@@ -457,9 +563,12 @@ element[ID_PROP_NAME] = id; | ||
function hasId(element) { | ||
return element[ID_PROP_NAME] !== undefined; | ||
} | ||
return { | ||
get: getId, | ||
set: setId | ||
get: getId | ||
}; | ||
}; | ||
},{}],7:[function(require,module,exports){ | ||
},{}],9:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -502,3 +611,3 @@ | ||
},{}],8:[function(require,module,exports){ | ||
},{}],10:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -540,4 +649,4 @@ | ||
}; | ||
},{}]},{},[3])(3) | ||
},{}]},{},[5])(5) | ||
}); | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9ncnVudC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYnJvd3Nlci1kZXRlY3Rvci5qcyIsInNyYy9jb2xsZWN0aW9uLXV0aWxzLmpzIiwic3JjL2VsZW1lbnQtcmVzaXplLWRldGVjdG9yLmpzIiwic3JjL2VsZW1lbnQtdXRpbHMuanMiLCJzcmMvaWQtZ2VuZXJhdG9yLmpzIiwic3JjL2lkLWhhbmRsZXIuanMiLCJzcmMvbGlzdGVuZXItaGFuZGxlci5qcyIsInNyYy9yZXBvcnRlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGRldGVjdG9yID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuZGV0ZWN0b3IuaXNJRSA9IGZ1bmN0aW9uKHZlcnNpb24pIHtcbiAgICBmdW5jdGlvbiBpc0FueUllVmVyc2lvbigpIHtcbiAgICAgICAgdmFyIGFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICByZXR1cm4gYWdlbnQuaW5kZXhPZihcIm1zaWVcIikgIT09IC0xIHx8IGFnZW50LmluZGV4T2YoXCJ0cmlkZW50XCIpICE9PSAtMTtcbiAgICB9XG5cbiAgICBpZighaXNBbnlJZVZlcnNpb24oKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYoIXZlcnNpb24pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy9TaGFtZWxlc3NseSBzdG9sZW4gZnJvbSBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9wYWRvbHNleS81Mjc2ODNcbiAgICB2YXIgaWVWZXJzaW9uID0gKGZ1bmN0aW9uKCl7XG4gICAgICAgIHZhciB1bmRlZixcbiAgICAgICAgICAgIHYgPSAzLFxuICAgICAgICAgICAgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSxcbiAgICAgICAgICAgIGFsbCA9IGRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZShcImlcIik7XG5cbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgZGl2LmlubmVySFRNTCA9IFwiPCEtLVtpZiBndCBJRSBcIiArICgrK3YpICsgXCJdPjxpPjwvaT48IVtlbmRpZl0tLT5cIjtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoYWxsWzBdKTtcblxuICAgICAgICByZXR1cm4gdiA+IDQgPyB2IDogdW5kZWY7XG4gICAgfSgpKTtcblxuICAgIHJldHVybiB2ZXJzaW9uID09PSBpZVZlcnNpb247XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciB1dGlscyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8qKlxuICogTG9vcHMgdGhyb3VnaCB0aGUgY29sbGVjdGlvbiBhbmQgY2FsbHMgdGhlIGNhbGxiYWNrIGZvciBlYWNoIGVsZW1lbnQuIGlmIHRoZSBjYWxsYmFjayByZXR1cm5zIHRydXRoeSwgdGhlIGxvb3AgaXMgYnJva2VuIGFuZCByZXR1cm5zIHRoZSBzYW1lIHZhbHVlLlxuICogQHB1YmxpY1xuICogQHBhcmFtIHsqfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGxvb3AgdGhyb3VnaC4gTmVlZHMgdG8gaGF2ZSBhIGxlbmd0aCBwcm9wZXJ0eSBzZXQgYW5kIGhhdmUgaW5kaWNlcyBzZXQgZnJvbSAwIHRvIGxlbmd0aCAtIDEuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIGZvciBlYWNoIGVsZW1lbnQuIFRoZSBlbGVtZW50IHdpbGwgYmUgZ2l2ZW4gYXMgYSBwYXJhbWV0ZXIgdG8gdGhlIGNhbGxiYWNrLiBJZiB0aGlzIGNhbGxiYWNrIHJldHVybnMgdHJ1dGh5LCB0aGUgbG9vcCBpcyBicm9rZW4gYW5kIHRoZSBzYW1lIHZhbHVlIGlzIHJldHVybmVkLlxuICogQHJldHVybnMgeyp9IFRoZSB2YWx1ZSB0aGF0IGEgY2FsbGJhY2sgaGFzIHJldHVybmVkIChpZiB0cnV0aHkpLiBPdGhlcndpc2Ugbm90aGluZy5cbiAqL1xudXRpbHMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGNhbGxiYWNrKSB7XG4gICAgZm9yKHZhciBpID0gMDsgaSA8IGNvbGxlY3Rpb24ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGNhbGxiYWNrKGNvbGxlY3Rpb25baV0pO1xuICAgICAgICBpZihyZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9XG59O1xuIiwiLy9IZWF2aWx5IGluc3BpcmVkIGJ5IGh0dHA6Ly93d3cuYmFja2FsbGV5Y29kZXIuY29tLzIwMTMvMDMvMTgvY3Jvc3MtYnJvd3Nlci1ldmVudC1iYXNlZC1lbGVtZW50LXJlc2l6ZS1kZXRlY3Rpb24vXG5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoXCIuL2NvbGxlY3Rpb24tdXRpbHNcIikuZm9yRWFjaDtcbnZhciBlbGVtZW50VXRpbHNNYWtlciA9IHJlcXVpcmUoXCIuL2VsZW1lbnQtdXRpbHNcIik7XG52YXIgbGlzdGVuZXJIYW5kbGVyTWFrZXIgPSByZXF1aXJlKFwiLi9saXN0ZW5lci1oYW5kbGVyXCIpO1xudmFyIGlkR2VuZXJhdG9yTWFrZXIgPSByZXF1aXJlKFwiLi9pZC1nZW5lcmF0b3JcIik7XG52YXIgaWRIYW5kbGVyTWFrZXIgPSByZXF1aXJlKFwiLi9pZC1oYW5kbGVyXCIpO1xudmFyIHJlcG9ydGVyTWFrZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKTtcblxuLyoqXG4gKiBAdHlwZWRlZiBpZEhhbmRsZXJcbiAqIEB0eXBlIHtvYmplY3R9XG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBnZXQgR2V0cyB0aGUgcmVzaXplIGRldGVjdG9yIGlkIG9mIHRoZSBlbGVtZW50LlxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gc2V0IEdlbmVyYXRlIGFuZCBzZXRzIHRoZSByZXNpemUgZGV0ZWN0b3IgaWQgb2YgdGhlIGVsZW1lbnQuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBPcHRpb25zXG4gKiBAdHlwZSB7b2JqZWN0fVxuICogQHByb3BlcnR5IHtib29sZWFufSBjYWxsT25BZGQgICAgRGV0ZXJtaW5lcyBpZiBsaXN0ZW5lcnMgc2hvdWxkIGJlIGNhbGxlZCB3aGVuIHRoZXkgYXJlIGdldHRpbmcgYWRkZWQuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCBpcyB0cnVlLiBJZiB0cnVlLCB0aGUgbGlzdGVuZXIgaXMgZ3VhcmFudGVlZCB0byBiZSBjYWxsZWQgd2hlbiBpdCBoYXMgYmVlbiBhZGRlZC4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZiBmYWxzZSwgdGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGd1YXJlbnRlZWQgdG8gYmUgY2FsbGVkIHdoZW4gaXQgaGFzIGJlZW4gYWRkZWQgKGRvZXMgbm90IHByZXZlbnQgaXQgZnJvbSBiZWluZyBjYWxsZWQpLlxuICogQHByb3BlcnR5IHtpZEhhbmRsZXJ9IGlkSGFuZGxlciAgQSBjdXN0b20gaWQgaGFuZGxlciB0aGF0IGlzIHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nLCBzZXR0aW5nIGFuZCByZXRyaWV2aW5nIGlkJ3MgZm9yIGVsZW1lbnRzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYgbm90IHByb3ZpZGVkLCBhIGRlZmF1bHQgaWQgaGFuZGxlciB3aWxsIGJlIHVzZWQuXG4gKiBAcHJvcGVydHkge3JlcG9ydGVyfSByZXBvcnRlciAgICBBIGN1c3RvbSByZXBvcnRlciB0aGF0IGhhbmRsZXMgcmVwb3J0aW5nIGxvZ3MsIHdhcm5pbmdzIGFuZCBlcnJvcnMuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYgbm90IHByb3ZpZGVkLCBhIGRlZmF1bHQgaWQgaGFuZGxlciB3aWxsIGJlIHVzZWQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZiBzZXQgdG8gZmFsc2UsIHRoZW4gbm90aGluZyB3aWxsIGJlIHJlcG9ydGVkLlxuICovXG5cbi8qKlxuICogQ3JlYXRlcyBhbiBlbGVtZW50IHJlc2l6ZSBkZXRlY3RvciBpbnN0YW5jZS5cbiAqIEBwdWJsaWNcbiAqIEBwYXJhbSB7T3B0aW9ucz99IG9wdGlvbnMgT3B0aW9uYWwgZ2xvYmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgd2lsbCBkZWNpZGUgaG93IHRoaXMgaW5zdGFuY2Ugd2lsbCB3b3JrLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgIC8vT3B0aW9ucyB0byBiZSB1c2VkIGFzIGRlZmF1bHQgZm9yIHRoZSBsaXN0ZW5UbyBmdW5jdGlvbi5cbiAgICB2YXIgZ2xvYmFsT3B0aW9ucyA9IHt9O1xuICAgIGdsb2JhbE9wdGlvbnMuY2FsbE9uQWRkID0gISFnZXRPcHRpb24ob3B0aW9ucywgXCJjYWxsT25BZGRcIiwgdHJ1ZSk7XG5cbiAgICAvL2lkSGFuZGxlciBpcyBjdXJyZW50bHkgbm90IGFuIG9wdGlvbiB0byB0aGUgbGlzdGVuVG8gZnVuY3Rpb24sIHNvIGl0IHNob3VsZCBub3QgYmUgYWRkZWQgdG8gZ2xvYmFsT3B0aW9ucy5cbiAgICB2YXIgaWRIYW5kbGVyID0gb3B0aW9ucy5pZEhhbmRsZXI7XG5cbiAgICBpZighaWRIYW5kbGVyKSB7XG4gICAgICAgIHZhciBpZEdlbmVyYXRvciA9IGlkR2VuZXJhdG9yTWFrZXIoKTtcbiAgICAgICAgdmFyIGRlZmF1bHRJZEhhbmRsZXIgPSBpZEhhbmRsZXJNYWtlcihpZEdlbmVyYXRvcik7XG4gICAgICAgIGlkSGFuZGxlciA9IGRlZmF1bHRJZEhhbmRsZXI7XG4gICAgfVxuXG4gICAgLy9yZXBvcnRlciBpcyBjdXJyZW50bHkgbm90IGFuIG9wdGlvbiB0byB0aGUgbGlzdGVuVG8gZnVuY3Rpb24sIHNvIGl0IHNob3VsZCBub3QgYmUgYWRkZWQgdG8gZ2xvYmFsT3B0aW9ucy5cbiAgICB2YXIgcmVwb3J0ZXIgPSBvcHRpb25zLnJlcG9ydGVyO1xuXG4gICAgaWYoIXJlcG9ydGVyKSB7XG4gICAgICAgIC8vSWYgb3B0aW9ucy5yZXBvcnRlciBpcyBmYWxzZSwgdGhlbiB0aGUgcmVwb3J0ZXIgc2hvdWxkIGJlIHF1aWV0LlxuICAgICAgICB2YXIgcXVpZXQgPSByZXBvcnRlciA9PT0gZmFsc2U7XG4gICAgICAgIHJlcG9ydGVyID0gcmVwb3J0ZXJNYWtlcihxdWlldCk7XG4gICAgfVxuXG4gICAgdmFyIGV2ZW50TGlzdGVuZXJIYW5kbGVyID0gbGlzdGVuZXJIYW5kbGVyTWFrZXIoaWRIYW5kbGVyKTtcbiAgICB2YXIgZWxlbWVudFV0aWxzID0gZWxlbWVudFV0aWxzTWFrZXIoaWRIYW5kbGVyKTtcblxuICAgIC8qKlxuICAgICAqIE1ha2VzIHRoZSBnaXZlbiBlbGVtZW50cyByZXNpemUtZGV0ZWN0YWJsZSBhbmQgc3RhcnRzIGxpc3RlbmluZyB0byByZXNpemUgZXZlbnRzIG9uIHRoZSBlbGVtZW50cy4gQ2FsbHMgdGhlIGV2ZW50IGNhbGxiYWNrIGZvciBlYWNoIGV2ZW50IGZvciBlYWNoIGVsZW1lbnQuXG4gICAgICogQHB1YmxpY1xuICAgICAqIEBwYXJhbSB7T3B0aW9ucz99IG9wdGlvbnMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QuIFRoZXNlIG9wdGlvbnMgd2lsbCBvdmVycmlkZSB0aGUgZ2xvYmFsIG9wdGlvbnMuIFNvbWUgb3B0aW9ucyBtYXkgbm90IGJlIG92ZXJyaWRlbiwgc3VjaCBhcyBpZEhhbmRsZXIuXG4gICAgICogQHBhcmFtIHtlbGVtZW50W118ZWxlbWVudH0gZWxlbWVudHMgVGhlIGdpdmVuIGFycmF5IG9mIGVsZW1lbnRzIHRvIGRldGVjdCByZXNpemUgZXZlbnRzIG9mLiBTaW5nbGUgZWxlbWVudCBpcyBhbHNvIHZhbGlkLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIFRoZSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCBmb3IgZWFjaCByZXNpemUgZXZlbnQgZm9yIGVhY2ggZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0ZW5UbyhvcHRpb25zLCBlbGVtZW50cywgbGlzdGVuZXIpIHtcbiAgICAgICAgZnVuY3Rpb24gb25SZXNpemVDYWxsYmFjayhlbGVtZW50KSB7XG4gICAgICAgICAgICB2YXIgbGlzdGVuZXJzID0gZXZlbnRMaXN0ZW5lckhhbmRsZXIuZ2V0KGVsZW1lbnQpO1xuXG4gICAgICAgICAgICBmb3JFYWNoKGxpc3RlbmVycywgZnVuY3Rpb24gY2FsbExpc3RlbmVyUHJveHkobGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcihlbGVtZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gb25FbGVtZW50UmVhZHlUb0FkZExpc3RlbmVyKGNhbGxPbkFkZCwgZWxlbWVudCwgbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGV2ZW50TGlzdGVuZXJIYW5kbGVyLmFkZChlbGVtZW50LCBsaXN0ZW5lcik7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmKGNhbGxPbkFkZCkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy9PcHRpb25zIG9iamVjdCBtYXkgYmUgb21pdHRlZC5cbiAgICAgICAgaWYoIWxpc3RlbmVyKSB7XG4gICAgICAgICAgICBsaXN0ZW5lciA9IGVsZW1lbnRzO1xuICAgICAgICAgICAgZWxlbWVudHMgPSBvcHRpb25zO1xuICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoIWVsZW1lbnRzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBdCBsZWFzdCBvbmUgZWxlbWVudCByZXF1aXJlZC5cIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZighbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkxpc3RlbmVyIHJlcXVpcmVkLlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKGVsZW1lbnRzLmxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBlbGVtZW50cyA9IFtlbGVtZW50c107XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2FsbE9uQWRkID0gZ2V0T3B0aW9uKG9wdGlvbnMsIFwiY2FsbE9uQWRkXCIsIGdsb2JhbE9wdGlvbnMuY2FsbE9uQWRkKTtcblxuICAgICAgICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiBhdHRhY2hMaXN0ZW5lclRvRWxlbWVudChlbGVtZW50KSB7XG4gICAgICAgICAgICAvL1RoZSBlbGVtZW50IG1heSBjaGFuZ2Ugc2l6ZSBkaXJlY3RseSBhZnRlciB0aGUgY2FsbCB0byBsaXN0ZW5Ubywgd2hpY2ggd291bGQgYmUgdW5hYmxlIHRvIGRldGVjdCBpdCBiZWNhdXNlXG4gICAgICAgICAgICAvL3RoZSBhc3luYyBhZGRpbmcgb2YgdGhlIG9iamVjdC4gQnkgY2hlY2tpbmcgdGhlIHNpemUgYmVmb3JlIGFuZCBhZnRlciwgdGhlIHNpemUgY2hhbmdlIGNhbiBzdGlsbCBiZSBkZXRlY3RlZFxuICAgICAgICAgICAgLy9hbmQgdGhlIGxpc3RlbmVyIGNhbiBiZSBjYWxsZWQgYWNjb3JkaW5nbHkuXG4gICAgICAgICAgICB2YXIgcHJlV2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgdmFyIHByZUhlaWdodCA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICAgICAgICBpZighZWxlbWVudFV0aWxzLmlzRGV0ZWN0YWJsZShlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIC8vVGhlIGVsZW1lbnQgaXMgbm90IHByZXBhcmVkIHRvIGJlIGRldGVjdGFibGUsIHNvIGRvIHByZXBhcmUgaXQgYW5kIGFkZCBhIGxpc3RlbmVyIHRvIGl0LlxuICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50VXRpbHMubWFrZURldGVjdGFibGUocmVwb3J0ZXIsIGVsZW1lbnQsIGZ1bmN0aW9uIG9uRWxlbWVudERldGVjdGFibGUoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50VXRpbHMuYWRkTGlzdGVuZXIoZWxlbWVudCwgb25SZXNpemVDYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgICAgIG9uRWxlbWVudFJlYWR5VG9BZGRMaXN0ZW5lcihjYWxsT25BZGQsIGVsZW1lbnQsIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgICAgICAvL09ubHkgaGVyZSB0aGUgdW5jYXVnaHQgcmVzaXplIG1heSBvY2N1ciAoc2luY2UgdGhpcyBjb2RlIGlzIGFzeW5jKS5cbiAgICAgICAgICAgICAgICAgICAgLy9DaGVjayBpZiB0aGUgc2l6ZSBpcyB0aGUgc2FtZSBhcyB3aGVuIGFkZGluZyB0aGUgbGlzdGVuZXIuXG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3N0V2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zdEhlaWdodCA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICAgICAgICAgICAgICAgIC8vSWYgY2FsbE9uQWRkIGlzIHRydWUsIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgaGF2ZSBiZWVuIGNhbGxlZCBlaXRoZXIgd2F5LCBzbyBubyBuZWVkIHRvIGNhbGwgdGhlIGxpc3RlbmVyIG1hbnVhbGx5IHRoZW4uXG4gICAgICAgICAgICAgICAgICAgIGlmKCFjYWxsT25BZGQgJiYgKHByZVdpZHRoICE9PSBwb3N0V2lkdGggfHwgcHJlSGVpZ2h0ICE9PSBwb3N0SGVpZ2h0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy9UaGUgZWxlbWVudCB3YXMgY2hhbmdlZCB3aGlsZSB0aGUgb2JqZWN0IHdhcyBiZWluZyBhZGRlZC4gQ2FsbCB0aGUgbGlzdGVuZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcihlbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICAvL1RoZSBlbGVtZW50IGhhcyBiZWVuIHByZXBhcmVkIHRvIGJlIGRldGVjdGFibGUgYW5kIGlzIHJlYWR5IHRvIGJlIGxpc3RlbmVkIHRvLlxuICAgICAgICAgICAgb25FbGVtZW50UmVhZHlUb0FkZExpc3RlbmVyKGNhbGxPbkFkZCwgZWxlbWVudCwgbGlzdGVuZXIpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBsaXN0ZW5UbzogbGlzdGVuVG9cbiAgICB9O1xufTtcblxuZnVuY3Rpb24gZ2V0T3B0aW9uKG9wdGlvbnMsIG5hbWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHZhciB2YWx1ZSA9IG9wdGlvbnNbbmFtZV07XG5cbiAgICBpZigodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCkgJiYgZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKFwiLi9jb2xsZWN0aW9uLXV0aWxzXCIpLmZvckVhY2g7XG52YXIgYnJvd3NlckRldGVjdG9yID0gcmVxdWlyZShcIi4vYnJvd3Nlci1kZXRlY3RvclwiKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpZEhhbmRsZXIpIHtcbiAgICAvKipcbiAgICAgKiBUZWxscyBpZiB0aGUgZWxlbWVudCBoYXMgYmVlbiBtYWRlIGRldGVjdGFibGUgYW5kIHJlYWR5IHRvIGJlIGxpc3RlbmVkIGZvciByZXNpemUgZXZlbnRzLlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IFRoZSBlbGVtZW50IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIG9yIGZhbHNlIGRlcGVuZGluZyBvbiBpZiB0aGUgZWxlbWVudCBpcyBkZXRlY3RhYmxlIG9yIG5vdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0RldGVjdGFibGUoZWxlbWVudCkge1xuICAgICAgICBpZihicm93c2VyRGV0ZWN0b3IuaXNJRSg4KSkge1xuICAgICAgICAgICAgLy9JRSA4IGRvZXMgbm90IHVzZSB0aGUgb2JqZWN0IG1ldGhvZC5cbiAgICAgICAgICAgIC8vQ2hlY2sgb25seSBpZiB0aGUgZWxlbWVudCBoYXMgYmVlbiBnaXZlbiBhbiBpZC5cbiAgICAgICAgICAgIHJldHVybiAhIWlkSGFuZGxlci5nZXQoZWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gISFnZXRPYmplY3QoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIHJlc2l6ZSBldmVudCBsaXN0ZW5lciB0byB0aGUgZWxlbWVudC5cbiAgICAgKiBAcHVibGljXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRoYXQgc2hvdWxkIGhhdmUgdGhlIGxpc3RlbmVyIGFkZGVkLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBjYWxsYmFjayB0byBiZSBjYWxsZWQgZm9yIGVhY2ggcmVzaXplIGV2ZW50IG9mIHRoZSBlbGVtZW50LiBUaGUgZWxlbWVudCB3aWxsIGJlIGdpdmVuIGFzIGEgcGFyYW1ldGVyIHRvIHRoZSBsaXN0ZW5lciBjYWxsYmFjay5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhZGRMaXN0ZW5lcihlbGVtZW50LCBsaXN0ZW5lcikge1xuICAgICAgICBpZighaXNEZXRlY3RhYmxlKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFbGVtZW50IGlzIG5vdCBkZXRlY3RhYmxlLlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGxpc3RlbmVyUHJveHkoKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcihlbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKGJyb3dzZXJEZXRlY3Rvci5pc0lFKDgpKSB7XG4gICAgICAgICAgICAvL0lFIDggZG9lcyBub3Qgc3VwcG9ydCBvYmplY3QsIGJ1dCBzdXBwb3J0cyB0aGUgcmVzaXplIGV2ZW50IGRpcmVjdGx5IG9uIGVsZW1lbnRzLlxuICAgICAgICAgICAgZWxlbWVudC5hdHRhY2hFdmVudChcIm9ucmVzaXplXCIsIGxpc3RlbmVyUHJveHkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IGdldE9iamVjdChlbGVtZW50KTtcbiAgICAgICAgICAgIG9iamVjdC5jb250ZW50RG9jdW1lbnQuZGVmYXVsdFZpZXcuYWRkRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLCBsaXN0ZW5lclByb3h5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2VzIGFuIGVsZW1lbnQgZGV0ZWN0YWJsZSBhbmQgcmVhZHkgdG8gYmUgbGlzdGVuZWQgZm9yIHJlc2l6ZSBldmVudHMuIFdpbGwgY2FsbCB0aGUgY2FsbGJhY2sgd2hlbiB0aGUgZWxlbWVudCBpcyByZWFkeSB0byBiZSBsaXN0ZW5lZCBmb3IgcmVzaXplIGNoYW5nZXMuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gbWFrZSBkZXRlY3RhYmxlXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBlbGVtZW50IGlzIHJlYWR5IHRvIGJlIGxpc3RlbmVkIGZvciByZXNpemUgY2hhbmdlcy4gV2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgZWxlbWVudCBhcyBmaXJzdCBwYXJhbWV0ZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFrZURldGVjdGFibGUocmVwb3J0ZXIsIGVsZW1lbnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIGZ1bmN0aW9uIGluamVjdE9iamVjdChpZCwgZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBPQkpFQ1RfU1RZTEUgPSBcImRpc3BsYXk6IGJsb2NrOyBwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogMDsgbGVmdDogMDsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsgYm9yZGVyOiBub25lOyBwYWRkaW5nOiAwOyBtYXJnaW46IDA7IG9wYWNpdHk6IDA7IHotaW5kZXg6IC0xMDAwOyBwb2ludGVyLWV2ZW50czogbm9uZTtcIjtcblxuICAgICAgICAgICAgZnVuY3Rpb24gb25PYmplY3RMb2FkKCkge1xuICAgICAgICAgICAgICAgIC8qanNoaW50IHZhbGlkdGhpczogdHJ1ZSAqL1xuXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0RG9jdW1lbnQoZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgLy9PcGVyYSAxMiBzZWVtIHRvIGNhbGwgdGhlIG9iamVjdC5vbmxvYWQgYmVmb3JlIHRoZSBhY3R1YWwgZG9jdW1lbnQgaGFzIGJlZW4gY3JlYXRlZC5cbiAgICAgICAgICAgICAgICAgICAgLy9TbyBpZiBpdCBpcyBub3QgcHJlc2VudCwgcG9sbCBpdCB3aXRoIGFuIHRpbWVvdXQgdW50aWwgaXQgaXMgcHJlc2VudC5cbiAgICAgICAgICAgICAgICAgICAgLy9UT0RPOiBDb3VsZCBtYXliZSBiZSBoYW5kbGVkIGJldHRlciB3aXRoIG9iamVjdC5vbnJlYWR5c3RhdGVjaGFuZ2Ugb3Igc2ltaWxhci5cbiAgICAgICAgICAgICAgICAgICAgaWYoIWVsZW1lbnQuY29udGVudERvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uIGNoZWNrRm9yT2JqZWN0RG9jdW1lbnQoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RG9jdW1lbnQoZWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZWxlbWVudC5jb250ZW50RG9jdW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vQ3JlYXRlIHRoZSBzdHlsZSBlbGVtZW50IHRvIGJlIGFkZGVkIHRvIHRoZSBvYmplY3QuXG4gICAgICAgICAgICAgICAgZ2V0RG9jdW1lbnQodGhpcywgZnVuY3Rpb24gb25PYmplY3REb2N1bWVudFJlYWR5KG9iamVjdERvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHlsZSA9IG9iamVjdERvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGUuaW5uZXJIVE1MID0gXCJodG1sLCBib2R5IHsgbWFyZ2luOiAwOyBwYWRkaW5nOiAwIH0gZGl2IHsgLXdlYmtpdC10cmFuc2l0aW9uOiBvcGFjaXR5IDAuMDFzOyAtbXMtdHJhbnNpdGlvbjogb3BhY2l0eSAwLjAxczsgLW8tdHJhbnNpdGlvbjogb3BhY2l0eSAwLjAxczsgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjAxczsgb3BhY2l0eTogMDsgfVwiO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vVE9ETzogUmVtb3ZlIGFueSBzdHlsZXMgdGhhdCBoYXMgYmVlbiBzZXQgb24gdGhlIG9iamVjdC4gT25seSB0aGUgc3R5bGUgYWJvdmUgc2hvdWxkIGJlIHN0eWxpbmcgdGhlIG9iamVjdC5cblxuICAgICAgICAgICAgICAgICAgICAvL0FwcGVuZCB0aGUgc3R5bGUgdG8gdGhlIG9iamVjdC5cbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0RG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy9UT0RPOiBJcyB0aGlzIG5lZWRlZCBoZXJlP1xuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuc3R5bGUuY3NzVGV4dCA9IE9CSkVDVF9TVFlMRTtcblxuICAgICAgICAgICAgICAgICAgICAvL05vdGlmeSB0aGF0IHRoZSBlbGVtZW50IGlzIHJlYWR5IHRvIGJlIGxpc3RlbmVkIHRvLlxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy9UaGUgdGFyZ2V0IGVsZW1lbnQgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCAoZXZlcnl0aGluZyBleGNlcHQgc3RhdGljKSBzbyB0aGUgYWJzb2x1dGUgcG9zaXRpb25lZCBvYmplY3Qgd2lsbCBiZSBwb3NpdGlvbmVkIHJlbGF0aXZlIHRvIHRoZSB0YXJnZXQgZWxlbWVudC5cbiAgICAgICAgICAgIHZhciBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG4gICAgICAgICAgICBpZihzdHlsZS5wb3NpdGlvbiA9PT0gXCJzdGF0aWNcIikge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG5cbiAgICAgICAgICAgICAgICB2YXIgcmVtb3ZlUmVsYXRpdmVTdHlsZXMgPSBmdW5jdGlvbihyZXBvcnRlciwgZWxlbWVudCwgc3R5bGUsIHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldE51bWVyaWNhbFZhbHVlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUucmVwbGFjZSgvW14tXFxkXFwuXS9nLCBcIlwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHN0eWxlW3Byb3BlcnR5XTtcblxuICAgICAgICAgICAgICAgICAgICBpZih2YWx1ZSAhPT0gXCJhdXRvXCIgJiYgZ2V0TnVtZXJpY2FsVmFsdWUodmFsdWUpICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZXIud2FybihcIkFuIGVsZW1lbnQgdGhhdCBpcyBwb3NpdGlvbmVkIHN0YXRpYyBoYXMgc3R5bGUuXCIgKyBwcm9wZXJ0eSArIFwiPVwiICsgdmFsdWUgKyBcIiB3aGljaCBpcyBpZ25vcmVkIGR1ZSB0byB0aGUgc3RhdGljIHBvc2l0aW9uaW5nLiBUaGUgZWxlbWVudCB3aWxsIG5lZWQgdG8gYmUgcG9zaXRpb25lZCByZWxhdGl2ZSwgc28gdGhlIHN0eWxlLlwiICsgcHJvcGVydHkgKyBcIiB3aWxsIGJlIHNldCB0byAwLiBFbGVtZW50OiBcIiwgZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlW3Byb3BlcnR5XSA9IDA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy9DaGVjayBzbyB0aGF0IHRoZXJlIGFyZSBubyBhY2NpZGVudGFsIHN0eWxlcyB0aGF0IHdpbGwgbWFrZSB0aGUgZWxlbWVudCBzdHlsZWQgZGlmZmVyZW50bHkgbm93IHRoYXQgaXMgaXMgcmVsYXRpdmUuXG4gICAgICAgICAgICAgICAgLy9JZiB0aGVyZSBhcmUgYW55LCBzZXQgdGhlbSB0byAwICh0aGlzIHNob3VsZCBiZSBva2F5IHdpdGggdGhlIHVzZXIgc2luY2UgdGhlIHN0eWxlIHByb3BlcnRpZXMgZGlkIG5vdGhpbmcgYmVmb3JlIFtzaW5jZSB0aGUgZWxlbWVudCB3YXMgcG9zaXRpb25lZCBzdGF0aWNdIGFueXdheSkuXG4gICAgICAgICAgICAgICAgcmVtb3ZlUmVsYXRpdmVTdHlsZXMocmVwb3J0ZXIsIGVsZW1lbnQsIHN0eWxlLCBcInRvcFwiKTtcbiAgICAgICAgICAgICAgICByZW1vdmVSZWxhdGl2ZVN0eWxlcyhyZXBvcnRlciwgZWxlbWVudCwgc3R5bGUsIFwicmlnaHRcIik7XG4gICAgICAgICAgICAgICAgcmVtb3ZlUmVsYXRpdmVTdHlsZXMocmVwb3J0ZXIsIGVsZW1lbnQsIHN0eWxlLCBcImJvdHRvbVwiKTtcbiAgICAgICAgICAgICAgICByZW1vdmVSZWxhdGl2ZVN0eWxlcyhyZXBvcnRlciwgZWxlbWVudCwgc3R5bGUsIFwibGVmdFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy9BZGQgYW4gb2JqZWN0IGVsZW1lbnQgYXMgYSBjaGlsZCB0byB0aGUgdGFyZ2V0IGVsZW1lbnQgdGhhdCB3aWxsIGJlIGxpc3RlbmVkIHRvIGZvciByZXNpemUgZXZlbnRzLlxuICAgICAgICAgICAgdmFyIG9iamVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJvYmplY3RcIik7XG4gICAgICAgICAgICBvYmplY3QudHlwZSA9IFwidGV4dC9odG1sXCI7XG4gICAgICAgICAgICBvYmplY3Quc3R5bGUuY3NzVGV4dCA9IE9CSkVDVF9TVFlMRTtcbiAgICAgICAgICAgIG9iamVjdC5vbmxvYWQgPSBvbk9iamVjdExvYWQ7XG4gICAgICAgICAgICBvYmplY3QuX2VyZE9iamVjdElkID0gaWQ7XG5cbiAgICAgICAgICAgIC8vU2FmYXJpOiBUaGlzIG11c3Qgb2NjdXIgYmVmb3JlIGFkZGluZyB0aGUgb2JqZWN0IHRvIHRoZSBET00uXG4gICAgICAgICAgICAvL0lFOiBEb2VzIG5vdCBsaWtlIHRoYXQgdGhpcyBoYXBwZW5zIGJlZm9yZSwgZXZlbiBpZiBpdCBpcyBhbHNvIGFkZGVkIGFmdGVyLlxuICAgICAgICAgICAgaWYoIWJyb3dzZXJEZXRlY3Rvci5pc0lFKCkpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZGF0YSA9IFwiYWJvdXQ6YmxhbmtcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChvYmplY3QpO1xuXG4gICAgICAgICAgICAvL0lFOiBUaGlzIG11c3Qgb2NjdXIgYWZ0ZXIgYWRkaW5nIHRoZSBvYmplY3QgdG8gdGhlIERPTS5cbiAgICAgICAgICAgIGlmKGJyb3dzZXJEZXRlY3Rvci5pc0lFKCkpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZGF0YSA9IFwiYWJvdXQ6YmxhbmtcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vQ3JlYXRlIGFuIHVuaXF1ZSBlcmQtdGFyZ2V0LWlkIGZvciB0aGUgdGFyZ2V0IGVsZW1lbnQsIHNvIHRoYXQgZXZlbnQgbGlzdGVuZXJzIGNhbiBiZSBpZGVudGlmaWVkIHRvIHRoaXMgZWxlbWVudC5cbiAgICAgICAgdmFyIGlkID0gaWRIYW5kbGVyLnNldChlbGVtZW50KTtcblxuICAgICAgICBpZihicm93c2VyRGV0ZWN0b3IuaXNJRSg4KSkge1xuICAgICAgICAgICAgLy9JRSA4IGRvZXMgbm90IHN1cHBvcnQgb2JqZWN0cyBwcm9wZXJseS4gTHVja2lseSB0aGV5IGRvIHN1cHBvcnQgdGhlIHJlc2l6ZSBldmVudC5cbiAgICAgICAgICAgIC8vU28gZG8gbm90IGluamVjdCB0aGUgb2JqZWN0IGFuZCBub3RpZnkgdGhhdCB0aGUgZWxlbWVudCBpcyBhbHJlYWR5IHJlYWR5IHRvIGJlIGxpc3RlbmVkIHRvLlxuICAgICAgICAgICAgLy9UaGUgZXZlbnQgaGFuZGxlciBmb3IgdGhlIHJlc2l6ZSBldmVudCBpcyBhdHRhY2hlZCBpbiB0aGUgdXRpbHMuYWRkTGlzdGVuZXIgaW5zdGVhZC5cbiAgICAgICAgICAgIGNhbGxiYWNrKGVsZW1lbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5qZWN0T2JqZWN0KGlkLCBlbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZCBvYmplY3Qgb2YgdGhlIHRhcmdldCBlbGVtZW50LlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBlbGVtZW50IFRoZSB0YXJnZXQgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyBUaGUgb2JqZWN0IGVsZW1lbnQgb2YgdGhlIHRhcmdldC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPYmplY3QoZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZm9yRWFjaChlbGVtZW50LmNoaWxkcmVuLCBmdW5jdGlvbiBpc09iamVjdChjaGlsZCkge1xuICAgICAgICAgICAgaWYoY2hpbGQuX2VyZE9iamVjdElkICE9PSB1bmRlZmluZWQgJiYgY2hpbGQuX2VyZE9iamVjdElkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBpc0RldGVjdGFibGU6IGlzRGV0ZWN0YWJsZSxcbiAgICAgICAgbWFrZURldGVjdGFibGU6IG1ha2VEZXRlY3RhYmxlLFxuICAgICAgICBhZGRMaXN0ZW5lcjogYWRkTGlzdGVuZXIsXG4gICAgfTtcbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaWRDb3VudCA9IDE7XG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZXMgYSBuZXcgdW5pcXVlIGlkIGluIHRoZSBjb250ZXh0LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBBIHVuaXF1ZSBpZCBpbiB0aGUgY29udGV4dC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZW5lcmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIGlkQ291bnQrKztcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBnZW5lcmF0ZTogZ2VuZXJhdGVcbiAgICB9O1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGlkR2VuZXJhdG9yKSB7XG4gICAgdmFyIElEX1BST1BfTkFNRSA9IFwiX2VyZFRhcmdldElkXCI7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSByZXNpemUgZGV0ZWN0b3IgaWQgb2YgdGhlIGVsZW1lbnQuXG4gICAgICogQHB1YmxpY1xuICAgICAqIEBwYXJhbSB7ZWxlbWVudH0gVGhlIHRhcmdldCBlbGVtZW50IHRvIGdldCB0aGUgaWQgb2YuXG4gICAgICogQHJldHVybnMge3N0cmluZ3xudW1iZXJ9IFRoZSBpZCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRJZChlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50W0lEX1BST1BfTkFNRV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcmVzaXplIGRldGVjdG9yIGlkIG9mIHRoZSBlbGVtZW50LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IFRoZSB0YXJnZXQgZWxlbWVudCB0byBzZXQgdGhlIGlkIHRvLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nP30gQW4gb3B0aW9uYWwgaWQgdG8gc2V0IHRvIHRoZSBlbGVtZW50LiBJZiBub3Qgc3BlY2lmaWVkLCBhbiBpZCB3aWxsIGJlIGdlbmVyYXRlZC4gQWxsIGlkJ3MgbXVzdCBiZSB1bmlxdWUuXG4gICAgICogQHJldHVybnMge3N0cmluZ3xudW1iZXJ9IFRoZSBpZCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRJZChlbGVtZW50LCBpZCkge1xuICAgICAgICBpZighaWQgJiYgaWQgIT09IDApIHtcbiAgICAgICAgICAgIC8vTnVtYmVyIHNob3VsZCBiZSBnZW5lcmF0ZWQuXG4gICAgICAgICAgICBpZCA9IGlkR2VuZXJhdG9yLmdlbmVyYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBlbGVtZW50W0lEX1BST1BfTkFNRV0gPSBpZDtcblxuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0OiBnZXRJZCxcbiAgICAgICAgc2V0OiBzZXRJZFxuICAgIH07XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaWRIYW5kbGVyKSB7XG4gICAgdmFyIGV2ZW50TGlzdGVuZXJzID0ge307XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gZ2V0IGFsbCBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEByZXR1cm5zIEFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldExpc3RlbmVycyhlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBldmVudExpc3RlbmVyc1tpZEhhbmRsZXIuZ2V0KGVsZW1lbnQpXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdG9yZXMgdGhlIGdpdmVuIGxpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gZWxlbWVudC4gV2lsbCBub3QgYWN0dWFsbHkgYWRkIHRoZSBsaXN0ZW5lciB0byB0aGUgZWxlbWVudC5cbiAgICAgKiBAcHVibGljXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRoYXQgc2hvdWxkIGhhdmUgdGhlIGxpc3RlbmVyIGFkZGVkLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIFRoZSBjYWxsYmFjayB0aGF0IHRoZSBlbGVtZW50IGhhcyBhZGRlZC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhZGRMaXN0ZW5lcihlbGVtZW50LCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaWQgPSBpZEhhbmRsZXIuZ2V0KGVsZW1lbnQpO1xuXG4gICAgICAgIGlmKCFldmVudExpc3RlbmVyc1tpZF0pIHtcbiAgICAgICAgICAgIGV2ZW50TGlzdGVuZXJzW2lkXSA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgZXZlbnRMaXN0ZW5lcnNbaWRdLnB1c2gobGlzdGVuZXIpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGdldDogZ2V0TGlzdGVuZXJzLFxuICAgICAgICBhZGQ6IGFkZExpc3RlbmVyXG4gICAgfTtcbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuLyogZ2xvYmFsIGNvbnNvbGU6IGZhbHNlICovXG5cbi8qKlxuICogUmVwb3J0ZXIgdGhhdCBoYW5kbGVzIHRoZSByZXBvcnRpbmcgb2YgbG9ncywgd2FybmluZ3MgYW5kIGVycm9ycy5cbiAqIEBwdWJsaWNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gcXVpZXQgVGVsbHMgaWYgdGhlIHJlcG9ydGVyIHNob3VsZCBiZSBxdWlldCBvciBub3QuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ocXVpZXQpIHtcbiAgICBmdW5jdGlvbiBub29wKCkge1xuICAgICAgICAvL0RvZXMgbm90aGluZy5cbiAgICB9XG5cbiAgICB2YXIgcmVwb3J0ZXIgPSB7XG4gICAgICAgIGxvZzogbm9vcCxcbiAgICAgICAgd2Fybjogbm9vcCxcbiAgICAgICAgZXJyb3I6IG5vb3BcbiAgICB9O1xuXG4gICAgaWYoIXF1aWV0ICYmIHdpbmRvdy5jb25zb2xlKSB7XG4gICAgICAgIHZhciBhdHRhY2hGdW5jdGlvbiA9IGZ1bmN0aW9uKHJlcG9ydGVyLCBuYW1lKSB7XG4gICAgICAgICAgICAvL1RoZSBwcm94eSBpcyBuZWVkZWQgdG8gYmUgYWJsZSB0byBjYWxsIHRoZSBtZXRob2Qgd2l0aCB0aGUgY29uc29sZSBjb250ZXh0LFxuICAgICAgICAgICAgLy9zaW5jZSB3ZSBjYW5ub3QgdXNlIGJpbmQuXG4gICAgICAgICAgICByZXBvcnRlcltuYW1lXSA9IGZ1bmN0aW9uIHJlcG9ydGVyUHJveHkoKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZVtuYW1lXS5hcHBseShjb25zb2xlLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuICAgICAgICBhdHRhY2hGdW5jdGlvbihyZXBvcnRlciwgXCJsb2dcIik7XG4gICAgICAgIGF0dGFjaEZ1bmN0aW9uKHJlcG9ydGVyLCBcIndhcm5cIik7XG4gICAgICAgIGF0dGFjaEZ1bmN0aW9uKHJlcG9ydGVyLCBcImVycm9yXCIpO1xuICAgIH1cblxuICAgIHJldHVybiByZXBvcnRlcjtcbn07Il19 | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9ncnVudC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYmF0Y2gtdXBkYXRlci9zcmMvYmF0Y2gtdXBkYXRlci5qcyIsIm5vZGVfbW9kdWxlcy9iYXRjaC11cGRhdGVyL3NyYy91dGlscy5qcyIsInNyYy9icm93c2VyLWRldGVjdG9yLmpzIiwic3JjL2NvbGxlY3Rpb24tdXRpbHMuanMiLCJzcmMvZWxlbWVudC1yZXNpemUtZGV0ZWN0b3IuanMiLCJzcmMvZWxlbWVudC11dGlscy5qcyIsInNyYy9pZC1nZW5lcmF0b3IuanMiLCJzcmMvaWQtaGFuZGxlci5qcyIsInNyYy9saXN0ZW5lci1oYW5kbGVyLmpzIiwic3JjL3JlcG9ydGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIHV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYmF0Y2hVcGRhdGVyTWFrZXIob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgdmFyIHJlcG9ydGVyICAgID0gb3B0aW9ucy5yZXBvcnRlcjtcbiAgICB2YXIgYXN5bmMgICAgICAgPSB1dGlscy5nZXRPcHRpb24ob3B0aW9ucywgXCJhc3luY1wiLCB0cnVlKTtcbiAgICB2YXIgYXV0b1VwZGF0ZSAgPSB1dGlscy5nZXRPcHRpb24ob3B0aW9ucywgXCJhdXRvXCIsIHRydWUpO1xuXG4gICAgaWYoYXV0b1VwZGF0ZSAmJiAhYXN5bmMpIHtcbiAgICAgICAgcmVwb3J0ZXIud2FybihcIkludmFsaWQgb3B0aW9ucyBjb21iaW5hdGlvbi4gYXV0bz10cnVlIGFuZCBhc3luYz1mYWxzZSBpcyBpbnZhbGlkLiBTZXR0aW5nIGFzeW5jPXRydWUuXCIpO1xuICAgICAgICBhc3luYyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYoIXJlcG9ydGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVyIHJlcXVpcmVkLlwiKTtcbiAgICB9XG5cbiAgICB2YXIgYmF0Y2hTaXplID0gMDtcbiAgICB2YXIgYmF0Y2ggPSB7fTtcbiAgICB2YXIgaGFuZGxlcjtcblxuICAgIGZ1bmN0aW9uIHF1ZXVlVXBkYXRlKGVsZW1lbnQsIHVwZGF0ZXIpIHtcbiAgICAgICAgaWYoYXV0b1VwZGF0ZSAmJiBhc3luYyAmJiBiYXRjaFNpemUgPT09IDApIHtcbiAgICAgICAgICAgIHVwZGF0ZUJhdGNoQXN5bmMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKCFiYXRjaFtlbGVtZW50XSkge1xuICAgICAgICAgICAgYmF0Y2hbZWxlbWVudF0gPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJhdGNoW2VsZW1lbnRdLnB1c2godXBkYXRlcik7XG4gICAgICAgIGJhdGNoU2l6ZSsrO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZvcmNlVXBkYXRlQmF0Y2godXBkYXRlQXN5bmMpIHtcbiAgICAgICAgaWYodXBkYXRlQXN5bmMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdXBkYXRlQXN5bmMgPSBhc3luYztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKGhhbmRsZXIpIHtcbiAgICAgICAgICAgIGNhbmNlbEZyYW1lKGhhbmRsZXIpO1xuICAgICAgICAgICAgaGFuZGxlciA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZihhc3luYykge1xuICAgICAgICAgICAgdXBkYXRlQmF0Y2hBc3luYygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdXBkYXRlQmF0Y2goKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZUJhdGNoKCkge1xuICAgICAgICBmb3IodmFyIGVsZW1lbnQgaW4gYmF0Y2gpIHtcbiAgICAgICAgICAgIGlmKGJhdGNoLmhhc093blByb3BlcnR5KGVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHVwZGF0ZXJzID0gYmF0Y2hbZWxlbWVudF07XG5cbiAgICAgICAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdXBkYXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVwZGF0ZXIgPSB1cGRhdGVyc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjbGVhckJhdGNoKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlQmF0Y2hBc3luYygpIHtcbiAgICAgICAgaGFuZGxlciA9IHJlcXVlc3RGcmFtZShmdW5jdGlvbiBwZXJmb3JtVXBkYXRlKCkge1xuICAgICAgICAgICAgdXBkYXRlQmF0Y2goKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2xlYXJCYXRjaCgpIHtcbiAgICAgICAgYmF0Y2hTaXplID0gMDtcbiAgICAgICAgYmF0Y2ggPSB7fTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYW5jZWxGcmFtZShsaXN0ZW5lcikge1xuICAgICAgICAvLyB2YXIgY2FuY2VsID0gd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lIHx8IHdpbmRvdy5tb3pDYW5jZWxBbmltYXRpb25GcmFtZSB8fCB3aW5kb3cud2Via2l0Q2FuY2VsQW5pbWF0aW9uRnJhbWUgfHwgd2luZG93LmNsZWFyVGltZW91dDtcbiAgICAgICAgdmFyIGNhbmNlbCA9IHdpbmRvdy5jbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjYW5jZWwobGlzdGVuZXIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlcXVlc3RGcmFtZShjYWxsYmFjaykge1xuICAgICAgICAvLyB2YXIgcmFmID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCB3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IHdpbmRvdy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgZnVuY3Rpb24oZm4pIHsgcmV0dXJuIHdpbmRvdy5zZXRUaW1lb3V0KGZuLCAyMCk7IH07XG4gICAgICAgIHZhciByYWYgPSBmdW5jdGlvbihmbikgeyByZXR1cm4gd2luZG93LnNldFRpbWVvdXQoZm4sIDApOyB9O1xuICAgICAgICByZXR1cm4gcmFmKGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICB1cGRhdGU6IHF1ZXVlVXBkYXRlLFxuICAgICAgICBmb3JjZTogZm9yY2VVcGRhdGVCYXRjaFxuICAgIH07XG59OyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgdXRpbHMgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG51dGlscy5nZXRPcHRpb24gPSBnZXRPcHRpb247XG5cbmZ1bmN0aW9uIGdldE9wdGlvbihvcHRpb25zLCBuYW1lLCBkZWZhdWx0VmFsdWUpIHtcbiAgICB2YXIgdmFsdWUgPSBvcHRpb25zW25hbWVdO1xuXG4gICAgaWYoKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwpICYmIGRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBkZXRlY3RvciA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbmRldGVjdG9yLmlzSUUgPSBmdW5jdGlvbih2ZXJzaW9uKSB7XG4gICAgZnVuY3Rpb24gaXNBbnlJZVZlcnNpb24oKSB7XG4gICAgICAgIHZhciBhZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIGFnZW50LmluZGV4T2YoXCJtc2llXCIpICE9PSAtMSB8fCBhZ2VudC5pbmRleE9mKFwidHJpZGVudFwiKSAhPT0gLTE7XG4gICAgfVxuXG4gICAgaWYoIWlzQW55SWVWZXJzaW9uKCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmKCF2ZXJzaW9uKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vU2hhbWVsZXNzbHkgc3RvbGVuIGZyb20gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vcGFkb2xzZXkvNTI3NjgzXG4gICAgdmFyIGllVmVyc2lvbiA9IChmdW5jdGlvbigpe1xuICAgICAgICB2YXIgdW5kZWYsXG4gICAgICAgICAgICB2ID0gMyxcbiAgICAgICAgICAgIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiksXG4gICAgICAgICAgICBhbGwgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJpXCIpO1xuXG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIGRpdi5pbm5lckhUTUwgPSBcIjwhLS1baWYgZ3QgSUUgXCIgKyAoKyt2KSArIFwiXT48aT48L2k+PCFbZW5kaWZdLS0+XCI7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGFsbFswXSk7XG5cbiAgICAgICAgcmV0dXJuIHYgPiA0ID8gdiA6IHVuZGVmO1xuICAgIH0oKSk7XG5cbiAgICByZXR1cm4gdmVyc2lvbiA9PT0gaWVWZXJzaW9uO1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgdXRpbHMgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vKipcbiAqIExvb3BzIHRocm91Z2ggdGhlIGNvbGxlY3Rpb24gYW5kIGNhbGxzIHRoZSBjYWxsYmFjayBmb3IgZWFjaCBlbGVtZW50LiBpZiB0aGUgY2FsbGJhY2sgcmV0dXJucyB0cnV0aHksIHRoZSBsb29wIGlzIGJyb2tlbiBhbmQgcmV0dXJucyB0aGUgc2FtZSB2YWx1ZS5cbiAqIEBwdWJsaWNcbiAqIEBwYXJhbSB7Kn0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBsb29wIHRocm91Z2guIE5lZWRzIHRvIGhhdmUgYSBsZW5ndGggcHJvcGVydHkgc2V0IGFuZCBoYXZlIGluZGljZXMgc2V0IGZyb20gMCB0byBsZW5ndGggLSAxLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBmb3IgZWFjaCBlbGVtZW50LiBUaGUgZWxlbWVudCB3aWxsIGJlIGdpdmVuIGFzIGEgcGFyYW1ldGVyIHRvIHRoZSBjYWxsYmFjay4gSWYgdGhpcyBjYWxsYmFjayByZXR1cm5zIHRydXRoeSwgdGhlIGxvb3AgaXMgYnJva2VuIGFuZCB0aGUgc2FtZSB2YWx1ZSBpcyByZXR1cm5lZC5cbiAqIEByZXR1cm5zIHsqfSBUaGUgdmFsdWUgdGhhdCBhIGNhbGxiYWNrIGhhcyByZXR1cm5lZCAoaWYgdHJ1dGh5KS4gT3RoZXJ3aXNlIG5vdGhpbmcuXG4gKi9cbnV0aWxzLmZvckVhY2ggPSBmdW5jdGlvbihjb2xsZWN0aW9uLCBjYWxsYmFjaykge1xuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjb2xsZWN0aW9uLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjYWxsYmFjayhjb2xsZWN0aW9uW2ldKTtcbiAgICAgICAgaWYocmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfVxufTtcbiIsIi8vSGVhdmlseSBpbnNwaXJlZCBieSBodHRwOi8vd3d3LmJhY2thbGxleWNvZGVyLmNvbS8yMDEzLzAzLzE4L2Nyb3NzLWJyb3dzZXItZXZlbnQtYmFzZWQtZWxlbWVudC1yZXNpemUtZGV0ZWN0aW9uL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKFwiLi9jb2xsZWN0aW9uLXV0aWxzXCIpLmZvckVhY2g7XG52YXIgZWxlbWVudFV0aWxzTWFrZXIgPSByZXF1aXJlKFwiLi9lbGVtZW50LXV0aWxzXCIpO1xudmFyIGxpc3RlbmVySGFuZGxlck1ha2VyID0gcmVxdWlyZShcIi4vbGlzdGVuZXItaGFuZGxlclwiKTtcbnZhciBpZEdlbmVyYXRvck1ha2VyID0gcmVxdWlyZShcIi4vaWQtZ2VuZXJhdG9yXCIpO1xudmFyIGlkSGFuZGxlck1ha2VyID0gcmVxdWlyZShcIi4vaWQtaGFuZGxlclwiKTtcbnZhciByZXBvcnRlck1ha2VyID0gcmVxdWlyZShcIi4vcmVwb3J0ZXJcIik7XG52YXIgYmF0Y2hVcGRhdGVyID0gcmVxdWlyZShcImJhdGNoLXVwZGF0ZXJcIik7XG5cbi8qKlxuICogQHR5cGVkZWYgaWRIYW5kbGVyXG4gKiBAdHlwZSB7b2JqZWN0fVxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gZ2V0IEdldHMgdGhlIHJlc2l6ZSBkZXRlY3RvciBpZCBvZiB0aGUgZWxlbWVudC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IHNldCBHZW5lcmF0ZSBhbmQgc2V0cyB0aGUgcmVzaXplIGRldGVjdG9yIGlkIG9mIHRoZSBlbGVtZW50LlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgT3B0aW9uc1xuICogQHR5cGUge29iamVjdH1cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gY2FsbE9uQWRkICAgIERldGVybWluZXMgaWYgbGlzdGVuZXJzIHNob3VsZCBiZSBjYWxsZWQgd2hlbiB0aGV5IGFyZSBnZXR0aW5nIGFkZGVkLiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHQgaXMgdHJ1ZS4gSWYgdHJ1ZSwgdGhlIGxpc3RlbmVyIGlzIGd1YXJhbnRlZWQgdG8gYmUgY2FsbGVkIHdoZW4gaXQgaGFzIGJlZW4gYWRkZWQuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYgZmFsc2UsIHRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBndWFyZW50ZWVkIHRvIGJlIGNhbGxlZCB3aGVuIGl0IGhhcyBiZWVuIGFkZGVkIChkb2VzIG5vdCBwcmV2ZW50IGl0IGZyb20gYmVpbmcgY2FsbGVkKS5cbiAqIEBwcm9wZXJ0eSB7aWRIYW5kbGVyfSBpZEhhbmRsZXIgIEEgY3VzdG9tIGlkIGhhbmRsZXIgdGhhdCBpcyByZXNwb25zaWJsZSBmb3IgZ2VuZXJhdGluZywgc2V0dGluZyBhbmQgcmV0cmlldmluZyBpZCdzIGZvciBlbGVtZW50cy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIG5vdCBwcm92aWRlZCwgYSBkZWZhdWx0IGlkIGhhbmRsZXIgd2lsbCBiZSB1c2VkLlxuICogQHByb3BlcnR5IHtyZXBvcnRlcn0gcmVwb3J0ZXIgICAgQSBjdXN0b20gcmVwb3J0ZXIgdGhhdCBoYW5kbGVzIHJlcG9ydGluZyBsb2dzLCB3YXJuaW5ncyBhbmQgZXJyb3JzLiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIG5vdCBwcm92aWRlZCwgYSBkZWZhdWx0IGlkIGhhbmRsZXIgd2lsbCBiZSB1c2VkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYgc2V0IHRvIGZhbHNlLCB0aGVuIG5vdGhpbmcgd2lsbCBiZSByZXBvcnRlZC5cbiAqL1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gZWxlbWVudCByZXNpemUgZGV0ZWN0b3IgaW5zdGFuY2UuXG4gKiBAcHVibGljXG4gKiBAcGFyYW0ge09wdGlvbnM/fSBvcHRpb25zIE9wdGlvbmFsIGdsb2JhbCBvcHRpb25zIG9iamVjdCB0aGF0IHdpbGwgZGVjaWRlIGhvdyB0aGlzIGluc3RhbmNlIHdpbGwgd29yay5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICAvL2lkSGFuZGxlciBpcyBjdXJyZW50bHkgbm90IGFuIG9wdGlvbiB0byB0aGUgbGlzdGVuVG8gZnVuY3Rpb24sIHNvIGl0IHNob3VsZCBub3QgYmUgYWRkZWQgdG8gZ2xvYmFsT3B0aW9ucy5cbiAgICB2YXIgaWRIYW5kbGVyID0gb3B0aW9ucy5pZEhhbmRsZXI7XG5cbiAgICBpZighaWRIYW5kbGVyKSB7XG4gICAgICAgIHZhciBpZEdlbmVyYXRvciA9IGlkR2VuZXJhdG9yTWFrZXIoKTtcbiAgICAgICAgdmFyIGRlZmF1bHRJZEhhbmRsZXIgPSBpZEhhbmRsZXJNYWtlcihpZEdlbmVyYXRvcik7XG4gICAgICAgIGlkSGFuZGxlciA9IGRlZmF1bHRJZEhhbmRsZXI7XG4gICAgfVxuXG4gICAgLy9yZXBvcnRlciBpcyBjdXJyZW50bHkgbm90IGFuIG9wdGlvbiB0byB0aGUgbGlzdGVuVG8gZnVuY3Rpb24sIHNvIGl0IHNob3VsZCBub3QgYmUgYWRkZWQgdG8gZ2xvYmFsT3B0aW9ucy5cbiAgICB2YXIgcmVwb3J0ZXIgPSBvcHRpb25zLnJlcG9ydGVyO1xuXG4gICAgaWYoIXJlcG9ydGVyKSB7XG4gICAgICAgIC8vSWYgb3B0aW9ucy5yZXBvcnRlciBpcyBmYWxzZSwgdGhlbiB0aGUgcmVwb3J0ZXIgc2hvdWxkIGJlIHF1aWV0LlxuICAgICAgICB2YXIgcXVpZXQgPSByZXBvcnRlciA9PT0gZmFsc2U7XG4gICAgICAgIHJlcG9ydGVyID0gcmVwb3J0ZXJNYWtlcihxdWlldCk7XG4gICAgfVxuXG4gICAgLy9PcHRpb25zIHRvIGJlIHVzZWQgYXMgZGVmYXVsdCBmb3IgdGhlIGxpc3RlblRvIGZ1bmN0aW9uLlxuICAgIHZhciBnbG9iYWxPcHRpb25zID0ge307XG4gICAgZ2xvYmFsT3B0aW9ucy5jYWxsT25BZGQgICAgID0gISFnZXRPcHRpb24ob3B0aW9ucywgXCJjYWxsT25BZGRcIiwgdHJ1ZSk7XG4gICAgZ2xvYmFsT3B0aW9ucy5iYXRjaFVwZGF0ZXIgID0gZ2V0T3B0aW9uKG9wdGlvbnMsIFwiYmF0Y2hVcGRhdGVyXCIsIGJhdGNoVXBkYXRlcih7IHJlcG9ydGVyOiByZXBvcnRlciB9KSk7XG5cbiAgICB2YXIgZXZlbnRMaXN0ZW5lckhhbmRsZXIgPSBsaXN0ZW5lckhhbmRsZXJNYWtlcihpZEhhbmRsZXIpO1xuICAgIHZhciBlbGVtZW50VXRpbHMgPSBlbGVtZW50VXRpbHNNYWtlcihpZEhhbmRsZXIpO1xuXG4gICAgLyoqXG4gICAgICogTWFrZXMgdGhlIGdpdmVuIGVsZW1lbnRzIHJlc2l6ZS1kZXRlY3RhYmxlIGFuZCBzdGFydHMgbGlzdGVuaW5nIHRvIHJlc2l6ZSBldmVudHMgb24gdGhlIGVsZW1lbnRzLiBDYWxscyB0aGUgZXZlbnQgY2FsbGJhY2sgZm9yIGVhY2ggZXZlbnQgZm9yIGVhY2ggZWxlbWVudC5cbiAgICAgKiBAcHVibGljXG4gICAgICogQHBhcmFtIHtPcHRpb25zP30gb3B0aW9ucyBPcHRpb25hbCBvcHRpb25zIG9iamVjdC4gVGhlc2Ugb3B0aW9ucyB3aWxsIG92ZXJyaWRlIHRoZSBnbG9iYWwgb3B0aW9ucy4gU29tZSBvcHRpb25zIG1heSBub3QgYmUgb3ZlcnJpZGVuLCBzdWNoIGFzIGlkSGFuZGxlci5cbiAgICAgKiBAcGFyYW0ge2VsZW1lbnRbXXxlbGVtZW50fSBlbGVtZW50cyBUaGUgZ2l2ZW4gYXJyYXkgb2YgZWxlbWVudHMgdG8gZGV0ZWN0IHJlc2l6ZSBldmVudHMgb2YuIFNpbmdsZSBlbGVtZW50IGlzIGFsc28gdmFsaWQuXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGNhbGxiYWNrIHRvIGJlIGV4ZWN1dGVkIGZvciBlYWNoIHJlc2l6ZSBldmVudCBmb3IgZWFjaCBlbGVtZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RlblRvKG9wdGlvbnMsIGVsZW1lbnRzLCBsaXN0ZW5lcikge1xuICAgICAgICBmdW5jdGlvbiBvblJlc2l6ZUNhbGxiYWNrKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHZhciBsaXN0ZW5lcnMgPSBldmVudExpc3RlbmVySGFuZGxlci5nZXQoZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGZvckVhY2gobGlzdGVuZXJzLCBmdW5jdGlvbiBjYWxsTGlzdGVuZXJQcm94eShsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyKGVsZW1lbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBvbkVsZW1lbnRSZWFkeVRvQWRkTGlzdGVuZXIoY2FsbE9uQWRkLCBlbGVtZW50LCBsaXN0ZW5lcikge1xuICAgICAgICAgICAgZXZlbnRMaXN0ZW5lckhhbmRsZXIuYWRkKGVsZW1lbnQsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYoY2FsbE9uQWRkKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvL09wdGlvbnMgb2JqZWN0IG1heSBiZSBvbWl0dGVkLlxuICAgICAgICBpZighbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyID0gZWxlbWVudHM7XG4gICAgICAgICAgICBlbGVtZW50cyA9IG9wdGlvbnM7XG4gICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIH1cblxuICAgICAgICBpZighZWxlbWVudHMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkF0IGxlYXN0IG9uZSBlbGVtZW50IHJlcXVpcmVkLlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKCFsaXN0ZW5lcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTGlzdGVuZXIgcmVxdWlyZWQuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoZWxlbWVudHMubGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGVsZW1lbnRzID0gW2VsZW1lbnRzXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjYWxsT25BZGQgICAgICAgPSBnZXRPcHRpb24ob3B0aW9ucywgXCJjYWxsT25BZGRcIiwgZ2xvYmFsT3B0aW9ucy5jYWxsT25BZGQpO1xuICAgICAgICB2YXIgYmF0Y2hVcGRhdGVyICAgID0gZ2V0T3B0aW9uKG9wdGlvbnMsIFwiYmF0Y2hVcGRhdGVyXCIsIGdsb2JhbE9wdGlvbnMuYmF0Y2hVcGRhdGVyKTtcblxuICAgICAgICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiBhdHRhY2hMaXN0ZW5lclRvRWxlbWVudChlbGVtZW50KSB7XG4gICAgICAgICAgICBpZighZWxlbWVudFV0aWxzLmlzRGV0ZWN0YWJsZShlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIC8vVGhlIGVsZW1lbnQgaXMgbm90IHByZXBhcmVkIHRvIGJlIGRldGVjdGFibGUsIHNvIGRvIHByZXBhcmUgaXQgYW5kIGFkZCBhIGxpc3RlbmVyIHRvIGl0LlxuICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50VXRpbHMubWFrZURldGVjdGFibGUoYmF0Y2hVcGRhdGVyLCByZXBvcnRlciwgZWxlbWVudCwgZnVuY3Rpb24gb25FbGVtZW50RGV0ZWN0YWJsZShlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRVdGlscy5hZGRMaXN0ZW5lcihlbGVtZW50LCBvblJlc2l6ZUNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICAgICAgb25FbGVtZW50UmVhZHlUb0FkZExpc3RlbmVyKGNhbGxPbkFkZCwgZWxlbWVudCwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICAvL1RoZSBlbGVtZW50IGhhcyBiZWVuIHByZXBhcmVkIHRvIGJlIGRldGVjdGFibGUgYW5kIGlzIHJlYWR5IHRvIGJlIGxpc3RlbmVkIHRvLlxuICAgICAgICAgICAgb25FbGVtZW50UmVhZHlUb0FkZExpc3RlbmVyKGNhbGxPbkFkZCwgZWxlbWVudCwgbGlzdGVuZXIpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBsaXN0ZW5UbzogbGlzdGVuVG9cbiAgICB9O1xufTtcblxuZnVuY3Rpb24gZ2V0T3B0aW9uKG9wdGlvbnMsIG5hbWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHZhciB2YWx1ZSA9IG9wdGlvbnNbbmFtZV07XG5cbiAgICBpZigodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCkgJiYgZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKFwiLi9jb2xsZWN0aW9uLXV0aWxzXCIpLmZvckVhY2g7XG52YXIgYnJvd3NlckRldGVjdG9yID0gcmVxdWlyZShcIi4vYnJvd3Nlci1kZXRlY3RvclwiKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpZEhhbmRsZXIpIHtcbiAgICAvKipcbiAgICAgKiBUZWxscyBpZiB0aGUgZWxlbWVudCBoYXMgYmVlbiBtYWRlIGRldGVjdGFibGUgYW5kIHJlYWR5IHRvIGJlIGxpc3RlbmVkIGZvciByZXNpemUgZXZlbnRzLlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IFRoZSBlbGVtZW50IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIG9yIGZhbHNlIGRlcGVuZGluZyBvbiBpZiB0aGUgZWxlbWVudCBpcyBkZXRlY3RhYmxlIG9yIG5vdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0RldGVjdGFibGUoZWxlbWVudCkge1xuICAgICAgICBpZihicm93c2VyRGV0ZWN0b3IuaXNJRSg4KSkge1xuICAgICAgICAgICAgLy9JRSA4IGRvZXMgbm90IHVzZSB0aGUgb2JqZWN0IG1ldGhvZC5cbiAgICAgICAgICAgIC8vQ2hlY2sgb25seSBpZiB0aGUgZWxlbWVudCBoYXMgYmVlbiBnaXZlbiBhbiBpZC5cbiAgICAgICAgICAgIHJldHVybiAhIWlkSGFuZGxlci5nZXQoZWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gISFnZXRPYmplY3QoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIHJlc2l6ZSBldmVudCBsaXN0ZW5lciB0byB0aGUgZWxlbWVudC5cbiAgICAgKiBAcHVibGljXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRoYXQgc2hvdWxkIGhhdmUgdGhlIGxpc3RlbmVyIGFkZGVkLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBjYWxsYmFjayB0byBiZSBjYWxsZWQgZm9yIGVhY2ggcmVzaXplIGV2ZW50IG9mIHRoZSBlbGVtZW50LiBUaGUgZWxlbWVudCB3aWxsIGJlIGdpdmVuIGFzIGEgcGFyYW1ldGVyIHRvIHRoZSBsaXN0ZW5lciBjYWxsYmFjay5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhZGRMaXN0ZW5lcihlbGVtZW50LCBsaXN0ZW5lcikge1xuICAgICAgICBpZighaXNEZXRlY3RhYmxlKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFbGVtZW50IGlzIG5vdCBkZXRlY3RhYmxlLlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGxpc3RlbmVyUHJveHkoKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcihlbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKGJyb3dzZXJEZXRlY3Rvci5pc0lFKDgpKSB7XG4gICAgICAgICAgICAvL0lFIDggZG9lcyBub3Qgc3VwcG9ydCBvYmplY3QsIGJ1dCBzdXBwb3J0cyB0aGUgcmVzaXplIGV2ZW50IGRpcmVjdGx5IG9uIGVsZW1lbnRzLlxuICAgICAgICAgICAgZWxlbWVudC5hdHRhY2hFdmVudChcIm9ucmVzaXplXCIsIGxpc3RlbmVyUHJveHkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IGdldE9iamVjdChlbGVtZW50KTtcbiAgICAgICAgICAgIG9iamVjdC5jb250ZW50RG9jdW1lbnQuZGVmYXVsdFZpZXcuYWRkRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLCBsaXN0ZW5lclByb3h5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2VzIGFuIGVsZW1lbnQgZGV0ZWN0YWJsZSBhbmQgcmVhZHkgdG8gYmUgbGlzdGVuZWQgZm9yIHJlc2l6ZSBldmVudHMuIFdpbGwgY2FsbCB0aGUgY2FsbGJhY2sgd2hlbiB0aGUgZWxlbWVudCBpcyByZWFkeSB0byBiZSBsaXN0ZW5lZCBmb3IgcmVzaXplIGNoYW5nZXMuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gbWFrZSBkZXRlY3RhYmxlXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBlbGVtZW50IGlzIHJlYWR5IHRvIGJlIGxpc3RlbmVkIGZvciByZXNpemUgY2hhbmdlcy4gV2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgZWxlbWVudCBhcyBmaXJzdCBwYXJhbWV0ZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFrZURldGVjdGFibGUoYmF0Y2hVcGRhdGVyLCByZXBvcnRlciwgZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgZnVuY3Rpb24gaW5qZWN0T2JqZWN0KGlkLCBlbGVtZW50LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgdmFyIE9CSkVDVF9TVFlMRSA9IFwiZGlzcGxheTogYmxvY2s7IHBvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiAwOyBsZWZ0OiAwOyB3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlOyBib3JkZXI6IG5vbmU7IHBhZGRpbmc6IDA7IG1hcmdpbjogMDsgb3BhY2l0eTogMDsgei1pbmRleDogLTEwMDA7IHBvaW50ZXItZXZlbnRzOiBub25lO1wiO1xuXG4gICAgICAgICAgICBmdW5jdGlvbiBvbk9iamVjdExvYWQoKSB7XG4gICAgICAgICAgICAgICAgLypqc2hpbnQgdmFsaWR0aGlzOiB0cnVlICovXG5cbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXREb2N1bWVudChlbGVtZW50LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAvL09wZXJhIDEyIHNlZW0gdG8gY2FsbCB0aGUgb2JqZWN0Lm9ubG9hZCBiZWZvcmUgdGhlIGFjdHVhbCBkb2N1bWVudCBoYXMgYmVlbiBjcmVhdGVkLlxuICAgICAgICAgICAgICAgICAgICAvL1NvIGlmIGl0IGlzIG5vdCBwcmVzZW50LCBwb2xsIGl0IHdpdGggYW4gdGltZW91dCB1bnRpbCBpdCBpcyBwcmVzZW50LlxuICAgICAgICAgICAgICAgICAgICAvL1RPRE86IENvdWxkIG1heWJlIGJlIGhhbmRsZWQgYmV0dGVyIHdpdGggb2JqZWN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSBvciBzaW1pbGFyLlxuICAgICAgICAgICAgICAgICAgICBpZighZWxlbWVudC5jb250ZW50RG9jdW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gY2hlY2tGb3JPYmplY3REb2N1bWVudCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXREb2N1bWVudChlbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAxMDApO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlbGVtZW50LmNvbnRlbnREb2N1bWVudCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy9NdXRhdGluZyB0aGUgb2JqZWN0IGVsZW1lbnQgaGVyZSBzZWVtcyB0byBmaXJlIGFub3RoZXIgbG9hZCBldmVudC5cbiAgICAgICAgICAgICAgICAvL011dGF0aW5nIHRoZSBpbm5lciBkb2N1bWVudCBvZiB0aGUgb2JqZWN0IGVsZW1lbnQgaXMgZmluZSB0aG91Z2guXG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdEVsZW1lbnQgPSB0aGlzO1xuXG4gICAgICAgICAgICAgICAgLy9DcmVhdGUgdGhlIHN0eWxlIGVsZW1lbnQgdG8gYmUgYWRkZWQgdG8gdGhlIG9iamVjdC5cbiAgICAgICAgICAgICAgICBnZXREb2N1bWVudChvYmplY3RFbGVtZW50LCBmdW5jdGlvbiBvbk9iamVjdERvY3VtZW50UmVhZHkob2JqZWN0RG9jdW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gb2JqZWN0RG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICAgICAgICAgICAgICAgICAgICBzdHlsZS5pbm5lckhUTUwgPSBcImh0bWwsIGJvZHkgeyBtYXJnaW46IDA7IHBhZGRpbmc6IDAgfSBkaXYgeyAtd2Via2l0LXRyYW5zaXRpb246IG9wYWNpdHkgMC4wMXM7IC1tcy10cmFuc2l0aW9uOiBvcGFjaXR5IDAuMDFzOyAtby10cmFuc2l0aW9uOiBvcGFjaXR5IDAuMDFzOyB0cmFuc2l0aW9uOiBvcGFjaXR5IDAuMDFzOyBvcGFjaXR5OiAwOyB9XCI7XG5cbiAgICAgICAgICAgICAgICAgICAgLy9UT0RPOiBSZW1vdmUgYW55IHN0eWxlcyB0aGF0IGhhcyBiZWVuIHNldCBvbiB0aGUgb2JqZWN0LiBPbmx5IHRoZSBzdHlsZSBhYm92ZSBzaG91bGQgYmUgc3R5bGluZyB0aGUgb2JqZWN0LlxuXG4gICAgICAgICAgICAgICAgICAgIC8vQXBwZW5kIHRoZSBzdHlsZSB0byB0aGUgb2JqZWN0LlxuICAgICAgICAgICAgICAgICAgICBvYmplY3REb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblxuICAgICAgICAgICAgICAgICAgICAvL05vdGlmeSB0aGF0IHRoZSBlbGVtZW50IGlzIHJlYWR5IHRvIGJlIGxpc3RlbmVkIHRvLlxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy9UaGUgdGFyZ2V0IGVsZW1lbnQgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCAoZXZlcnl0aGluZyBleGNlcHQgc3RhdGljKSBzbyB0aGUgYWJzb2x1dGUgcG9zaXRpb25lZCBvYmplY3Qgd2lsbCBiZSBwb3NpdGlvbmVkIHJlbGF0aXZlIHRvIHRoZSB0YXJnZXQgZWxlbWVudC5cbiAgICAgICAgICAgIHZhciBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG4gICAgICAgICAgICB2YXIgcG9zaXRpb24gPSBzdHlsZS5wb3NpdGlvbjtcblxuICAgICAgICAgICAgZnVuY3Rpb24gbXV0YXRlRG9tKCkge1xuICAgICAgICAgICAgICAgIGlmKHBvc2l0aW9uID09PSBcInN0YXRpY1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlbW92ZVJlbGF0aXZlU3R5bGVzID0gZnVuY3Rpb24ocmVwb3J0ZXIsIGVsZW1lbnQsIHN0eWxlLCBwcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0TnVtZXJpY2FsVmFsdWUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUucmVwbGFjZSgvW14tXFxkXFwuXS9nLCBcIlwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gc3R5bGVbcHJvcGVydHldO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZih2YWx1ZSAhPT0gXCJhdXRvXCIgJiYgZ2V0TnVtZXJpY2FsVmFsdWUodmFsdWUpICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydGVyLndhcm4oXCJBbiBlbGVtZW50IHRoYXQgaXMgcG9zaXRpb25lZCBzdGF0aWMgaGFzIHN0eWxlLlwiICsgcHJvcGVydHkgKyBcIj1cIiArIHZhbHVlICsgXCIgd2hpY2ggaXMgaWdub3JlZCBkdWUgdG8gdGhlIHN0YXRpYyBwb3NpdGlvbmluZy4gVGhlIGVsZW1lbnQgd2lsbCBuZWVkIHRvIGJlIHBvc2l0aW9uZWQgcmVsYXRpdmUsIHNvIHRoZSBzdHlsZS5cIiArIHByb3BlcnR5ICsgXCIgd2lsbCBiZSBzZXQgdG8gMC4gRWxlbWVudDogXCIsIGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVbcHJvcGVydHldID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAvL0NoZWNrIHNvIHRoYXQgdGhlcmUgYXJlIG5vIGFjY2lkZW50YWwgc3R5bGVzIHRoYXQgd2lsbCBtYWtlIHRoZSBlbGVtZW50IHN0eWxlZCBkaWZmZXJlbnRseSBub3cgdGhhdCBpcyBpcyByZWxhdGl2ZS5cbiAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGVyZSBhcmUgYW55LCBzZXQgdGhlbSB0byAwICh0aGlzIHNob3VsZCBiZSBva2F5IHdpdGggdGhlIHVzZXIgc2luY2UgdGhlIHN0eWxlIHByb3BlcnRpZXMgZGlkIG5vdGhpbmcgYmVmb3JlIFtzaW5jZSB0aGUgZWxlbWVudCB3YXMgcG9zaXRpb25lZCBzdGF0aWNdIGFueXdheSkuXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZVJlbGF0aXZlU3R5bGVzKHJlcG9ydGVyLCBlbGVtZW50LCBzdHlsZSwgXCJ0b3BcIik7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZVJlbGF0aXZlU3R5bGVzKHJlcG9ydGVyLCBlbGVtZW50LCBzdHlsZSwgXCJyaWdodFwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUmVsYXRpdmVTdHlsZXMocmVwb3J0ZXIsIGVsZW1lbnQsIHN0eWxlLCBcImJvdHRvbVwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUmVsYXRpdmVTdHlsZXMocmVwb3J0ZXIsIGVsZW1lbnQsIHN0eWxlLCBcImxlZnRcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy9BZGQgYW4gb2JqZWN0IGVsZW1lbnQgYXMgYSBjaGlsZCB0byB0aGUgdGFyZ2V0IGVsZW1lbnQgdGhhdCB3aWxsIGJlIGxpc3RlbmVkIHRvIGZvciByZXNpemUgZXZlbnRzLlxuICAgICAgICAgICAgICAgIHZhciBvYmplY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwib2JqZWN0XCIpO1xuICAgICAgICAgICAgICAgIG9iamVjdC5zdHlsZS5jc3NUZXh0ID0gT0JKRUNUX1NUWUxFO1xuICAgICAgICAgICAgICAgIG9iamVjdC50eXBlID0gXCJ0ZXh0L2h0bWxcIjtcbiAgICAgICAgICAgICAgICBvYmplY3Qub25sb2FkID0gb25PYmplY3RMb2FkO1xuICAgICAgICAgICAgICAgIG9iamVjdC5fZXJkT2JqZWN0SWQgPSBpZDtcblxuICAgICAgICAgICAgICAgIC8vU2FmYXJpOiBUaGlzIG11c3Qgb2NjdXIgYmVmb3JlIGFkZGluZyB0aGUgb2JqZWN0IHRvIHRoZSBET00uXG4gICAgICAgICAgICAgICAgLy9JRTogRG9lcyBub3QgbGlrZSB0aGF0IHRoaXMgaGFwcGVucyBiZWZvcmUsIGV2ZW4gaWYgaXQgaXMgYWxzbyBhZGRlZCBhZnRlci5cbiAgICAgICAgICAgICAgICBpZighYnJvd3NlckRldGVjdG9yLmlzSUUoKSkge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZGF0YSA9IFwiYWJvdXQ6YmxhbmtcIjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKG9iamVjdCk7XG5cbiAgICAgICAgICAgICAgICAvL0lFOiBUaGlzIG11c3Qgb2NjdXIgYWZ0ZXIgYWRkaW5nIHRoZSBvYmplY3QgdG8gdGhlIERPTS5cbiAgICAgICAgICAgICAgICBpZihicm93c2VyRGV0ZWN0b3IuaXNJRSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5kYXRhID0gXCJhYm91dDpibGFua1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYoYmF0Y2hVcGRhdGVyKSB7XG4gICAgICAgICAgICAgICAgYmF0Y2hVcGRhdGVyLnVwZGF0ZShpZCwgbXV0YXRlRG9tKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbXV0YXRlRG9tKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvL09idGFpbiB0aGUgaWQgb2YgdGhlIGVsZW1lbnQgKHdpbGwgYmUgZ2VuZXJhdGVkIGlmIG5vdCBwcmVzZW50KSwgc28gdGhhdCBldmVudCBsaXN0ZW5lcnMgY2FuIGJlIGlkZW50aWZpZWQgdG8gdGhpcyBlbGVtZW50LlxuICAgICAgICB2YXIgaWQgPSBpZEhhbmRsZXIuZ2V0KGVsZW1lbnQpO1xuXG4gICAgICAgIGlmKGJyb3dzZXJEZXRlY3Rvci5pc0lFKDgpKSB7XG4gICAgICAgICAgICAvL0lFIDggZG9lcyBub3Qgc3VwcG9ydCBvYmplY3RzIHByb3Blcmx5LiBMdWNraWx5IHRoZXkgZG8gc3VwcG9ydCB0aGUgcmVzaXplIGV2ZW50LlxuICAgICAgICAgICAgLy9TbyBkbyBub3QgaW5qZWN0IHRoZSBvYmplY3QgYW5kIG5vdGlmeSB0aGF0IHRoZSBlbGVtZW50IGlzIGFscmVhZHkgcmVhZHkgdG8gYmUgbGlzdGVuZWQgdG8uXG4gICAgICAgICAgICAvL1RoZSBldmVudCBoYW5kbGVyIGZvciB0aGUgcmVzaXplIGV2ZW50IGlzIGF0dGFjaGVkIGluIHRoZSB1dGlscy5hZGRMaXN0ZW5lciBpbnN0ZWFkLlxuICAgICAgICAgICAgY2FsbGJhY2soZWxlbWVudCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbmplY3RPYmplY3QoaWQsIGVsZW1lbnQsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGNoaWxkIG9iamVjdCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IGVsZW1lbnQgVGhlIHRhcmdldCBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIFRoZSBvYmplY3QgZWxlbWVudCBvZiB0aGUgdGFyZ2V0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE9iamVjdChlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBmb3JFYWNoKGVsZW1lbnQuY2hpbGRyZW4sIGZ1bmN0aW9uIGlzT2JqZWN0KGNoaWxkKSB7XG4gICAgICAgICAgICBpZihjaGlsZC5fZXJkT2JqZWN0SWQgIT09IHVuZGVmaW5lZCAmJiBjaGlsZC5fZXJkT2JqZWN0SWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGlzRGV0ZWN0YWJsZTogaXNEZXRlY3RhYmxlLFxuICAgICAgICBtYWtlRGV0ZWN0YWJsZTogbWFrZURldGVjdGFibGUsXG4gICAgICAgIGFkZExpc3RlbmVyOiBhZGRMaXN0ZW5lcixcbiAgICB9O1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBpZENvdW50ID0gMTtcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhIG5ldyB1bmlxdWUgaWQgaW4gdGhlIGNvbnRleHQuXG4gICAgICogQHB1YmxpY1xuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEEgdW5pcXVlIGlkIGluIHRoZSBjb250ZXh0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdlbmVyYXRlKCkge1xuICAgICAgICByZXR1cm4gaWRDb3VudCsrO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGdlbmVyYXRlOiBnZW5lcmF0ZVxuICAgIH07XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaWRHZW5lcmF0b3IpIHtcbiAgICB2YXIgSURfUFJPUF9OQU1FID0gXCJfZXJkVGFyZ2V0SWRcIjtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHJlc2l6ZSBkZXRlY3RvciBpZCBvZiB0aGUgZWxlbWVudC4gSWYgdGhlIGVsZW1lbnQgZG9lcyBub3QgaGF2ZSBhbiBpZCwgb25lIHdpbGwgYmUgYXNzaWduZWQgdG8gdGhlIGVsZW1lbnQuXG4gICAgICogQHB1YmxpY1xuICAgICAqIEBwYXJhbSB7ZWxlbWVudH0gZWxlbWVudCBUaGUgdGFyZ2V0IGVsZW1lbnQgdG8gZ2V0IHRoZSBpZCBvZi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW4/fSByZWFkb25seSBBbiBpZCB3aWxsIG5vdCBiZSBhc3NpZ25lZCB0byB0aGUgZWxlbWVudCBpZiB0aGUgcmVhZG9ubHkgcGFyYW1ldGVyIGlzIHRydWUuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAgICogQHJldHVybnMge3N0cmluZ3xudW1iZXJ9IFRoZSBpZCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRJZChlbGVtZW50LCByZWFkb25seSkge1xuICAgICAgICBpZighcmVhZG9ubHkgJiYgIWhhc0lkKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBzZXRJZChlbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlbGVtZW50W0lEX1BST1BfTkFNRV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0SWQoZWxlbWVudCkge1xuICAgICAgICB2YXIgaWQgPSBpZEdlbmVyYXRvci5nZW5lcmF0ZSgpO1xuXG4gICAgICAgIGVsZW1lbnRbSURfUFJPUF9OQU1FXSA9IGlkO1xuXG4gICAgICAgIHJldHVybiBpZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYXNJZChlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50W0lEX1BST1BfTkFNRV0gIT09IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBnZXQ6IGdldElkXG4gICAgfTtcbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpZEhhbmRsZXIpIHtcbiAgICB2YXIgZXZlbnRMaXN0ZW5lcnMgPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgYWxsIGxpc3RlbmVycyBmb3IgdGhlIGdpdmVuIGVsZW1lbnQuXG4gICAgICogQHB1YmxpY1xuICAgICAqIEBwYXJhbSB7ZWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBnZXQgYWxsIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHJldHVybnMgQWxsIGxpc3RlbmVycyBmb3IgdGhlIGdpdmVuIGVsZW1lbnQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGV2ZW50TGlzdGVuZXJzW2lkSGFuZGxlci5nZXQoZWxlbWVudCldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0b3JlcyB0aGUgZ2l2ZW4gbGlzdGVuZXIgZm9yIHRoZSBnaXZlbiBlbGVtZW50LiBXaWxsIG5vdCBhY3R1YWxseSBhZGQgdGhlIGxpc3RlbmVyIHRvIHRoZSBlbGVtZW50LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdGhhdCBzaG91bGQgaGF2ZSB0aGUgbGlzdGVuZXIgYWRkZWQuXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGNhbGxiYWNrIHRoYXQgdGhlIGVsZW1lbnQgaGFzIGFkZGVkLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFkZExpc3RlbmVyKGVsZW1lbnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBpZCA9IGlkSGFuZGxlci5nZXQoZWxlbWVudCk7XG5cbiAgICAgICAgaWYoIWV2ZW50TGlzdGVuZXJzW2lkXSkge1xuICAgICAgICAgICAgZXZlbnRMaXN0ZW5lcnNbaWRdID0gW107XG4gICAgICAgIH1cblxuICAgICAgICBldmVudExpc3RlbmVyc1tpZF0ucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0OiBnZXRMaXN0ZW5lcnMsXG4gICAgICAgIGFkZDogYWRkTGlzdGVuZXJcbiAgICB9O1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vKiBnbG9iYWwgY29uc29sZTogZmFsc2UgKi9cblxuLyoqXG4gKiBSZXBvcnRlciB0aGF0IGhhbmRsZXMgdGhlIHJlcG9ydGluZyBvZiBsb2dzLCB3YXJuaW5ncyBhbmQgZXJyb3JzLlxuICogQHB1YmxpY1xuICogQHBhcmFtIHtib29sZWFufSBxdWlldCBUZWxscyBpZiB0aGUgcmVwb3J0ZXIgc2hvdWxkIGJlIHF1aWV0IG9yIG5vdC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihxdWlldCkge1xuICAgIGZ1bmN0aW9uIG5vb3AoKSB7XG4gICAgICAgIC8vRG9lcyBub3RoaW5nLlxuICAgIH1cblxuICAgIHZhciByZXBvcnRlciA9IHtcbiAgICAgICAgbG9nOiBub29wLFxuICAgICAgICB3YXJuOiBub29wLFxuICAgICAgICBlcnJvcjogbm9vcFxuICAgIH07XG5cbiAgICBpZighcXVpZXQgJiYgd2luZG93LmNvbnNvbGUpIHtcbiAgICAgICAgdmFyIGF0dGFjaEZ1bmN0aW9uID0gZnVuY3Rpb24ocmVwb3J0ZXIsIG5hbWUpIHtcbiAgICAgICAgICAgIC8vVGhlIHByb3h5IGlzIG5lZWRlZCB0byBiZSBhYmxlIHRvIGNhbGwgdGhlIG1ldGhvZCB3aXRoIHRoZSBjb25zb2xlIGNvbnRleHQsXG4gICAgICAgICAgICAvL3NpbmNlIHdlIGNhbm5vdCB1c2UgYmluZC5cbiAgICAgICAgICAgIHJlcG9ydGVyW25hbWVdID0gZnVuY3Rpb24gcmVwb3J0ZXJQcm94eSgpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlW25hbWVdLmFwcGx5KGNvbnNvbGUsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG4gICAgICAgIGF0dGFjaEZ1bmN0aW9uKHJlcG9ydGVyLCBcImxvZ1wiKTtcbiAgICAgICAgYXR0YWNoRnVuY3Rpb24ocmVwb3J0ZXIsIFwid2FyblwiKTtcbiAgICAgICAgYXR0YWNoRnVuY3Rpb24ocmVwb3J0ZXIsIFwiZXJyb3JcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcG9ydGVyO1xufTsiXX0= |
/*! | ||
* element-resize-detector 0.2.4 (2015-03-25, 14:46) | ||
* element-resize-detector 0.2.7 (2015-04-08, 14:28) | ||
* https://github.com/wnr/element-resize-detector | ||
@@ -10,2 +10,116 @@ * Licensed under MIT | ||
var utils = require("./utils"); | ||
module.exports = function batchUpdaterMaker(options) { | ||
options = options || {}; | ||
var reporter = options.reporter; | ||
var async = utils.getOption(options, "async", true); | ||
var autoUpdate = utils.getOption(options, "auto", true); | ||
if(autoUpdate && !async) { | ||
reporter.warn("Invalid options combination. auto=true and async=false is invalid. Setting async=true."); | ||
async = true; | ||
} | ||
if(!reporter) { | ||
throw new Error("Reporter required."); | ||
} | ||
var batchSize = 0; | ||
var batch = {}; | ||
var handler; | ||
function queueUpdate(element, updater) { | ||
if(autoUpdate && async && batchSize === 0) { | ||
updateBatchAsync(); | ||
} | ||
if(!batch[element]) { | ||
batch[element] = []; | ||
} | ||
batch[element].push(updater); | ||
batchSize++; | ||
} | ||
function forceUpdateBatch(updateAsync) { | ||
if(updateAsync === undefined) { | ||
updateAsync = async; | ||
} | ||
if(handler) { | ||
cancelFrame(handler); | ||
handler = null; | ||
} | ||
if(async) { | ||
updateBatchAsync(); | ||
} else { | ||
updateBatch(); | ||
} | ||
} | ||
function updateBatch() { | ||
for(var element in batch) { | ||
if(batch.hasOwnProperty(element)) { | ||
var updaters = batch[element]; | ||
for(var i = 0; i < updaters.length; i++) { | ||
var updater = updaters[i]; | ||
updater(); | ||
} | ||
} | ||
} | ||
clearBatch(); | ||
} | ||
function updateBatchAsync() { | ||
handler = requestFrame(function performUpdate() { | ||
updateBatch(); | ||
}); | ||
} | ||
function clearBatch() { | ||
batchSize = 0; | ||
batch = {}; | ||
} | ||
function cancelFrame(listener) { | ||
// var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout; | ||
var cancel = window.clearTimeout; | ||
return cancel(listener); | ||
} | ||
function requestFrame(callback) { | ||
// var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(fn) { return window.setTimeout(fn, 20); }; | ||
var raf = function(fn) { return window.setTimeout(fn, 0); }; | ||
return raf(callback); | ||
} | ||
return { | ||
update: queueUpdate, | ||
force: forceUpdateBatch | ||
}; | ||
}; | ||
},{"./utils":2}],2:[function(require,module,exports){ | ||
"use strict"; | ||
var utils = module.exports = {}; | ||
utils.getOption = getOption; | ||
function getOption(options, name, defaultValue) { | ||
var value = options[name]; | ||
if((value === undefined || value === null) && defaultValue !== undefined) { | ||
return defaultValue; | ||
} | ||
return value; | ||
} | ||
},{}],3:[function(require,module,exports){ | ||
"use strict"; | ||
var detector = module.exports = {}; | ||
@@ -45,3 +159,3 @@ | ||
},{}],2:[function(require,module,exports){ | ||
},{}],4:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -67,3 +181,3 @@ | ||
},{}],3:[function(require,module,exports){ | ||
},{}],5:[function(require,module,exports){ | ||
//Heavily inspired by http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/ | ||
@@ -79,2 +193,3 @@ | ||
var reporterMaker = require("./reporter"); | ||
var batchUpdater = require("batch-updater"); | ||
@@ -109,6 +224,2 @@ /** | ||
//Options to be used as default for the listenTo function. | ||
var globalOptions = {}; | ||
globalOptions.callOnAdd = !!getOption(options, "callOnAdd", true); | ||
//idHandler is currently not an option to the listenTo function, so it should not be added to globalOptions. | ||
@@ -132,2 +243,7 @@ var idHandler = options.idHandler; | ||
//Options to be used as default for the listenTo function. | ||
var globalOptions = {}; | ||
globalOptions.callOnAdd = !!getOption(options, "callOnAdd", true); | ||
globalOptions.batchUpdater = getOption(options, "batchUpdater", batchUpdater({ reporter: reporter })); | ||
var eventListenerHandler = listenerHandlerMaker(idHandler); | ||
@@ -179,27 +295,11 @@ var elementUtils = elementUtilsMaker(idHandler); | ||
var callOnAdd = getOption(options, "callOnAdd", globalOptions.callOnAdd); | ||
var callOnAdd = getOption(options, "callOnAdd", globalOptions.callOnAdd); | ||
var batchUpdater = getOption(options, "batchUpdater", globalOptions.batchUpdater); | ||
forEach(elements, function attachListenerToElement(element) { | ||
//The element may change size directly after the call to listenTo, which would be unable to detect it because | ||
//the async adding of the object. By checking the size before and after, the size change can still be detected | ||
//and the listener can be called accordingly. | ||
var preWidth = element.offsetWidth; | ||
var preHeight = element.offsetHeight; | ||
if(!elementUtils.isDetectable(element)) { | ||
//The element is not prepared to be detectable, so do prepare it and add a listener to it. | ||
return elementUtils.makeDetectable(reporter, element, function onElementDetectable(element) { | ||
return elementUtils.makeDetectable(batchUpdater, reporter, element, function onElementDetectable(element) { | ||
elementUtils.addListener(element, onResizeCallback); | ||
onElementReadyToAddListener(callOnAdd, element, listener); | ||
//Only here the uncaught resize may occur (since this code is async). | ||
//Check if the size is the same as when adding the listener. | ||
var postWidth = element.offsetWidth; | ||
var postHeight = element.offsetHeight; | ||
//If callOnAdd is true, then the listener will have been called either way, so no need to call the listener manually then. | ||
if(!callOnAdd && (preWidth !== postWidth || preHeight !== postHeight)) { | ||
//The element was changed while the object was being added. Call the listener. | ||
listener(element); | ||
} | ||
}); | ||
@@ -228,3 +328,3 @@ } | ||
},{"./collection-utils":2,"./element-utils":4,"./id-generator":5,"./id-handler":6,"./listener-handler":7,"./reporter":8}],4:[function(require,module,exports){ | ||
},{"./collection-utils":4,"./element-utils":6,"./id-generator":7,"./id-handler":8,"./listener-handler":9,"./reporter":10,"batch-updater":1}],6:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -282,3 +382,3 @@ | ||
*/ | ||
function makeDetectable(reporter, element, callback) { | ||
function makeDetectable(batchUpdater, reporter, element, callback) { | ||
function injectObject(id, element, callback) { | ||
@@ -305,4 +405,8 @@ var OBJECT_STYLE = "display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;"; | ||
//Mutating the object element here seems to fire another load event. | ||
//Mutating the inner document of the object element is fine though. | ||
var objectElement = this; | ||
//Create the style element to be added to the object. | ||
var objectDocument = getDocument(this, function onObjectDocumentReady(objectDocument) { | ||
getDocument(objectElement, function onObjectDocumentReady(objectDocument) { | ||
var style = objectDocument.createElement("style"); | ||
@@ -316,5 +420,2 @@ style.innerHTML = "html, body { margin: 0; padding: 0 } div { -webkit-transition: opacity 0.01s; -ms-transition: opacity 0.01s; -o-transition: opacity 0.01s; transition: opacity 0.01s; opacity: 0; }"; | ||
//TODO: Is this needed here? | ||
//this.style.cssText = OBJECT_STYLE; | ||
//Notify that the element is ready to be listened to. | ||
@@ -327,49 +428,59 @@ callback(element); | ||
var style = getComputedStyle(element); | ||
if(style.position === "static") { | ||
element.style.position = "relative"; | ||
var position = style.position; | ||
var removeRelativeStyles = function(reporter, element, style, property) { | ||
function getNumericalValue(value) { | ||
return value.replace(/[^-\d\.]/g, ""); | ||
} | ||
function mutateDom() { | ||
if(position === "static") { | ||
element.style.position = "relative"; | ||
var value = style[property]; | ||
var removeRelativeStyles = function(reporter, element, style, property) { | ||
function getNumericalValue(value) { | ||
return value.replace(/[^-\d\.]/g, ""); | ||
} | ||
if(value !== "auto" && getNumericalValue(value) !== "0") { | ||
reporter.warn("An element that is positioned static has style." + property + "=" + value + " which is ignored due to the static positioning. The element will need to be positioned relative, so the style." + property + " will be set to 0. Element: ", element); | ||
element.style[property] = 0; | ||
} | ||
}; | ||
var value = style[property]; | ||
//Check so that there are no accidental styles that will make the element styled differently now that is is relative. | ||
//If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway). | ||
removeRelativeStyles(reporter, element, style, "top"); | ||
removeRelativeStyles(reporter, element, style, "right"); | ||
removeRelativeStyles(reporter, element, style, "bottom"); | ||
removeRelativeStyles(reporter, element, style, "left"); | ||
} | ||
if(value !== "auto" && getNumericalValue(value) !== "0") { | ||
reporter.warn("An element that is positioned static has style." + property + "=" + value + " which is ignored due to the static positioning. The element will need to be positioned relative, so the style." + property + " will be set to 0. Element: ", element); | ||
element.style[property] = 0; | ||
} | ||
}; | ||
//Add an object element as a child to the target element that will be listened to for resize events. | ||
var object = document.createElement("object"); | ||
object.type = "text/html"; | ||
object.style.cssText = OBJECT_STYLE; | ||
object.onload = onObjectLoad; | ||
object._erdObjectId = id; | ||
//Check so that there are no accidental styles that will make the element styled differently now that is is relative. | ||
//If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway). | ||
removeRelativeStyles(reporter, element, style, "top"); | ||
removeRelativeStyles(reporter, element, style, "right"); | ||
removeRelativeStyles(reporter, element, style, "bottom"); | ||
removeRelativeStyles(reporter, element, style, "left"); | ||
} | ||
//Safari: This must occur before adding the object to the DOM. | ||
//IE: Does not like that this happens before, even if it is also added after. | ||
if(!browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
//Add an object element as a child to the target element that will be listened to for resize events. | ||
var object = document.createElement("object"); | ||
object.style.cssText = OBJECT_STYLE; | ||
object.type = "text/html"; | ||
object.onload = onObjectLoad; | ||
object._erdObjectId = id; | ||
element.appendChild(object); | ||
//Safari: This must occur before adding the object to the DOM. | ||
//IE: Does not like that this happens before, even if it is also added after. | ||
if(!browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
//IE: This must occur after adding the object to the DOM. | ||
if(browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
element.appendChild(object); | ||
//IE: This must occur after adding the object to the DOM. | ||
if(browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
} | ||
if(batchUpdater) { | ||
batchUpdater.update(id, mutateDom); | ||
} else { | ||
mutateDom(); | ||
} | ||
} | ||
//Create an unique erd-target-id for the target element, so that event listeners can be identified to this element. | ||
var id = idHandler.set(element); | ||
//Obtain the id of the element (will be generated if not present), so that event listeners can be identified to this element. | ||
var id = idHandler.get(element); | ||
@@ -407,3 +518,3 @@ if(browserDetector.isIE(8)) { | ||
},{"./browser-detector":1,"./collection-utils":2}],5:[function(require,module,exports){ | ||
},{"./browser-detector":3,"./collection-utils":4}],7:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -428,3 +539,3 @@ | ||
},{}],6:[function(require,module,exports){ | ||
},{}],8:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -436,23 +547,18 @@ | ||
/** | ||
* Gets the resize detector id of the element. | ||
* Gets the resize detector id of the element. If the element does not have an id, one will be assigned to the element. | ||
* @public | ||
* @param {element} The target element to get the id of. | ||
* @param {element} element The target element to get the id of. | ||
* @param {boolean?} readonly An id will not be assigned to the element if the readonly parameter is true. Default is false. | ||
* @returns {string|number} The id of the element. | ||
*/ | ||
function getId(element) { | ||
function getId(element, readonly) { | ||
if(!readonly && !hasId(element)) { | ||
setId(element); | ||
} | ||
return element[ID_PROP_NAME]; | ||
} | ||
/** | ||
* Sets the resize detector id of the element. | ||
* @public | ||
* @param {element} The target element to set the id to. | ||
* @param {string?} An optional id to set to the element. If not specified, an id will be generated. All id's must be unique. | ||
* @returns {string|number} The id of the element. | ||
*/ | ||
function setId(element, id) { | ||
if(!id && id !== 0) { | ||
//Number should be generated. | ||
id = idGenerator.generate(); | ||
} | ||
function setId(element) { | ||
var id = idGenerator.generate(); | ||
@@ -464,9 +570,12 @@ element[ID_PROP_NAME] = id; | ||
function hasId(element) { | ||
return element[ID_PROP_NAME] !== undefined; | ||
} | ||
return { | ||
get: getId, | ||
set: setId | ||
get: getId | ||
}; | ||
}; | ||
},{}],7:[function(require,module,exports){ | ||
},{}],9:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -509,3 +618,3 @@ | ||
},{}],8:[function(require,module,exports){ | ||
},{}],10:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -547,3 +656,3 @@ | ||
}; | ||
},{}]},{},[3])(3) | ||
},{}]},{},[5])(5) | ||
}); |
/*! | ||
* element-resize-detector 0.2.4 (2015-03-25, 14:46) | ||
* element-resize-detector 0.2.7 (2015-04-08, 14:28) | ||
* https://github.com/wnr/element-resize-detector | ||
@@ -7,2 +7,2 @@ * Licensed under MIT | ||
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.elementResizeDetectorMaker=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b){"use strict";var c=b.exports={};c.isIE=function(a){function b(){var a=navigator.userAgent.toLowerCase();return-1!==a.indexOf("msie")||-1!==a.indexOf("trident")}if(!b())return!1;if(!a)return!0;var c=function(){var a,b=3,c=document.createElement("div"),d=c.getElementsByTagName("i");do c.innerHTML="<!--[if gt IE "+ ++b+"]><i></i><![endif]-->";while(d[0]);return b>4?b:a}();return a===c}},{}],2:[function(a,b){"use strict";var c=b.exports={};c.forEach=function(a,b){for(var c=0;c<a.length;c++){var d=b(a[c]);if(d)return d}}},{}],3:[function(a,b){"use strict";function c(a,b,c){var d=a[b];return void 0!==d&&null!==d||void 0===c?d:c}var d=a("./collection-utils").forEach,e=a("./element-utils"),f=a("./listener-handler"),g=a("./id-generator"),h=a("./id-handler"),i=a("./reporter");b.exports=function(a){function b(a,b,e){function f(a){var b=p.get(a);d(b,function(b){b(a)})}function g(a,b,c){p.add(b,c),a&&c(b)}if(e||(e=b,b=a,a={}),!b)throw new Error("At least one element required.");if(!e)throw new Error("Listener required.");void 0===b.length&&(b=[b]);var h=c(a,"callOnAdd",j.callOnAdd);d(b,function(a){var b=a.offsetWidth,c=a.offsetHeight;return q.isDetectable(a)?void g(h,a,e):q.makeDetectable(n,a,function(a){q.addListener(a,f),g(h,a,e);var d=a.offsetWidth,i=a.offsetHeight;h||b===d&&c===i||e(a)})})}a=a||{};var j={};j.callOnAdd=!!c(a,"callOnAdd",!0);var k=a.idHandler;if(!k){var l=g(),m=h(l);k=m}var n=a.reporter;if(!n){var o=n===!1;n=i(o)}var p=f(k),q=e(k);return{listenTo:b}}},{"./collection-utils":2,"./element-utils":4,"./id-generator":5,"./id-handler":6,"./listener-handler":7,"./reporter":8}],4:[function(a,b){"use strict";var c=a("./collection-utils").forEach,d=a("./browser-detector");b.exports=function(a){function b(b){return d.isIE(8)?!!a.get(b):!!g(b)}function e(a,c){function e(){c(a)}if(!b(a))throw new Error("Element is not detectable.");if(d.isIE(8))a.attachEvent("onresize",e);else{var f=g(a);f.contentDocument.defaultView.addEventListener("resize",e)}}function f(b,c,e){function f(a,c,e){function f(){function a(b,c){return b.contentDocument?void c(b.contentDocument):void setTimeout(function(){a(b,c)},100)}a(this,function(a){var b=a.createElement("style");b.innerHTML="html, body { margin: 0; padding: 0 } div { -webkit-transition: opacity 0.01s; -ms-transition: opacity 0.01s; -o-transition: opacity 0.01s; transition: opacity 0.01s; opacity: 0; }",a.head.appendChild(b),e(c)})}var g="display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;",h=getComputedStyle(c);if("static"===h.position){c.style.position="relative";var i=function(a,b,c,d){function e(a){return a.replace(/[^-\d\.]/g,"")}var f=c[d];"auto"!==f&&"0"!==e(f)&&(a.warn("An element that is positioned static has style."+d+"="+f+" which is ignored due to the static positioning. The element will need to be positioned relative, so the style."+d+" will be set to 0. Element: ",b),b.style[d]=0)};i(b,c,h,"top"),i(b,c,h,"right"),i(b,c,h,"bottom"),i(b,c,h,"left")}var j=document.createElement("object");j.type="text/html",j.style.cssText=g,j.onload=f,j._erdObjectId=a,d.isIE()||(j.data="about:blank"),c.appendChild(j),d.isIE()&&(j.data="about:blank")}var g=a.set(c);d.isIE(8)?e(c):f(g,c,e)}function g(a){return c(a.children,function(a){return void 0!==a._erdObjectId&&null!==a._erdObjectId?a:void 0})}return{isDetectable:b,makeDetectable:f,addListener:e}}},{"./browser-detector":1,"./collection-utils":2}],5:[function(a,b){"use strict";b.exports=function(){function a(){return b++}var b=1;return{generate:a}}},{}],6:[function(a,b){"use strict";b.exports=function(a){function b(a){return a[d]}function c(b,c){return c||0===c||(c=a.generate()),b[d]=c,c}var d="_erdTargetId";return{get:b,set:c}}},{}],7:[function(a,b){"use strict";b.exports=function(a){function b(b){return d[a.get(b)]}function c(b,c){var e=a.get(b);d[e]||(d[e]=[]),d[e].push(c)}var d={};return{get:b,add:c}}},{}],8:[function(a,b){"use strict";b.exports=function(a){function b(){}var c={log:b,warn:b,error:b};if(!a&&window.console){var d=function(a,b){a[b]=function(){console[b].apply(console,arguments)}};d(c,"log"),d(c,"warn"),d(c,"error")}return c}},{}]},{},[3])(3)}); | ||
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.elementResizeDetectorMaker=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b){"use strict";var c=a("./utils");b.exports=function(a){function b(a,b){l&&k&&0===n&&f(),o[a]||(o[a]=[]),o[a].push(b),n++}function d(a){void 0===a&&(a=k),m&&(h(m),m=null),k?f():e()}function e(){for(var a in o)if(o.hasOwnProperty(a))for(var b=o[a],c=0;c<b.length;c++){var d=b[c];d()}g()}function f(){m=i(function(){e()})}function g(){n=0,o={}}function h(a){var b=window.clearTimeout;return b(a)}function i(a){var b=function(a){return window.setTimeout(a,0)};return b(a)}a=a||{};var j=a.reporter,k=c.getOption(a,"async",!0),l=c.getOption(a,"auto",!0);if(l&&!k&&(j.warn("Invalid options combination. auto=true and async=false is invalid. Setting async=true."),k=!0),!j)throw new Error("Reporter required.");var m,n=0,o={};return{update:b,force:d}}},{"./utils":2}],2:[function(a,b){"use strict";function c(a,b,c){var d=a[b];return void 0!==d&&null!==d||void 0===c?d:c}var d=b.exports={};d.getOption=c},{}],3:[function(a,b){"use strict";var c=b.exports={};c.isIE=function(a){function b(){var a=navigator.userAgent.toLowerCase();return-1!==a.indexOf("msie")||-1!==a.indexOf("trident")}if(!b())return!1;if(!a)return!0;var c=function(){var a,b=3,c=document.createElement("div"),d=c.getElementsByTagName("i");do c.innerHTML="<!--[if gt IE "+ ++b+"]><i></i><![endif]-->";while(d[0]);return b>4?b:a}();return a===c}},{}],4:[function(a,b){"use strict";var c=b.exports={};c.forEach=function(a,b){for(var c=0;c<a.length;c++){var d=b(a[c]);if(d)return d}}},{}],5:[function(a,b){"use strict";function c(a,b,c){var d=a[b];return void 0!==d&&null!==d||void 0===c?d:c}var d=a("./collection-utils").forEach,e=a("./element-utils"),f=a("./listener-handler"),g=a("./id-generator"),h=a("./id-handler"),i=a("./reporter"),j=a("batch-updater");b.exports=function(a){function b(a,b,e){function f(a){var b=q.get(a);d(b,function(b){b(a)})}function g(a,b,c){q.add(b,c),a&&c(b)}if(e||(e=b,b=a,a={}),!b)throw new Error("At least one element required.");if(!e)throw new Error("Listener required.");void 0===b.length&&(b=[b]);var h=c(a,"callOnAdd",p.callOnAdd),i=c(a,"batchUpdater",p.batchUpdater);d(b,function(a){return r.isDetectable(a)?void g(h,a,e):r.makeDetectable(i,n,a,function(a){r.addListener(a,f),g(h,a,e)})})}a=a||{};var k=a.idHandler;if(!k){var l=g(),m=h(l);k=m}var n=a.reporter;if(!n){var o=n===!1;n=i(o)}var p={};p.callOnAdd=!!c(a,"callOnAdd",!0),p.batchUpdater=c(a,"batchUpdater",j({reporter:n}));var q=f(k),r=e(k);return{listenTo:b}}},{"./collection-utils":4,"./element-utils":6,"./id-generator":7,"./id-handler":8,"./listener-handler":9,"./reporter":10,"batch-updater":1}],6:[function(a,b){"use strict";var c=a("./collection-utils").forEach,d=a("./browser-detector");b.exports=function(a){function b(b){return d.isIE(8)?!!a.get(b):!!g(b)}function e(a,c){function e(){c(a)}if(!b(a))throw new Error("Element is not detectable.");if(d.isIE(8))a.attachEvent("onresize",e);else{var f=g(a);f.contentDocument.defaultView.addEventListener("resize",e)}}function f(b,c,e,f){function g(a,e,f){function g(){function a(b,c){return b.contentDocument?void c(b.contentDocument):void setTimeout(function(){a(b,c)},100)}var b=this;a(b,function(a){var b=a.createElement("style");b.innerHTML="html, body { margin: 0; padding: 0 } div { -webkit-transition: opacity 0.01s; -ms-transition: opacity 0.01s; -o-transition: opacity 0.01s; transition: opacity 0.01s; opacity: 0; }",a.head.appendChild(b),f(e)})}function h(){if("static"===k){e.style.position="relative";var b=function(a,b,c,d){function e(a){return a.replace(/[^-\d\.]/g,"")}var f=c[d];"auto"!==f&&"0"!==e(f)&&(a.warn("An element that is positioned static has style."+d+"="+f+" which is ignored due to the static positioning. The element will need to be positioned relative, so the style."+d+" will be set to 0. Element: ",b),b.style[d]=0)};b(c,e,j,"top"),b(c,e,j,"right"),b(c,e,j,"bottom"),b(c,e,j,"left")}var f=document.createElement("object");f.style.cssText=i,f.type="text/html",f.onload=g,f._erdObjectId=a,d.isIE()||(f.data="about:blank"),e.appendChild(f),d.isIE()&&(f.data="about:blank")}var i="display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;",j=getComputedStyle(e),k=j.position;b?b.update(a,h):h()}var h=a.get(e);d.isIE(8)?f(e):g(h,e,f)}function g(a){return c(a.children,function(a){return void 0!==a._erdObjectId&&null!==a._erdObjectId?a:void 0})}return{isDetectable:b,makeDetectable:f,addListener:e}}},{"./browser-detector":3,"./collection-utils":4}],7:[function(a,b){"use strict";b.exports=function(){function a(){return b++}var b=1;return{generate:a}}},{}],8:[function(a,b){"use strict";b.exports=function(a){function b(a,b){return b||d(a)||c(a),a[e]}function c(b){var c=a.generate();return b[e]=c,c}function d(a){return void 0!==a[e]}var e="_erdTargetId";return{get:b}}},{}],9:[function(a,b){"use strict";b.exports=function(a){function b(b){return d[a.get(b)]}function c(b,c){var e=a.get(b);d[e]||(d[e]=[]),d[e].push(c)}var d={};return{get:b,add:c}}},{}],10:[function(a,b){"use strict";b.exports=function(a){function b(){}var c={log:b,warn:b,error:b};if(!a&&window.console){var d=function(a,b){a[b]=function(){console[b].apply(console,arguments)}};d(c,"log"),d(c,"warn"),d(c,"error")}return c}},{}]},{},[5])(5)}); |
{ | ||
"name": "element-resize-detector", | ||
"version": "0.2.5", | ||
"version": "0.2.8", | ||
"description": "resize event emitter for elements.", | ||
@@ -13,2 +13,5 @@ "homepage": "https://github.com/wnr/element-resize-detector", | ||
"license": "MIT", | ||
"dependencies": { | ||
"batch-updater": "^0.1.0" | ||
}, | ||
"devDependencies": { | ||
@@ -15,0 +18,0 @@ "grunt": "^0.4.5", |
@@ -11,2 +11,3 @@ //Heavily inspired by http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/ | ||
var reporterMaker = require("./reporter"); | ||
var batchUpdater = require("batch-updater"); | ||
@@ -41,6 +42,2 @@ /** | ||
//Options to be used as default for the listenTo function. | ||
var globalOptions = {}; | ||
globalOptions.callOnAdd = !!getOption(options, "callOnAdd", true); | ||
//idHandler is currently not an option to the listenTo function, so it should not be added to globalOptions. | ||
@@ -64,2 +61,7 @@ var idHandler = options.idHandler; | ||
//Options to be used as default for the listenTo function. | ||
var globalOptions = {}; | ||
globalOptions.callOnAdd = !!getOption(options, "callOnAdd", true); | ||
globalOptions.batchUpdater = getOption(options, "batchUpdater", batchUpdater({ reporter: reporter })); | ||
var eventListenerHandler = listenerHandlerMaker(idHandler); | ||
@@ -111,27 +113,11 @@ var elementUtils = elementUtilsMaker(idHandler); | ||
var callOnAdd = getOption(options, "callOnAdd", globalOptions.callOnAdd); | ||
var callOnAdd = getOption(options, "callOnAdd", globalOptions.callOnAdd); | ||
var batchUpdater = getOption(options, "batchUpdater", globalOptions.batchUpdater); | ||
forEach(elements, function attachListenerToElement(element) { | ||
//The element may change size directly after the call to listenTo, which would be unable to detect it because | ||
//the async adding of the object. By checking the size before and after, the size change can still be detected | ||
//and the listener can be called accordingly. | ||
var preWidth = element.offsetWidth; | ||
var preHeight = element.offsetHeight; | ||
if(!elementUtils.isDetectable(element)) { | ||
//The element is not prepared to be detectable, so do prepare it and add a listener to it. | ||
return elementUtils.makeDetectable(reporter, element, function onElementDetectable(element) { | ||
return elementUtils.makeDetectable(batchUpdater, reporter, element, function onElementDetectable(element) { | ||
elementUtils.addListener(element, onResizeCallback); | ||
onElementReadyToAddListener(callOnAdd, element, listener); | ||
//Only here the uncaught resize may occur (since this code is async). | ||
//Check if the size is the same as when adding the listener. | ||
var postWidth = element.offsetWidth; | ||
var postHeight = element.offsetHeight; | ||
//If callOnAdd is true, then the listener will have been called either way, so no need to call the listener manually then. | ||
if(!callOnAdd && (preWidth !== postWidth || preHeight !== postHeight)) { | ||
//The element was changed while the object was being added. Call the listener. | ||
listener(element); | ||
} | ||
}); | ||
@@ -138,0 +124,0 @@ } |
@@ -53,3 +53,3 @@ "use strict"; | ||
*/ | ||
function makeDetectable(reporter, element, callback) { | ||
function makeDetectable(batchUpdater, reporter, element, callback) { | ||
function injectObject(id, element, callback) { | ||
@@ -76,4 +76,8 @@ var OBJECT_STYLE = "display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;"; | ||
//Mutating the object element here seems to fire another load event. | ||
//Mutating the inner document of the object element is fine though. | ||
var objectElement = this; | ||
//Create the style element to be added to the object. | ||
getDocument(this, function onObjectDocumentReady(objectDocument) { | ||
getDocument(objectElement, function onObjectDocumentReady(objectDocument) { | ||
var style = objectDocument.createElement("style"); | ||
@@ -87,5 +91,2 @@ style.innerHTML = "html, body { margin: 0; padding: 0 } div { -webkit-transition: opacity 0.01s; -ms-transition: opacity 0.01s; -o-transition: opacity 0.01s; transition: opacity 0.01s; opacity: 0; }"; | ||
//TODO: Is this needed here? | ||
//this.style.cssText = OBJECT_STYLE; | ||
//Notify that the element is ready to be listened to. | ||
@@ -98,49 +99,59 @@ callback(element); | ||
var style = getComputedStyle(element); | ||
if(style.position === "static") { | ||
element.style.position = "relative"; | ||
var position = style.position; | ||
var removeRelativeStyles = function(reporter, element, style, property) { | ||
function getNumericalValue(value) { | ||
return value.replace(/[^-\d\.]/g, ""); | ||
} | ||
function mutateDom() { | ||
if(position === "static") { | ||
element.style.position = "relative"; | ||
var value = style[property]; | ||
var removeRelativeStyles = function(reporter, element, style, property) { | ||
function getNumericalValue(value) { | ||
return value.replace(/[^-\d\.]/g, ""); | ||
} | ||
if(value !== "auto" && getNumericalValue(value) !== "0") { | ||
reporter.warn("An element that is positioned static has style." + property + "=" + value + " which is ignored due to the static positioning. The element will need to be positioned relative, so the style." + property + " will be set to 0. Element: ", element); | ||
element.style[property] = 0; | ||
} | ||
}; | ||
var value = style[property]; | ||
//Check so that there are no accidental styles that will make the element styled differently now that is is relative. | ||
//If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway). | ||
removeRelativeStyles(reporter, element, style, "top"); | ||
removeRelativeStyles(reporter, element, style, "right"); | ||
removeRelativeStyles(reporter, element, style, "bottom"); | ||
removeRelativeStyles(reporter, element, style, "left"); | ||
} | ||
if(value !== "auto" && getNumericalValue(value) !== "0") { | ||
reporter.warn("An element that is positioned static has style." + property + "=" + value + " which is ignored due to the static positioning. The element will need to be positioned relative, so the style." + property + " will be set to 0. Element: ", element); | ||
element.style[property] = 0; | ||
} | ||
}; | ||
//Add an object element as a child to the target element that will be listened to for resize events. | ||
var object = document.createElement("object"); | ||
object.type = "text/html"; | ||
object.style.cssText = OBJECT_STYLE; | ||
object.onload = onObjectLoad; | ||
object._erdObjectId = id; | ||
//Check so that there are no accidental styles that will make the element styled differently now that is is relative. | ||
//If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway). | ||
removeRelativeStyles(reporter, element, style, "top"); | ||
removeRelativeStyles(reporter, element, style, "right"); | ||
removeRelativeStyles(reporter, element, style, "bottom"); | ||
removeRelativeStyles(reporter, element, style, "left"); | ||
} | ||
//Safari: This must occur before adding the object to the DOM. | ||
//IE: Does not like that this happens before, even if it is also added after. | ||
if(!browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
//Add an object element as a child to the target element that will be listened to for resize events. | ||
var object = document.createElement("object"); | ||
object.style.cssText = OBJECT_STYLE; | ||
object.type = "text/html"; | ||
object.onload = onObjectLoad; | ||
object._erdObjectId = id; | ||
element.appendChild(object); | ||
//Safari: This must occur before adding the object to the DOM. | ||
//IE: Does not like that this happens before, even if it is also added after. | ||
if(!browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
//IE: This must occur after adding the object to the DOM. | ||
if(browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
element.appendChild(object); | ||
//IE: This must occur after adding the object to the DOM. | ||
if(browserDetector.isIE()) { | ||
object.data = "about:blank"; | ||
} | ||
} | ||
if(batchUpdater) { | ||
batchUpdater.update(id, mutateDom); | ||
} else { | ||
mutateDom(); | ||
} | ||
} | ||
//Create an unique erd-target-id for the target element, so that event listeners can be identified to this element. | ||
var id = idHandler.set(element); | ||
//Obtain the id of the element (will be generated if not present), so that event listeners can be identified to this element. | ||
var id = idHandler.get(element); | ||
@@ -147,0 +158,0 @@ if(browserDetector.isIE(8)) { |
@@ -7,23 +7,18 @@ "use strict"; | ||
/** | ||
* Gets the resize detector id of the element. | ||
* Gets the resize detector id of the element. If the element does not have an id, one will be assigned to the element. | ||
* @public | ||
* @param {element} The target element to get the id of. | ||
* @param {element} element The target element to get the id of. | ||
* @param {boolean?} readonly An id will not be assigned to the element if the readonly parameter is true. Default is false. | ||
* @returns {string|number} The id of the element. | ||
*/ | ||
function getId(element) { | ||
function getId(element, readonly) { | ||
if(!readonly && !hasId(element)) { | ||
setId(element); | ||
} | ||
return element[ID_PROP_NAME]; | ||
} | ||
/** | ||
* Sets the resize detector id of the element. | ||
* @public | ||
* @param {element} The target element to set the id to. | ||
* @param {string?} An optional id to set to the element. If not specified, an id will be generated. All id's must be unique. | ||
* @returns {string|number} The id of the element. | ||
*/ | ||
function setId(element, id) { | ||
if(!id && id !== 0) { | ||
//Number should be generated. | ||
id = idGenerator.generate(); | ||
} | ||
function setId(element) { | ||
var id = idGenerator.generate(); | ||
@@ -35,6 +30,9 @@ element[ID_PROP_NAME] = id; | ||
function hasId(element) { | ||
return element[ID_PROP_NAME] !== undefined; | ||
} | ||
return { | ||
get: getId, | ||
set: setId | ||
get: getId | ||
}; | ||
}; |
@@ -209,3 +209,3 @@ /* global describe:false, it:false, beforeEach:false, expect:false, elementResizeDetectorMaker:false, _:false, $:false, jasmine:false */ | ||
var erd = elementResizeDetectorMaker({ | ||
callOnAdd: false, | ||
callOnAdd: true, | ||
reporter: reporter | ||
@@ -216,7 +216,6 @@ }); | ||
erd.listenTo($("#test, #test2"), listener1); | ||
$("#test").width(300); | ||
setTimeout(function() { | ||
expect(listener1).toHaveBeenCalledWith($("#test")[0]); | ||
expect(listener1).not.toHaveBeenCalledWith($("#test2")[0]); | ||
expect(listener1).toHaveBeenCalledWith($("#test2")[0]); | ||
done(); | ||
@@ -231,15 +230,15 @@ }, 100); | ||
get: function(element) { | ||
return $(element).attr(ID_ATTR); | ||
}, | ||
set: function(element) { | ||
var id; | ||
if(element[ID_ATTR] === undefined) { | ||
var id; | ||
if($(element).attr("id") === "test") { | ||
id = "test+1"; | ||
} else if($(element).attr("id") === "test2") { | ||
id = "test2+2"; | ||
if($(element).attr("id") === "test") { | ||
id = "test+1"; | ||
} else if($(element).attr("id") === "test2") { | ||
id = "test2+2"; | ||
} | ||
$(element).attr(ID_ATTR, id); | ||
} | ||
$(element).attr(ID_ATTR, id); | ||
return id; | ||
return $(element).attr(ID_ATTR); | ||
} | ||
@@ -314,4 +313,6 @@ }; | ||
if(window.console) { | ||
console.warn = oldWarn; | ||
expect(called).toEqual(true); | ||
setTimeout(function() { | ||
console.warn = oldWarn; | ||
expect(called).toEqual(true); | ||
}, 200); | ||
} | ||
@@ -318,0 +319,0 @@ }); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
140531
24
2231
1
+ Addedbatch-updater@^0.1.0
+ Addedbatch-updater@0.1.0(transitive)