UNPKG

handsfree

Version:

A library for creating head-controlled, handsfree user interfaces via computer vision just...like...✨...that!

814 lines (812 loc) 7.91 MB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["Handsfree"] = factory(); else root["Handsfree"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ function hotDisposeChunk(chunkId) { /******/ delete installedChunks[chunkId]; /******/ } /******/ var parentHotUpdateCallback = this["webpackHotUpdateHandsfree"]; /******/ this["webpackHotUpdateHandsfree"] = // eslint-disable-next-line no-unused-vars /******/ function webpackHotUpdateCallback(chunkId, moreModules) { /******/ hotAddUpdateChunk(chunkId, moreModules); /******/ if (parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules); /******/ } ; /******/ /******/ // eslint-disable-next-line no-unused-vars /******/ function hotDownloadUpdateChunk(chunkId) { /******/ var head = document.getElementsByTagName("head")[0]; /******/ var script = document.createElement("script"); /******/ script.charset = "utf-8"; /******/ script.src = __webpack_require__.p + "" + chunkId + "." + hotCurrentHash + ".hot-update.js"; /******/ if (null) script.crossOrigin = null; /******/ head.appendChild(script); /******/ } /******/ /******/ // eslint-disable-next-line no-unused-vars /******/ function hotDownloadManifest(requestTimeout) { /******/ requestTimeout = requestTimeout || 10000; /******/ return new Promise(function(resolve, reject) { /******/ if (typeof XMLHttpRequest === "undefined") { /******/ return reject(new Error("No browser support")); /******/ } /******/ try { /******/ var request = new XMLHttpRequest(); /******/ var requestPath = __webpack_require__.p + "" + hotCurrentHash + ".hot-update.json"; /******/ request.open("GET", requestPath, true); /******/ request.timeout = requestTimeout; /******/ request.send(null); /******/ } catch (err) { /******/ return reject(err); /******/ } /******/ request.onreadystatechange = function() { /******/ if (request.readyState !== 4) return; /******/ if (request.status === 0) { /******/ // timeout /******/ reject( /******/ new Error("Manifest request to " + requestPath + " timed out.") /******/ ); /******/ } else if (request.status === 404) { /******/ // no update available /******/ resolve(); /******/ } else if (request.status !== 200 && request.status !== 304) { /******/ // other failure /******/ reject(new Error("Manifest request to " + requestPath + " failed.")); /******/ } else { /******/ // success /******/ try { /******/ var update = JSON.parse(request.responseText); /******/ } catch (e) { /******/ reject(e); /******/ return; /******/ } /******/ resolve(update); /******/ } /******/ }; /******/ }); /******/ } /******/ /******/ var hotApplyOnUpdate = true; /******/ // eslint-disable-next-line no-unused-vars /******/ var hotCurrentHash = "069be2a1c6b9d323a819"; /******/ var hotRequestTimeout = 10000; /******/ var hotCurrentModuleData = {}; /******/ var hotCurrentChildModule; /******/ // eslint-disable-next-line no-unused-vars /******/ var hotCurrentParents = []; /******/ // eslint-disable-next-line no-unused-vars /******/ var hotCurrentParentsTemp = []; /******/ /******/ // eslint-disable-next-line no-unused-vars /******/ function hotCreateRequire(moduleId) { /******/ var me = installedModules[moduleId]; /******/ if (!me) return __webpack_require__; /******/ var fn = function(request) { /******/ if (me.hot.active) { /******/ if (installedModules[request]) { /******/ if (installedModules[request].parents.indexOf(moduleId) === -1) { /******/ installedModules[request].parents.push(moduleId); /******/ } /******/ } else { /******/ hotCurrentParents = [moduleId]; /******/ hotCurrentChildModule = request; /******/ } /******/ if (me.children.indexOf(request) === -1) { /******/ me.children.push(request); /******/ } /******/ } else { /******/ console.warn( /******/ "[HMR] unexpected require(" + /******/ request + /******/ ") from disposed module " + /******/ moduleId /******/ ); /******/ hotCurrentParents = []; /******/ } /******/ return __webpack_require__(request); /******/ }; /******/ var ObjectFactory = function ObjectFactory(name) { /******/ return { /******/ configurable: true, /******/ enumerable: true, /******/ get: function() { /******/ return __webpack_require__[name]; /******/ }, /******/ set: function(value) { /******/ __webpack_require__[name] = value; /******/ } /******/ }; /******/ }; /******/ for (var name in __webpack_require__) { /******/ if ( /******/ Object.prototype.hasOwnProperty.call(__webpack_require__, name) && /******/ name !== "e" && /******/ name !== "t" /******/ ) { /******/ Object.defineProperty(fn, name, ObjectFactory(name)); /******/ } /******/ } /******/ fn.e = function(chunkId) { /******/ if (hotStatus === "ready") hotSetStatus("prepare"); /******/ hotChunksLoading++; /******/ return __webpack_require__.e(chunkId).then(finishChunkLoading, function(err) { /******/ finishChunkLoading(); /******/ throw err; /******/ }); /******/ /******/ function finishChunkLoading() { /******/ hotChunksLoading--; /******/ if (hotStatus === "prepare") { /******/ if (!hotWaitingFilesMap[chunkId]) { /******/ hotEnsureUpdateChunk(chunkId); /******/ } /******/ if (hotChunksLoading === 0 && hotWaitingFiles === 0) { /******/ hotUpdateDownloaded(); /******/ } /******/ } /******/ } /******/ }; /******/ fn.t = function(value, mode) { /******/ if (mode & 1) value = fn(value); /******/ return __webpack_require__.t(value, mode & ~1); /******/ }; /******/ return fn; /******/ } /******/ /******/ // eslint-disable-next-line no-unused-vars /******/ function hotCreateModule(moduleId) { /******/ var hot = { /******/ // private stuff /******/ _acceptedDependencies: {}, /******/ _declinedDependencies: {}, /******/ _selfAccepted: false, /******/ _selfDeclined: false, /******/ _disposeHandlers: [], /******/ _main: hotCurrentChildModule !== moduleId, /******/ /******/ // Module API /******/ active: true, /******/ accept: function(dep, callback) { /******/ if (dep === undefined) hot._selfAccepted = true; /******/ else if (typeof dep === "function") hot._selfAccepted = dep; /******/ else if (typeof dep === "object") /******/ for (var i = 0; i < dep.length; i++) /******/ hot._acceptedDependencies[dep[i]] = callback || function() {}; /******/ else hot._acceptedDependencies[dep] = callback || function() {}; /******/ }, /******/ decline: function(dep) { /******/ if (dep === undefined) hot._selfDeclined = true; /******/ else if (typeof dep === "object") /******/ for (var i = 0; i < dep.length; i++) /******/ hot._declinedDependencies[dep[i]] = true; /******/ else hot._declinedDependencies[dep] = true; /******/ }, /******/ dispose: function(callback) { /******/ hot._disposeHandlers.push(callback); /******/ }, /******/ addDisposeHandler: function(callback) { /******/ hot._disposeHandlers.push(callback); /******/ }, /******/ removeDisposeHandler: function(callback) { /******/ var idx = hot._disposeHandlers.indexOf(callback); /******/ if (idx >= 0) hot._disposeHandlers.splice(idx, 1); /******/ }, /******/ /******/ // Management API /******/ check: hotCheck, /******/ apply: hotApply, /******/ status: function(l) { /******/ if (!l) return hotStatus; /******/ hotStatusHandlers.push(l); /******/ }, /******/ addStatusHandler: function(l) { /******/ hotStatusHandlers.push(l); /******/ }, /******/ removeStatusHandler: function(l) { /******/ var idx = hotStatusHandlers.indexOf(l); /******/ if (idx >= 0) hotStatusHandlers.splice(idx, 1); /******/ }, /******/ /******/ //inherit from previous dispose call /******/ data: hotCurrentModuleData[moduleId] /******/ }; /******/ hotCurrentChildModule = undefined; /******/ return hot; /******/ } /******/ /******/ var hotStatusHandlers = []; /******/ var hotStatus = "idle"; /******/ /******/ function hotSetStatus(newStatus) { /******/ hotStatus = newStatus; /******/ for (var i = 0; i < hotStatusHandlers.length; i++) /******/ hotStatusHandlers[i].call(null, newStatus); /******/ } /******/ /******/ // while downloading /******/ var hotWaitingFiles = 0; /******/ var hotChunksLoading = 0; /******/ var hotWaitingFilesMap = {}; /******/ var hotRequestedFilesMap = {}; /******/ var hotAvailableFilesMap = {}; /******/ var hotDeferred; /******/ /******/ // The update info /******/ var hotUpdate, hotUpdateNewHash; /******/ /******/ function toModuleId(id) { /******/ var isNumber = +id + "" === id; /******/ return isNumber ? +id : id; /******/ } /******/ /******/ function hotCheck(apply) { /******/ if (hotStatus !== "idle") { /******/ throw new Error("check() is only allowed in idle status"); /******/ } /******/ hotApplyOnUpdate = apply; /******/ hotSetStatus("check"); /******/ return hotDownloadManifest(hotRequestTimeout).then(function(update) { /******/ if (!update) { /******/ hotSetStatus("idle"); /******/ return null; /******/ } /******/ hotRequestedFilesMap = {}; /******/ hotWaitingFilesMap = {}; /******/ hotAvailableFilesMap = update.c; /******/ hotUpdateNewHash = update.h; /******/ /******/ hotSetStatus("prepare"); /******/ var promise = new Promise(function(resolve, reject) { /******/ hotDeferred = { /******/ resolve: resolve, /******/ reject: reject /******/ }; /******/ }); /******/ hotUpdate = {}; /******/ var chunkId = "handsfree"; /******/ // eslint-disable-next-line no-lone-blocks /******/ { /******/ /*globals chunkId */ /******/ hotEnsureUpdateChunk(chunkId); /******/ } /******/ if ( /******/ hotStatus === "prepare" && /******/ hotChunksLoading === 0 && /******/ hotWaitingFiles === 0 /******/ ) { /******/ hotUpdateDownloaded(); /******/ } /******/ return promise; /******/ }); /******/ } /******/ /******/ // eslint-disable-next-line no-unused-vars /******/ function hotAddUpdateChunk(chunkId, moreModules) { /******/ if (!hotAvailableFilesMap[chunkId] || !hotRequestedFilesMap[chunkId]) /******/ return; /******/ hotRequestedFilesMap[chunkId] = false; /******/ for (var moduleId in moreModules) { /******/ if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { /******/ hotUpdate[moduleId] = moreModules[moduleId]; /******/ } /******/ } /******/ if (--hotWaitingFiles === 0 && hotChunksLoading === 0) { /******/ hotUpdateDownloaded(); /******/ } /******/ } /******/ /******/ function hotEnsureUpdateChunk(chunkId) { /******/ if (!hotAvailableFilesMap[chunkId]) { /******/ hotWaitingFilesMap[chunkId] = true; /******/ } else { /******/ hotRequestedFilesMap[chunkId] = true; /******/ hotWaitingFiles++; /******/ hotDownloadUpdateChunk(chunkId); /******/ } /******/ } /******/ /******/ function hotUpdateDownloaded() { /******/ hotSetStatus("ready"); /******/ var deferred = hotDeferred; /******/ hotDeferred = null; /******/ if (!deferred) return; /******/ if (hotApplyOnUpdate) { /******/ // Wrap deferred object in Promise to mark it as a well-handled Promise to /******/ // avoid triggering uncaught exception warning in Chrome. /******/ // See https://bugs.chromium.org/p/chromium/issues/detail?id=465666 /******/ Promise.resolve() /******/ .then(function() { /******/ return hotApply(hotApplyOnUpdate); /******/ }) /******/ .then( /******/ function(result) { /******/ deferred.resolve(result); /******/ }, /******/ function(err) { /******/ deferred.reject(err); /******/ } /******/ ); /******/ } else { /******/ var outdatedModules = []; /******/ for (var id in hotUpdate) { /******/ if (Object.prototype.hasOwnProperty.call(hotUpdate, id)) { /******/ outdatedModules.push(toModuleId(id)); /******/ } /******/ } /******/ deferred.resolve(outdatedModules); /******/ } /******/ } /******/ /******/ function hotApply(options) { /******/ if (hotStatus !== "ready") /******/ throw new Error("apply() is only allowed in ready status"); /******/ options = options || {}; /******/ /******/ var cb; /******/ var i; /******/ var j; /******/ var module; /******/ var moduleId; /******/ /******/ function getAffectedStuff(updateModuleId) { /******/ var outdatedModules = [updateModuleId]; /******/ var outdatedDependencies = {}; /******/ /******/ var queue = outdatedModules.slice().map(function(id) { /******/ return { /******/ chain: [id], /******/ id: id /******/ }; /******/ }); /******/ while (queue.length > 0) { /******/ var queueItem = queue.pop(); /******/ var moduleId = queueItem.id; /******/ var chain = queueItem.chain; /******/ module = installedModules[moduleId]; /******/ if (!module || module.hot._selfAccepted) continue; /******/ if (module.hot._selfDeclined) { /******/ return { /******/ type: "self-declined", /******/ chain: chain, /******/ moduleId: moduleId /******/ }; /******/ } /******/ if (module.hot._main) { /******/ return { /******/ type: "unaccepted", /******/ chain: chain, /******/ moduleId: moduleId /******/ }; /******/ } /******/ for (var i = 0; i < module.parents.length; i++) { /******/ var parentId = module.parents[i]; /******/ var parent = installedModules[parentId]; /******/ if (!parent) continue; /******/ if (parent.hot._declinedDependencies[moduleId]) { /******/ return { /******/ type: "declined", /******/ chain: chain.concat([parentId]), /******/ moduleId: moduleId, /******/ parentId: parentId /******/ }; /******/ } /******/ if (outdatedModules.indexOf(parentId) !== -1) continue; /******/ if (parent.hot._acceptedDependencies[moduleId]) { /******/ if (!outdatedDependencies[parentId]) /******/ outdatedDependencies[parentId] = []; /******/ addAllToSet(outdatedDependencies[parentId], [moduleId]); /******/ continue; /******/ } /******/ delete outdatedDependencies[parentId]; /******/ outdatedModules.push(parentId); /******/ queue.push({ /******/ chain: chain.concat([parentId]), /******/ id: parentId /******/ }); /******/ } /******/ } /******/ /******/ return { /******/ type: "accepted", /******/ moduleId: updateModuleId, /******/ outdatedModules: outdatedModules, /******/ outdatedDependencies: outdatedDependencies /******/ }; /******/ } /******/ /******/ function addAllToSet(a, b) { /******/ for (var i = 0; i < b.length; i++) { /******/ var item = b[i]; /******/ if (a.indexOf(item) === -1) a.push(item); /******/ } /******/ } /******/ /******/ // at begin all updates modules are outdated /******/ // the "outdated" status can propagate to parents if they don't accept the children /******/ var outdatedDependencies = {}; /******/ var outdatedModules = []; /******/ var appliedUpdate = {}; /******/ /******/ var warnUnexpectedRequire = function warnUnexpectedRequire() { /******/ console.warn( /******/ "[HMR] unexpected require(" + result.moduleId + ") to disposed module" /******/ ); /******/ }; /******/ /******/ for (var id in hotUpdate) { /******/ if (Object.prototype.hasOwnProperty.call(hotUpdate, id)) { /******/ moduleId = toModuleId(id); /******/ /** @type {TODO} */ /******/ var result; /******/ if (hotUpdate[id]) { /******/ result = getAffectedStuff(moduleId); /******/ } else { /******/ result = { /******/ type: "disposed", /******/ moduleId: id /******/ }; /******/ } /******/ /** @type {Error|false} */ /******/ var abortError = false; /******/ var doApply = false; /******/ var doDispose = false; /******/ var chainInfo = ""; /******/ if (result.chain) { /******/ chainInfo = "\nUpdate propagation: " + result.chain.join(" -> "); /******/ } /******/ switch (result.type) { /******/ case "self-declined": /******/ if (options.onDeclined) options.onDeclined(result); /******/ if (!options.ignoreDeclined) /******/ abortError = new Error( /******/ "Aborted because of self decline: " + /******/ result.moduleId + /******/ chainInfo /******/ ); /******/ break; /******/ case "declined": /******/ if (options.onDeclined) options.onDeclined(result); /******/ if (!options.ignoreDeclined) /******/ abortError = new Error( /******/ "Aborted because of declined dependency: " + /******/ result.moduleId + /******/ " in " + /******/ result.parentId + /******/ chainInfo /******/ ); /******/ break; /******/ case "unaccepted": /******/ if (options.onUnaccepted) options.onUnaccepted(result); /******/ if (!options.ignoreUnaccepted) /******/ abortError = new Error( /******/ "Aborted because " + moduleId + " is not accepted" + chainInfo /******/ ); /******/ break; /******/ case "accepted": /******/ if (options.onAccepted) options.onAccepted(result); /******/ doApply = true; /******/ break; /******/ case "disposed": /******/ if (options.onDisposed) options.onDisposed(result); /******/ doDispose = true; /******/ break; /******/ default: /******/ throw new Error("Unexception type " + result.type); /******/ } /******/ if (abortError) { /******/ hotSetStatus("abort"); /******/ return Promise.reject(abortError); /******/ } /******/ if (doApply) { /******/ appliedUpdate[moduleId] = hotUpdate[moduleId]; /******/ addAllToSet(outdatedModules, result.outdatedModules); /******/ for (moduleId in result.outdatedDependencies) { /******/ if ( /******/ Object.prototype.hasOwnProperty.call( /******/ result.outdatedDependencies, /******/ moduleId /******/ ) /******/ ) { /******/ if (!outdatedDependencies[moduleId]) /******/ outdatedDependencies[moduleId] = []; /******/ addAllToSet( /******/ outdatedDependencies[moduleId], /******/ result.outdatedDependencies[moduleId] /******/ ); /******/ } /******/ } /******/ } /******/ if (doDispose) { /******/ addAllToSet(outdatedModules, [result.moduleId]); /******/ appliedUpdate[moduleId] = warnUnexpectedRequire; /******/ } /******/ } /******/ } /******/ /******/ // Store self accepted outdated modules to require them later by the module system /******/ var outdatedSelfAcceptedModules = []; /******/ for (i = 0; i < outdatedModules.length; i++) { /******/ moduleId = outdatedModules[i]; /******/ if ( /******/ installedModules[moduleId] && /******/ installedModules[moduleId].hot._selfAccepted /******/ ) /******/ outdatedSelfAcceptedModules.push({ /******/ module: moduleId, /******/ errorHandler: installedModules[moduleId].hot._selfAccepted /******/ }); /******/ } /******/ /******/ // Now in "dispose" phase /******/ hotSetStatus("dispose"); /******/ Object.keys(hotAvailableFilesMap).forEach(function(chunkId) { /******/ if (hotAvailableFilesMap[chunkId] === false) { /******/ hotDisposeChunk(chunkId); /******/ } /******/ }); /******/ /******/ var idx; /******/ var queue = outdatedModules.slice(); /******/ while (queue.length > 0) { /******/ moduleId = queue.pop(); /******/ module = installedModules[moduleId]; /******/ if (!module) continue; /******/ /******/ var data = {}; /******/ /******/ // Call dispose handlers /******/ var disposeHandlers = module.hot._disposeHandlers; /******/ for (j = 0; j < disposeHandlers.length; j++) { /******/ cb = disposeHandlers[j]; /******/ cb(data); /******/ } /******/ hotCurrentModuleData[moduleId] = data; /******/ /******/ // disable module (this disables requires from this module) /******/ module.hot.active = false; /******/ /******/ // remove module from cache /******/ delete installedModules[moduleId]; /******/ /******/ // when disposing there is no need to call dispose handler /******/ delete outdatedDependencies[moduleId]; /******/ /******/ // remove "parents" references from all children /******/ for (j = 0; j < module.children.length; j++) { /******/ var child = installedModules[module.children[j]]; /******/ if (!child) continue; /******/ idx = child.parents.indexOf(moduleId); /******/ if (idx >= 0) { /******/ child.parents.splice(idx, 1); /******/ } /******/ } /******/ } /******/ /******/ // remove outdated dependency from module children /******/ var dependency; /******/ var moduleOutdatedDependencies; /******/ for (moduleId in outdatedDependencies) { /******/ if ( /******/ Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId) /******/ ) { /******/ module = installedModules[moduleId]; /******/ if (module) { /******/ moduleOutdatedDependencies = outdatedDependencies[moduleId]; /******/ for (j = 0; j < moduleOutdatedDependencies.length; j++) { /******/ dependency = moduleOutdatedDependencies[j]; /******/ idx = module.children.indexOf(dependency); /******/ if (idx >= 0) module.children.splice(idx, 1); /******/ } /******/ } /******/ } /******/ } /******/ /******/ // Not in "apply" phase /******/ hotSetStatus("apply"); /******/ /******/ hotCurrentHash = hotUpdateNewHash; /******/ /******/ // insert new code /******/ for (moduleId in appliedUpdate) { /******/ if (Object.prototype.hasOwnProperty.call(appliedUpdate, moduleId)) { /******/ modules[moduleId] = appliedUpdate[moduleId]; /******/ } /******/ } /******/ /******/ // call accept handlers /******/ var error = null; /******/ for (moduleId in outdatedDependencies) { /******/ if ( /******/ Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId) /******/ ) { /******/ module = installedModules[moduleId]; /******/ if (module) { /******/ moduleOutdatedDependencies = outdatedDependencies[moduleId]; /******/ var callbacks = []; /******/ for (i = 0; i < moduleOutdatedDependencies.length; i++) { /******/ dependency = moduleOutdatedDependencies[i]; /******/ cb = module.hot._acceptedDependencies[dependency]; /******/ if (cb) { /******/ if (callbacks.indexOf(cb) !== -1) continue; /******/ callbacks.push(cb); /******/ } /******/ } /******/ for (i = 0; i < callbacks.length; i++) { /******/ cb = callbacks[i]; /******/ try { /******/ cb(moduleOutdatedDependencies); /******/ } catch (err) { /******/ if (options.onErrored) { /******/ options.onErrored({ /******/ type: "accept-errored", /******/ moduleId: moduleId, /******/ dependencyId: moduleOutdatedDependencies[i], /******/ error: err /******/ }); /******/ } /******/ if (!options.ignoreErrored) { /******/ if (!error) error = err; /******/ } /******/ } /******/ } /******/ } /******/ } /******/ } /******/ /******/ // Load self accepted modules /******/ for (i = 0; i < outdatedSelfAcceptedModules.length; i++) { /******/ var item = outdatedSelfAcceptedModules[i]; /******/ moduleId = item.module; /******/ hotCurrentParents = [moduleId]; /******/ try { /******/ __webpack_require__(moduleId); /******/ } catch (err) { /******/ if (typeof item.errorHandler === "function") { /******/ try { /******/ item.errorHandler(err); /******/ } catch (err2) { /******/ if (options.onErrored) { /******/ options.onErrored({ /******/ type: "self-accept-error-handler-errored", /******/ moduleId: moduleId, /******/ error: err2, /******/ originalError: err /******/ }); /******/ } /******/ if (!options.ignoreErrored) { /******/ if (!error) error = err2; /******/ } /******/ if (!error) error = err; /******/ } /******/ } else { /******/ if (options.onErrored) { /******/ options.onErrored({ /******/ type: "self-accept-errored", /******/ moduleId: moduleId, /******/ error: err /******/ }); /******/ } /******/ if (!options.ignoreErrored) { /******/ if (!error) error = err; /******/ } /******/ } /******/ } /******/ } /******/ /******/ // handle errors in accept handlers and self accepted module load /******/ if (error) { /******/ hotSetStatus("fail"); /******/ return Promise.reject(error); /******/ } /******/ /******/ hotSetStatus("idle"); /******/ return new Promise(function(resolve) { /******/ resolve(outdatedModules); /******/ }); /******/ } /******/ /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {}, /******/ hot: hotCreateModule(moduleId), /******/ parents: (hotCurrentParentsTemp = hotCurrentParents, hotCurrentParents = [], hotCurrentParentsTemp), /******/ children: [] /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId)); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/"; /******/ /******/ // __webpack_hash__ /******/ __webpack_require__.h = function() { return hotCurrentHash; }; /******/ /******/ /******/ // Load entry module and return exports /******/ return hotCreateRequire(3)(__webpack_require__.s = 3); /******/ }) /************************************************************************/ /******/ ({ /***/ "./handsfree.js/Handsfree.js": /*!***********************************!*\ !*** ./handsfree.js/Handsfree.js ***! \***********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { eval("/**\r\n * ✨\r\n * (\\. \\ ,/)\r\n * \\( |\\ )/\r\n * //\\ | \\ /\\\\\r\n * (/ /\\_#👓#_/\\ \\)\r\n * \\/\\ #### /\\/\r\n * `##'\r\n * \r\n * 🔮 /Handsfree.js 🔮\r\n * \r\n * @description Use computer vision to handsfree-ify websites, apps, games,\r\n * tools, robotics and anything else with a webcam just...like...✨...that!\r\n * \r\n * # NOTES\r\n * - via Node: This is what you get when you require('handsfree')\r\n * -- eg: const Handsfree = require('handsfree')\r\n * const handsfree = new Handsfree(opts)\r\n * \r\n * - via <script>: This class is exposed via a global Handsfree module object\r\n * -- eg: <script src=\"https://unpkg.com/handsfree/@<4/dist/handsfree.js\"></script>\r\n * <script>const handsfree = new Handsfree(opts)</scrtip>\r\n * \r\n * - **Caps matter**\r\n * -- Handsfree with capital H refers to the class\r\n * -- We use handsfree with a lower h to refer to an instance, like: const handsfree = new Handsfree()\r\n * \r\n * ---\r\n * \r\n * # Globals\r\n * The following globals are added when using handsfree.js:\r\n * \r\n * - `Handsfree`\r\n * - `HandsfreePose`\r\n * \r\n * ---\r\n * \r\n * # HOW TO HELP\r\n * - For improvements to the cursor, @see /handsfree.js/components/Cursor.js\r\n * - For details about BRFv4 and the faces object @see https://github.com/Tastenkunst/brfv4_javascript_examples\r\n * \r\n * - Star and fork the project on GitHub @see https://github.com/labofoz/handsfreejs\r\n * - Check out existing issues @see https://github.com/labofoz/handsfreejs/issues\r\n * - Search this project for \"@todo\"\r\n * ---\r\n * \r\n * @see handsfree.js.org\r\n * @see https://github.com/labofoz/handsfreejs\r\n * @see https://glitch.com/@handsfreejs\r\n * @see https://unpkg.com/handsfree/@<4/dist/handsfree.js\r\n * @see https://twitter.com/labofoz\r\n * \r\n */\r\nconst {trimStart, merge, forEach} = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\")\r\n\r\nclass Handsfree {\r\n /**\r\n * Doing nothing by default (eg: new Handsfree()) would:\r\n * - Inject and hide necessary video/canvas elements\r\n * - Begin downloading the BRFv4 model (~9mb)\r\n * \r\n * @param {Object} opts The config object, @see /README.md\r\n * \r\n * @emits handsfree:instantiated Helps disconnected parts of your app know that handsfree is ready\r\n */\r\n constructor (opts = {}) {\r\n /**\r\n * A collection of pose objects {face} for this.settings.maxPoses\r\n */\r\n this.pose = []\r\n\r\n /**\r\n * Your settings\r\n * - This really just acts as a namespace for plugins to pull settings from\r\n * - To set a setting during instantiation, use:\r\n * const handsfree = new Handsfree({setting: {mySetting: value}})\r\n */\r\n this.opts = opts\r\n opts.settings = opts.settings || {}\r\n this.settings = merge(defaultSettings, opts.settings)\r\n\r\n /**\r\n * This will store all the plugins by name: handsfree.use({name: 'myPlugin})\r\n * - Adds it in here as: handsfree.plugin{myPlugin: {...}}\r\n * - And if you need to acess a plugin, just use: handsfree.plugin[pluginName]\r\n */\r\n this.plugin = {}\r\n\r\n /**\r\n * Contains a collection of all the handsfree.on(eventName, callback)\r\n * - Everytime you `handsfree.on(eventName, callback)`, it's added to\r\n * as: `this.listening[eventName].push(callback)`\r\n * - Calling `handsfree.off()` will stop listening to events\r\n */\r\n this.listening = {}\r\n\r\n /**\r\n * Contains the state of the core debugger, which includes:\r\n * - <div> container with\r\n * -- a <video> to grab the webcam stream from\r\n * -- a <canvas> to draw debug info on\r\n */\r\n this.debug = {\r\n // Whether to show the core debugger (true) or not (false)\r\n isEnabled: !!opts.debug,\r\n // Whether we're actually debugging or not\r\n isDebugging: false,\r\n // The webcam stream\r\n $webcam: null,\r\n // The canvas to display debug info on\r\n $canvas: null,\r\n // The canvas context\r\n ctx: null,\r\n // The wrapping element\r\n $wrap: null\r\n }\r\n\r\n /**\r\n * Configs for trackers\r\n */\r\n this.tracker = {\r\n brf: {\r\n // Whether BRFv4 is disabled or not\r\n _isDisabled: !this.settings.tracker.brf.enabled,\r\n // The BRFv4 model\r\n model: null,\r\n // Whether the BRFv4 model has been loaded\r\n isReady: false,\r\n // Whether the model is being loaded or not\r\n isLoading: false,\r\n },\r\n posenet: {\r\n // Whether posenet is disabled or not\r\n _isDisabled: !this.settings.tracker.posenet.enabled,\r\n // The PoseNet model\r\n model: null,\r\n // Whether the posenet model has been loaded\r\n isReady: false,\r\n // Whether the model is being loaded or not\r\n isLoading: false,\r\n }\r\n }\r\n\r\n /**\r\n * Configs for BRFv4\r\n * @see https://tastenkunst.github.io/brfv4_docs/\r\n */\r\n this.brf = {\r\n // Will fallback to ASM if Web ASM isn't supported\r\n baseURL: `${Handsfree.libPath}brf/`,\r\n // The BRFv4 Manager\r\n manager: {},\r\n // The BRFv4 Resolution\r\n resolution: null,\r\n // The loaded BRFv4 sdk library\r\n sdk: null,\r\n // The SDK version we're using\r\n sdkName: 'BRFv4_JS_TK110718_v4.1.0_trial',\r\n // The Web ASM buffer\r\n WASMBuffer: null\r\n }\r\n\r\n /**\r\n * Cursor properties\r\n * @todo This should be an array for multi-user support @see https://github.com/BrowseHandsfree/handsfreeJS/issues/46\r\n */\r\n this.cursor = {\r\n // Position on window\r\n x: -100,\r\n y: -100,\r\n // The actual cursor element\r\n $el: null\r\n }\r\n // Helper object to remove jittering\r\n this.tweenFaces = []\r\n this.tweenBody = []\r\n\r\n // True when webcam stream is set and poses are being tracked\r\n // - this.isTracking && requestAnimationFrame(Handsfree.trackPoses())\r\n this.isTracking = false\r\n // Whether Web Assembly is supported\r\n this.isWASMSupported = typeof WebAssembly === 'object'\r\n // Whether handsfree is supported\r\n this.isSupported = this.checkForMediaSupport()\r\n\r\n /**\r\n * Initialize the instance\r\n * Let the browser know that we've finished instantiated\r\n */\r\n this.init()\r\n this.toggleCursor(!opts.hideCursor)\r\n document.body.classList.add('handsfree-stopped')\r\n window.dispatchEvent(new CustomEvent('handsfree:instantiated', {detail: opts}))\r\n }\r\n\r\n /**\r\n * Starts the webcam stream\r\n * - Adds .handsfree-started and removes -handsfree-stopped from the <body>\r\n * - This stream is completely killed when handsfree.stop() is called\r\n * -- A new stream is therefore created every time handsfree.start() is called after handsfree.stop()\r\n * -- This takes a few moments to happen (less than a second in my experience)\r\n * - If models are not initialized, it'll do so first\r\n * - If models are initialized, it'll start pose estimation\r\n * \r\n * @emits handsfree:loading {detail: {progress: 0}} Useful giving user feedback\r\n */\r\n start () {\r\n this.toggleDebugger(this.debug.isEnabled)\r\n document.body.classList.add('handsfree-started')\r\n document.body.classList.remove('handsfree-stopped')\r\n window.dispatchEvent(new CustomEvent('handsfree:loading', {detail: {progress: 0}}))\r\n\r\n window.navigator.mediaDevices.getUserMedia(this.settings.webcam).then(mediaStream => {\r\n this.debug.$webcam.srcObject = mediaStream\r\n this.debug.$webcam.play()\r\n this.onStartHooks()\r\n\r\n if (this.settings.tracker.brf.enabled) {\r\n if (!this.brf.sdk) {\r\n window.dispatchEvent(new CustomEvent('handsfree:loading', {detail: {progress: 10}}))\r\n this.startBRFv4()\r\n } else {\r\n window.dispatchEvent(new CustomEvent('handsfree:loading', {detail: {progress: 100}}))\r\n this.isTracking = true\r\n this.brf.manager.setNumFacesToTrack(this.settings.maxPoses)\r\n this.trackPoses()\r\n }\r\n } else if (this.settings.tracker.posenet.enabled) {\r\n this.isTracking = true\r\n this.resizeCanvas()\r\n this.trackPoses()\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * Stop tracking and release webcam streams\r\n * - Removes .handsfree-started and adds .handsfree-stopped to <body>\r\n * - Kills all webcam streams\r\n * - Disables debugger\r\n */\r\n stop () {\r\n document.body.classList.remove('handsfree-started')\r\n document.body.classList.add('handsfree-stopped')\r\n\r\n if (this.isTracking) {\r\n this.isTracking = false\r\n this.debug.$webcam.srcObject.getTracks().forEach(track => track.stop())\r\n this.toggleDebugger(false)\r\n this.onStopHooks()\r\n }\r\n }\r\n\r\n /**\r\n * Goes through and tracks poses for all active models\r\n */\r\n trackPoses () {\r\n this.debug.ctx.clearRect(0, 0, this.debug.$canvas.width, this.debug.$canvas.height)\r\n\r\n // BRFv4 (face tracker)\r\n if (!this.tracker.brf._isDisabled && this.tracker.brf.isReady) {\r\n this.trackFaces()\r\n }\r\n\r\n // PoseNet (full body pose estimator)\r\n if (!this.tracker.posenet._isDisabled && this.tracker.posenet.isReady) {\r\n this.trackBody()\r\n }\r\n\r\n // Do things with poses\r\n this.setPosesFromCache()\r\n this.debug.isDebugging && this.debugPoses()\r\n this.getCursors()\r\n this.setTouchedElement()\r\n this.onFrameHooks(this.pose)\r\n\r\n /**\r\n * Dispatch global event and reloop\r\n * - Only reloops if .isTracking\r\n */\r\n window.dispatchEvent(new CustomEvent('handsfree:trackPoses', {detail: {\r\n scope: this,\r\n poses: this.pose\r\n }}))\r\n this.isTracking && requestAnimationFrame(() => this.trackPoses())\r\n }\r\n\r\n /**\r\n * Sets the cursor, based on the dominant tracker\r\n */\r\n getCursors () {\r\n if (!this.tracker.brf._isDisabled) {\r\n this.getBRFCursors()\r\n } else if (!this.tracker.posenet._isDisabled) {\r\n this.getPoseNetCursors()\r\n }\r\n }\r\n \r\n /**\r\n * Updates this.pose with cached data\r\n */\r\n setPosesFromCache () {\r\n forEach(this.poseCache, (cache, pose) => {\r\n for (let i = 0; i < cache.length; i++) {\r\n this.pose[i][pose] = cache[i]\r\n }\r\n })\r\n }\r\n \r\n /**\r\n * Returns the element under the cursor and stores it as pose.cursor.$target\r\n * - If there's no target, then null is returned\r\n * \r\n * @todo move this to Cursor.js\r\n */\r\n setTouchedElement () {\r\n this.pose.forEach(pose => {\r\n if (pose.cursor && pose.cursor.x && pose.cursor.y) {\r\n pose.cursor.$target = document.elementFromPoint(pose.cursor.x, pose.cursor.y)\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * Dispatches an event to `handsfree:${eventName}`\r\n * \r\n * @param {String} eventName The event name to dispatch, appended to `handsfree:`\r\n * @param {Any} args Any extra arguments to pass\r\n */\r\n dispatch (eventName, ...args) {\r\n window.dispatchEvent(new CustomEvent(`handsfree:${eventName}`, {detail: args}))\r\n }\r\n\r\n /**\r\n * Adds a listener to `handsfree:${eventName}`\r\n * - The callback receives the arguments, not the event object\r\n * - Passes over any additional arguments\r\n * \r\n * @param {String} eventName The event name to call, appended to `handsfree:`\r\n * @param {Function} callback The callback to call\r\n */\r\n on (eventName, callback) {\r\n const self = this\r\n const handler = function (ev) {callback.call(self, ev)}\r\n window.addEventListener(`handsfree:${eventName}`, handler)\r\n\r\n if (!this.listening[eventName]) this.listening[eventName] = []\r\n this.listening[eventName].push(handler)\r\n }\r\n\r\n /**\r\n * Stops listening to events\r\n * @param {String} eventName The event name to stop listening to\r\n * - Leave empty to turn off ALL events\r\n */\r\n off (eventName = null) {\r\n // Remove by name\r\n if (eventName) {\r\n // Only remove listeners that exist\r\n if (this.listening[eventName]) {\r\n this.listening[eventName].forEach(callback => {\r\n window.removeEventListener(`handsfree:${eventName}`, callback)\r\n })\r\n delete this.listening[eventName]\r\n }\r\n // Remove all\r\n } else {\r\n forEach(this.listening, (callback, eventName) => {this.off(eventName)})\r\n }\r\n }\r\n\r\n /**\r\n * Toggle Cursor\r\n * @param {Boolean|Null} state Whether to turn it on (true), off (false), or flip between the two (null)\r\n */\r\n toggleCursor (state = null) {\r\n if (typeof state === 'boolean') this.settings.hideCursor = !state\r\n else this.settings.hideCursor = !this.settings.hideCursor\r\n\r\n if (this.settings.hideCursor) {\r\n document.body.classList.add('handsfree-hide-cursor')\r\n } else {\r\n document.body.classList.remove('handsfree-hide-cursor')\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Configs\r\n * @todo make use of environment variables too @see https://github.com/BrowseHandsfree/handsfreeJS/issues/48\r\n */\r\nconst defaultSettings = __webpack_require__(/*! ./config/default-settings */ \"./handsfree.js/config/default-settings.js\")\r\nconst pkg = __webpack_require__(/*! ../package.json */ \"./package.json\")\r\n\r\n// Add class to body to style loading\r\ndocument.body.classList.add('handsfree-is-loading')\r\n\r\n// Set the lib path to whereever this file is, this is required for loading the BRFv4 SDK\r\nconst libSrc = document.currentScript.getAttribute('src')\r\nHandsfree.libPath = trimStart(libSrc.replace('handsfree.js', ''), '/')\r\n\r\n// Set the lib domain too\r\nif (libSrc[0] === '/' || libSrc.substring(0, 4) !== 'http') {\r\n Handsfree.libDomain = window.location.origin + '/' + Handsfree.libPath\r\n} else {\r\n Handsfree.libDomain = Handsfree.libPath\r\n}\r\n\r\n// Let the magic begin ✨\r\n__webpack_require__(/*! ./methods/Setup */ \"./handsfree.js/methods/Setup.js\")(Handsfree)\r\n__webpack_require__(/*! ./methods/Util */ \"./handsfree.js/methods/Util.js\")(Handsfree)\r\n__webpack_require__(/*! ./methods/Debug */ \"./handsfree.js/methods/Debug.js\")(Handsfree)\r\n__webpack_require__(/*! ./methods/Plugin */ \"./handsfree.js/methods/Plugin.js\")(Handsfree)\r\n__webpack_require__(/*! ./trackers/BRF */ \"./handsfree.js/trackers/BRF.js\")(Handsfree)\r\n__webpack_require__(/*! ./trackers/PoseNet */ \"./handsfree.js/trackers/PoseNet.js\")(Handsfree)\r\n\r\n// Finally, include stylesheets\r\nHandsfree.version = pkg.version\r\n__webpack_require__(/*! ../public/handsfree.styl */ \"./public/handsfree.styl\")\r\nmodule.exports = Handsfree//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9oYW5kc2ZyZWUuanMvSGFuZHNmcmVlLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSGFuZHNmcmVlLy4vaGFuZHNmcmVlLmpzL0hhbmRzZnJlZS5qcz8zYjBjIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAg4pyoXHJcbiAqICAgICAgICAgICAgICAgICAgICAgICAgKFxcLiAgIFxcICAgICAgLC8pXHJcbiAqICAgICAgICAgICAgICAgICAgICAgICAgIFxcKCAgIHxcXCAgICAgKS9cclxuICogICAgICAgICAgICAgICAgICAgICAgICAgLy9cXCAgfCBcXCAgIC9cXFxcXHJcbiAqICAgICAgICAgICAgICAgICAgICAgICAoLyAvXFxfI/CfkZMjXy9cXCBcXClcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgXFwvXFwgICMjIyMgIC9cXC9cclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAjIydcclxuICogXHJcbiAqICAgICAgICAgICAgICAgICAgICAgIPCflK4gL0hhbmRzZnJlZS5qcyDwn5SuXHJcbiAqIFxyXG4gKiBAZGVzY3JpcHRpb24gVXNlIGNvbXB1dGVyIHZpc2lvbiB0byBoYW5kc2ZyZWUtaWZ5IHdlYnNpdGVzLCBhcHBzLCBnYW1lcyxcclxuICogdG9vbHMsIHJvYm90aWNzIGFuZCBhbnl0aGluZyBlbHNlIHdpdGggYSB3ZWJjYW0ganVzdC4uLmxpa2UuLi7inKguLi50aGF0IVxyXG4gKiBcclxuICogIyBOT1RFU1xyXG4gKiAtIHZpYSBOb2RlOiBUaGlzIGlzIHdoYXQgeW91IGdldCB3aGVuIHlvdSByZXF1aXJlKCdoYW5kc2ZyZWUnKVxyXG4gKiAtLSBlZzogY29uc3QgSGFuZHNmcmVlID0gcmVxdWlyZSgnaGFuZHNmcmVlJylcclxuICogICAgICAgIGNvbnN0IGhhbmRzZnJlZSA9IG5ldyBIYW5kc2ZyZWUob3B0cylcclxuICogXHJcbiAqIC0gdmlhIDxzY3JpcHQ+OiBUaGlzIGNsYXNzIGlzIGV4cG9zZWQgdmlhIGEgZ2xvYmFsIEhhbmRzZnJlZSBtb2R1bGUgb2JqZWN0XHJcbiAqIC0tIGVnOiA8c2NyaXB0IHNyYz1cImh0dHBzOi8vdW5wa2cuY29tL2hhbmRzZnJlZS9APDQvZGlzdC9oYW5kc2ZyZWUuanNcIj48L3NjcmlwdD5cclxuICogICAgICAgIDxzY3JpcHQ+Y29uc3QgaGFuZHNmcmVlID0gbmV3IEhhbmRzZnJlZShvcHRzKTwvc2NydGlwPlxyXG4gKiBcclxuICogLSAqKkNhcHMgbWF0dGVyKipcclxuICogLS0gSGFuZHNmcmVlIHdpdGggY2FwaXRhbCBIIHJlZmVycyB0byB0aGUgY2xhc3NcclxuICogLS0gV2UgdXNlIGhhbmRzZnJlZSB3aXRoIGEgbG93ZXIgaCB0byByZWZlciB0byBhbiBpbnN0YW5jZSwgbGlrZTogY29uc3QgaGFuZHNmcmVlID0gbmV3IEhhbmRzZnJlZSgpXHJcbiAqIFxyXG4gKiAtLS1cclxuICogXHJcbiAqICMgR2xvYmFsc1xyXG4gKiBUaGUgZm9sbG93aW5nIGdsb2JhbHMgYXJlIGFkZGVkIHdoZW4gdXNpbmcgaGFuZHNmcmVlLmpzOlxyXG4gKiBcclxuICogLSBgSGFuZHNmcmVlYFxyXG4gKiAtIGBIYW5kc2ZyZWVQb3NlYFxyXG4gKiBcclxuICogLS0tXHJcbiAqIFxyXG4gKiAjIEhPVyBUTyBIRUxQXHJcbiAqIC0gRm9yIGltcHJvdmVtZW50cyB0byB0aGUgY3Vyc29yLCBAc2VlIC9oYW5kc2ZyZWUuanMvY29tcG9uZW50cy9DdXJzb3IuanNcclxuICogLSBGb3IgZGV0YWlscyBhYm91dCBCUkZ2NCBhbmQgdGhlIGZhY2VzIG9iamVjdCBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9UYXN0ZW5rdW5zdC9icmZ2NF9qYXZhc2NyaXB0X2V4YW1wbGVzXHJcbiAqIFxyXG4gKiAtIFN0YXIgYW5kIGZvcmsgdGhlIHByb2plY3Qgb24gR2l0SHViIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2xhYm9mb3ovaGFuZHNmcmVlanNcclxuICogLSBDaGVjayBvdXQgZXhpc3RpbmcgaXNzdWVzIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2xhYm9mb3ovaGFuZHNmcmVlanMvaXNzdWVzXHJcbiAqIC0gU2VhcmNoIHRoaXMgcHJvamVjdCBmb3IgXCJAdG9kb1wiXHJcbiAqIC0tLVxyXG4gKiBcclxuICogQHNlZSBoYW5kc2ZyZWUuanMub3JnXHJcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2xhYm9mb3ovaGFuZHNmcmVlanNcclxuICogQHNlZSBodHRwczovL2dsaXRjaC5jb20vQGhhbmRzZnJlZWpzXHJcbiAqIEBzZWUgaHR0cHM6Ly91bnBrZy5jb20vaGFuZHNmcmVlL0A8NC9kaXN0L2hhbmRzZnJlZS5qc1xyXG4gKiBAc2VlIGh0dHBzOi8vdHdpdHRlci5jb20vbGFib2ZvelxyXG4gKiBcclxuICovXHJcbmNvbnN0IHt0cmltU3RhcnQsIG1lcmdlLCBmb3JFYWNofSA9IHJlcXVpcmUoJ2xvZGFzaCcpXHJcblxyXG5jbGFzcyBIYW5kc2ZyZWUge1xyXG4gIC8qKlxyXG4gICAqIERvaW5nIG5vdGhpbmcgYnkgZGVmYXVsdCAoZWc6IG5ldyBIYW5kc2ZyZWUoKSkgd291bGQ6XHJcbiAgICogLSBJbmplY3QgYW5kIGhpZGUgbmVjZXNzYXJ5IHZpZGVvL2NhbnZhcyBlbGVtZW50c1xyXG4gICAqIC0gQmVnaW4gZG93bmxvYWRpbmcgdGhlIEJSRnY0IG1vZGVsICh+OW1iKVxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIFRoZSBjb25maWcgb2JqZWN0LCBAc2VlIC9SRUFETUUubWRcclxuICAgKiBcclxuICAgKiBAZW1pdHMgaGFuZHNmcmVlOmluc3RhbnRpYXRlZCBIZWxwcyBkaXNjb25uZWN0ZWQgcGFydHMgb2YgeW91ciBhcHAga25vdyB0aGF0IGhhbmRzZnJlZSBpcyByZWFkeVxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yIChvcHRzID0ge30pIHtcclxuICAgIC8qKlxyXG4gICAgICogQSBjb2xsZWN0aW9uIG9mIHBvc2Ugb2JqZWN0cyB7ZmFjZX0gZm9yIHRoaXMuc2V0dGluZ3MubWF4UG9zZXNcclxuICAgICAqL1xyXG4gICAgdGhpcy5wb3NlID0gW11cclxuXHJcbiAgICAvKipcclxuICAgICAqIFlvdXIgc2V0dGluZ3NcclxuICAgICAqIC0gVGhpcyByZWFsbHkganVzdCBhY3RzIGFzIGEgbmFtZXNwYWNlIGZvciBwbHVnaW5zIHRvIHB1bGwgc2V0dGluZ3MgZnJvbVxyXG4gICAgICogLSBUbyBzZXQgYSBzZXR0aW5nIGR1cmluZyBpbnN0YW50aWF0aW9uLCB1c2U6XHJcbiAgICAgKiAgICBjb25zdCBoYW5kc2ZyZWUgPSBuZXcgSGFuZHNmcmVlKHtzZXR0aW5nOiB7bXlTZXR0aW5nOiB2YWx1ZX19KVxyXG4gICAgICovXHJcbiAgICB0aGlzLm9wdHMgPSBvcHRzXHJcbiAgICBvcHRzLnNldHRpbmdzID0gb3B0cy5zZXR0aW5ncyB8fCB7fVxyXG4gICAgdGhpcy5zZXR0aW5ncyA9IG1lcmdlKGRlZmF1bHRTZXR0aW5ncywgb3B0cy5zZXR0aW5ncylcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoaXMgd2lsbCBzdG9yZSBhbGwgdGhlIHBsdWdpbnMgYnkgbmFtZTogaGFuZHNmcmVlLnVzZSh7bmFtZTogJ215UGx1Z2lufSlcclxuICAgICAqIC0gQWRkcyBpdCBpbiBoZXJlIGFzOiBoYW5kc2ZyZWUucGx1Z2lue215UGx1Z2luOiB7Li4ufX1cclxuICAgICAqIC0gQW5kIGlmIHlvdSBuZWVkIHRvIGFjZXNzIGEgcGx1Z2luLCBqdXN0IHVzZTogaGFuZHNmcmVlLnBsdWdpbltwbHVnaW5OYW1lXVxyXG4gICAgICovXHJcbiAgICB0aGlzLnBsdWdpbiA9IHt9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb250YWlucyBhIGNvbGxlY3Rpb24gb2YgYWxsIHRoZSBoYW5kc2ZyZWUub24oZXZlbnROYW1lLCBjYWxsYmFjaylcclxuICAgICAqIC0gRXZlcnl0aW1lIHlvdSBgaGFuZHNmcmVlLm9uKGV2ZW50TmFtZSwgY2FsbGJhY2spYCwgaXQncyBhZGRlZCB0b1xyXG4gICAgICogICBhczogYHRoaXMubGlzdGVuaW5nW2V2ZW50TmFtZV0ucHVzaChjYWxsYmFjaylgXHJcbiAgICAgKiAtIENhbGxpbmcgYGhhbmRzZnJ