/*! (c) gotoAndPlay | All rights reserved */
(window["webpackJsonpapplication"] = window["webpackJsonpapplication"] || []).push([["module-4"],{

/***/ "./node_modules/file-saver/dist/FileSaver.min.js":
/*!*******************************************************!*\
  !*** ./node_modules/file-saver/dist/FileSaver.min.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(a,b){if(true)!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (b),
				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else {}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(b,c,d){var e=new XMLHttpRequest;e.open("GET",b),e.responseType="blob",e.onload=function(){a(e.response,c,d)},e.onerror=function(){console.error("could not download file")},e.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(a,b,d,e){if(e=e||open("","_blank"),e&&(e.document.title=e.document.body.innerText="downloading..."),"string"==typeof a)return c(a,b,d);var g="application/octet-stream"===a.type,h=/constructor/i.test(f.HTMLElement)||f.safari,i=/CriOS\/[\d]+/.test(navigator.userAgent);if((i||g&&h)&&"object"==typeof FileReader){var j=new FileReader;j.onloadend=function(){var a=j.result;a=i?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),e?e.location.href=a:location=a,e=null},j.readAsDataURL(a)}else{var k=f.URL||f.webkitURL,l=k.createObjectURL(a);e?e.location=l:location.href=l,e=null,setTimeout(function(){k.revokeObjectURL(l)},4E4)}});f.saveAs=a.saveAs=a, true&&(module.exports=a)});

//# sourceMappingURL=FileSaver.min.js.map
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./node_modules/moment/locale sync recursive ^\\.\\/.*$":
/*!**************************************************!*\
  !*** ./node_modules/moment/locale sync ^\.\/.*$ ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var map = {
	"./af": "./node_modules/moment/locale/af.js",
	"./af.js": "./node_modules/moment/locale/af.js",
	"./ar": "./node_modules/moment/locale/ar.js",
	"./ar-dz": "./node_modules/moment/locale/ar-dz.js",
	"./ar-dz.js": "./node_modules/moment/locale/ar-dz.js",
	"./ar-kw": "./node_modules/moment/locale/ar-kw.js",
	"./ar-kw.js": "./node_modules/moment/locale/ar-kw.js",
	"./ar-ly": "./node_modules/moment/locale/ar-ly.js",
	"./ar-ly.js": "./node_modules/moment/locale/ar-ly.js",
	"./ar-ma": "./node_modules/moment/locale/ar-ma.js",
	"./ar-ma.js": "./node_modules/moment/locale/ar-ma.js",
	"./ar-sa": "./node_modules/moment/locale/ar-sa.js",
	"./ar-sa.js": "./node_modules/moment/locale/ar-sa.js",
	"./ar-tn": "./node_modules/moment/locale/ar-tn.js",
	"./ar-tn.js": "./node_modules/moment/locale/ar-tn.js",
	"./ar.js": "./node_modules/moment/locale/ar.js",
	"./az": "./node_modules/moment/locale/az.js",
	"./az.js": "./node_modules/moment/locale/az.js",
	"./be": "./node_modules/moment/locale/be.js",
	"./be.js": "./node_modules/moment/locale/be.js",
	"./bg": "./node_modules/moment/locale/bg.js",
	"./bg.js": "./node_modules/moment/locale/bg.js",
	"./bm": "./node_modules/moment/locale/bm.js",
	"./bm.js": "./node_modules/moment/locale/bm.js",
	"./bn": "./node_modules/moment/locale/bn.js",
	"./bn.js": "./node_modules/moment/locale/bn.js",
	"./bo": "./node_modules/moment/locale/bo.js",
	"./bo.js": "./node_modules/moment/locale/bo.js",
	"./br": "./node_modules/moment/locale/br.js",
	"./br.js": "./node_modules/moment/locale/br.js",
	"./bs": "./node_modules/moment/locale/bs.js",
	"./bs.js": "./node_modules/moment/locale/bs.js",
	"./ca": "./node_modules/moment/locale/ca.js",
	"./ca.js": "./node_modules/moment/locale/ca.js",
	"./cs": "./node_modules/moment/locale/cs.js",
	"./cs.js": "./node_modules/moment/locale/cs.js",
	"./cv": "./node_modules/moment/locale/cv.js",
	"./cv.js": "./node_modules/moment/locale/cv.js",
	"./cy": "./node_modules/moment/locale/cy.js",
	"./cy.js": "./node_modules/moment/locale/cy.js",
	"./da": "./node_modules/moment/locale/da.js",
	"./da.js": "./node_modules/moment/locale/da.js",
	"./de": "./node_modules/moment/locale/de.js",
	"./de-at": "./node_modules/moment/locale/de-at.js",
	"./de-at.js": "./node_modules/moment/locale/de-at.js",
	"./de-ch": "./node_modules/moment/locale/de-ch.js",
	"./de-ch.js": "./node_modules/moment/locale/de-ch.js",
	"./de.js": "./node_modules/moment/locale/de.js",
	"./dv": "./node_modules/moment/locale/dv.js",
	"./dv.js": "./node_modules/moment/locale/dv.js",
	"./el": "./node_modules/moment/locale/el.js",
	"./el.js": "./node_modules/moment/locale/el.js",
	"./en-SG": "./node_modules/moment/locale/en-SG.js",
	"./en-SG.js": "./node_modules/moment/locale/en-SG.js",
	"./en-au": "./node_modules/moment/locale/en-au.js",
	"./en-au.js": "./node_modules/moment/locale/en-au.js",
	"./en-ca": "./node_modules/moment/locale/en-ca.js",
	"./en-ca.js": "./node_modules/moment/locale/en-ca.js",
	"./en-gb": "./node_modules/moment/locale/en-gb.js",
	"./en-gb.js": "./node_modules/moment/locale/en-gb.js",
	"./en-ie": "./node_modules/moment/locale/en-ie.js",
	"./en-ie.js": "./node_modules/moment/locale/en-ie.js",
	"./en-il": "./node_modules/moment/locale/en-il.js",
	"./en-il.js": "./node_modules/moment/locale/en-il.js",
	"./en-nz": "./node_modules/moment/locale/en-nz.js",
	"./en-nz.js": "./node_modules/moment/locale/en-nz.js",
	"./eo": "./node_modules/moment/locale/eo.js",
	"./eo.js": "./node_modules/moment/locale/eo.js",
	"./es": "./node_modules/moment/locale/es.js",
	"./es-do": "./node_modules/moment/locale/es-do.js",
	"./es-do.js": "./node_modules/moment/locale/es-do.js",
	"./es-us": "./node_modules/moment/locale/es-us.js",
	"./es-us.js": "./node_modules/moment/locale/es-us.js",
	"./es.js": "./node_modules/moment/locale/es.js",
	"./et": "./node_modules/moment/locale/et.js",
	"./et.js": "./node_modules/moment/locale/et.js",
	"./eu": "./node_modules/moment/locale/eu.js",
	"./eu.js": "./node_modules/moment/locale/eu.js",
	"./fa": "./node_modules/moment/locale/fa.js",
	"./fa.js": "./node_modules/moment/locale/fa.js",
	"./fi": "./node_modules/moment/locale/fi.js",
	"./fi.js": "./node_modules/moment/locale/fi.js",
	"./fo": "./node_modules/moment/locale/fo.js",
	"./fo.js": "./node_modules/moment/locale/fo.js",
	"./fr": "./node_modules/moment/locale/fr.js",
	"./fr-ca": "./node_modules/moment/locale/fr-ca.js",
	"./fr-ca.js": "./node_modules/moment/locale/fr-ca.js",
	"./fr-ch": "./node_modules/moment/locale/fr-ch.js",
	"./fr-ch.js": "./node_modules/moment/locale/fr-ch.js",
	"./fr.js": "./node_modules/moment/locale/fr.js",
	"./fy": "./node_modules/moment/locale/fy.js",
	"./fy.js": "./node_modules/moment/locale/fy.js",
	"./ga": "./node_modules/moment/locale/ga.js",
	"./ga.js": "./node_modules/moment/locale/ga.js",
	"./gd": "./node_modules/moment/locale/gd.js",
	"./gd.js": "./node_modules/moment/locale/gd.js",
	"./gl": "./node_modules/moment/locale/gl.js",
	"./gl.js": "./node_modules/moment/locale/gl.js",
	"./gom-latn": "./node_modules/moment/locale/gom-latn.js",
	"./gom-latn.js": "./node_modules/moment/locale/gom-latn.js",
	"./gu": "./node_modules/moment/locale/gu.js",
	"./gu.js": "./node_modules/moment/locale/gu.js",
	"./he": "./node_modules/moment/locale/he.js",
	"./he.js": "./node_modules/moment/locale/he.js",
	"./hi": "./node_modules/moment/locale/hi.js",
	"./hi.js": "./node_modules/moment/locale/hi.js",
	"./hr": "./node_modules/moment/locale/hr.js",
	"./hr.js": "./node_modules/moment/locale/hr.js",
	"./hu": "./node_modules/moment/locale/hu.js",
	"./hu.js": "./node_modules/moment/locale/hu.js",
	"./hy-am": "./node_modules/moment/locale/hy-am.js",
	"./hy-am.js": "./node_modules/moment/locale/hy-am.js",
	"./id": "./node_modules/moment/locale/id.js",
	"./id.js": "./node_modules/moment/locale/id.js",
	"./is": "./node_modules/moment/locale/is.js",
	"./is.js": "./node_modules/moment/locale/is.js",
	"./it": "./node_modules/moment/locale/it.js",
	"./it-ch": "./node_modules/moment/locale/it-ch.js",
	"./it-ch.js": "./node_modules/moment/locale/it-ch.js",
	"./it.js": "./node_modules/moment/locale/it.js",
	"./ja": "./node_modules/moment/locale/ja.js",
	"./ja.js": "./node_modules/moment/locale/ja.js",
	"./jv": "./node_modules/moment/locale/jv.js",
	"./jv.js": "./node_modules/moment/locale/jv.js",
	"./ka": "./node_modules/moment/locale/ka.js",
	"./ka.js": "./node_modules/moment/locale/ka.js",
	"./kk": "./node_modules/moment/locale/kk.js",
	"./kk.js": "./node_modules/moment/locale/kk.js",
	"./km": "./node_modules/moment/locale/km.js",
	"./km.js": "./node_modules/moment/locale/km.js",
	"./kn": "./node_modules/moment/locale/kn.js",
	"./kn.js": "./node_modules/moment/locale/kn.js",
	"./ko": "./node_modules/moment/locale/ko.js",
	"./ko.js": "./node_modules/moment/locale/ko.js",
	"./ku": "./node_modules/moment/locale/ku.js",
	"./ku.js": "./node_modules/moment/locale/ku.js",
	"./ky": "./node_modules/moment/locale/ky.js",
	"./ky.js": "./node_modules/moment/locale/ky.js",
	"./lb": "./node_modules/moment/locale/lb.js",
	"./lb.js": "./node_modules/moment/locale/lb.js",
	"./lo": "./node_modules/moment/locale/lo.js",
	"./lo.js": "./node_modules/moment/locale/lo.js",
	"./lt": "./node_modules/moment/locale/lt.js",
	"./lt.js": "./node_modules/moment/locale/lt.js",
	"./lv": "./node_modules/moment/locale/lv.js",
	"./lv.js": "./node_modules/moment/locale/lv.js",
	"./me": "./node_modules/moment/locale/me.js",
	"./me.js": "./node_modules/moment/locale/me.js",
	"./mi": "./node_modules/moment/locale/mi.js",
	"./mi.js": "./node_modules/moment/locale/mi.js",
	"./mk": "./node_modules/moment/locale/mk.js",
	"./mk.js": "./node_modules/moment/locale/mk.js",
	"./ml": "./node_modules/moment/locale/ml.js",
	"./ml.js": "./node_modules/moment/locale/ml.js",
	"./mn": "./node_modules/moment/locale/mn.js",
	"./mn.js": "./node_modules/moment/locale/mn.js",
	"./mr": "./node_modules/moment/locale/mr.js",
	"./mr.js": "./node_modules/moment/locale/mr.js",
	"./ms": "./node_modules/moment/locale/ms.js",
	"./ms-my": "./node_modules/moment/locale/ms-my.js",
	"./ms-my.js": "./node_modules/moment/locale/ms-my.js",
	"./ms.js": "./node_modules/moment/locale/ms.js",
	"./mt": "./node_modules/moment/locale/mt.js",
	"./mt.js": "./node_modules/moment/locale/mt.js",
	"./my": "./node_modules/moment/locale/my.js",
	"./my.js": "./node_modules/moment/locale/my.js",
	"./nb": "./node_modules/moment/locale/nb.js",
	"./nb.js": "./node_modules/moment/locale/nb.js",
	"./ne": "./node_modules/moment/locale/ne.js",
	"./ne.js": "./node_modules/moment/locale/ne.js",
	"./nl": "./node_modules/moment/locale/nl.js",
	"./nl-be": "./node_modules/moment/locale/nl-be.js",
	"./nl-be.js": "./node_modules/moment/locale/nl-be.js",
	"./nl.js": "./node_modules/moment/locale/nl.js",
	"./nn": "./node_modules/moment/locale/nn.js",
	"./nn.js": "./node_modules/moment/locale/nn.js",
	"./pa-in": "./node_modules/moment/locale/pa-in.js",
	"./pa-in.js": "./node_modules/moment/locale/pa-in.js",
	"./pl": "./node_modules/moment/locale/pl.js",
	"./pl.js": "./node_modules/moment/locale/pl.js",
	"./pt": "./node_modules/moment/locale/pt.js",
	"./pt-br": "./node_modules/moment/locale/pt-br.js",
	"./pt-br.js": "./node_modules/moment/locale/pt-br.js",
	"./pt.js": "./node_modules/moment/locale/pt.js",
	"./ro": "./node_modules/moment/locale/ro.js",
	"./ro.js": "./node_modules/moment/locale/ro.js",
	"./ru": "./node_modules/moment/locale/ru.js",
	"./ru.js": "./node_modules/moment/locale/ru.js",
	"./sd": "./node_modules/moment/locale/sd.js",
	"./sd.js": "./node_modules/moment/locale/sd.js",
	"./se": "./node_modules/moment/locale/se.js",
	"./se.js": "./node_modules/moment/locale/se.js",
	"./si": "./node_modules/moment/locale/si.js",
	"./si.js": "./node_modules/moment/locale/si.js",
	"./sk": "./node_modules/moment/locale/sk.js",
	"./sk.js": "./node_modules/moment/locale/sk.js",
	"./sl": "./node_modules/moment/locale/sl.js",
	"./sl.js": "./node_modules/moment/locale/sl.js",
	"./sq": "./node_modules/moment/locale/sq.js",
	"./sq.js": "./node_modules/moment/locale/sq.js",
	"./sr": "./node_modules/moment/locale/sr.js",
	"./sr-cyrl": "./node_modules/moment/locale/sr-cyrl.js",
	"./sr-cyrl.js": "./node_modules/moment/locale/sr-cyrl.js",
	"./sr.js": "./node_modules/moment/locale/sr.js",
	"./ss": "./node_modules/moment/locale/ss.js",
	"./ss.js": "./node_modules/moment/locale/ss.js",
	"./sv": "./node_modules/moment/locale/sv.js",
	"./sv.js": "./node_modules/moment/locale/sv.js",
	"./sw": "./node_modules/moment/locale/sw.js",
	"./sw.js": "./node_modules/moment/locale/sw.js",
	"./ta": "./node_modules/moment/locale/ta.js",
	"./ta.js": "./node_modules/moment/locale/ta.js",
	"./te": "./node_modules/moment/locale/te.js",
	"./te.js": "./node_modules/moment/locale/te.js",
	"./tet": "./node_modules/moment/locale/tet.js",
	"./tet.js": "./node_modules/moment/locale/tet.js",
	"./tg": "./node_modules/moment/locale/tg.js",
	"./tg.js": "./node_modules/moment/locale/tg.js",
	"./th": "./node_modules/moment/locale/th.js",
	"./th.js": "./node_modules/moment/locale/th.js",
	"./tl-ph": "./node_modules/moment/locale/tl-ph.js",
	"./tl-ph.js": "./node_modules/moment/locale/tl-ph.js",
	"./tlh": "./node_modules/moment/locale/tlh.js",
	"./tlh.js": "./node_modules/moment/locale/tlh.js",
	"./tr": "./node_modules/moment/locale/tr.js",
	"./tr.js": "./node_modules/moment/locale/tr.js",
	"./tzl": "./node_modules/moment/locale/tzl.js",
	"./tzl.js": "./node_modules/moment/locale/tzl.js",
	"./tzm": "./node_modules/moment/locale/tzm.js",
	"./tzm-latn": "./node_modules/moment/locale/tzm-latn.js",
	"./tzm-latn.js": "./node_modules/moment/locale/tzm-latn.js",
	"./tzm.js": "./node_modules/moment/locale/tzm.js",
	"./ug-cn": "./node_modules/moment/locale/ug-cn.js",
	"./ug-cn.js": "./node_modules/moment/locale/ug-cn.js",
	"./uk": "./node_modules/moment/locale/uk.js",
	"./uk.js": "./node_modules/moment/locale/uk.js",
	"./ur": "./node_modules/moment/locale/ur.js",
	"./ur.js": "./node_modules/moment/locale/ur.js",
	"./uz": "./node_modules/moment/locale/uz.js",
	"./uz-latn": "./node_modules/moment/locale/uz-latn.js",
	"./uz-latn.js": "./node_modules/moment/locale/uz-latn.js",
	"./uz.js": "./node_modules/moment/locale/uz.js",
	"./vi": "./node_modules/moment/locale/vi.js",
	"./vi.js": "./node_modules/moment/locale/vi.js",
	"./x-pseudo": "./node_modules/moment/locale/x-pseudo.js",
	"./x-pseudo.js": "./node_modules/moment/locale/x-pseudo.js",
	"./yo": "./node_modules/moment/locale/yo.js",
	"./yo.js": "./node_modules/moment/locale/yo.js",
	"./zh-cn": "./node_modules/moment/locale/zh-cn.js",
	"./zh-cn.js": "./node_modules/moment/locale/zh-cn.js",
	"./zh-hk": "./node_modules/moment/locale/zh-hk.js",
	"./zh-hk.js": "./node_modules/moment/locale/zh-hk.js",
	"./zh-tw": "./node_modules/moment/locale/zh-tw.js",
	"./zh-tw.js": "./node_modules/moment/locale/zh-tw.js"
};


function webpackContext(req) {
	var id = webpackContextResolve(req);
	return __webpack_require__(id);
}
function webpackContextResolve(req) {
	if(!__webpack_require__.o(map, req)) {
		var e = new Error("Cannot find module '" + req + "'");
		e.code = 'MODULE_NOT_FOUND';
		throw e;
	}
	return map[req];
}
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "./node_modules/moment/locale sync recursive ^\\.\\/.*$";

/***/ }),

/***/ "./node_modules/webpack/buildin/global.js":
/*!***********************************!*\
  !*** (webpack)/buildin/global.js ***!
  \***********************************/
/*! no static exports found */
/***/ (function(module, exports) {

var g;

// This works in non-strict mode
g = (function() {
	return this;
})();

try {
	// This works if eval is allowed (see CSP)
	g = g || new Function("return this")();
} catch (e) {
	// This works if the window reference is available
	if (typeof window === "object") g = window;
}

// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}

module.exports = g;


/***/ }),

/***/ "./src/data/command-history.js":
/*!*************************************!*\
  !*** ./src/data/command-history.js ***!
  \*************************************/
/*! exports provided: CommandHistory */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CommandHistory", function() { return CommandHistory; });
class CommandHistory
{
	constructor(size = 100)
	{
		this._size = size;

		this.clear();
		this._loadState();
	}

	addCommand(cmd)
	{
		if (this._history.length >= this._size)
			this._history.splice(0, 1);

		this._history.push(cmd);
		this._pos = this._history.length;
		this._tempCmd = '';

		this._saveState();
	}

	addTempCommand(cmd)
	{
		this._tempCmd = cmd;
		this._pos = this._history.length;
	}

	rewind()
	{
		if (this._pos > 0)
			this._pos--;

		return this._history[this._pos];
	}

	forward()
	{
		if (this._pos < this._history.length)
			this._pos++;

		if (this._pos <= this._history.length - 1)
			return this._history[this._pos];
		else
			return this._tempCmd;
	}

	getList()
	{
		return this._history;
	}

	getSize()
	{
		return this._history.length
	}

	clear()
	{
		this._history = [];
		this._pos = 0;
		this._tempCmd = '';
	}

	_saveState()
	{
		Cookies.set('console-history', {
			history: this._history
		}, {expires: 36000});
	}

	_loadState()
	{
		let data = Cookies.getJSON('console-history')

		if (data)
		{
			this._history = data.history;
			this._pos = this._history.length;
		}
	}
}


/***/ }),

/***/ "./src/modules/console.js":
/*!********************************!*\
  !*** ./src/modules/console.js ***!
  \********************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Console; });
/* harmony import */ var _base_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-module */ "./src/modules/base-module.js");
/* harmony import */ var _data_command_history__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../data/command-history */ "./src/data/command-history.js");
/* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! file-saver */ "./node_modules/file-saver/dist/FileSaver.min.js");
/* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(file_saver__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! moment */ "./node_modules/moment/moment.js");
/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _utils_utilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/utilities */ "./src/utils/utilities.js");






class Console extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
{
	constructor()
	{
	    super('console');

		// Outgoing requests
		this.REQ_CMD = 'cmd';
		this.REQ_HINT = 'hint';
		this.REQ_SCRIPT = 'script';

		// Incoming responses
		this.RES_CMD = 'cmd';
		this.RES_HINT = 'hint';
		this.RES_SCRIPT = 'script';
		this.RES_ERROR_LOCKED = 'locked';

		this.VERSION = '3.0.0';
		this.TOKENS = ['=', 'from ', 'import '];

		this.TRANSCRIPT_TEMPLATE = `
		<html>
		<head>
			<title>SFS2X ADMIN CONSOLE Session Transcript</title>
			<style type='text/css' media='screen'>
				body, pre {
					background-color: #333;
					font-size: .8rem;
					font-family: Monaco,'Courier New', monospace;
				}

				h3 {
					color: #f8f9fa;
				}

				pre {
					white-space: pre-wrap;
					-moz-tab-size: 5;
					tab-size: 5;
				}

				.text-console {
					color: #28F32D;
				}

				.text-error {
					color: #dc3545;
				}

				.text-highlight {
					color: #ffc107;
				}

				.text-command {
					color: #f8f9fa;
				}
			</style>
		</head>
		<body>
			<h3><!--HEADER--></h3>
			<pre><!--TRANSCRIPT--></pre>
		</body>
		</html>
		`;

		this._cmdHistory = new _data_command_history__WEBPACK_IMPORTED_MODULE_1__["CommandHistory"]();
	}

	//------------------------------------
	// COMMON MODULE INTERFACE METHODS
	// This members are used by the main controller
	// to communicate with the module's controller.
	//------------------------------------

	initialize(idData, shellController)
	{
		// Call super method
		super.initialize(idData, shellController);

		$('#cns-input').on('keyup', $.proxy(this.onInputKeyUp, this));
		$('#cns-input').on('keydown', $.proxy(this.onInputKeyDown, this));

		// Show welcome message
		this._showWelcomeMessage();

		// Focus on prompt input
		$('#cns-input').focus();

		// Add global click listener to close hint panel
		$(this).on('click', $.proxy(this._onGenericClick, this));

		// Add global window resize listener to close hint panel
		$(window).on('resize', $.proxy(this._onGenericClick, this));

		// Add buttons click listeners
		$('#cns-clearButton').on('click', $.proxy(this._onClearConsoleClick, this));
		$('#cns-runButton').on('click', $.proxy(this._onRunScriptClick, this));
		$('#cns-exportButton').on('click', $.proxy(this._onExportSessionClick, this));

		// Initialize "upload script" modal
		this._uploadScriptModal = $('#cns-uploadModal');
		this._uploadScriptModal.modal({
			backdrop: 'static',
			keyboard: false,
			show: false
		});

		// Initialize kendo uploader
		this._uploader = $('#cns-uploader').kendoUpload({
			allowedExtensions: ['.py'],
			multiple: false,
			template: function(dataItem) {
				dataItem.bytesToSize = _utils_utilities__WEBPACK_IMPORTED_MODULE_4__["bytesToSize"]; // Pass bytesToSize utility function to template
				return kendo.template(`
					<span class='k-progress w-100'></span>
					<span class="">
						<span class="k-file-name" title="#=name#">#=name#</span>
						<span class="k-file-size">Size: #=bytesToSize(size, 1, 'Bytes')#</span>
					</span>
				`)(dataItem);
			},
	        localization: {
	            select: 'Select file...'
	        }
		}).data('kendoUpload');

		// Add listener to modal hide event
		this._uploadScriptModal.on('hidden.bs.modal', $.proxy(this._onUploadScriptrModalHidden, this));

		// Add listener to modal button
		$('#cns-uploadScriptButton').on('click', $.proxy(this._onUploadScriptrButtonCLick, this));
	}

	destroy()
	{
		// Call super method
		super.destroy();

		$('#cns-clearButton').off('click');
		$('#cns-runButton').off('click');
		$('#cns-exportButton').off('click');
		$('#cns-uploadScriptButton').off('click');

		$(this).off('click');
		$(window).off('resize');

		this._uploadScriptModal.off('hidden.bs.modal');
		this._uploadScriptModal.modal('dispose');
	}

	onExtensionCommand(command, data)
	{
		if (command == this.RES_CMD || command == this.RES_SCRIPT)
		{
			const result = data.getUtfString('r');
			const error = data.getUtfString('e');

			if (result != null)
				this._writeConsole(result);
			else if (error != null)
				this._writeConsole(`<span class="text-error">ERROR</span> ${this._parseHtml(error)}`);
		}

		else if (command == this.RES_HINT)
		{
			this._lastHints = data.getUtfStringArray('h');

			this._showHintPanel();
		}

		else if (command == this.RES_ERROR_LOCKED)
		{
			this._writeConsole(`<span class="text-error">ERROR</span> <span class="text-highlight">Console module is locked from server side. Please follow the instructions you were given to unlock it.</span>`);
		}
	}

	//---------------------------------
	// UI EVENT LISTENERS
	//---------------------------------

	onInputKeyDown(e)
	{
		// Save previous input value
		this._prevInput = $('#cns-input').val();

		const keyName = e.key;

		if (keyName == 'ArrowUp' || keyName == 'ArrowDown' || keyName == 'Tab')
		{
			e.preventDefault();
		}
	}

	onInputKeyUp(e)
	{
		const keyName = e.key;
		const input = $('#cns-input').val();

		// Copy input to dummy
		$('#cns-input-dummy').html(input);

		//--- DOT (CODE HINTING) -----------------------------------------------
		if (keyName == '.')
		{
			// Close hint panel if open
			if (this._isHintPanelOpen)
				this._closeHintPanel();

			// Request code hints
			this._requestHints(input);
		}

		//--- ENTER ------------------------------------------------------------
		else if	(keyName == 'Enter' && input.length > 0)
		{
			// Get selected hint
			if (this._isHintPanelOpen)
			{
				this._setInputOnHintSelected();
			}
			else
			{
				// Send command to server
				let sfso = new SFS2X.SFSObject();
				sfso.putUtfString('c', input);
				this.sendExtensionRequest(this.REQ_CMD, sfso);

				// Write command to console
				this._writeConsole(input, true);

				// Clear hints
				this._lastHints = null;

				// Clear input
				this._clearInput();

				// Add command to history
				this._cmdHistory.addCommand(input);
			}
		}

		//--- ENTER ------------------------------------------------------------
		else if	(keyName == 'Tab')
		{
			// Get selected hint
			if (this._isHintPanelOpen)
			{
				if (this._hintPanel.find('.hint-item.selected').length > 0)
					this._setInputOnHintSelected();
			}
		}

		//--- CTRL+BACKSPACE (CLEAR CONSOLE) -----------------------------------
		else if (e.ctrlKey && keyName == 'Backspace')
		{
			this._onClearConsoleClick();
		}

		//--- BACKSPACE ------------------------------------------------------
		else if (keyName == 'Backspace')
		{
			// Check the deleted char
			if (this._prevInput.substring(this._prevInput.length - 1) == '.')
			{
				// Reset hinting
				this._resetHinting(input);
			}

			// Update hint panel if open
			if (this._isHintPanelOpen)
				this._updateHintPanel();
		}

		//--- ESC (CLEAR) ------------------------------------------------------
		else if (keyName == 'Escape')
		{
			// Close hint panel if open
			if (this._isHintPanelOpen)
				this._closeHintPanel();

			else
			{
				// Clear hints
				this._lastHints = null;

				// Clear input
				this._clearInput();
			}
		}

		//--- ARROW UP ---------------------------------------------------------
		else if (keyName == 'ArrowUp')
		{
			// If hint panel is open, set selection
			if (this._isHintPanelOpen)
			{
				this._currHintFocus--;

				this._setHintItemSelected();
			}

			// Browse history
			else
			{
				this._setInputOnHistorySelected(this._cmdHistory.rewind());
			}
		}

		//--- ARROW DOWN -------------------------------------------------------
		else if (keyName == 'ArrowDown')
		{
			// If hint panel is open, set selection
			if (this._isHintPanelOpen)
			{
				this._currHintFocus++;

				this._setHintItemSelected();
			}

			// Browse history
			else
			{
				this._setInputOnHistorySelected(this._cmdHistory.forward());
			}
		}

		//--- ARROW LEFT & RIGHT -----------------------------------------------
		else if (keyName == 'ArrowLeft' || keyName == 'ArrowRight')
		{
			// Close hint panel if open
			if (this._isHintPanelOpen)
				this._closeHintPanel();
		}

		//--- ANY OTHER KEY ----------------------------------------------------
		else
		{
			// Update temp in command history
			this._cmdHistory.addTempCommand(input);

			if (input.length == $('#cns-input')[0].selectionEnd)
			{
				// Update hint panel if open
				if (this._isHintPanelOpen)
					this._updateHintPanel();

				// Show hint panel
				else
					this._showHintPanel();
			}
			else
			{
				// Reset hinting
				this._resetHinting(input);
			}
		}
	}

	_onClearConsoleClick()
	{
		$('#cns-console').empty();
	}

	_onHintItemClick(e)
	{
		e.preventDefault();

		// Set clicked item as selected
		e.currentTarget.classList.add('selected');

		// Set input value
		this._setInputOnHintSelected();

		// Focus on prompt input
		$('#cns-input').focus();
	}

	_onGenericClick()
	{
		// Close hint panel if open
		if (this._isHintPanelOpen)
			this._closeHintPanel();
	}

	_onExportSessionClick()
	{
		let date = moment__WEBPACK_IMPORTED_MODULE_3__();

		let transcript = this.TRANSCRIPT_TEMPLATE.replace('<!--HEADER-->', `Saved on ${date.format('dddd, MMMM Do YYYY, HH:mm:ss')}`);
		transcript = transcript.replace('<!--TRANSCRIPT-->', $('#cns-console').html());

		let blob = new Blob([transcript], {type: 'text/html;charset=utf-8'});

		file_saver__WEBPACK_IMPORTED_MODULE_2__["saveAs"](blob, `ConsoleSession_${date.format('YYYYMMDD_HHmmss')}.html`);
	}

	_onRunScriptClick()
	{
		// Open modal
		this._uploadScriptModal.modal('show');
	}

	_onUploadScriptrModalHidden()
	{
		// Clear uploader
		this._uploader.clearAllFiles();
	}

	_onUploadScriptrButtonCLick()
	{
		if (this._uploader.getFiles().length > 0)
		{
			let file = this._uploader.getFiles()[0].rawFile;

			file.arrayBuffer().then(buffer => {
				this._writeConsole(`EXEC: ${file.name}`, true);

				let sfso = new SFS2X.SFSObject();
				sfso.putByteArray('script', new Uint8Array(buffer));

				this.sendExtensionRequest(this.REQ_SCRIPT, sfso);
			});

			// Close modal
			this._uploadScriptModal.modal('hide');
		}
	}

	//------------------------------------
	// PRIVATE METHODS
	//------------------------------------

	_showWelcomeMessage()
	{
		this._writeConsole(`--------------------------------------\nADMIN_CONSOLE, version ${this.VERSION}\n--------------------------------------\nType help() for assistance.\n`, false, false);
	}

	_clearInput()
	{
		$('#cns-input').val('');
		$('#cns-input-dummy').html('');
	}

	_setInputOnHintSelected()
	{
		if (this._hintPanel)
		{
			const input = $('#cns-input').val();
			const selectedVal = this._hintPanel.find('.hint-item.selected input').val();
			const newInput = input.substring(0, input.lastIndexOf('.')) + '.' + selectedVal;

			$('#cns-input').val(newInput);
			$('#cns-input-dummy').html(newInput);

			this._closeHintPanel();
		}
	}

	_setInputOnHistorySelected(command)
	{
		$('#cns-input').val(command);
		$('#cns-input-dummy').html(command);
	}

	_writeConsole(txt, isInput = false, linebreak = true)
	{
		let msg;

		if (isInput)
			msg = `<span class="text-command">&gt; ${txt}</span>`;
		else
			msg = `<span class="text-console">${txt}</span>`;

		if (linebreak)
			msg = `\n${msg}`;

		// Append text to console
		$('#cns-console').append(msg);

		// scroll console to bottom
		$('#cns-console').scrollTop(function() { return this.scrollHeight; });
	}

	_parseHtml(ss)
	{
		ss = ss.replace('<', '&lt;');
		ss = ss.replace('>', '&gt;');

		return ss;
	}

	_showHintPanel()
	{
		if (this._lastHints != null && this._lastHints.length > 0)
		{
			this._currHintFocus = -1;

			// Create panel
			this._hintPanel = $('<div>', {'class': 'hint-panel'});
			$(this).append(this._hintPanel);

			// Show hints
			this._updateHintPanel();
		}
	}

	_closeHintPanel()
	{
		this._hintPanel.remove();
		this._hintPanel = null;
	}

	_updateHintPanel()
	{
		if (this._lastHints != null && this._lastHints.length > 0)
		{
			// Clear hints panel
			this._hintPanel.empty();

			const dotIndex = $('#cns-input').val().lastIndexOf('.');
			let lastWord = '';

			if (dotIndex > -1)
				lastWord = $('#cns-input').val().substr(dotIndex + 1, $('#cns-input').val().length);

			let isEmpty = true;

			for (let word of this._lastHints)
			{
				// Check if the item starts with the same letters as the input's last word
				if (lastWord == '' || word.substr(0, lastWord.length).toUpperCase() == lastWord.toUpperCase())
				{
					// Create div
					let item = $('<div>', {'class': 'hint-item'});

					// Show value, and make the matching letters bold
					item.append(`<strong>${word.substr(0, lastWord.length)}</strong>${word.substr(lastWord.length)}`);

					// Insert an input field that will hold the current item's value
					item.append(`<input type="hidden" value="${word}">`);

					// Add click listener
					item.on('click', $.proxy(this._onHintItemClick, this));

					this._hintPanel.append(item);

					isEmpty = false;
				}
			}

			// If panel is empty, rmove it
			if (isEmpty)
				this._closeHintPanel();

			// Else set panel position
			else
			{
				const extContPos = $('#cns-input-container-2').position();
				const intContPos = $('#cns-input-container-1').position();

				let left = extContPos.left + intContPos.left + $('#cns-input-dummy').outerWidth();
				let top = extContPos.top + intContPos.top - this._hintPanel.outerHeight();

				if (left > window.innerWidth - this._hintPanel.outerWidth())
					left = window.innerWidth - this._hintPanel.outerWidth();

				this._hintPanel.css({top: top, left: left, position: 'absolute'});
			}
		}
	}

	_requestHints(input)
	{
		// Clear previous hints
		this._lastHints = null;

		// Parse input
		let hintParent = this._extractHintParent(input);
		
		// Request code hint
		let params = new SFS2X.SFSObject();
		params.putUtfString('c', hintParent);

		this.sendExtensionRequest(this.REQ_HINT, params);
	}

	_extractHintParent(inVal)
	{
		let outVal = null;

		for (let tok of this.TOKENS)
		{
			const p = inVal.indexOf(tok);

			if (p > -1)
			{
				outVal = inVal.substring(p + tok.length, inVal.length).trim();
				break;
			}
		}

		if (outVal == null)
			outVal = inVal;

		// Remove dot at the end if needed
		if (outVal.endsWith('.'))
			outVal = outVal.substr(0, outVal.length - 1);

		return outVal;
	}

	_setHintItemSelected()
	{
		let items = this._hintPanel.find('.hint-item');
		items.removeClass('selected');

		if (this._currHintFocus >= items.length)
			this._currHintFocus = 0;

    	if (this._currHintFocus < 0)
			this._currHintFocus = items.length - 1;

		let item = items.eq(this._currHintFocus);
		item.addClass('selected');

		// Scroll to item
		this._hintPanel.scrollTop(this._hintPanel.scrollTop() + item.position().top);
	}

	_resetHinting(input)
	{
		// Close hint panel
		if (this._isHintPanelOpen)
			this._closeHintPanel();

		// Clear hints
		this._lastHints = null;

		// Get previous word
		const dotIndex = input.lastIndexOf('.');

		if (dotIndex > -1)
		{
			let value = input.substring(0, dotIndex);

			// Request code hints
			this._requestHints(value);
		}
	}

	//---------------------------------
	// PRIVATE GETTERS
	//---------------------------------

	get _isHintPanelOpen()
	{
		return this._hintPanel != null;
	}
}

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))

/***/ })

}]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64, 