handsfree
Version:
A library for creating head-controlled, handsfree user interfaces via computer vision just...like...✨...that!
814 lines (812 loc) • 7.91 MB
JavaScript
(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