/******/ (function(modules) { // webpackBootstrap
/******/ 	// 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: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// 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 = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./webpack/vendors/custom/tinymce.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./node_modules/tinymce/themes/mobile/theme.js":
/*!*****************************************************!*\
  !*** ./node_modules/tinymce/themes/mobile/theme.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Copyright (c) Tiny Technologies, Inc. All rights reserved.\n * Licensed under the LGPL or a commercial license.\n * For LGPL see License.txt in the project root for license information.\n * For commercial licenses see https://www.tiny.cloud/\n *\n * Version: 5.1.5 (2019-12-19)\n */\n(function (domGlobals) {\n    'use strict';\n\n    var __assign = function () {\n      __assign = Object.assign || function __assign(t) {\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\n          s = arguments[i];\n          for (var p in s)\n            if (Object.prototype.hasOwnProperty.call(s, p))\n              t[p] = s[p];\n        }\n        return t;\n      };\n      return __assign.apply(this, arguments);\n    };\n    function __rest(s, e) {\n      var t = {};\n      for (var p in s)\n        if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n          t[p] = s[p];\n      if (s != null && typeof Object.getOwnPropertySymbols === 'function')\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n          if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n            t[p[i]] = s[p[i]];\n        }\n      return t;\n    }\n    function __spreadArrays() {\n      for (var s = 0, i = 0, il = arguments.length; i < il; i++)\n        s += arguments[i].length;\n      for (var r = Array(s), k = 0, i = 0; i < il; i++)\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n          r[k] = a[j];\n      return r;\n    }\n\n    var noop = function () {\n    };\n    var compose = function (fa, fb) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return fa(fb.apply(null, args));\n      };\n    };\n    var constant = function (value) {\n      return function () {\n        return value;\n      };\n    };\n    var identity = function (x) {\n      return x;\n    };\n    function curry(fn) {\n      var initialArgs = [];\n      for (var _i = 1; _i < arguments.length; _i++) {\n        initialArgs[_i - 1] = arguments[_i];\n      }\n      return function () {\n        var restArgs = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          restArgs[_i] = arguments[_i];\n        }\n        var all = initialArgs.concat(restArgs);\n        return fn.apply(null, all);\n      };\n    }\n    var not = function (f) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return !f.apply(null, args);\n      };\n    };\n    var die = function (msg) {\n      return function () {\n        throw new Error(msg);\n      };\n    };\n    var apply = function (f) {\n      return f();\n    };\n    var never = constant(false);\n    var always = constant(true);\n\n    var none = function () {\n      return NONE;\n    };\n    var NONE = function () {\n      var eq = function (o) {\n        return o.isNone();\n      };\n      var call = function (thunk) {\n        return thunk();\n      };\n      var id = function (n) {\n        return n;\n      };\n      var me = {\n        fold: function (n, s) {\n          return n();\n        },\n        is: never,\n        isSome: never,\n        isNone: always,\n        getOr: id,\n        getOrThunk: call,\n        getOrDie: function (msg) {\n          throw new Error(msg || 'error: getOrDie called on none.');\n        },\n        getOrNull: constant(null),\n        getOrUndefined: constant(undefined),\n        or: id,\n        orThunk: call,\n        map: none,\n        each: noop,\n        bind: none,\n        exists: never,\n        forall: always,\n        filter: none,\n        equals: eq,\n        equals_: eq,\n        toArray: function () {\n          return [];\n        },\n        toString: constant('none()')\n      };\n      if (Object.freeze) {\n        Object.freeze(me);\n      }\n      return me;\n    }();\n    var some = function (a) {\n      var constant_a = constant(a);\n      var self = function () {\n        return me;\n      };\n      var bind = function (f) {\n        return f(a);\n      };\n      var me = {\n        fold: function (n, s) {\n          return s(a);\n        },\n        is: function (v) {\n          return a === v;\n        },\n        isSome: always,\n        isNone: never,\n        getOr: constant_a,\n        getOrThunk: constant_a,\n        getOrDie: constant_a,\n        getOrNull: constant_a,\n        getOrUndefined: constant_a,\n        or: self,\n        orThunk: self,\n        map: function (f) {\n          return some(f(a));\n        },\n        each: function (f) {\n          f(a);\n        },\n        bind: bind,\n        exists: bind,\n        forall: bind,\n        filter: function (f) {\n          return f(a) ? me : NONE;\n        },\n        toArray: function () {\n          return [a];\n        },\n        toString: function () {\n          return 'some(' + a + ')';\n        },\n        equals: function (o) {\n          return o.is(a);\n        },\n        equals_: function (o, elementEq) {\n          return o.fold(never, function (b) {\n            return elementEq(a, b);\n          });\n        }\n      };\n      return me;\n    };\n    var from = function (value) {\n      return value === null || value === undefined ? NONE : some(value);\n    };\n    var Option = {\n      some: some,\n      none: none,\n      from: from\n    };\n\n    var keys = Object.keys;\n    var hasOwnProperty = Object.hasOwnProperty;\n    var each = function (obj, f) {\n      var props = keys(obj);\n      for (var k = 0, len = props.length; k < len; k++) {\n        var i = props[k];\n        var x = obj[i];\n        f(x, i);\n      }\n    };\n    var map = function (obj, f) {\n      return tupleMap(obj, function (x, i) {\n        return {\n          k: i,\n          v: f(x, i)\n        };\n      });\n    };\n    var tupleMap = function (obj, f) {\n      var r = {};\n      each(obj, function (x, i) {\n        var tuple = f(x, i);\n        r[tuple.k] = tuple.v;\n      });\n      return r;\n    };\n    var mapToArray = function (obj, f) {\n      var r = [];\n      each(obj, function (value, name) {\n        r.push(f(value, name));\n      });\n      return r;\n    };\n    var find = function (obj, pred) {\n      var props = keys(obj);\n      for (var k = 0, len = props.length; k < len; k++) {\n        var i = props[k];\n        var x = obj[i];\n        if (pred(x, i, obj)) {\n          return Option.some(x);\n        }\n      }\n      return Option.none();\n    };\n    var values = function (obj) {\n      return mapToArray(obj, function (v) {\n        return v;\n      });\n    };\n    var has = function (obj, key) {\n      return hasOwnProperty.call(obj, key);\n    };\n\n    var Cell = function (initial) {\n      var value = initial;\n      var get = function () {\n        return value;\n      };\n      var set = function (v) {\n        value = v;\n      };\n      var clone = function () {\n        return Cell(get());\n      };\n      return {\n        get: get,\n        set: set,\n        clone: clone\n      };\n    };\n\n    var firstMatch = function (regexes, s) {\n      for (var i = 0; i < regexes.length; i++) {\n        var x = regexes[i];\n        if (x.test(s)) {\n          return x;\n        }\n      }\n      return undefined;\n    };\n    var find$1 = function (regexes, agent) {\n      var r = firstMatch(regexes, agent);\n      if (!r) {\n        return {\n          major: 0,\n          minor: 0\n        };\n      }\n      var group = function (i) {\n        return Number(agent.replace(r, '$' + i));\n      };\n      return nu(group(1), group(2));\n    };\n    var detect = function (versionRegexes, agent) {\n      var cleanedAgent = String(agent).toLowerCase();\n      if (versionRegexes.length === 0) {\n        return unknown();\n      }\n      return find$1(versionRegexes, cleanedAgent);\n    };\n    var unknown = function () {\n      return nu(0, 0);\n    };\n    var nu = function (major, minor) {\n      return {\n        major: major,\n        minor: minor\n      };\n    };\n    var Version = {\n      nu: nu,\n      detect: detect,\n      unknown: unknown\n    };\n\n    var edge = 'Edge';\n    var chrome = 'Chrome';\n    var ie = 'IE';\n    var opera = 'Opera';\n    var firefox = 'Firefox';\n    var safari = 'Safari';\n    var isBrowser = function (name, current) {\n      return function () {\n        return current === name;\n      };\n    };\n    var unknown$1 = function () {\n      return nu$1({\n        current: undefined,\n        version: Version.unknown()\n      });\n    };\n    var nu$1 = function (info) {\n      var current = info.current;\n      var version = info.version;\n      return {\n        current: current,\n        version: version,\n        isEdge: isBrowser(edge, current),\n        isChrome: isBrowser(chrome, current),\n        isIE: isBrowser(ie, current),\n        isOpera: isBrowser(opera, current),\n        isFirefox: isBrowser(firefox, current),\n        isSafari: isBrowser(safari, current)\n      };\n    };\n    var Browser = {\n      unknown: unknown$1,\n      nu: nu$1,\n      edge: constant(edge),\n      chrome: constant(chrome),\n      ie: constant(ie),\n      opera: constant(opera),\n      firefox: constant(firefox),\n      safari: constant(safari)\n    };\n\n    var windows = 'Windows';\n    var ios = 'iOS';\n    var android = 'Android';\n    var linux = 'Linux';\n    var osx = 'OSX';\n    var solaris = 'Solaris';\n    var freebsd = 'FreeBSD';\n    var isOS = function (name, current) {\n      return function () {\n        return current === name;\n      };\n    };\n    var unknown$2 = function () {\n      return nu$2({\n        current: undefined,\n        version: Version.unknown()\n      });\n    };\n    var nu$2 = function (info) {\n      var current = info.current;\n      var version = info.version;\n      return {\n        current: current,\n        version: version,\n        isWindows: isOS(windows, current),\n        isiOS: isOS(ios, current),\n        isAndroid: isOS(android, current),\n        isOSX: isOS(osx, current),\n        isLinux: isOS(linux, current),\n        isSolaris: isOS(solaris, current),\n        isFreeBSD: isOS(freebsd, current)\n      };\n    };\n    var OperatingSystem = {\n      unknown: unknown$2,\n      nu: nu$2,\n      windows: constant(windows),\n      ios: constant(ios),\n      android: constant(android),\n      linux: constant(linux),\n      osx: constant(osx),\n      solaris: constant(solaris),\n      freebsd: constant(freebsd)\n    };\n\n    var DeviceType = function (os, browser, userAgent, mediaMatch) {\n      var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;\n      var isiPhone = os.isiOS() && !isiPad;\n      var isMobile = os.isiOS() || os.isAndroid();\n      var isTouch = isMobile || mediaMatch('(pointer:coarse)');\n      var isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');\n      var isPhone = isiPhone || isMobile && !isTablet;\n      var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;\n      var isDesktop = !isPhone && !isTablet && !iOSwebview;\n      return {\n        isiPad: constant(isiPad),\n        isiPhone: constant(isiPhone),\n        isTablet: constant(isTablet),\n        isPhone: constant(isPhone),\n        isTouch: constant(isTouch),\n        isAndroid: os.isAndroid,\n        isiOS: os.isiOS,\n        isWebView: constant(iOSwebview),\n        isDesktop: constant(isDesktop)\n      };\n    };\n\n    var typeOf = function (x) {\n      if (x === null) {\n        return 'null';\n      }\n      var t = typeof x;\n      if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {\n        return 'array';\n      }\n      if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {\n        return 'string';\n      }\n      return t;\n    };\n    var isType = function (type) {\n      return function (value) {\n        return typeOf(value) === type;\n      };\n    };\n    var isString = isType('string');\n    var isObject = isType('object');\n    var isArray = isType('array');\n    var isBoolean = isType('boolean');\n    var isFunction = isType('function');\n    var isNumber = isType('number');\n\n    var nativeSlice = Array.prototype.slice;\n    var nativeIndexOf = Array.prototype.indexOf;\n    var nativePush = Array.prototype.push;\n    var rawIndexOf = function (ts, t) {\n      return nativeIndexOf.call(ts, t);\n    };\n    var contains = function (xs, x) {\n      return rawIndexOf(xs, x) > -1;\n    };\n    var exists = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return true;\n        }\n      }\n      return false;\n    };\n    var map$1 = function (xs, f) {\n      var len = xs.length;\n      var r = new Array(len);\n      for (var i = 0; i < len; i++) {\n        var x = xs[i];\n        r[i] = f(x, i);\n      }\n      return r;\n    };\n    var each$1 = function (xs, f) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        f(x, i);\n      }\n    };\n    var eachr = function (xs, f) {\n      for (var i = xs.length - 1; i >= 0; i--) {\n        var x = xs[i];\n        f(x, i);\n      }\n    };\n    var filter = function (xs, pred) {\n      var r = [];\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          r.push(x);\n        }\n      }\n      return r;\n    };\n    var foldr = function (xs, f, acc) {\n      eachr(xs, function (x) {\n        acc = f(acc, x);\n      });\n      return acc;\n    };\n    var foldl = function (xs, f, acc) {\n      each$1(xs, function (x) {\n        acc = f(acc, x);\n      });\n      return acc;\n    };\n    var find$2 = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return Option.some(x);\n        }\n      }\n      return Option.none();\n    };\n    var findIndex = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return Option.some(i);\n        }\n      }\n      return Option.none();\n    };\n    var flatten = function (xs) {\n      var r = [];\n      for (var i = 0, len = xs.length; i < len; ++i) {\n        if (!isArray(xs[i])) {\n          throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);\n        }\n        nativePush.apply(r, xs[i]);\n      }\n      return r;\n    };\n    var bind = function (xs, f) {\n      var output = map$1(xs, f);\n      return flatten(output);\n    };\n    var forall = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; ++i) {\n        var x = xs[i];\n        if (pred(x, i) !== true) {\n          return false;\n        }\n      }\n      return true;\n    };\n    var reverse = function (xs) {\n      var r = nativeSlice.call(xs, 0);\n      r.reverse();\n      return r;\n    };\n    var difference = function (a1, a2) {\n      return filter(a1, function (x) {\n        return !contains(a2, x);\n      });\n    };\n    var pure = function (x) {\n      return [x];\n    };\n    var from$1 = isFunction(Array.from) ? Array.from : function (x) {\n      return nativeSlice.call(x);\n    };\n\n    var detect$1 = function (candidates, userAgent) {\n      var agent = String(userAgent).toLowerCase();\n      return find$2(candidates, function (candidate) {\n        return candidate.search(agent);\n      });\n    };\n    var detectBrowser = function (browsers, userAgent) {\n      return detect$1(browsers, userAgent).map(function (browser) {\n        var version = Version.detect(browser.versionRegexes, userAgent);\n        return {\n          current: browser.name,\n          version: version\n        };\n      });\n    };\n    var detectOs = function (oses, userAgent) {\n      return detect$1(oses, userAgent).map(function (os) {\n        var version = Version.detect(os.versionRegexes, userAgent);\n        return {\n          current: os.name,\n          version: version\n        };\n      });\n    };\n    var UaString = {\n      detectBrowser: detectBrowser,\n      detectOs: detectOs\n    };\n\n    var checkRange = function (str, substr, start) {\n      if (substr === '') {\n        return true;\n      }\n      if (str.length < substr.length) {\n        return false;\n      }\n      var x = str.substr(start, start + substr.length);\n      return x === substr;\n    };\n    var supplant = function (str, obj) {\n      var isStringOrNumber = function (a) {\n        var t = typeof a;\n        return t === 'string' || t === 'number';\n      };\n      return str.replace(/\\$\\{([^{}]*)\\}/g, function (fullMatch, key) {\n        var value = obj[key];\n        return isStringOrNumber(value) ? value.toString() : fullMatch;\n      });\n    };\n    var contains$1 = function (str, substr) {\n      return str.indexOf(substr) !== -1;\n    };\n    var endsWith = function (str, suffix) {\n      return checkRange(str, suffix, str.length - suffix.length);\n    };\n    var trim = function (str) {\n      return str.replace(/^\\s+|\\s+$/g, '');\n    };\n\n    var normalVersionRegex = /.*?version\\/\\ ?([0-9]+)\\.([0-9]+).*/;\n    var checkContains = function (target) {\n      return function (uastring) {\n        return contains$1(uastring, target);\n      };\n    };\n    var browsers = [\n      {\n        name: 'Edge',\n        versionRegexes: [/.*?edge\\/ ?([0-9]+)\\.([0-9]+)$/],\n        search: function (uastring) {\n          return contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit');\n        }\n      },\n      {\n        name: 'Chrome',\n        versionRegexes: [\n          /.*?chrome\\/([0-9]+)\\.([0-9]+).*/,\n          normalVersionRegex\n        ],\n        search: function (uastring) {\n          return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe');\n        }\n      },\n      {\n        name: 'IE',\n        versionRegexes: [\n          /.*?msie\\ ?([0-9]+)\\.([0-9]+).*/,\n          /.*?rv:([0-9]+)\\.([0-9]+).*/\n        ],\n        search: function (uastring) {\n          return contains$1(uastring, 'msie') || contains$1(uastring, 'trident');\n        }\n      },\n      {\n        name: 'Opera',\n        versionRegexes: [\n          normalVersionRegex,\n          /.*?opera\\/([0-9]+)\\.([0-9]+).*/\n        ],\n        search: checkContains('opera')\n      },\n      {\n        name: 'Firefox',\n        versionRegexes: [/.*?firefox\\/\\ ?([0-9]+)\\.([0-9]+).*/],\n        search: checkContains('firefox')\n      },\n      {\n        name: 'Safari',\n        versionRegexes: [\n          normalVersionRegex,\n          /.*?cpu os ([0-9]+)_([0-9]+).*/\n        ],\n        search: function (uastring) {\n          return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit');\n        }\n      }\n    ];\n    var oses = [\n      {\n        name: 'Windows',\n        search: checkContains('win'),\n        versionRegexes: [/.*?windows\\ nt\\ ?([0-9]+)\\.([0-9]+).*/]\n      },\n      {\n        name: 'iOS',\n        search: function (uastring) {\n          return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad');\n        },\n        versionRegexes: [\n          /.*?version\\/\\ ?([0-9]+)\\.([0-9]+).*/,\n          /.*cpu os ([0-9]+)_([0-9]+).*/,\n          /.*cpu iphone os ([0-9]+)_([0-9]+).*/\n        ]\n      },\n      {\n        name: 'Android',\n        search: checkContains('android'),\n        versionRegexes: [/.*?android\\ ?([0-9]+)\\.([0-9]+).*/]\n      },\n      {\n        name: 'OSX',\n        search: checkContains('os x'),\n        versionRegexes: [/.*?os\\ x\\ ?([0-9]+)_([0-9]+).*/]\n      },\n      {\n        name: 'Linux',\n        search: checkContains('linux'),\n        versionRegexes: []\n      },\n      {\n        name: 'Solaris',\n        search: checkContains('sunos'),\n        versionRegexes: []\n      },\n      {\n        name: 'FreeBSD',\n        search: checkContains('freebsd'),\n        versionRegexes: []\n      }\n    ];\n    var PlatformInfo = {\n      browsers: constant(browsers),\n      oses: constant(oses)\n    };\n\n    var detect$2 = function (userAgent, mediaMatch) {\n      var browsers = PlatformInfo.browsers();\n      var oses = PlatformInfo.oses();\n      var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);\n      var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);\n      var deviceType = DeviceType(os, browser, userAgent, mediaMatch);\n      return {\n        browser: browser,\n        os: os,\n        deviceType: deviceType\n      };\n    };\n    var PlatformDetection = { detect: detect$2 };\n\n    var mediaMatch = function (query) {\n      return domGlobals.window.matchMedia(query).matches;\n    };\n    var platform = Cell(PlatformDetection.detect(domGlobals.navigator.userAgent, mediaMatch));\n    var detect$3 = function () {\n      return platform.get();\n    };\n\n    var touchstart = constant('touchstart');\n    var touchmove = constant('touchmove');\n    var touchend = constant('touchend');\n    var mousedown = constant('mousedown');\n    var mousemove = constant('mousemove');\n    var mouseup = constant('mouseup');\n    var mouseover = constant('mouseover');\n    var keydown = constant('keydown');\n    var keyup = constant('keyup');\n    var input = constant('input');\n    var change = constant('change');\n    var click = constant('click');\n    var transitionend = constant('transitionend');\n    var selectstart = constant('selectstart');\n\n    var alloy = { tap: constant('alloy.tap') };\n    var focus = constant('alloy.focus');\n    var postBlur = constant('alloy.blur.post');\n    var postPaste = constant('alloy.paste.post');\n    var receive = constant('alloy.receive');\n    var execute = constant('alloy.execute');\n    var focusItem = constant('alloy.focus.item');\n    var tap = alloy.tap;\n    var longpress = constant('alloy.longpress');\n    var systemInit = constant('alloy.system.init');\n    var attachedToDom = constant('alloy.system.attached');\n    var detachedFromDom = constant('alloy.system.detached');\n    var focusShifted = constant('alloy.focusmanager.shifted');\n    var highlight = constant('alloy.highlight');\n    var dehighlight = constant('alloy.dehighlight');\n\n    var emit = function (component, event) {\n      dispatchWith(component, component.element(), event, {});\n    };\n    var emitWith = function (component, event, properties) {\n      dispatchWith(component, component.element(), event, properties);\n    };\n    var emitExecute = function (component) {\n      emit(component, execute());\n    };\n    var dispatch = function (component, target, event) {\n      dispatchWith(component, target, event, {});\n    };\n    var dispatchWith = function (component, target, event, properties) {\n      var data = __assign({ target: target }, properties);\n      component.getSystem().triggerEvent(event, target, map(data, constant));\n    };\n    var dispatchEvent = function (component, target, event, simulatedEvent) {\n      component.getSystem().triggerEvent(event, target, simulatedEvent.event());\n    };\n    var dispatchFocus = function (component, target) {\n      component.getSystem().triggerFocus(target, component.element());\n    };\n\n    var cached = function (f) {\n      var called = false;\n      var r;\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (!called) {\n          called = true;\n          r = f.apply(null, args);\n        }\n        return r;\n      };\n    };\n\n    var fromHtml = function (html, scope) {\n      var doc = scope || domGlobals.document;\n      var div = doc.createElement('div');\n      div.innerHTML = html;\n      if (!div.hasChildNodes() || div.childNodes.length > 1) {\n        domGlobals.console.error('HTML does not have a single root node', html);\n        throw new Error('HTML must have a single root node');\n      }\n      return fromDom(div.childNodes[0]);\n    };\n    var fromTag = function (tag, scope) {\n      var doc = scope || domGlobals.document;\n      var node = doc.createElement(tag);\n      return fromDom(node);\n    };\n    var fromText = function (text, scope) {\n      var doc = scope || domGlobals.document;\n      var node = doc.createTextNode(text);\n      return fromDom(node);\n    };\n    var fromDom = function (node) {\n      if (node === null || node === undefined) {\n        throw new Error('Node cannot be null or undefined');\n      }\n      return { dom: constant(node) };\n    };\n    var fromPoint = function (docElm, x, y) {\n      var doc = docElm.dom();\n      return Option.from(doc.elementFromPoint(x, y)).map(fromDom);\n    };\n    var Element = {\n      fromHtml: fromHtml,\n      fromTag: fromTag,\n      fromText: fromText,\n      fromDom: fromDom,\n      fromPoint: fromPoint\n    };\n\n    var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;\n    var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;\n    var COMMENT = domGlobals.Node.COMMENT_NODE;\n    var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;\n    var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;\n    var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;\n    var ELEMENT = domGlobals.Node.ELEMENT_NODE;\n    var TEXT = domGlobals.Node.TEXT_NODE;\n    var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;\n    var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;\n    var ENTITY = domGlobals.Node.ENTITY_NODE;\n    var NOTATION = domGlobals.Node.NOTATION_NODE;\n\n    var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();\n\n    var name = function (element) {\n      var r = element.dom().nodeName;\n      return r.toLowerCase();\n    };\n    var type = function (element) {\n      return element.dom().nodeType;\n    };\n    var isType$1 = function (t) {\n      return function (element) {\n        return type(element) === t;\n      };\n    };\n    var isElement = isType$1(ELEMENT);\n    var isText = isType$1(TEXT);\n\n    var inBody = function (element) {\n      var dom = isText(element) ? element.dom().parentNode : element.dom();\n      return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom);\n    };\n    var body = cached(function () {\n      return getBody(Element.fromDom(domGlobals.document));\n    });\n    var getBody = function (doc) {\n      var b = doc.dom().body;\n      if (b === null || b === undefined) {\n        throw new Error('Body is not available yet');\n      }\n      return Element.fromDom(b);\n    };\n\n    var Immutable = function () {\n      var fields = [];\n      for (var _i = 0; _i < arguments.length; _i++) {\n        fields[_i] = arguments[_i];\n      }\n      return function () {\n        var values = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          values[_i] = arguments[_i];\n        }\n        if (fields.length !== values.length) {\n          throw new Error('Wrong number of arguments to struct. Expected \"[' + fields.length + ']\", got ' + values.length + ' arguments');\n        }\n        var struct = {};\n        each$1(fields, function (name, i) {\n          struct[name] = constant(values[i]);\n        });\n        return struct;\n      };\n    };\n\n    var sort = function (arr) {\n      return arr.slice(0).sort();\n    };\n    var reqMessage = function (required, keys) {\n      throw new Error('All required keys (' + sort(required).join(', ') + ') were not specified. Specified keys were: ' + sort(keys).join(', ') + '.');\n    };\n    var unsuppMessage = function (unsupported) {\n      throw new Error('Unsupported keys for object: ' + sort(unsupported).join(', '));\n    };\n    var validateStrArr = function (label, array) {\n      if (!isArray(array)) {\n        throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.');\n      }\n      each$1(array, function (a) {\n        if (!isString(a)) {\n          throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.');\n        }\n      });\n    };\n    var checkDupes = function (everything) {\n      var sorted = sort(everything);\n      var dupe = find$2(sorted, function (s, i) {\n        return i < sorted.length - 1 && s === sorted[i + 1];\n      });\n      dupe.each(function (d) {\n        throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].');\n      });\n    };\n\n    var MixedBag = function (required, optional) {\n      var everything = required.concat(optional);\n      if (everything.length === 0) {\n        throw new Error('You must specify at least one required or optional field.');\n      }\n      validateStrArr('required', required);\n      validateStrArr('optional', optional);\n      checkDupes(everything);\n      return function (obj) {\n        var keys$1 = keys(obj);\n        var allReqd = forall(required, function (req) {\n          return contains(keys$1, req);\n        });\n        if (!allReqd) {\n          reqMessage(required, keys$1);\n        }\n        var unsupported = filter(keys$1, function (key) {\n          return !contains(everything, key);\n        });\n        if (unsupported.length > 0) {\n          unsuppMessage(unsupported);\n        }\n        var r = {};\n        each$1(required, function (req) {\n          r[req] = constant(obj[req]);\n        });\n        each$1(optional, function (opt) {\n          r[opt] = constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]) : Option.none());\n        });\n        return r;\n      };\n    };\n\n    var compareDocumentPosition = function (a, b, match) {\n      return (a.compareDocumentPosition(b) & match) !== 0;\n    };\n    var documentPositionPreceding = function (a, b) {\n      return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_PRECEDING);\n    };\n    var documentPositionContainedBy = function (a, b) {\n      return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_CONTAINED_BY);\n    };\n    var Node = {\n      documentPositionPreceding: documentPositionPreceding,\n      documentPositionContainedBy: documentPositionContainedBy\n    };\n\n    var ELEMENT$1 = ELEMENT;\n    var DOCUMENT$1 = DOCUMENT;\n    var is = function (element, selector) {\n      var dom = element.dom();\n      if (dom.nodeType !== ELEMENT$1) {\n        return false;\n      } else {\n        var elem = dom;\n        if (elem.matches !== undefined) {\n          return elem.matches(selector);\n        } else if (elem.msMatchesSelector !== undefined) {\n          return elem.msMatchesSelector(selector);\n        } else if (elem.webkitMatchesSelector !== undefined) {\n          return elem.webkitMatchesSelector(selector);\n        } else if (elem.mozMatchesSelector !== undefined) {\n          return elem.mozMatchesSelector(selector);\n        } else {\n          throw new Error('Browser lacks native selectors');\n        }\n      }\n    };\n    var bypassSelector = function (dom) {\n      return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0;\n    };\n    var all = function (selector, scope) {\n      var base = scope === undefined ? domGlobals.document : scope.dom();\n      return bypassSelector(base) ? [] : map$1(base.querySelectorAll(selector), Element.fromDom);\n    };\n    var one = function (selector, scope) {\n      var base = scope === undefined ? domGlobals.document : scope.dom();\n      return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom);\n    };\n\n    var eq = function (e1, e2) {\n      return e1.dom() === e2.dom();\n    };\n    var regularContains = function (e1, e2) {\n      var d1 = e1.dom();\n      var d2 = e2.dom();\n      return d1 === d2 ? false : d1.contains(d2);\n    };\n    var ieContains = function (e1, e2) {\n      return Node.documentPositionContainedBy(e1.dom(), e2.dom());\n    };\n    var browser = detect$3().browser;\n    var contains$2 = browser.isIE() ? ieContains : regularContains;\n\n    var owner = function (element) {\n      return Element.fromDom(element.dom().ownerDocument);\n    };\n    var defaultView = function (element) {\n      return Element.fromDom(element.dom().ownerDocument.defaultView);\n    };\n    var parent = function (element) {\n      return Option.from(element.dom().parentNode).map(Element.fromDom);\n    };\n    var parents = function (element, isRoot) {\n      var stop = isFunction(isRoot) ? isRoot : never;\n      var dom = element.dom();\n      var ret = [];\n      while (dom.parentNode !== null && dom.parentNode !== undefined) {\n        var rawParent = dom.parentNode;\n        var p = Element.fromDom(rawParent);\n        ret.push(p);\n        if (stop(p) === true) {\n          break;\n        } else {\n          dom = rawParent;\n        }\n      }\n      return ret;\n    };\n    var siblings = function (element) {\n      var filterSelf = function (elements) {\n        return filter(elements, function (x) {\n          return !eq(element, x);\n        });\n      };\n      return parent(element).map(children).map(filterSelf).getOr([]);\n    };\n    var nextSibling = function (element) {\n      return Option.from(element.dom().nextSibling).map(Element.fromDom);\n    };\n    var children = function (element) {\n      return map$1(element.dom().childNodes, Element.fromDom);\n    };\n    var child = function (element, index) {\n      var cs = element.dom().childNodes;\n      return Option.from(cs[index]).map(Element.fromDom);\n    };\n    var firstChild = function (element) {\n      return child(element, 0);\n    };\n    var spot = Immutable('element', 'offset');\n\n    var before = function (marker, element) {\n      var parent$1 = parent(marker);\n      parent$1.each(function (v) {\n        v.dom().insertBefore(element.dom(), marker.dom());\n      });\n    };\n    var after = function (marker, element) {\n      var sibling = nextSibling(marker);\n      sibling.fold(function () {\n        var parent$1 = parent(marker);\n        parent$1.each(function (v) {\n          append(v, element);\n        });\n      }, function (v) {\n        before(v, element);\n      });\n    };\n    var prepend = function (parent, element) {\n      var firstChild$1 = firstChild(parent);\n      firstChild$1.fold(function () {\n        append(parent, element);\n      }, function (v) {\n        parent.dom().insertBefore(element.dom(), v.dom());\n      });\n    };\n    var append = function (parent, element) {\n      parent.dom().appendChild(element.dom());\n    };\n    var appendAt = function (parent, element, index) {\n      child(parent, index).fold(function () {\n        append(parent, element);\n      }, function (v) {\n        before(v, element);\n      });\n    };\n\n    var append$1 = function (parent, elements) {\n      each$1(elements, function (x) {\n        append(parent, x);\n      });\n    };\n\n    var empty = function (element) {\n      element.dom().textContent = '';\n      each$1(children(element), function (rogue) {\n        remove(rogue);\n      });\n    };\n    var remove = function (element) {\n      var dom = element.dom();\n      if (dom.parentNode !== null) {\n        dom.parentNode.removeChild(dom);\n      }\n    };\n\n    var fireDetaching = function (component) {\n      emit(component, detachedFromDom());\n      var children = component.components();\n      each$1(children, fireDetaching);\n    };\n    var fireAttaching = function (component) {\n      var children = component.components();\n      each$1(children, fireAttaching);\n      emit(component, attachedToDom());\n    };\n    var attach = function (parent, child) {\n      append(parent.element(), child.element());\n    };\n    var detachChildren = function (component) {\n      each$1(component.components(), function (childComp) {\n        return remove(childComp.element());\n      });\n      empty(component.element());\n      component.syncComponents();\n    };\n    var replaceChildren = function (component, newChildren) {\n      var subs = component.components();\n      detachChildren(component);\n      var deleted = difference(subs, newChildren);\n      each$1(deleted, function (comp) {\n        fireDetaching(comp);\n        component.getSystem().removeFromWorld(comp);\n      });\n      each$1(newChildren, function (childComp) {\n        if (!childComp.getSystem().isConnected()) {\n          component.getSystem().addToWorld(childComp);\n          attach(component, childComp);\n          if (inBody(component.element())) {\n            fireAttaching(childComp);\n          }\n        } else {\n          attach(component, childComp);\n        }\n        component.syncComponents();\n      });\n    };\n\n    var attach$1 = function (parent, child) {\n      attachWith(parent, child, append);\n    };\n    var attachWith = function (parent, child, insertion) {\n      parent.getSystem().addToWorld(child);\n      insertion(parent.element(), child.element());\n      if (inBody(parent.element())) {\n        fireAttaching(child);\n      }\n      parent.syncComponents();\n    };\n    var doDetach = function (component) {\n      fireDetaching(component);\n      remove(component.element());\n      component.getSystem().removeFromWorld(component);\n    };\n    var detach = function (component) {\n      var parent$1 = parent(component.element()).bind(function (p) {\n        return component.getSystem().getByDom(p).toOption();\n      });\n      doDetach(component);\n      parent$1.each(function (p) {\n        p.syncComponents();\n      });\n    };\n    var attachSystemAfter = function (element, guiSystem) {\n      attachSystemWith(element, guiSystem, after);\n    };\n    var attachSystemWith = function (element, guiSystem, inserter) {\n      inserter(element, guiSystem.element());\n      var children$1 = children(guiSystem.element());\n      each$1(children$1, function (child) {\n        guiSystem.getByDom(child).each(fireAttaching);\n      });\n    };\n    var detachSystem = function (guiSystem) {\n      var children$1 = children(guiSystem.element());\n      each$1(children$1, function (child) {\n        guiSystem.getByDom(child).each(fireDetaching);\n      });\n      remove(guiSystem.element());\n    };\n\n    var value = function (o) {\n      var is = function (v) {\n        return o === v;\n      };\n      var or = function (opt) {\n        return value(o);\n      };\n      var orThunk = function (f) {\n        return value(o);\n      };\n      var map = function (f) {\n        return value(f(o));\n      };\n      var mapError = function (f) {\n        return value(o);\n      };\n      var each = function (f) {\n        f(o);\n      };\n      var bind = function (f) {\n        return f(o);\n      };\n      var fold = function (_, onValue) {\n        return onValue(o);\n      };\n      var exists = function (f) {\n        return f(o);\n      };\n      var forall = function (f) {\n        return f(o);\n      };\n      var toOption = function () {\n        return Option.some(o);\n      };\n      return {\n        is: is,\n        isValue: always,\n        isError: never,\n        getOr: constant(o),\n        getOrThunk: constant(o),\n        getOrDie: constant(o),\n        or: or,\n        orThunk: orThunk,\n        fold: fold,\n        map: map,\n        mapError: mapError,\n        each: each,\n        bind: bind,\n        exists: exists,\n        forall: forall,\n        toOption: toOption\n      };\n    };\n    var error = function (message) {\n      var getOrThunk = function (f) {\n        return f();\n      };\n      var getOrDie = function () {\n        return die(String(message))();\n      };\n      var or = function (opt) {\n        return opt;\n      };\n      var orThunk = function (f) {\n        return f();\n      };\n      var map = function (f) {\n        return error(message);\n      };\n      var mapError = function (f) {\n        return error(f(message));\n      };\n      var bind = function (f) {\n        return error(message);\n      };\n      var fold = function (onError, _) {\n        return onError(message);\n      };\n      return {\n        is: never,\n        isValue: never,\n        isError: always,\n        getOr: identity,\n        getOrThunk: getOrThunk,\n        getOrDie: getOrDie,\n        or: or,\n        orThunk: orThunk,\n        fold: fold,\n        map: map,\n        mapError: mapError,\n        each: noop,\n        bind: bind,\n        exists: never,\n        forall: always,\n        toOption: Option.none\n      };\n    };\n    var fromOption = function (opt, err) {\n      return opt.fold(function () {\n        return error(err);\n      }, value);\n    };\n    var Result = {\n      value: value,\n      error: error,\n      fromOption: fromOption\n    };\n\n    var generate = function (cases) {\n      if (!isArray(cases)) {\n        throw new Error('cases must be an array');\n      }\n      if (cases.length === 0) {\n        throw new Error('there must be at least one case');\n      }\n      var constructors = [];\n      var adt = {};\n      each$1(cases, function (acase, count) {\n        var keys$1 = keys(acase);\n        if (keys$1.length !== 1) {\n          throw new Error('one and only one name per case');\n        }\n        var key = keys$1[0];\n        var value = acase[key];\n        if (adt[key] !== undefined) {\n          throw new Error('duplicate key detected:' + key);\n        } else if (key === 'cata') {\n          throw new Error('cannot have a case named cata (sorry)');\n        } else if (!isArray(value)) {\n          throw new Error('case arguments must be an array');\n        }\n        constructors.push(key);\n        adt[key] = function () {\n          var argLength = arguments.length;\n          if (argLength !== value.length) {\n            throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);\n          }\n          var args = new Array(argLength);\n          for (var i = 0; i < args.length; i++) {\n            args[i] = arguments[i];\n          }\n          var match = function (branches) {\n            var branchKeys = keys(branches);\n            if (constructors.length !== branchKeys.length) {\n              throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\\nActual: ' + branchKeys.join(','));\n            }\n            var allReqd = forall(constructors, function (reqKey) {\n              return contains(branchKeys, reqKey);\n            });\n            if (!allReqd) {\n              throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\\nRequired: ' + constructors.join(', '));\n            }\n            return branches[key].apply(null, args);\n          };\n          return {\n            fold: function () {\n              if (arguments.length !== cases.length) {\n                throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length);\n              }\n              var target = arguments[count];\n              return target.apply(null, args);\n            },\n            match: match,\n            log: function (label) {\n              domGlobals.console.log(label, {\n                constructors: constructors,\n                constructor: key,\n                params: args\n              });\n            }\n          };\n        };\n      });\n      return adt;\n    };\n    var Adt = { generate: generate };\n\n    var hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n    var shallow = function (old, nu) {\n      return nu;\n    };\n    var deep = function (old, nu) {\n      var bothObjects = isObject(old) && isObject(nu);\n      return bothObjects ? deepMerge(old, nu) : nu;\n    };\n    var baseMerge = function (merger) {\n      return function () {\n        var objects = new Array(arguments.length);\n        for (var i = 0; i < objects.length; i++) {\n          objects[i] = arguments[i];\n        }\n        if (objects.length === 0) {\n          throw new Error('Can\\'t merge zero objects');\n        }\n        var ret = {};\n        for (var j = 0; j < objects.length; j++) {\n          var curObject = objects[j];\n          for (var key in curObject) {\n            if (hasOwnProperty$1.call(curObject, key)) {\n              ret[key] = merger(ret[key], curObject[key]);\n            }\n          }\n        }\n        return ret;\n      };\n    };\n    var deepMerge = baseMerge(deep);\n    var merge = baseMerge(shallow);\n\n    var adt = Adt.generate([\n      { strict: [] },\n      { defaultedThunk: ['fallbackThunk'] },\n      { asOption: [] },\n      { asDefaultedOptionThunk: ['fallbackThunk'] },\n      { mergeWithThunk: ['baseThunk'] }\n    ]);\n    var defaulted = function (fallback) {\n      return adt.defaultedThunk(constant(fallback));\n    };\n    var mergeWith = function (base) {\n      return adt.mergeWithThunk(constant(base));\n    };\n    var strict = adt.strict;\n    var asOption = adt.asOption;\n    var defaultedThunk = adt.defaultedThunk;\n    var mergeWithThunk = adt.mergeWithThunk;\n\n    var exclude = function (obj, fields) {\n      var r = {};\n      each(obj, function (v, k) {\n        if (!contains(fields, k)) {\n          r[k] = v;\n        }\n      });\n      return r;\n    };\n\n    var readOpt = function (key) {\n      return function (obj) {\n        return has(obj, key) ? Option.from(obj[key]) : Option.none();\n      };\n    };\n    var readOr = function (key, fallback) {\n      return function (obj) {\n        return has(obj, key) ? obj[key] : fallback;\n      };\n    };\n    var readOptFrom = function (obj, key) {\n      return readOpt(key)(obj);\n    };\n    var hasKey = function (obj, key) {\n      return has(obj, key) && obj[key] !== undefined && obj[key] !== null;\n    };\n\n    var wrap = function (key, value) {\n      var r = {};\n      r[key] = value;\n      return r;\n    };\n    var wrapAll = function (keyvalues) {\n      var r = {};\n      each$1(keyvalues, function (kv) {\n        r[kv.key] = kv.value;\n      });\n      return r;\n    };\n\n    var comparison = Adt.generate([\n      {\n        bothErrors: [\n          'error1',\n          'error2'\n        ]\n      },\n      {\n        firstError: [\n          'error1',\n          'value2'\n        ]\n      },\n      {\n        secondError: [\n          'value1',\n          'error2'\n        ]\n      },\n      {\n        bothValues: [\n          'value1',\n          'value2'\n        ]\n      }\n    ]);\n    var partition = function (results) {\n      var errors = [];\n      var values = [];\n      each$1(results, function (result) {\n        result.fold(function (err) {\n          errors.push(err);\n        }, function (value) {\n          values.push(value);\n        });\n      });\n      return {\n        errors: errors,\n        values: values\n      };\n    };\n\n    var exclude$1 = function (obj, fields) {\n      return exclude(obj, fields);\n    };\n    var readOpt$1 = function (key) {\n      return readOpt(key);\n    };\n    var readOr$1 = function (key, fallback) {\n      return readOr(key, fallback);\n    };\n    var readOptFrom$1 = function (obj, key) {\n      return readOptFrom(obj, key);\n    };\n    var wrap$1 = function (key, value) {\n      return wrap(key, value);\n    };\n    var wrapAll$1 = function (keyvalues) {\n      return wrapAll(keyvalues);\n    };\n    var mergeValues = function (values, base) {\n      return values.length === 0 ? Result.value(base) : Result.value(deepMerge(base, merge.apply(undefined, values)));\n    };\n    var mergeErrors = function (errors) {\n      return Result.error(flatten(errors));\n    };\n    var consolidate = function (objs, base) {\n      var partitions = partition(objs);\n      return partitions.errors.length > 0 ? mergeErrors(partitions.errors) : mergeValues(partitions.values, base);\n    };\n    var hasKey$1 = function (obj, key) {\n      return hasKey(obj, key);\n    };\n\n    var SimpleResultType;\n    (function (SimpleResultType) {\n      SimpleResultType[SimpleResultType['Error'] = 0] = 'Error';\n      SimpleResultType[SimpleResultType['Value'] = 1] = 'Value';\n    }(SimpleResultType || (SimpleResultType = {})));\n    var fold = function (res, onError, onValue) {\n      return res.stype === SimpleResultType.Error ? onError(res.serror) : onValue(res.svalue);\n    };\n    var partition$1 = function (results) {\n      var values = [];\n      var errors = [];\n      each$1(results, function (obj) {\n        fold(obj, function (err) {\n          return errors.push(err);\n        }, function (val) {\n          return values.push(val);\n        });\n      });\n      return {\n        values: values,\n        errors: errors\n      };\n    };\n    var mapError = function (res, f) {\n      if (res.stype === SimpleResultType.Error) {\n        return {\n          stype: SimpleResultType.Error,\n          serror: f(res.serror)\n        };\n      } else {\n        return res;\n      }\n    };\n    var map$2 = function (res, f) {\n      if (res.stype === SimpleResultType.Value) {\n        return {\n          stype: SimpleResultType.Value,\n          svalue: f(res.svalue)\n        };\n      } else {\n        return res;\n      }\n    };\n    var bind$1 = function (res, f) {\n      if (res.stype === SimpleResultType.Value) {\n        return f(res.svalue);\n      } else {\n        return res;\n      }\n    };\n    var bindError = function (res, f) {\n      if (res.stype === SimpleResultType.Error) {\n        return f(res.serror);\n      } else {\n        return res;\n      }\n    };\n    var svalue = function (v) {\n      return {\n        stype: SimpleResultType.Value,\n        svalue: v\n      };\n    };\n    var serror = function (e) {\n      return {\n        stype: SimpleResultType.Error,\n        serror: e\n      };\n    };\n    var toResult = function (res) {\n      return fold(res, Result.error, Result.value);\n    };\n    var fromResult = function (res) {\n      return res.fold(serror, svalue);\n    };\n    var SimpleResult = {\n      fromResult: fromResult,\n      toResult: toResult,\n      svalue: svalue,\n      partition: partition$1,\n      serror: serror,\n      bind: bind$1,\n      bindError: bindError,\n      map: map$2,\n      mapError: mapError,\n      fold: fold\n    };\n\n    var mergeValues$1 = function (values, base) {\n      return values.length > 0 ? SimpleResult.svalue(deepMerge(base, merge.apply(undefined, values))) : SimpleResult.svalue(base);\n    };\n    var mergeErrors$1 = function (errors) {\n      return compose(SimpleResult.serror, flatten)(errors);\n    };\n    var consolidateObj = function (objects, base) {\n      var partition = SimpleResult.partition(objects);\n      return partition.errors.length > 0 ? mergeErrors$1(partition.errors) : mergeValues$1(partition.values, base);\n    };\n    var consolidateArr = function (objects) {\n      var partitions = SimpleResult.partition(objects);\n      return partitions.errors.length > 0 ? mergeErrors$1(partitions.errors) : SimpleResult.svalue(partitions.values);\n    };\n    var ResultCombine = {\n      consolidateObj: consolidateObj,\n      consolidateArr: consolidateArr\n    };\n\n    var typeAdt = Adt.generate([\n      {\n        setOf: [\n          'validator',\n          'valueType'\n        ]\n      },\n      { arrOf: ['valueType'] },\n      { objOf: ['fields'] },\n      { itemOf: ['validator'] },\n      {\n        choiceOf: [\n          'key',\n          'branches'\n        ]\n      },\n      { thunk: ['description'] },\n      {\n        func: [\n          'args',\n          'outputSchema'\n        ]\n      }\n    ]);\n    var fieldAdt = Adt.generate([\n      {\n        field: [\n          'name',\n          'presence',\n          'type'\n        ]\n      },\n      { state: ['name'] }\n    ]);\n\n    var formatObj = function (input) {\n      return isObject(input) && keys(input).length > 100 ? ' removed due to size' : JSON.stringify(input, null, 2);\n    };\n    var formatErrors = function (errors) {\n      var es = errors.length > 10 ? errors.slice(0, 10).concat([{\n          path: [],\n          getErrorInfo: function () {\n            return '... (only showing first ten failures)';\n          }\n        }]) : errors;\n      return map$1(es, function (e) {\n        return 'Failed path: (' + e.path.join(' > ') + ')\\n' + e.getErrorInfo();\n      });\n    };\n\n    var nu$3 = function (path, getErrorInfo) {\n      return SimpleResult.serror([{\n          path: path,\n          getErrorInfo: getErrorInfo\n        }]);\n    };\n    var missingStrict = function (path, key, obj) {\n      return nu$3(path, function () {\n        return 'Could not find valid *strict* value for \"' + key + '\" in ' + formatObj(obj);\n      });\n    };\n    var missingKey = function (path, key) {\n      return nu$3(path, function () {\n        return 'Choice schema did not contain choice key: \"' + key + '\"';\n      });\n    };\n    var missingBranch = function (path, branches, branch) {\n      return nu$3(path, function () {\n        return 'The chosen schema: \"' + branch + '\" did not exist in branches: ' + formatObj(branches);\n      });\n    };\n    var unsupportedFields = function (path, unsupported) {\n      return nu$3(path, function () {\n        return 'There are unsupported fields: [' + unsupported.join(', ') + '] specified';\n      });\n    };\n    var custom = function (path, err) {\n      return nu$3(path, function () {\n        return err;\n      });\n    };\n\n    var adt$1 = Adt.generate([\n      {\n        field: [\n          'key',\n          'okey',\n          'presence',\n          'prop'\n        ]\n      },\n      {\n        state: [\n          'okey',\n          'instantiator'\n        ]\n      }\n    ]);\n    var strictAccess = function (path, obj, key) {\n      return readOptFrom(obj, key).fold(function () {\n        return missingStrict(path, key, obj);\n      }, SimpleResult.svalue);\n    };\n    var fallbackAccess = function (obj, key, fallbackThunk) {\n      var v = readOptFrom(obj, key).fold(function () {\n        return fallbackThunk(obj);\n      }, identity);\n      return SimpleResult.svalue(v);\n    };\n    var optionAccess = function (obj, key) {\n      return SimpleResult.svalue(readOptFrom(obj, key));\n    };\n    var optionDefaultedAccess = function (obj, key, fallback) {\n      var opt = readOptFrom(obj, key).map(function (val) {\n        return val === true ? fallback(obj) : val;\n      });\n      return SimpleResult.svalue(opt);\n    };\n    var cExtractOne = function (path, obj, field, strength) {\n      return field.fold(function (key, okey, presence, prop) {\n        var bundle = function (av) {\n          var result = prop.extract(path.concat([key]), strength, av);\n          return SimpleResult.map(result, function (res) {\n            return wrap(okey, strength(res));\n          });\n        };\n        var bundleAsOption = function (optValue) {\n          return optValue.fold(function () {\n            var outcome = wrap(okey, strength(Option.none()));\n            return SimpleResult.svalue(outcome);\n          }, function (ov) {\n            var result = prop.extract(path.concat([key]), strength, ov);\n            return SimpleResult.map(result, function (res) {\n              return wrap(okey, strength(Option.some(res)));\n            });\n          });\n        };\n        return function () {\n          return presence.fold(function () {\n            return SimpleResult.bind(strictAccess(path, obj, key), bundle);\n          }, function (fallbackThunk) {\n            return SimpleResult.bind(fallbackAccess(obj, key, fallbackThunk), bundle);\n          }, function () {\n            return SimpleResult.bind(optionAccess(obj, key), bundleAsOption);\n          }, function (fallbackThunk) {\n            return SimpleResult.bind(optionDefaultedAccess(obj, key, fallbackThunk), bundleAsOption);\n          }, function (baseThunk) {\n            var base = baseThunk(obj);\n            var result = SimpleResult.map(fallbackAccess(obj, key, constant({})), function (v) {\n              return deepMerge(base, v);\n            });\n            return SimpleResult.bind(result, bundle);\n          });\n        }();\n      }, function (okey, instantiator) {\n        var state = instantiator(obj);\n        return SimpleResult.svalue(wrap(okey, strength(state)));\n      });\n    };\n    var cExtract = function (path, obj, fields, strength) {\n      var results = map$1(fields, function (field) {\n        return cExtractOne(path, obj, field, strength);\n      });\n      return ResultCombine.consolidateObj(results, {});\n    };\n    var value$1 = function (validator) {\n      var extract = function (path, strength, val) {\n        return SimpleResult.bindError(validator(val, strength), function (err) {\n          return custom(path, err);\n        });\n      };\n      var toString = function () {\n        return 'val';\n      };\n      var toDsl = function () {\n        return typeAdt.itemOf(validator);\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var getSetKeys = function (obj) {\n      var keys$1 = keys(obj);\n      return filter(keys$1, function (k) {\n        return hasKey$1(obj, k);\n      });\n    };\n    var objOfOnly = function (fields) {\n      var delegate = objOf(fields);\n      var fieldNames = foldr(fields, function (acc, f) {\n        return f.fold(function (key) {\n          return deepMerge(acc, wrap$1(key, true));\n        }, constant(acc));\n      }, {});\n      var extract = function (path, strength, o) {\n        var keys = isBoolean(o) ? [] : getSetKeys(o);\n        var extra = filter(keys, function (k) {\n          return !hasKey$1(fieldNames, k);\n        });\n        return extra.length === 0 ? delegate.extract(path, strength, o) : unsupportedFields(path, extra);\n      };\n      return {\n        extract: extract,\n        toString: delegate.toString,\n        toDsl: delegate.toDsl\n      };\n    };\n    var objOf = function (fields) {\n      var extract = function (path, strength, o) {\n        return cExtract(path, o, fields, strength);\n      };\n      var toString = function () {\n        var fieldStrings = map$1(fields, function (field) {\n          return field.fold(function (key, okey, presence, prop) {\n            return key + ' -> ' + prop.toString();\n          }, function (okey, instantiator) {\n            return 'state(' + okey + ')';\n          });\n        });\n        return 'obj{\\n' + fieldStrings.join('\\n') + '}';\n      };\n      var toDsl = function () {\n        return typeAdt.objOf(map$1(fields, function (f) {\n          return f.fold(function (key, okey, presence, prop) {\n            return fieldAdt.field(key, presence, prop);\n          }, function (okey, instantiator) {\n            return fieldAdt.state(okey);\n          });\n        }));\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var arrOf = function (prop) {\n      var extract = function (path, strength, array) {\n        var results = map$1(array, function (a, i) {\n          return prop.extract(path.concat(['[' + i + ']']), strength, a);\n        });\n        return ResultCombine.consolidateArr(results);\n      };\n      var toString = function () {\n        return 'array(' + prop.toString() + ')';\n      };\n      var toDsl = function () {\n        return typeAdt.arrOf(prop);\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var setOf = function (validator, prop) {\n      var validateKeys = function (path, keys) {\n        return arrOf(value$1(validator)).extract(path, identity, keys);\n      };\n      var extract = function (path, strength, o) {\n        var keys$1 = keys(o);\n        var validatedKeys = validateKeys(path, keys$1);\n        return SimpleResult.bind(validatedKeys, function (validKeys) {\n          var schema = map$1(validKeys, function (vk) {\n            return adt$1.field(vk, vk, strict(), prop);\n          });\n          return objOf(schema).extract(path, strength, o);\n        });\n      };\n      var toString = function () {\n        return 'setOf(' + prop.toString() + ')';\n      };\n      var toDsl = function () {\n        return typeAdt.setOf(validator, prop);\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var anyValue = constant(value$1(SimpleResult.svalue));\n    var state = adt$1.state;\n    var field = adt$1.field;\n\n    var chooseFrom = function (path, strength, input, branches, ch) {\n      var fields = readOptFrom$1(branches, ch);\n      return fields.fold(function () {\n        return missingBranch(path, branches, ch);\n      }, function (vp) {\n        return vp.extract(path.concat(['branch: ' + ch]), strength, input);\n      });\n    };\n    var choose = function (key, branches) {\n      var extract = function (path, strength, input) {\n        var choice = readOptFrom$1(input, key);\n        return choice.fold(function () {\n          return missingKey(path, key);\n        }, function (chosen) {\n          return chooseFrom(path, strength, input, branches, chosen);\n        });\n      };\n      var toString = function () {\n        return 'chooseOn(' + key + '). Possible values: ' + keys(branches);\n      };\n      var toDsl = function () {\n        return typeAdt.choiceOf(key, branches);\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n\n    var _anyValue = value$1(SimpleResult.svalue);\n    var valueOf = function (validator) {\n      return value$1(function (v) {\n        return validator(v).fold(SimpleResult.serror, SimpleResult.svalue);\n      });\n    };\n    var setOf$1 = function (validator, prop) {\n      return setOf(function (v) {\n        return SimpleResult.fromResult(validator(v));\n      }, prop);\n    };\n    var extract = function (label, prop, strength, obj) {\n      var res = prop.extract([label], strength, obj);\n      return SimpleResult.mapError(res, function (errs) {\n        return {\n          input: obj,\n          errors: errs\n        };\n      });\n    };\n    var asRaw = function (label, prop, obj) {\n      return SimpleResult.toResult(extract(label, prop, identity, obj));\n    };\n    var getOrDie = function (extraction) {\n      return extraction.fold(function (errInfo) {\n        throw new Error(formatError(errInfo));\n      }, identity);\n    };\n    var asRawOrDie = function (label, prop, obj) {\n      return getOrDie(asRaw(label, prop, obj));\n    };\n    var formatError = function (errInfo) {\n      return 'Errors: \\n' + formatErrors(errInfo.errors) + '\\n\\nInput object: ' + formatObj(errInfo.input);\n    };\n    var choose$1 = function (key, branches) {\n      return choose(key, map(branches, objOf));\n    };\n    var anyValue$1 = constant(_anyValue);\n    var typedValue = function (validator, expectedType) {\n      return value$1(function (a) {\n        var actualType = typeof a;\n        return validator(a) ? SimpleResult.svalue(a) : SimpleResult.serror('Expected type: ' + expectedType + ' but got: ' + actualType);\n      });\n    };\n    var functionProcessor = typedValue(isFunction, 'function');\n\n    var strict$1 = function (key) {\n      return field(key, key, strict(), anyValue());\n    };\n    var strictOf = function (key, schema) {\n      return field(key, key, strict(), schema);\n    };\n    var strictFunction = function (key) {\n      return strictOf(key, functionProcessor);\n    };\n    var forbid = function (key, message) {\n      return field(key, key, asOption(), value$1(function (v) {\n        return SimpleResult.serror('The field: ' + key + ' is forbidden. ' + message);\n      }));\n    };\n    var strictObjOf = function (key, objSchema) {\n      return field(key, key, strict(), objOf(objSchema));\n    };\n    var option = function (key) {\n      return field(key, key, asOption(), anyValue());\n    };\n    var optionOf = function (key, schema) {\n      return field(key, key, asOption(), schema);\n    };\n    var optionObjOf = function (key, objSchema) {\n      return optionOf(key, objOf(objSchema));\n    };\n    var optionObjOfOnly = function (key, objSchema) {\n      return optionOf(key, objOfOnly(objSchema));\n    };\n    var defaulted$1 = function (key, fallback) {\n      return field(key, key, defaulted(fallback), anyValue());\n    };\n    var defaultedOf = function (key, fallback, schema) {\n      return field(key, key, defaulted(fallback), schema);\n    };\n    var defaultedObjOf = function (key, fallback, objSchema) {\n      return defaultedOf(key, fallback, objOf(objSchema));\n    };\n    var state$1 = function (okey, instantiator) {\n      return state(okey, instantiator);\n    };\n\n    var isSource = function (component, simulatedEvent) {\n      return eq(component.element(), simulatedEvent.event().target());\n    };\n\n    function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {\n      return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot);\n    }\n\n    var ancestor = function (scope, predicate, isRoot) {\n      var element = scope.dom();\n      var stop = isFunction(isRoot) ? isRoot : constant(false);\n      while (element.parentNode) {\n        element = element.parentNode;\n        var el = Element.fromDom(element);\n        if (predicate(el)) {\n          return Option.some(el);\n        } else if (stop(el)) {\n          break;\n        }\n      }\n      return Option.none();\n    };\n    var closest = function (scope, predicate, isRoot) {\n      var is = function (s, test) {\n        return test(s);\n      };\n      return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);\n    };\n    var descendant = function (scope, predicate) {\n      var descend = function (node) {\n        for (var i = 0; i < node.childNodes.length; i++) {\n          var child_1 = Element.fromDom(node.childNodes[i]);\n          if (predicate(child_1)) {\n            return Option.some(child_1);\n          }\n          var res = descend(node.childNodes[i]);\n          if (res.isSome()) {\n            return res;\n          }\n        }\n        return Option.none();\n      };\n      return descend(scope.dom());\n    };\n\n    var closest$1 = function (target, transform, isRoot) {\n      var delegate = closest(target, function (elem) {\n        return transform(elem).isSome();\n      }, isRoot);\n      return delegate.bind(transform);\n    };\n\n    var nu$4 = function (parts) {\n      if (!hasKey$1(parts, 'can') && !hasKey$1(parts, 'abort') && !hasKey$1(parts, 'run')) {\n        throw new Error('EventHandler defined by: ' + JSON.stringify(parts, null, 2) + ' does not have can, abort, or run!');\n      }\n      return asRawOrDie('Extracting event.handler', objOfOnly([\n        defaulted$1('can', constant(true)),\n        defaulted$1('abort', constant(false)),\n        defaulted$1('run', noop)\n      ]), parts);\n    };\n    var all$1 = function (handlers, f) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return foldl(handlers, function (acc, handler) {\n          return acc && f(handler).apply(undefined, args);\n        }, true);\n      };\n    };\n    var any = function (handlers, f) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return foldl(handlers, function (acc, handler) {\n          return acc || f(handler).apply(undefined, args);\n        }, false);\n      };\n    };\n    var read = function (handler) {\n      return isFunction(handler) ? {\n        can: constant(true),\n        abort: constant(false),\n        run: handler\n      } : handler;\n    };\n    var fuse = function (handlers) {\n      var can = all$1(handlers, function (handler) {\n        return handler.can;\n      });\n      var abort = any(handlers, function (handler) {\n        return handler.abort;\n      });\n      var run = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        each$1(handlers, function (handler) {\n          handler.run.apply(undefined, args);\n        });\n      };\n      return nu$4({\n        can: can,\n        abort: abort,\n        run: run\n      });\n    };\n\n    var derive = function (configs) {\n      return wrapAll$1(configs);\n    };\n    var abort = function (name, predicate) {\n      return {\n        key: name,\n        value: nu$4({ abort: predicate })\n      };\n    };\n    var can = function (name, predicate) {\n      return {\n        key: name,\n        value: nu$4({ can: predicate })\n      };\n    };\n    var run = function (name, handler) {\n      return {\n        key: name,\n        value: nu$4({ run: handler })\n      };\n    };\n    var runActionExtra = function (name, action, extra) {\n      return {\n        key: name,\n        value: nu$4({\n          run: function (component, simulatedEvent) {\n            action.apply(undefined, [\n              component,\n              simulatedEvent\n            ].concat(extra));\n          }\n        })\n      };\n    };\n    var runOnName = function (name) {\n      return function (handler) {\n        return run(name, handler);\n      };\n    };\n    var runOnSourceName = function (name) {\n      return function (handler) {\n        return {\n          key: name,\n          value: nu$4({\n            run: function (component, simulatedEvent) {\n              if (isSource(component, simulatedEvent)) {\n                handler(component, simulatedEvent);\n              }\n            }\n          })\n        };\n      };\n    };\n    var redirectToUid = function (name, uid) {\n      return run(name, function (component, simulatedEvent) {\n        component.getSystem().getByUid(uid).each(function (redirectee) {\n          dispatchEvent(redirectee, redirectee.element(), name, simulatedEvent);\n        });\n      });\n    };\n    var redirectToPart = function (name, detail, partName) {\n      var uid = detail.partUids[partName];\n      return redirectToUid(name, uid);\n    };\n    var cutter = function (name) {\n      return run(name, function (component, simulatedEvent) {\n        simulatedEvent.cut();\n      });\n    };\n    var stopper = function (name) {\n      return run(name, function (component, simulatedEvent) {\n        simulatedEvent.stop();\n      });\n    };\n    var runOnSource = function (name, f) {\n      return runOnSourceName(name)(f);\n    };\n    var runOnAttached = runOnSourceName(attachedToDom());\n    var runOnDetached = runOnSourceName(detachedFromDom());\n    var runOnInit = runOnSourceName(systemInit());\n    var runOnExecute = runOnName(execute());\n\n    var markAsBehaviourApi = function (f, apiName, apiFunction) {\n      var delegate = apiFunction.toString();\n      var endIndex = delegate.indexOf(')') + 1;\n      var openBracketIndex = delegate.indexOf('(');\n      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\\s*/);\n      f.toFunctionAnnotation = function () {\n        return {\n          name: apiName,\n          parameters: cleanParameters(parameters.slice(0, 1).concat(parameters.slice(3)))\n        };\n      };\n      return f;\n    };\n    var cleanParameters = function (parameters) {\n      return map$1(parameters, function (p) {\n        return endsWith(p, '/*') ? p.substring(0, p.length - '/*'.length) : p;\n      });\n    };\n    var markAsExtraApi = function (f, extraName) {\n      var delegate = f.toString();\n      var endIndex = delegate.indexOf(')') + 1;\n      var openBracketIndex = delegate.indexOf('(');\n      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\\s*/);\n      f.toFunctionAnnotation = function () {\n        return {\n          name: extraName,\n          parameters: cleanParameters(parameters)\n        };\n      };\n      return f;\n    };\n    var markAsSketchApi = function (f, apiFunction) {\n      var delegate = apiFunction.toString();\n      var endIndex = delegate.indexOf(')') + 1;\n      var openBracketIndex = delegate.indexOf('(');\n      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\\s*/);\n      f.toFunctionAnnotation = function () {\n        return {\n          name: 'OVERRIDE',\n          parameters: cleanParameters(parameters.slice(1))\n        };\n      };\n      return f;\n    };\n\n    var nu$5 = function (s) {\n      return {\n        classes: s.classes !== undefined ? s.classes : [],\n        attributes: s.attributes !== undefined ? s.attributes : {},\n        styles: s.styles !== undefined ? s.styles : {}\n      };\n    };\n    var merge$1 = function (defnA, mod) {\n      return __assign(__assign({}, defnA), {\n        attributes: __assign(__assign({}, defnA.attributes), mod.attributes),\n        styles: __assign(__assign({}, defnA.styles), mod.styles),\n        classes: defnA.classes.concat(mod.classes)\n      });\n    };\n\n    var executeEvent = function (bConfig, bState, executor) {\n      return runOnExecute(function (component) {\n        executor(component, bConfig, bState);\n      });\n    };\n    var loadEvent = function (bConfig, bState, f) {\n      return runOnInit(function (component, simulatedEvent) {\n        f(component, bConfig, bState);\n      });\n    };\n    var create = function (schema, name, active, apis, extra, state) {\n      var configSchema = objOfOnly(schema);\n      var schemaSchema = optionObjOf(name, [optionObjOfOnly('config', schema)]);\n      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);\n    };\n    var createModes = function (modes, name, active, apis, extra, state) {\n      var configSchema = modes;\n      var schemaSchema = optionObjOf(name, [optionOf('config', modes)]);\n      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);\n    };\n    var wrapApi = function (bName, apiFunction, apiName) {\n      var f = function (component) {\n        var rest = [];\n        for (var _i = 1; _i < arguments.length; _i++) {\n          rest[_i - 1] = arguments[_i];\n        }\n        var args = [component].concat(rest);\n        return component.config({ name: constant(bName) }).fold(function () {\n          throw new Error('We could not find any behaviour configuration for: ' + bName + '. Using API: ' + apiName);\n        }, function (info) {\n          var rest = Array.prototype.slice.call(args, 1);\n          return apiFunction.apply(undefined, [\n            component,\n            info.config,\n            info.state\n          ].concat(rest));\n        });\n      };\n      return markAsBehaviourApi(f, apiName, apiFunction);\n    };\n    var revokeBehaviour = function (name) {\n      return {\n        key: name,\n        value: undefined\n      };\n    };\n    var doCreate = function (configSchema, schemaSchema, name, active, apis, extra, state) {\n      var getConfig = function (info) {\n        return hasKey$1(info, name) ? info[name]() : Option.none();\n      };\n      var wrappedApis = map(apis, function (apiF, apiName) {\n        return wrapApi(name, apiF, apiName);\n      });\n      var wrappedExtra = map(extra, function (extraF, extraName) {\n        return markAsExtraApi(extraF, extraName);\n      });\n      var me = __assign(__assign(__assign({}, wrappedExtra), wrappedApis), {\n        revoke: curry(revokeBehaviour, name),\n        config: function (spec) {\n          var prepared = asRawOrDie(name + '-config', configSchema, spec);\n          return {\n            key: name,\n            value: {\n              config: prepared,\n              me: me,\n              configAsRaw: cached(function () {\n                return asRawOrDie(name + '-config', configSchema, spec);\n              }),\n              initialConfig: spec,\n              state: state\n            }\n          };\n        },\n        schema: function () {\n          return schemaSchema;\n        },\n        exhibit: function (info, base) {\n          return getConfig(info).bind(function (behaviourInfo) {\n            return readOptFrom$1(active, 'exhibit').map(function (exhibitor) {\n              return exhibitor(base, behaviourInfo.config, behaviourInfo.state);\n            });\n          }).getOr(nu$5({}));\n        },\n        name: function () {\n          return name;\n        },\n        handlers: function (info) {\n          return getConfig(info).map(function (behaviourInfo) {\n            var getEvents = readOr$1('events', function (a, b) {\n              return {};\n            })(active);\n            return getEvents(behaviourInfo.config, behaviourInfo.state);\n          }).getOr({});\n        }\n      });\n      return me;\n    };\n\n    var NoState = {\n      init: function () {\n        return nu$6({\n          readState: function () {\n            return 'No State required';\n          }\n        });\n      }\n    };\n    var nu$6 = function (spec) {\n      return spec;\n    };\n\n    var derive$1 = function (capabilities) {\n      return wrapAll$1(capabilities);\n    };\n    var simpleSchema = objOfOnly([\n      strict$1('fields'),\n      strict$1('name'),\n      defaulted$1('active', {}),\n      defaulted$1('apis', {}),\n      defaulted$1('state', NoState),\n      defaulted$1('extra', {})\n    ]);\n    var create$1 = function (data) {\n      var value = asRawOrDie('Creating behaviour: ' + data.name, simpleSchema, data);\n      return create(value.fields, value.name, value.active, value.apis, value.extra, value.state);\n    };\n    var modeSchema = objOfOnly([\n      strict$1('branchKey'),\n      strict$1('branches'),\n      strict$1('name'),\n      defaulted$1('active', {}),\n      defaulted$1('apis', {}),\n      defaulted$1('state', NoState),\n      defaulted$1('extra', {})\n    ]);\n    var createModes$1 = function (data) {\n      var value = asRawOrDie('Creating behaviour: ' + data.name, modeSchema, data);\n      return createModes(choose$1(value.branchKey, value.branches), value.name, value.active, value.apis, value.extra, value.state);\n    };\n    var revoke = constant(undefined);\n\n    var rawSet = function (dom, key, value) {\n      if (isString(value) || isBoolean(value) || isNumber(value)) {\n        dom.setAttribute(key, value + '');\n      } else {\n        domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom);\n        throw new Error('Attribute value was not simple');\n      }\n    };\n    var set = function (element, key, value) {\n      rawSet(element.dom(), key, value);\n    };\n    var setAll = function (element, attrs) {\n      var dom = element.dom();\n      each(attrs, function (v, k) {\n        rawSet(dom, k, v);\n      });\n    };\n    var get = function (element, key) {\n      var v = element.dom().getAttribute(key);\n      return v === null ? undefined : v;\n    };\n    var has$1 = function (element, key) {\n      var dom = element.dom();\n      return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;\n    };\n    var remove$1 = function (element, key) {\n      element.dom().removeAttribute(key);\n    };\n\n    var read$1 = function (element, attr) {\n      var value = get(element, attr);\n      return value === undefined || value === '' ? [] : value.split(' ');\n    };\n    var add = function (element, attr, id) {\n      var old = read$1(element, attr);\n      var nu = old.concat([id]);\n      set(element, attr, nu.join(' '));\n      return true;\n    };\n    var remove$2 = function (element, attr, id) {\n      var nu = filter(read$1(element, attr), function (v) {\n        return v !== id;\n      });\n      if (nu.length > 0) {\n        set(element, attr, nu.join(' '));\n      } else {\n        remove$1(element, attr);\n      }\n      return false;\n    };\n\n    var supports = function (element) {\n      return element.dom().classList !== undefined;\n    };\n    var get$1 = function (element) {\n      return read$1(element, 'class');\n    };\n    var add$1 = function (element, clazz) {\n      return add(element, 'class', clazz);\n    };\n    var remove$3 = function (element, clazz) {\n      return remove$2(element, 'class', clazz);\n    };\n\n    var add$2 = function (element, clazz) {\n      if (supports(element)) {\n        element.dom().classList.add(clazz);\n      } else {\n        add$1(element, clazz);\n      }\n    };\n    var cleanClass = function (element) {\n      var classList = supports(element) ? element.dom().classList : get$1(element);\n      if (classList.length === 0) {\n        remove$1(element, 'class');\n      }\n    };\n    var remove$4 = function (element, clazz) {\n      if (supports(element)) {\n        var classList = element.dom().classList;\n        classList.remove(clazz);\n      } else {\n        remove$3(element, clazz);\n      }\n      cleanClass(element);\n    };\n    var has$2 = function (element, clazz) {\n      return supports(element) && element.dom().classList.contains(clazz);\n    };\n\n    var swap = function (element, addCls, removeCls) {\n      remove$4(element, removeCls);\n      add$2(element, addCls);\n    };\n    var toAlpha = function (component, swapConfig, swapState) {\n      swap(component.element(), swapConfig.alpha, swapConfig.omega);\n    };\n    var toOmega = function (component, swapConfig, swapState) {\n      swap(component.element(), swapConfig.omega, swapConfig.alpha);\n    };\n    var clear = function (component, swapConfig, swapState) {\n      remove$4(component.element(), swapConfig.alpha);\n      remove$4(component.element(), swapConfig.omega);\n    };\n    var isAlpha = function (component, swapConfig, swapState) {\n      return has$2(component.element(), swapConfig.alpha);\n    };\n    var isOmega = function (component, swapConfig, swapState) {\n      return has$2(component.element(), swapConfig.omega);\n    };\n\n    var SwapApis = /*#__PURE__*/Object.freeze({\n        toAlpha: toAlpha,\n        toOmega: toOmega,\n        isAlpha: isAlpha,\n        isOmega: isOmega,\n        clear: clear\n    });\n\n    var SwapSchema = [\n      strict$1('alpha'),\n      strict$1('omega')\n    ];\n\n    var Swapping = create$1({\n      fields: SwapSchema,\n      name: 'swapping',\n      apis: SwapApis\n    });\n\n    var focus$1 = function (element) {\n      element.dom().focus();\n    };\n    var blur = function (element) {\n      element.dom().blur();\n    };\n    var hasFocus = function (element) {\n      var doc = owner(element).dom();\n      return element.dom() === doc.activeElement;\n    };\n    var active = function (_doc) {\n      var doc = _doc !== undefined ? _doc.dom() : domGlobals.document;\n      return Option.from(doc.activeElement).map(Element.fromDom);\n    };\n    var search = function (element) {\n      return active(owner(element)).filter(function (e) {\n        return element.dom().contains(e.dom());\n      });\n    };\n\n    var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');\n\n    var global$2 = tinymce.util.Tools.resolve('tinymce.ThemeManager');\n\n    var openLink = function (target) {\n      var link = domGlobals.document.createElement('a');\n      link.target = '_blank';\n      link.href = target.href;\n      link.rel = 'noreferrer noopener';\n      var nuEvt = domGlobals.document.createEvent('MouseEvents');\n      nuEvt.initMouseEvent('click', true, true, domGlobals.window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n      domGlobals.document.body.appendChild(link);\n      link.dispatchEvent(nuEvt);\n      domGlobals.document.body.removeChild(link);\n    };\n    var TinyCodeDupe = { openLink: openLink };\n\n    var isSkinDisabled = function (editor) {\n      return editor.settings.skin === false;\n    };\n    var readOnlyOnInit = function (editor) {\n      return false;\n    };\n\n    var formatChanged = 'formatChanged';\n    var orientationChanged = 'orientationChanged';\n    var dropupDismissed = 'dropupDismissed';\n    var TinyChannels = {\n      formatChanged: constant(formatChanged),\n      orientationChanged: constant(orientationChanged),\n      dropupDismissed: constant(dropupDismissed)\n    };\n\n    var fromHtml$1 = function (html, scope) {\n      var doc = scope || domGlobals.document;\n      var div = doc.createElement('div');\n      div.innerHTML = html;\n      return children(Element.fromDom(div));\n    };\n\n    var get$2 = function (element) {\n      return element.dom().innerHTML;\n    };\n    var set$1 = function (element, content) {\n      var owner$1 = owner(element);\n      var docDom = owner$1.dom();\n      var fragment = Element.fromDom(docDom.createDocumentFragment());\n      var contentElements = fromHtml$1(content, docDom);\n      append$1(fragment, contentElements);\n      empty(element);\n      append(element, fragment);\n    };\n    var getOuter = function (element) {\n      var container = Element.fromTag('div');\n      var clone = Element.fromDom(element.dom().cloneNode(true));\n      append(container, clone);\n      return get$2(container);\n    };\n\n    var clone = function (original, isDeep) {\n      return Element.fromDom(original.dom().cloneNode(isDeep));\n    };\n    var shallow$1 = function (original) {\n      return clone(original, false);\n    };\n\n    var getHtml = function (element) {\n      var clone = shallow$1(element);\n      return getOuter(clone);\n    };\n\n    var element = function (elem) {\n      return getHtml(elem);\n    };\n\n    var chooseChannels = function (channels, message) {\n      return message.universal() ? channels : filter(channels, function (ch) {\n        return contains(message.channels(), ch);\n      });\n    };\n    var events = function (receiveConfig) {\n      return derive([run(receive(), function (component, message) {\n          var channelMap = receiveConfig.channels;\n          var channels = keys(channelMap);\n          var targetChannels = chooseChannels(channels, message);\n          each$1(targetChannels, function (ch) {\n            var channelInfo = channelMap[ch];\n            var channelSchema = channelInfo.schema;\n            var data = asRawOrDie('channel[' + ch + '] data\\nReceiver: ' + element(component.element()), channelSchema, message.data());\n            channelInfo.onReceive(component, data);\n          });\n        })]);\n    };\n\n    var ActiveReceiving = /*#__PURE__*/Object.freeze({\n        events: events\n    });\n\n    var cat = function (arr) {\n      var r = [];\n      var push = function (x) {\n        r.push(x);\n      };\n      for (var i = 0; i < arr.length; i++) {\n        arr[i].each(push);\n      }\n      return r;\n    };\n    var sequence = function (arr) {\n      var r = [];\n      for (var i = 0; i < arr.length; i++) {\n        var x = arr[i];\n        if (x.isSome()) {\n          r.push(x.getOrDie());\n        } else {\n          return Option.none();\n        }\n      }\n      return Option.some(r);\n    };\n    var findMap = function (arr, f) {\n      for (var i = 0; i < arr.length; i++) {\n        var r = f(arr[i], i);\n        if (r.isSome()) {\n          return r;\n        }\n      }\n      return Option.none();\n    };\n    var someIf = function (b, a) {\n      return b ? Option.some(a) : Option.none();\n    };\n\n    var unknown$3 = 'unknown';\n    var EventConfiguration;\n    (function (EventConfiguration) {\n      EventConfiguration[EventConfiguration['STOP'] = 0] = 'STOP';\n      EventConfiguration[EventConfiguration['NORMAL'] = 1] = 'NORMAL';\n      EventConfiguration[EventConfiguration['LOGGING'] = 2] = 'LOGGING';\n    }(EventConfiguration || (EventConfiguration = {})));\n    var eventConfig = Cell({});\n    var makeEventLogger = function (eventName, initialTarget) {\n      var sequence = [];\n      var startTime = new Date().getTime();\n      return {\n        logEventCut: function (name, target, purpose) {\n          sequence.push({\n            outcome: 'cut',\n            target: target,\n            purpose: purpose\n          });\n        },\n        logEventStopped: function (name, target, purpose) {\n          sequence.push({\n            outcome: 'stopped',\n            target: target,\n            purpose: purpose\n          });\n        },\n        logNoParent: function (name, target, purpose) {\n          sequence.push({\n            outcome: 'no-parent',\n            target: target,\n            purpose: purpose\n          });\n        },\n        logEventNoHandlers: function (name, target) {\n          sequence.push({\n            outcome: 'no-handlers-left',\n            target: target\n          });\n        },\n        logEventResponse: function (name, target, purpose) {\n          sequence.push({\n            outcome: 'response',\n            purpose: purpose,\n            target: target\n          });\n        },\n        write: function () {\n          var finishTime = new Date().getTime();\n          if (contains([\n              'mousemove',\n              'mouseover',\n              'mouseout',\n              systemInit()\n            ], eventName)) {\n            return;\n          }\n          domGlobals.console.log(eventName, {\n            event: eventName,\n            time: finishTime - startTime,\n            target: initialTarget.dom(),\n            sequence: map$1(sequence, function (s) {\n              if (!contains([\n                  'cut',\n                  'stopped',\n                  'response'\n                ], s.outcome)) {\n                return s.outcome;\n              } else {\n                return '{' + s.purpose + '} ' + s.outcome + ' at (' + element(s.target) + ')';\n              }\n            })\n          });\n        }\n      };\n    };\n    var processEvent = function (eventName, initialTarget, f) {\n      var status = readOptFrom$1(eventConfig.get(), eventName).orThunk(function () {\n        var patterns = keys(eventConfig.get());\n        return findMap(patterns, function (p) {\n          return eventName.indexOf(p) > -1 ? Option.some(eventConfig.get()[p]) : Option.none();\n        });\n      }).getOr(EventConfiguration.NORMAL);\n      switch (status) {\n      case EventConfiguration.NORMAL:\n        return f(noLogger());\n      case EventConfiguration.LOGGING: {\n          var logger = makeEventLogger(eventName, initialTarget);\n          var output = f(logger);\n          logger.write();\n          return output;\n        }\n      case EventConfiguration.STOP:\n        return true;\n      }\n    };\n    var path = [\n      'alloy/data/Fields',\n      'alloy/debugging/Debugging'\n    ];\n    var getTrace = function () {\n      var err = new Error();\n      if (err.stack !== undefined) {\n        var lines = err.stack.split('\\n');\n        return find$2(lines, function (line) {\n          return line.indexOf('alloy') > 0 && !exists(path, function (p) {\n            return line.indexOf(p) > -1;\n          });\n        }).getOr(unknown$3);\n      } else {\n        return unknown$3;\n      }\n    };\n    var ignoreEvent = {\n      logEventCut: noop,\n      logEventStopped: noop,\n      logNoParent: noop,\n      logEventNoHandlers: noop,\n      logEventResponse: noop,\n      write: noop\n    };\n    var monitorEvent = function (eventName, initialTarget, f) {\n      return processEvent(eventName, initialTarget, f);\n    };\n    var noLogger = constant(ignoreEvent);\n\n    var menuFields = constant([\n      strict$1('menu'),\n      strict$1('selectedMenu')\n    ]);\n    var itemFields = constant([\n      strict$1('item'),\n      strict$1('selectedItem')\n    ]);\n    var schema = constant(objOf(itemFields().concat(menuFields())));\n    var itemSchema = constant(objOf(itemFields()));\n\n    var _initSize = strictObjOf('initSize', [\n      strict$1('numColumns'),\n      strict$1('numRows')\n    ]);\n    var itemMarkers = function () {\n      return strictOf('markers', itemSchema());\n    };\n    var tieredMenuMarkers = function () {\n      return strictObjOf('markers', [strict$1('backgroundMenu')].concat(menuFields()).concat(itemFields()));\n    };\n    var markers = function (required) {\n      return strictObjOf('markers', map$1(required, strict$1));\n    };\n    var onPresenceHandler = function (label, fieldName, presence) {\n      var trace = getTrace();\n      return field(fieldName, fieldName, presence, valueOf(function (f) {\n        return Result.value(function () {\n          var args = [];\n          for (var _i = 0; _i < arguments.length; _i++) {\n            args[_i] = arguments[_i];\n          }\n          return f.apply(undefined, args);\n        });\n      }));\n    };\n    var onHandler = function (fieldName) {\n      return onPresenceHandler('onHandler', fieldName, defaulted(noop));\n    };\n    var onKeyboardHandler = function (fieldName) {\n      return onPresenceHandler('onKeyboardHandler', fieldName, defaulted(Option.none));\n    };\n    var onStrictHandler = function (fieldName) {\n      return onPresenceHandler('onHandler', fieldName, strict());\n    };\n    var onStrictKeyboardHandler = function (fieldName) {\n      return onPresenceHandler('onKeyboardHandler', fieldName, strict());\n    };\n    var output = function (name, value) {\n      return state$1(name, constant(value));\n    };\n    var snapshot = function (name) {\n      return state$1(name, identity);\n    };\n    var initSize = constant(_initSize);\n\n    var ReceivingSchema = [strictOf('channels', setOf$1(Result.value, objOfOnly([\n        onStrictHandler('onReceive'),\n        defaulted$1('schema', anyValue$1())\n      ])))];\n\n    var Receiving = create$1({\n      fields: ReceivingSchema,\n      name: 'receiving',\n      active: ActiveReceiving\n    });\n\n    var updateAriaState = function (component, toggleConfig, toggleState) {\n      var ariaInfo = toggleConfig.aria;\n      ariaInfo.update(component, ariaInfo, toggleState.get());\n    };\n    var updateClass = function (component, toggleConfig, toggleState) {\n      toggleConfig.toggleClass.each(function (toggleClass) {\n        if (toggleState.get()) {\n          add$2(component.element(), toggleClass);\n        } else {\n          remove$4(component.element(), toggleClass);\n        }\n      });\n    };\n    var toggle = function (component, toggleConfig, toggleState) {\n      set$2(component, toggleConfig, toggleState, !toggleState.get());\n    };\n    var on = function (component, toggleConfig, toggleState) {\n      toggleState.set(true);\n      updateClass(component, toggleConfig, toggleState);\n      updateAriaState(component, toggleConfig, toggleState);\n    };\n    var off = function (component, toggleConfig, toggleState) {\n      toggleState.set(false);\n      updateClass(component, toggleConfig, toggleState);\n      updateAriaState(component, toggleConfig, toggleState);\n    };\n    var set$2 = function (component, toggleConfig, toggleState, state) {\n      var action = state ? on : off;\n      action(component, toggleConfig, toggleState);\n    };\n    var isOn = function (component, toggleConfig, toggleState) {\n      return toggleState.get();\n    };\n    var onLoad = function (component, toggleConfig, toggleState) {\n      set$2(component, toggleConfig, toggleState, toggleConfig.selected);\n    };\n\n    var ToggleApis = /*#__PURE__*/Object.freeze({\n        onLoad: onLoad,\n        toggle: toggle,\n        isOn: isOn,\n        on: on,\n        off: off,\n        set: set$2\n    });\n\n    var exhibit = function (base, toggleConfig, toggleState) {\n      return nu$5({});\n    };\n    var events$1 = function (toggleConfig, toggleState) {\n      var execute = executeEvent(toggleConfig, toggleState, toggle);\n      var load = loadEvent(toggleConfig, toggleState, onLoad);\n      return derive(flatten([\n        toggleConfig.toggleOnExecute ? [execute] : [],\n        [load]\n      ]));\n    };\n\n    var ActiveToggle = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit,\n        events: events$1\n    });\n\n    var SetupBehaviourCellState = function (initialState) {\n      var init = function () {\n        var cell = Cell(initialState);\n        var get = function () {\n          return cell.get();\n        };\n        var set = function (newState) {\n          return cell.set(newState);\n        };\n        var clear = function () {\n          return cell.set(initialState);\n        };\n        var readState = function () {\n          return cell.get();\n        };\n        return {\n          get: get,\n          set: set,\n          clear: clear,\n          readState: readState\n        };\n      };\n      return { init: init };\n    };\n\n    var updatePressed = function (component, ariaInfo, status) {\n      set(component.element(), 'aria-pressed', status);\n      if (ariaInfo.syncWithExpanded) {\n        updateExpanded(component, ariaInfo, status);\n      }\n    };\n    var updateSelected = function (component, ariaInfo, status) {\n      set(component.element(), 'aria-selected', status);\n    };\n    var updateChecked = function (component, ariaInfo, status) {\n      set(component.element(), 'aria-checked', status);\n    };\n    var updateExpanded = function (component, ariaInfo, status) {\n      set(component.element(), 'aria-expanded', status);\n    };\n\n    var ToggleSchema = [\n      defaulted$1('selected', false),\n      option('toggleClass'),\n      defaulted$1('toggleOnExecute', true),\n      defaultedOf('aria', { mode: 'none' }, choose$1('mode', {\n        pressed: [\n          defaulted$1('syncWithExpanded', false),\n          output('update', updatePressed)\n        ],\n        checked: [output('update', updateChecked)],\n        expanded: [output('update', updateExpanded)],\n        selected: [output('update', updateSelected)],\n        none: [output('update', noop)]\n      }))\n    ];\n\n    var Toggling = create$1({\n      fields: ToggleSchema,\n      name: 'toggling',\n      active: ActiveToggle,\n      apis: ToggleApis,\n      state: SetupBehaviourCellState(false)\n    });\n\n    var format = function (command, update) {\n      return Receiving.config({\n        channels: wrap$1(TinyChannels.formatChanged(), {\n          onReceive: function (button, data) {\n            if (data.command === command) {\n              update(button, data.state);\n            }\n          }\n        })\n      });\n    };\n    var orientation = function (onReceive) {\n      return Receiving.config({ channels: wrap$1(TinyChannels.orientationChanged(), { onReceive: onReceive }) });\n    };\n    var receive$1 = function (channel, onReceive) {\n      return {\n        key: channel,\n        value: { onReceive: onReceive }\n      };\n    };\n    var Receivers = {\n      format: format,\n      orientation: orientation,\n      receive: receive$1\n    };\n\n    var prefix = 'tinymce-mobile';\n    var resolve = function (p) {\n      return prefix + '-' + p;\n    };\n    var Styles = {\n      resolve: resolve,\n      prefix: constant(prefix)\n    };\n\n    var pointerEvents = function () {\n      var onClick = function (component, simulatedEvent) {\n        simulatedEvent.stop();\n        emitExecute(component);\n      };\n      return [\n        run(click(), onClick),\n        run(tap(), onClick),\n        cutter(touchstart()),\n        cutter(mousedown())\n      ];\n    };\n    var events$2 = function (optAction) {\n      var executeHandler = function (action) {\n        return runOnExecute(function (component, simulatedEvent) {\n          action(component);\n          simulatedEvent.stop();\n        });\n      };\n      return derive(flatten([\n        optAction.map(executeHandler).toArray(),\n        pointerEvents()\n      ]));\n    };\n\n    var focus$2 = function (component, focusConfig) {\n      if (!focusConfig.ignore) {\n        focus$1(component.element());\n        focusConfig.onFocus(component);\n      }\n    };\n    var blur$1 = function (component, focusConfig) {\n      if (!focusConfig.ignore) {\n        blur(component.element());\n      }\n    };\n    var isFocused = function (component) {\n      return hasFocus(component.element());\n    };\n\n    var FocusApis = /*#__PURE__*/Object.freeze({\n        focus: focus$2,\n        blur: blur$1,\n        isFocused: isFocused\n    });\n\n    var exhibit$1 = function (base, focusConfig) {\n      var mod = focusConfig.ignore ? {} : { attributes: { tabindex: '-1' } };\n      return nu$5(mod);\n    };\n    var events$3 = function (focusConfig) {\n      return derive([run(focus(), function (component, simulatedEvent) {\n          focus$2(component, focusConfig);\n          simulatedEvent.stop();\n        })].concat(focusConfig.stopMousedown ? [run(mousedown(), function (_, simulatedEvent) {\n          simulatedEvent.event().prevent();\n        })] : []));\n    };\n\n    var ActiveFocus = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$1,\n        events: events$3\n    });\n\n    var FocusSchema = [\n      onHandler('onFocus'),\n      defaulted$1('stopMousedown', false),\n      defaulted$1('ignore', false)\n    ];\n\n    var Focusing = create$1({\n      fields: FocusSchema,\n      name: 'focusing',\n      active: ActiveFocus,\n      apis: FocusApis\n    });\n\n    var isSupported = function (dom) {\n      return dom.style !== undefined && isFunction(dom.style.getPropertyValue);\n    };\n\n    var internalSet = function (dom, property, value) {\n      if (!isString(value)) {\n        domGlobals.console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);\n        throw new Error('CSS value must be a string: ' + value);\n      }\n      if (isSupported(dom)) {\n        dom.style.setProperty(property, value);\n      }\n    };\n    var internalRemove = function (dom, property) {\n      if (isSupported(dom)) {\n        dom.style.removeProperty(property);\n      }\n    };\n    var set$3 = function (element, property, value) {\n      var dom = element.dom();\n      internalSet(dom, property, value);\n    };\n    var setAll$1 = function (element, css) {\n      var dom = element.dom();\n      each(css, function (v, k) {\n        internalSet(dom, k, v);\n      });\n    };\n    var get$3 = function (element, property) {\n      var dom = element.dom();\n      var styles = domGlobals.window.getComputedStyle(dom);\n      var r = styles.getPropertyValue(property);\n      var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;\n      return v === null ? undefined : v;\n    };\n    var getUnsafeProperty = function (dom, property) {\n      return isSupported(dom) ? dom.style.getPropertyValue(property) : '';\n    };\n    var getRaw = function (element, property) {\n      var dom = element.dom();\n      var raw = getUnsafeProperty(dom, property);\n      return Option.from(raw).filter(function (r) {\n        return r.length > 0;\n      });\n    };\n    var remove$5 = function (element, property) {\n      var dom = element.dom();\n      internalRemove(dom, property);\n      if (has$1(element, 'style') && trim(get(element, 'style')) === '') {\n        remove$1(element, 'style');\n      }\n    };\n    var reflow = function (e) {\n      return e.dom().offsetWidth;\n    };\n\n    function Dimension (name, getOffset) {\n      var set = function (element, h) {\n        if (!isNumber(h) && !h.match(/^[0-9]+$/)) {\n          throw new Error(name + '.set accepts only positive integer values. Value was ' + h);\n        }\n        var dom = element.dom();\n        if (isSupported(dom)) {\n          dom.style[name] = h + 'px';\n        }\n      };\n      var get = function (element) {\n        var r = getOffset(element);\n        if (r <= 0 || r === null) {\n          var css = get$3(element, name);\n          return parseFloat(css) || 0;\n        }\n        return r;\n      };\n      var getOuter = get;\n      var aggregate = function (element, properties) {\n        return foldl(properties, function (acc, property) {\n          var val = get$3(element, property);\n          var value = val === undefined ? 0 : parseInt(val, 10);\n          return isNaN(value) ? acc : acc + value;\n        }, 0);\n      };\n      var max = function (element, value, properties) {\n        var cumulativeInclusions = aggregate(element, properties);\n        var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;\n        return absoluteMax;\n      };\n      return {\n        set: set,\n        get: get,\n        getOuter: getOuter,\n        aggregate: aggregate,\n        max: max\n      };\n    }\n\n    var api = Dimension('height', function (element) {\n      var dom = element.dom();\n      return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;\n    });\n    var get$4 = function (element) {\n      return api.get(element);\n    };\n\n    var ancestors = function (scope, predicate, isRoot) {\n      return filter(parents(scope, isRoot), predicate);\n    };\n    var siblings$1 = function (scope, predicate) {\n      return filter(siblings(scope), predicate);\n    };\n\n    var all$2 = function (selector) {\n      return all(selector);\n    };\n    var ancestors$1 = function (scope, selector, isRoot) {\n      return ancestors(scope, function (e) {\n        return is(e, selector);\n      }, isRoot);\n    };\n    var siblings$2 = function (scope, selector) {\n      return siblings$1(scope, function (e) {\n        return is(e, selector);\n      });\n    };\n    var descendants = function (scope, selector) {\n      return all(selector, scope);\n    };\n\n    var first = function (selector) {\n      return one(selector);\n    };\n    var ancestor$1 = function (scope, selector, isRoot) {\n      return ancestor(scope, function (e) {\n        return is(e, selector);\n      }, isRoot);\n    };\n    var descendant$1 = function (scope, selector) {\n      return one(selector, scope);\n    };\n    var closest$2 = function (scope, selector, isRoot) {\n      return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot);\n    };\n\n    var BACKSPACE = function () {\n      return [8];\n    };\n    var TAB = function () {\n      return [9];\n    };\n    var ENTER = function () {\n      return [13];\n    };\n    var ESCAPE = function () {\n      return [27];\n    };\n    var SPACE = function () {\n      return [32];\n    };\n    var LEFT = function () {\n      return [37];\n    };\n    var UP = function () {\n      return [38];\n    };\n    var RIGHT = function () {\n      return [39];\n    };\n    var DOWN = function () {\n      return [40];\n    };\n\n    var cyclePrev = function (values, index, predicate) {\n      var before = reverse(values.slice(0, index));\n      var after = reverse(values.slice(index + 1));\n      return find$2(before.concat(after), predicate);\n    };\n    var tryPrev = function (values, index, predicate) {\n      var before = reverse(values.slice(0, index));\n      return find$2(before, predicate);\n    };\n    var cycleNext = function (values, index, predicate) {\n      var before = values.slice(0, index);\n      var after = values.slice(index + 1);\n      return find$2(after.concat(before), predicate);\n    };\n    var tryNext = function (values, index, predicate) {\n      var after = values.slice(index + 1);\n      return find$2(after, predicate);\n    };\n\n    var inSet = function (keys) {\n      return function (event) {\n        var raw = event.raw();\n        return contains(keys, raw.which);\n      };\n    };\n    var and = function (preds) {\n      return function (event) {\n        return forall(preds, function (pred) {\n          return pred(event);\n        });\n      };\n    };\n    var isShift = function (event) {\n      var raw = event.raw();\n      return raw.shiftKey === true;\n    };\n    var isControl = function (event) {\n      var raw = event.raw();\n      return raw.ctrlKey === true;\n    };\n    var isNotShift = not(isShift);\n\n    var rule = function (matches, action) {\n      return {\n        matches: matches,\n        classification: action\n      };\n    };\n    var choose$2 = function (transitions, event) {\n      var transition = find$2(transitions, function (t) {\n        return t.matches(event);\n      });\n      return transition.map(function (t) {\n        return t.classification;\n      });\n    };\n\n    var cycleBy = function (value, delta, min, max) {\n      var r = value + delta;\n      if (r > max) {\n        return min;\n      } else {\n        return r < min ? max : r;\n      }\n    };\n    var cap = function (value, min, max) {\n      if (value <= min) {\n        return min;\n      } else {\n        return value >= max ? max : value;\n      }\n    };\n\n    var dehighlightAllExcept = function (component, hConfig, hState, skip) {\n      var highlighted = descendants(component.element(), '.' + hConfig.highlightClass);\n      each$1(highlighted, function (h) {\n        if (!exists(skip, function (skipComp) {\n            return skipComp.element() === h;\n          })) {\n          remove$4(h, hConfig.highlightClass);\n          component.getSystem().getByDom(h).each(function (target) {\n            hConfig.onDehighlight(component, target);\n            emit(target, dehighlight());\n          });\n        }\n      });\n    };\n    var dehighlightAll = function (component, hConfig, hState) {\n      return dehighlightAllExcept(component, hConfig, hState, []);\n    };\n    var dehighlight$1 = function (component, hConfig, hState, target) {\n      if (isHighlighted(component, hConfig, hState, target)) {\n        remove$4(target.element(), hConfig.highlightClass);\n        hConfig.onDehighlight(component, target);\n        emit(target, dehighlight());\n      }\n    };\n    var highlight$1 = function (component, hConfig, hState, target) {\n      dehighlightAllExcept(component, hConfig, hState, [target]);\n      if (!isHighlighted(component, hConfig, hState, target)) {\n        add$2(target.element(), hConfig.highlightClass);\n        hConfig.onHighlight(component, target);\n        emit(target, highlight());\n      }\n    };\n    var highlightFirst = function (component, hConfig, hState) {\n      getFirst(component, hConfig).each(function (firstComp) {\n        highlight$1(component, hConfig, hState, firstComp);\n      });\n    };\n    var highlightLast = function (component, hConfig, hState) {\n      getLast(component, hConfig).each(function (lastComp) {\n        highlight$1(component, hConfig, hState, lastComp);\n      });\n    };\n    var highlightAt = function (component, hConfig, hState, index) {\n      getByIndex(component, hConfig, hState, index).fold(function (err) {\n        throw new Error(err);\n      }, function (firstComp) {\n        highlight$1(component, hConfig, hState, firstComp);\n      });\n    };\n    var highlightBy = function (component, hConfig, hState, predicate) {\n      var candidates = getCandidates(component, hConfig);\n      var targetComp = find$2(candidates, predicate);\n      targetComp.each(function (c) {\n        highlight$1(component, hConfig, hState, c);\n      });\n    };\n    var isHighlighted = function (component, hConfig, hState, queryTarget) {\n      return has$2(queryTarget.element(), hConfig.highlightClass);\n    };\n    var getHighlighted = function (component, hConfig, hState) {\n      return descendant$1(component.element(), '.' + hConfig.highlightClass).bind(function (e) {\n        return component.getSystem().getByDom(e).toOption();\n      });\n    };\n    var getByIndex = function (component, hConfig, hState, index) {\n      var items = descendants(component.element(), '.' + hConfig.itemClass);\n      return Option.from(items[index]).fold(function () {\n        return Result.error('No element found with index ' + index);\n      }, component.getSystem().getByDom);\n    };\n    var getFirst = function (component, hConfig, hState) {\n      return descendant$1(component.element(), '.' + hConfig.itemClass).bind(function (e) {\n        return component.getSystem().getByDom(e).toOption();\n      });\n    };\n    var getLast = function (component, hConfig, hState) {\n      var items = descendants(component.element(), '.' + hConfig.itemClass);\n      var last = items.length > 0 ? Option.some(items[items.length - 1]) : Option.none();\n      return last.bind(function (c) {\n        return component.getSystem().getByDom(c).toOption();\n      });\n    };\n    var getDelta = function (component, hConfig, hState, delta) {\n      var items = descendants(component.element(), '.' + hConfig.itemClass);\n      var current = findIndex(items, function (item) {\n        return has$2(item, hConfig.highlightClass);\n      });\n      return current.bind(function (selected) {\n        var dest = cycleBy(selected, delta, 0, items.length - 1);\n        return component.getSystem().getByDom(items[dest]).toOption();\n      });\n    };\n    var getPrevious = function (component, hConfig, hState) {\n      return getDelta(component, hConfig, hState, -1);\n    };\n    var getNext = function (component, hConfig, hState) {\n      return getDelta(component, hConfig, hState, +1);\n    };\n    var getCandidates = function (component, hConfig, hState) {\n      var items = descendants(component.element(), '.' + hConfig.itemClass);\n      return cat(map$1(items, function (i) {\n        return component.getSystem().getByDom(i).toOption();\n      }));\n    };\n\n    var HighlightApis = /*#__PURE__*/Object.freeze({\n        dehighlightAll: dehighlightAll,\n        dehighlight: dehighlight$1,\n        highlight: highlight$1,\n        highlightFirst: highlightFirst,\n        highlightLast: highlightLast,\n        highlightAt: highlightAt,\n        highlightBy: highlightBy,\n        isHighlighted: isHighlighted,\n        getHighlighted: getHighlighted,\n        getFirst: getFirst,\n        getLast: getLast,\n        getPrevious: getPrevious,\n        getNext: getNext,\n        getCandidates: getCandidates\n    });\n\n    var HighlightSchema = [\n      strict$1('highlightClass'),\n      strict$1('itemClass'),\n      onHandler('onHighlight'),\n      onHandler('onDehighlight')\n    ];\n\n    var Highlighting = create$1({\n      fields: HighlightSchema,\n      name: 'highlighting',\n      apis: HighlightApis\n    });\n\n    var reportFocusShifting = function (component, prevFocus, newFocus) {\n      var noChange = prevFocus.exists(function (p) {\n        return newFocus.exists(function (n) {\n          return eq(n, p);\n        });\n      });\n      if (!noChange) {\n        emitWith(component, focusShifted(), {\n          prevFocus: prevFocus,\n          newFocus: newFocus\n        });\n      }\n    };\n    var dom = function () {\n      var get = function (component) {\n        return search(component.element());\n      };\n      var set = function (component, focusee) {\n        var prevFocus = get(component);\n        component.getSystem().triggerFocus(focusee, component.element());\n        var newFocus = get(component);\n        reportFocusShifting(component, prevFocus, newFocus);\n      };\n      return {\n        get: get,\n        set: set\n      };\n    };\n    var highlights = function () {\n      var get = function (component) {\n        return Highlighting.getHighlighted(component).map(function (item) {\n          return item.element();\n        });\n      };\n      var set = function (component, element) {\n        var prevFocus = get(component);\n        component.getSystem().getByDom(element).fold(noop, function (item) {\n          Highlighting.highlight(component, item);\n        });\n        var newFocus = get(component);\n        reportFocusShifting(component, prevFocus, newFocus);\n      };\n      return {\n        get: get,\n        set: set\n      };\n    };\n\n    var FocusInsideModes;\n    (function (FocusInsideModes) {\n      FocusInsideModes['OnFocusMode'] = 'onFocus';\n      FocusInsideModes['OnEnterOrSpaceMode'] = 'onEnterOrSpace';\n      FocusInsideModes['OnApiMode'] = 'onApi';\n    }(FocusInsideModes || (FocusInsideModes = {})));\n\n    var typical = function (infoSchema, stateInit, getKeydownRules, getKeyupRules, optFocusIn) {\n      var schema = function () {\n        return infoSchema.concat([\n          defaulted$1('focusManager', dom()),\n          defaultedOf('focusInside', 'onFocus', valueOf(function (val) {\n            return contains([\n              'onFocus',\n              'onEnterOrSpace',\n              'onApi'\n            ], val) ? Result.value(val) : Result.error('Invalid value for focusInside');\n          })),\n          output('handler', me),\n          output('state', stateInit),\n          output('sendFocusIn', optFocusIn)\n        ]);\n      };\n      var processKey = function (component, simulatedEvent, getRules, keyingConfig, keyingState) {\n        var rules = getRules(component, simulatedEvent, keyingConfig, keyingState);\n        return choose$2(rules, simulatedEvent.event()).bind(function (rule) {\n          return rule(component, simulatedEvent, keyingConfig, keyingState);\n        });\n      };\n      var toEvents = function (keyingConfig, keyingState) {\n        var onFocusHandler = keyingConfig.focusInside !== FocusInsideModes.OnFocusMode ? Option.none() : optFocusIn(keyingConfig).map(function (focusIn) {\n          return run(focus(), function (component, simulatedEvent) {\n            focusIn(component, keyingConfig, keyingState);\n            simulatedEvent.stop();\n          });\n        });\n        var tryGoInsideComponent = function (component, simulatedEvent) {\n          var isEnterOrSpace = inSet(SPACE().concat(ENTER()))(simulatedEvent.event());\n          if (keyingConfig.focusInside === FocusInsideModes.OnEnterOrSpaceMode && isEnterOrSpace && isSource(component, simulatedEvent)) {\n            optFocusIn(keyingConfig).each(function (focusIn) {\n              focusIn(component, keyingConfig, keyingState);\n              simulatedEvent.stop();\n            });\n          }\n        };\n        return derive(onFocusHandler.toArray().concat([\n          run(keydown(), function (component, simulatedEvent) {\n            processKey(component, simulatedEvent, getKeydownRules, keyingConfig, keyingState).fold(function () {\n              tryGoInsideComponent(component, simulatedEvent);\n            }, function (_) {\n              simulatedEvent.stop();\n            });\n          }),\n          run(keyup(), function (component, simulatedEvent) {\n            processKey(component, simulatedEvent, getKeyupRules, keyingConfig, keyingState).each(function (_) {\n              simulatedEvent.stop();\n            });\n          })\n        ]));\n      };\n      var me = {\n        schema: schema,\n        processKey: processKey,\n        toEvents: toEvents\n      };\n      return me;\n    };\n\n    var create$2 = function (cyclicField) {\n      var schema = [\n        option('onEscape'),\n        option('onEnter'),\n        defaulted$1('selector', '[data-alloy-tabstop=\"true\"]:not(:disabled)'),\n        defaulted$1('firstTabstop', 0),\n        defaulted$1('useTabstopAt', constant(true)),\n        option('visibilitySelector')\n      ].concat([cyclicField]);\n      var isVisible = function (tabbingConfig, element) {\n        var target = tabbingConfig.visibilitySelector.bind(function (sel) {\n          return closest$2(element, sel);\n        }).getOr(element);\n        return get$4(target) > 0;\n      };\n      var findInitial = function (component, tabbingConfig) {\n        var tabstops = descendants(component.element(), tabbingConfig.selector);\n        var visibles = filter(tabstops, function (elem) {\n          return isVisible(tabbingConfig, elem);\n        });\n        return Option.from(visibles[tabbingConfig.firstTabstop]);\n      };\n      var findCurrent = function (component, tabbingConfig) {\n        return tabbingConfig.focusManager.get(component).bind(function (elem) {\n          return closest$2(elem, tabbingConfig.selector);\n        });\n      };\n      var isTabstop = function (tabbingConfig, element) {\n        return isVisible(tabbingConfig, element) && tabbingConfig.useTabstopAt(element);\n      };\n      var focusIn = function (component, tabbingConfig) {\n        findInitial(component, tabbingConfig).each(function (target) {\n          tabbingConfig.focusManager.set(component, target);\n        });\n      };\n      var goFromTabstop = function (component, tabstops, stopIndex, tabbingConfig, cycle) {\n        return cycle(tabstops, stopIndex, function (elem) {\n          return isTabstop(tabbingConfig, elem);\n        }).fold(function () {\n          return tabbingConfig.cyclic ? Option.some(true) : Option.none();\n        }, function (target) {\n          tabbingConfig.focusManager.set(component, target);\n          return Option.some(true);\n        });\n      };\n      var go = function (component, simulatedEvent, tabbingConfig, cycle) {\n        var tabstops = descendants(component.element(), tabbingConfig.selector);\n        return findCurrent(component, tabbingConfig).bind(function (tabstop) {\n          var optStopIndex = findIndex(tabstops, curry(eq, tabstop));\n          return optStopIndex.bind(function (stopIndex) {\n            return goFromTabstop(component, tabstops, stopIndex, tabbingConfig, cycle);\n          });\n        });\n      };\n      var goBackwards = function (component, simulatedEvent, tabbingConfig, tabbingState) {\n        var navigate = tabbingConfig.cyclic ? cyclePrev : tryPrev;\n        return go(component, simulatedEvent, tabbingConfig, navigate);\n      };\n      var goForwards = function (component, simulatedEvent, tabbingConfig, tabbingState) {\n        var navigate = tabbingConfig.cyclic ? cycleNext : tryNext;\n        return go(component, simulatedEvent, tabbingConfig, navigate);\n      };\n      var execute = function (component, simulatedEvent, tabbingConfig, tabbingState) {\n        return tabbingConfig.onEnter.bind(function (f) {\n          return f(component, simulatedEvent);\n        });\n      };\n      var exit = function (component, simulatedEvent, tabbingConfig, tabbingState) {\n        return tabbingConfig.onEscape.bind(function (f) {\n          return f(component, simulatedEvent);\n        });\n      };\n      var getKeydownRules = constant([\n        rule(and([\n          isShift,\n          inSet(TAB())\n        ]), goBackwards),\n        rule(inSet(TAB()), goForwards),\n        rule(inSet(ESCAPE()), exit),\n        rule(and([\n          isNotShift,\n          inSet(ENTER())\n        ]), execute)\n      ]);\n      var getKeyupRules = constant([]);\n      return typical(schema, NoState.init, getKeydownRules, getKeyupRules, function () {\n        return Option.some(focusIn);\n      });\n    };\n\n    var AcyclicType = create$2(state$1('cyclic', constant(false)));\n\n    var CyclicType = create$2(state$1('cyclic', constant(true)));\n\n    var inside = function (target) {\n      return name(target) === 'input' && get(target, 'type') !== 'radio' || name(target) === 'textarea';\n    };\n\n    var doDefaultExecute = function (component, simulatedEvent, focused) {\n      dispatch(component, focused, execute());\n      return Option.some(true);\n    };\n    var defaultExecute = function (component, simulatedEvent, focused) {\n      return inside(focused) && inSet(SPACE())(simulatedEvent.event()) ? Option.none() : doDefaultExecute(component, simulatedEvent, focused);\n    };\n    var stopEventForFirefox = function (component, simulatedEvent) {\n      return Option.some(true);\n    };\n\n    var schema$1 = [\n      defaulted$1('execute', defaultExecute),\n      defaulted$1('useSpace', false),\n      defaulted$1('useEnter', true),\n      defaulted$1('useControlEnter', false),\n      defaulted$1('useDown', false)\n    ];\n    var execute$1 = function (component, simulatedEvent, executeConfig) {\n      return executeConfig.execute(component, simulatedEvent, component.element());\n    };\n    var getKeydownRules = function (component, simulatedEvent, executeConfig, executeState) {\n      var spaceExec = executeConfig.useSpace && !inside(component.element()) ? SPACE() : [];\n      var enterExec = executeConfig.useEnter ? ENTER() : [];\n      var downExec = executeConfig.useDown ? DOWN() : [];\n      var execKeys = spaceExec.concat(enterExec).concat(downExec);\n      return [rule(inSet(execKeys), execute$1)].concat(executeConfig.useControlEnter ? [rule(and([\n          isControl,\n          inSet(ENTER())\n        ]), execute$1)] : []);\n    };\n    var getKeyupRules = function (component, simulatedEvent, executeConfig, executeState) {\n      return executeConfig.useSpace && !inside(component.element()) ? [rule(inSet(SPACE()), stopEventForFirefox)] : [];\n    };\n    var ExecutionType = typical(schema$1, NoState.init, getKeydownRules, getKeyupRules, function () {\n      return Option.none();\n    });\n\n    var flatgrid = function (spec) {\n      var dimensions = Cell(Option.none());\n      var setGridSize = function (numRows, numColumns) {\n        dimensions.set(Option.some({\n          numRows: constant(numRows),\n          numColumns: constant(numColumns)\n        }));\n      };\n      var getNumRows = function () {\n        return dimensions.get().map(function (d) {\n          return d.numRows();\n        });\n      };\n      var getNumColumns = function () {\n        return dimensions.get().map(function (d) {\n          return d.numColumns();\n        });\n      };\n      return nu$6({\n        readState: function () {\n          return dimensions.get().map(function (d) {\n            return {\n              numRows: d.numRows(),\n              numColumns: d.numColumns()\n            };\n          }).getOr({\n            numRows: '?',\n            numColumns: '?'\n          });\n        },\n        setGridSize: setGridSize,\n        getNumRows: getNumRows,\n        getNumColumns: getNumColumns\n      });\n    };\n    var init = function (spec) {\n      return spec.state(spec);\n    };\n\n    var KeyingState = /*#__PURE__*/Object.freeze({\n        flatgrid: flatgrid,\n        init: init\n    });\n\n    var onDirection = function (isLtr, isRtl) {\n      return function (element) {\n        return getDirection(element) === 'rtl' ? isRtl : isLtr;\n      };\n    };\n    var getDirection = function (element) {\n      return get$3(element, 'direction') === 'rtl' ? 'rtl' : 'ltr';\n    };\n\n    var useH = function (movement) {\n      return function (component, simulatedEvent, config, state) {\n        var move = movement(component.element());\n        return use(move, component, simulatedEvent, config, state);\n      };\n    };\n    var west = function (moveLeft, moveRight) {\n      var movement = onDirection(moveLeft, moveRight);\n      return useH(movement);\n    };\n    var east = function (moveLeft, moveRight) {\n      var movement = onDirection(moveRight, moveLeft);\n      return useH(movement);\n    };\n    var useV = function (move) {\n      return function (component, simulatedEvent, config, state) {\n        return use(move, component, simulatedEvent, config, state);\n      };\n    };\n    var use = function (move, component, simulatedEvent, config, state) {\n      var outcome = config.focusManager.get(component).bind(function (focused) {\n        return move(component.element(), focused, config, state);\n      });\n      return outcome.map(function (newFocus) {\n        config.focusManager.set(component, newFocus);\n        return true;\n      });\n    };\n    var north = useV;\n    var south = useV;\n    var move = useV;\n\n    var isHidden = function (dom) {\n      return dom.offsetWidth <= 0 && dom.offsetHeight <= 0;\n    };\n    var isVisible = function (element) {\n      var dom = element.dom();\n      return !isHidden(dom);\n    };\n\n    var indexInfo = MixedBag([\n      'index',\n      'candidates'\n    ], []);\n    var locate = function (candidates, predicate) {\n      return findIndex(candidates, predicate).map(function (index) {\n        return indexInfo({\n          index: index,\n          candidates: candidates\n        });\n      });\n    };\n\n    var locateVisible = function (container, current, selector) {\n      var predicate = curry(eq, current);\n      var candidates = descendants(container, selector);\n      var visible = filter(candidates, isVisible);\n      return locate(visible, predicate);\n    };\n    var findIndex$1 = function (elements, target) {\n      return findIndex(elements, function (elem) {\n        return eq(target, elem);\n      });\n    };\n\n    var withGrid = function (values, index, numCols, f) {\n      var oldRow = Math.floor(index / numCols);\n      var oldColumn = index % numCols;\n      return f(oldRow, oldColumn).bind(function (address) {\n        var newIndex = address.row() * numCols + address.column();\n        return newIndex >= 0 && newIndex < values.length ? Option.some(values[newIndex]) : Option.none();\n      });\n    };\n    var cycleHorizontal = function (values, index, numRows, numCols, delta) {\n      return withGrid(values, index, numCols, function (oldRow, oldColumn) {\n        var onLastRow = oldRow === numRows - 1;\n        var colsInRow = onLastRow ? values.length - oldRow * numCols : numCols;\n        var newColumn = cycleBy(oldColumn, delta, 0, colsInRow - 1);\n        return Option.some({\n          row: constant(oldRow),\n          column: constant(newColumn)\n        });\n      });\n    };\n    var cycleVertical = function (values, index, numRows, numCols, delta) {\n      return withGrid(values, index, numCols, function (oldRow, oldColumn) {\n        var newRow = cycleBy(oldRow, delta, 0, numRows - 1);\n        var onLastRow = newRow === numRows - 1;\n        var colsInRow = onLastRow ? values.length - newRow * numCols : numCols;\n        var newCol = cap(oldColumn, 0, colsInRow - 1);\n        return Option.some({\n          row: constant(newRow),\n          column: constant(newCol)\n        });\n      });\n    };\n    var cycleRight = function (values, index, numRows, numCols) {\n      return cycleHorizontal(values, index, numRows, numCols, +1);\n    };\n    var cycleLeft = function (values, index, numRows, numCols) {\n      return cycleHorizontal(values, index, numRows, numCols, -1);\n    };\n    var cycleUp = function (values, index, numRows, numCols) {\n      return cycleVertical(values, index, numRows, numCols, -1);\n    };\n    var cycleDown = function (values, index, numRows, numCols) {\n      return cycleVertical(values, index, numRows, numCols, +1);\n    };\n\n    var schema$2 = [\n      strict$1('selector'),\n      defaulted$1('execute', defaultExecute),\n      onKeyboardHandler('onEscape'),\n      defaulted$1('captureTab', false),\n      initSize()\n    ];\n    var focusIn = function (component, gridConfig, gridState) {\n      descendant$1(component.element(), gridConfig.selector).each(function (first) {\n        gridConfig.focusManager.set(component, first);\n      });\n    };\n    var findCurrent = function (component, gridConfig) {\n      return gridConfig.focusManager.get(component).bind(function (elem) {\n        return closest$2(elem, gridConfig.selector);\n      });\n    };\n    var execute$2 = function (component, simulatedEvent, gridConfig, gridState) {\n      return findCurrent(component, gridConfig).bind(function (focused) {\n        return gridConfig.execute(component, simulatedEvent, focused);\n      });\n    };\n    var doMove = function (cycle) {\n      return function (element, focused, gridConfig, gridState) {\n        return locateVisible(element, focused, gridConfig.selector).bind(function (identified) {\n          return cycle(identified.candidates(), identified.index(), gridState.getNumRows().getOr(gridConfig.initSize.numRows), gridState.getNumColumns().getOr(gridConfig.initSize.numColumns));\n        });\n      };\n    };\n    var handleTab = function (component, simulatedEvent, gridConfig, gridState) {\n      return gridConfig.captureTab ? Option.some(true) : Option.none();\n    };\n    var doEscape = function (component, simulatedEvent, gridConfig, gridState) {\n      return gridConfig.onEscape(component, simulatedEvent);\n    };\n    var moveLeft = doMove(cycleLeft);\n    var moveRight = doMove(cycleRight);\n    var moveNorth = doMove(cycleUp);\n    var moveSouth = doMove(cycleDown);\n    var getKeydownRules$1 = constant([\n      rule(inSet(LEFT()), west(moveLeft, moveRight)),\n      rule(inSet(RIGHT()), east(moveLeft, moveRight)),\n      rule(inSet(UP()), north(moveNorth)),\n      rule(inSet(DOWN()), south(moveSouth)),\n      rule(and([\n        isShift,\n        inSet(TAB())\n      ]), handleTab),\n      rule(and([\n        isNotShift,\n        inSet(TAB())\n      ]), handleTab),\n      rule(inSet(ESCAPE()), doEscape),\n      rule(inSet(SPACE().concat(ENTER())), execute$2)\n    ]);\n    var getKeyupRules$1 = constant([rule(inSet(SPACE()), stopEventForFirefox)]);\n    var FlatgridType = typical(schema$2, flatgrid, getKeydownRules$1, getKeyupRules$1, function () {\n      return Option.some(focusIn);\n    });\n\n    var horizontal = function (container, selector, current, delta) {\n      var isDisabledButton = function (candidate) {\n        return name(candidate) === 'button' && get(candidate, 'disabled') === 'disabled';\n      };\n      var tryCycle = function (initial, index, candidates) {\n        var newIndex = cycleBy(index, delta, 0, candidates.length - 1);\n        if (newIndex === initial) {\n          return Option.none();\n        } else {\n          return isDisabledButton(candidates[newIndex]) ? tryCycle(initial, newIndex, candidates) : Option.from(candidates[newIndex]);\n        }\n      };\n      return locateVisible(container, current, selector).bind(function (identified) {\n        var index = identified.index();\n        var candidates = identified.candidates();\n        return tryCycle(index, index, candidates);\n      });\n    };\n\n    var schema$3 = [\n      strict$1('selector'),\n      defaulted$1('getInitial', Option.none),\n      defaulted$1('execute', defaultExecute),\n      onKeyboardHandler('onEscape'),\n      defaulted$1('executeOnMove', false),\n      defaulted$1('allowVertical', true)\n    ];\n    var findCurrent$1 = function (component, flowConfig) {\n      return flowConfig.focusManager.get(component).bind(function (elem) {\n        return closest$2(elem, flowConfig.selector);\n      });\n    };\n    var execute$3 = function (component, simulatedEvent, flowConfig) {\n      return findCurrent$1(component, flowConfig).bind(function (focused) {\n        return flowConfig.execute(component, simulatedEvent, focused);\n      });\n    };\n    var focusIn$1 = function (component, flowConfig) {\n      flowConfig.getInitial(component).orThunk(function () {\n        return descendant$1(component.element(), flowConfig.selector);\n      }).each(function (first) {\n        flowConfig.focusManager.set(component, first);\n      });\n    };\n    var moveLeft$1 = function (element, focused, info) {\n      return horizontal(element, info.selector, focused, -1);\n    };\n    var moveRight$1 = function (element, focused, info) {\n      return horizontal(element, info.selector, focused, +1);\n    };\n    var doMove$1 = function (movement) {\n      return function (component, simulatedEvent, flowConfig) {\n        return movement(component, simulatedEvent, flowConfig).bind(function () {\n          return flowConfig.executeOnMove ? execute$3(component, simulatedEvent, flowConfig) : Option.some(true);\n        });\n      };\n    };\n    var doEscape$1 = function (component, simulatedEvent, flowConfig, _flowState) {\n      return flowConfig.onEscape(component, simulatedEvent);\n    };\n    var getKeydownRules$2 = function (_component, _se, flowConfig, _flowState) {\n      var westMovers = LEFT().concat(flowConfig.allowVertical ? UP() : []);\n      var eastMovers = RIGHT().concat(flowConfig.allowVertical ? DOWN() : []);\n      return [\n        rule(inSet(westMovers), doMove$1(west(moveLeft$1, moveRight$1))),\n        rule(inSet(eastMovers), doMove$1(east(moveLeft$1, moveRight$1))),\n        rule(inSet(ENTER()), execute$3),\n        rule(inSet(SPACE()), execute$3),\n        rule(inSet(ESCAPE()), doEscape$1)\n      ];\n    };\n    var getKeyupRules$2 = constant([rule(inSet(SPACE()), stopEventForFirefox)]);\n    var FlowType = typical(schema$3, NoState.init, getKeydownRules$2, getKeyupRules$2, function () {\n      return Option.some(focusIn$1);\n    });\n\n    var outcome = MixedBag([\n      'rowIndex',\n      'columnIndex',\n      'cell'\n    ], []);\n    var toCell = function (matrix, rowIndex, columnIndex) {\n      return Option.from(matrix[rowIndex]).bind(function (row) {\n        return Option.from(row[columnIndex]).map(function (cell) {\n          return outcome({\n            rowIndex: rowIndex,\n            columnIndex: columnIndex,\n            cell: cell\n          });\n        });\n      });\n    };\n    var cycleHorizontal$1 = function (matrix, rowIndex, startCol, deltaCol) {\n      var row = matrix[rowIndex];\n      var colsInRow = row.length;\n      var newColIndex = cycleBy(startCol, deltaCol, 0, colsInRow - 1);\n      return toCell(matrix, rowIndex, newColIndex);\n    };\n    var cycleVertical$1 = function (matrix, colIndex, startRow, deltaRow) {\n      var nextRowIndex = cycleBy(startRow, deltaRow, 0, matrix.length - 1);\n      var colsInNextRow = matrix[nextRowIndex].length;\n      var nextColIndex = cap(colIndex, 0, colsInNextRow - 1);\n      return toCell(matrix, nextRowIndex, nextColIndex);\n    };\n    var moveHorizontal = function (matrix, rowIndex, startCol, deltaCol) {\n      var row = matrix[rowIndex];\n      var colsInRow = row.length;\n      var newColIndex = cap(startCol + deltaCol, 0, colsInRow - 1);\n      return toCell(matrix, rowIndex, newColIndex);\n    };\n    var moveVertical = function (matrix, colIndex, startRow, deltaRow) {\n      var nextRowIndex = cap(startRow + deltaRow, 0, matrix.length - 1);\n      var colsInNextRow = matrix[nextRowIndex].length;\n      var nextColIndex = cap(colIndex, 0, colsInNextRow - 1);\n      return toCell(matrix, nextRowIndex, nextColIndex);\n    };\n    var cycleRight$1 = function (matrix, startRow, startCol) {\n      return cycleHorizontal$1(matrix, startRow, startCol, +1);\n    };\n    var cycleLeft$1 = function (matrix, startRow, startCol) {\n      return cycleHorizontal$1(matrix, startRow, startCol, -1);\n    };\n    var cycleUp$1 = function (matrix, startRow, startCol) {\n      return cycleVertical$1(matrix, startCol, startRow, -1);\n    };\n    var cycleDown$1 = function (matrix, startRow, startCol) {\n      return cycleVertical$1(matrix, startCol, startRow, +1);\n    };\n    var moveLeft$2 = function (matrix, startRow, startCol) {\n      return moveHorizontal(matrix, startRow, startCol, -1);\n    };\n    var moveRight$2 = function (matrix, startRow, startCol) {\n      return moveHorizontal(matrix, startRow, startCol, +1);\n    };\n    var moveUp = function (matrix, startRow, startCol) {\n      return moveVertical(matrix, startCol, startRow, -1);\n    };\n    var moveDown = function (matrix, startRow, startCol) {\n      return moveVertical(matrix, startCol, startRow, +1);\n    };\n\n    var schema$4 = [\n      strictObjOf('selectors', [\n        strict$1('row'),\n        strict$1('cell')\n      ]),\n      defaulted$1('cycles', true),\n      defaulted$1('previousSelector', Option.none),\n      defaulted$1('execute', defaultExecute)\n    ];\n    var focusIn$2 = function (component, matrixConfig) {\n      var focused = matrixConfig.previousSelector(component).orThunk(function () {\n        var selectors = matrixConfig.selectors;\n        return descendant$1(component.element(), selectors.cell);\n      });\n      focused.each(function (cell) {\n        matrixConfig.focusManager.set(component, cell);\n      });\n    };\n    var execute$4 = function (component, simulatedEvent, matrixConfig) {\n      return search(component.element()).bind(function (focused) {\n        return matrixConfig.execute(component, simulatedEvent, focused);\n      });\n    };\n    var toMatrix = function (rows, matrixConfig) {\n      return map$1(rows, function (row) {\n        return descendants(row, matrixConfig.selectors.cell);\n      });\n    };\n    var doMove$2 = function (ifCycle, ifMove) {\n      return function (element, focused, matrixConfig) {\n        var move = matrixConfig.cycles ? ifCycle : ifMove;\n        return closest$2(focused, matrixConfig.selectors.row).bind(function (inRow) {\n          var cellsInRow = descendants(inRow, matrixConfig.selectors.cell);\n          return findIndex$1(cellsInRow, focused).bind(function (colIndex) {\n            var allRows = descendants(element, matrixConfig.selectors.row);\n            return findIndex$1(allRows, inRow).bind(function (rowIndex) {\n              var matrix = toMatrix(allRows, matrixConfig);\n              return move(matrix, rowIndex, colIndex).map(function (next) {\n                return next.cell();\n              });\n            });\n          });\n        });\n      };\n    };\n    var moveLeft$3 = doMove$2(cycleLeft$1, moveLeft$2);\n    var moveRight$3 = doMove$2(cycleRight$1, moveRight$2);\n    var moveNorth$1 = doMove$2(cycleUp$1, moveUp);\n    var moveSouth$1 = doMove$2(cycleDown$1, moveDown);\n    var getKeydownRules$3 = constant([\n      rule(inSet(LEFT()), west(moveLeft$3, moveRight$3)),\n      rule(inSet(RIGHT()), east(moveLeft$3, moveRight$3)),\n      rule(inSet(UP()), north(moveNorth$1)),\n      rule(inSet(DOWN()), south(moveSouth$1)),\n      rule(inSet(SPACE().concat(ENTER())), execute$4)\n    ]);\n    var getKeyupRules$3 = constant([rule(inSet(SPACE()), stopEventForFirefox)]);\n    var MatrixType = typical(schema$4, NoState.init, getKeydownRules$3, getKeyupRules$3, function () {\n      return Option.some(focusIn$2);\n    });\n\n    var schema$5 = [\n      strict$1('selector'),\n      defaulted$1('execute', defaultExecute),\n      defaulted$1('moveOnTab', false)\n    ];\n    var execute$5 = function (component, simulatedEvent, menuConfig) {\n      return menuConfig.focusManager.get(component).bind(function (focused) {\n        return menuConfig.execute(component, simulatedEvent, focused);\n      });\n    };\n    var focusIn$3 = function (component, menuConfig) {\n      descendant$1(component.element(), menuConfig.selector).each(function (first) {\n        menuConfig.focusManager.set(component, first);\n      });\n    };\n    var moveUp$1 = function (element, focused, info) {\n      return horizontal(element, info.selector, focused, -1);\n    };\n    var moveDown$1 = function (element, focused, info) {\n      return horizontal(element, info.selector, focused, +1);\n    };\n    var fireShiftTab = function (component, simulatedEvent, menuConfig) {\n      return menuConfig.moveOnTab ? move(moveUp$1)(component, simulatedEvent, menuConfig) : Option.none();\n    };\n    var fireTab = function (component, simulatedEvent, menuConfig) {\n      return menuConfig.moveOnTab ? move(moveDown$1)(component, simulatedEvent, menuConfig) : Option.none();\n    };\n    var getKeydownRules$4 = constant([\n      rule(inSet(UP()), move(moveUp$1)),\n      rule(inSet(DOWN()), move(moveDown$1)),\n      rule(and([\n        isShift,\n        inSet(TAB())\n      ]), fireShiftTab),\n      rule(and([\n        isNotShift,\n        inSet(TAB())\n      ]), fireTab),\n      rule(inSet(ENTER()), execute$5),\n      rule(inSet(SPACE()), execute$5)\n    ]);\n    var getKeyupRules$4 = constant([rule(inSet(SPACE()), stopEventForFirefox)]);\n    var MenuType = typical(schema$5, NoState.init, getKeydownRules$4, getKeyupRules$4, function () {\n      return Option.some(focusIn$3);\n    });\n\n    var schema$6 = [\n      onKeyboardHandler('onSpace'),\n      onKeyboardHandler('onEnter'),\n      onKeyboardHandler('onShiftEnter'),\n      onKeyboardHandler('onLeft'),\n      onKeyboardHandler('onRight'),\n      onKeyboardHandler('onTab'),\n      onKeyboardHandler('onShiftTab'),\n      onKeyboardHandler('onUp'),\n      onKeyboardHandler('onDown'),\n      onKeyboardHandler('onEscape'),\n      defaulted$1('stopSpaceKeyup', false),\n      option('focusIn')\n    ];\n    var getKeydownRules$5 = function (component, simulatedEvent, specialInfo) {\n      return [\n        rule(inSet(SPACE()), specialInfo.onSpace),\n        rule(and([\n          isNotShift,\n          inSet(ENTER())\n        ]), specialInfo.onEnter),\n        rule(and([\n          isShift,\n          inSet(ENTER())\n        ]), specialInfo.onShiftEnter),\n        rule(and([\n          isShift,\n          inSet(TAB())\n        ]), specialInfo.onShiftTab),\n        rule(and([\n          isNotShift,\n          inSet(TAB())\n        ]), specialInfo.onTab),\n        rule(inSet(UP()), specialInfo.onUp),\n        rule(inSet(DOWN()), specialInfo.onDown),\n        rule(inSet(LEFT()), specialInfo.onLeft),\n        rule(inSet(RIGHT()), specialInfo.onRight),\n        rule(inSet(SPACE()), specialInfo.onSpace),\n        rule(inSet(ESCAPE()), specialInfo.onEscape)\n      ];\n    };\n    var getKeyupRules$5 = function (component, simulatedEvent, specialInfo) {\n      return specialInfo.stopSpaceKeyup ? [rule(inSet(SPACE()), stopEventForFirefox)] : [];\n    };\n    var SpecialType = typical(schema$6, NoState.init, getKeydownRules$5, getKeyupRules$5, function (specialInfo) {\n      return specialInfo.focusIn;\n    });\n\n    var acyclic = AcyclicType.schema();\n    var cyclic = CyclicType.schema();\n    var flow = FlowType.schema();\n    var flatgrid$1 = FlatgridType.schema();\n    var matrix = MatrixType.schema();\n    var execution = ExecutionType.schema();\n    var menu = MenuType.schema();\n    var special = SpecialType.schema();\n\n    var KeyboardBranches = /*#__PURE__*/Object.freeze({\n        acyclic: acyclic,\n        cyclic: cyclic,\n        flow: flow,\n        flatgrid: flatgrid$1,\n        matrix: matrix,\n        execution: execution,\n        menu: menu,\n        special: special\n    });\n\n    var Keying = createModes$1({\n      branchKey: 'mode',\n      branches: KeyboardBranches,\n      name: 'keying',\n      active: {\n        events: function (keyingConfig, keyingState) {\n          var handler = keyingConfig.handler;\n          return handler.toEvents(keyingConfig, keyingState);\n        }\n      },\n      apis: {\n        focusIn: function (component, keyConfig, keyState) {\n          keyConfig.sendFocusIn(keyConfig).fold(function () {\n            component.getSystem().triggerFocus(component.element(), component.element());\n          }, function (sendFocusIn) {\n            sendFocusIn(component, keyConfig, keyState);\n          });\n        },\n        setGridSize: function (component, keyConfig, keyState, numRows, numColumns) {\n          if (!hasKey$1(keyState, 'setGridSize')) {\n            domGlobals.console.error('Layout does not support setGridSize');\n          } else {\n            keyState.setGridSize(numRows, numColumns);\n          }\n        }\n      },\n      state: KeyingState\n    });\n\n    var field$1 = function (name, forbidden) {\n      return defaultedObjOf(name, {}, map$1(forbidden, function (f) {\n        return forbid(f.name(), 'Cannot configure ' + f.name() + ' for ' + name);\n      }).concat([state$1('dump', identity)]));\n    };\n    var get$5 = function (data) {\n      return data.dump;\n    };\n    var augment = function (data, original) {\n      return __assign(__assign({}, data.dump), derive$1(original));\n    };\n    var SketchBehaviours = {\n      field: field$1,\n      augment: augment,\n      get: get$5\n    };\n\n    var _placeholder = 'placeholder';\n    var adt$2 = Adt.generate([\n      {\n        single: [\n          'required',\n          'valueThunk'\n        ]\n      },\n      {\n        multiple: [\n          'required',\n          'valueThunks'\n        ]\n      }\n    ]);\n    var subPlaceholder = function (owner, detail, compSpec, placeholders) {\n      if (owner.exists(function (o) {\n          return o !== compSpec.owner;\n        })) {\n        return adt$2.single(true, constant(compSpec));\n      }\n      return readOptFrom$1(placeholders, compSpec.name).fold(function () {\n        throw new Error('Unknown placeholder component: ' + compSpec.name + '\\nKnown: [' + keys(placeholders) + ']\\nNamespace: ' + owner.getOr('none') + '\\nSpec: ' + JSON.stringify(compSpec, null, 2));\n      }, function (newSpec) {\n        return newSpec.replace();\n      });\n    };\n    var scan = function (owner, detail, compSpec, placeholders) {\n      if (compSpec.uiType === _placeholder) {\n        return subPlaceholder(owner, detail, compSpec, placeholders);\n      } else {\n        return adt$2.single(false, constant(compSpec));\n      }\n    };\n    var substitute = function (owner, detail, compSpec, placeholders) {\n      var base = scan(owner, detail, compSpec, placeholders);\n      return base.fold(function (req, valueThunk) {\n        var value = valueThunk(detail, compSpec.config, compSpec.validated);\n        var childSpecs = readOptFrom$1(value, 'components').getOr([]);\n        var substituted = bind(childSpecs, function (c) {\n          return substitute(owner, detail, c, placeholders);\n        });\n        return [__assign(__assign({}, value), { components: substituted })];\n      }, function (req, valuesThunk) {\n        var values = valuesThunk(detail, compSpec.config, compSpec.validated);\n        var preprocessor = compSpec.validated.preprocess.getOr(identity);\n        return preprocessor(values);\n      });\n    };\n    var substituteAll = function (owner, detail, components, placeholders) {\n      return bind(components, function (c) {\n        return substitute(owner, detail, c, placeholders);\n      });\n    };\n    var oneReplace = function (label, replacements) {\n      var called = false;\n      var used = function () {\n        return called;\n      };\n      var replace = function () {\n        if (called === true) {\n          throw new Error('Trying to use the same placeholder more than once: ' + label);\n        }\n        called = true;\n        return replacements;\n      };\n      var required = function () {\n        return replacements.fold(function (req, _) {\n          return req;\n        }, function (req, _) {\n          return req;\n        });\n      };\n      return {\n        name: constant(label),\n        required: required,\n        used: used,\n        replace: replace\n      };\n    };\n    var substitutePlaces = function (owner, detail, components, placeholders) {\n      var ps = map(placeholders, function (ph, name) {\n        return oneReplace(name, ph);\n      });\n      var outcome = substituteAll(owner, detail, components, ps);\n      each(ps, function (p) {\n        if (p.used() === false && p.required()) {\n          throw new Error('Placeholder: ' + p.name() + ' was not found in components list\\nNamespace: ' + owner.getOr('none') + '\\nComponents: ' + JSON.stringify(detail.components, null, 2));\n        }\n      });\n      return outcome;\n    };\n    var single = adt$2.single;\n    var multiple = adt$2.multiple;\n    var placeholder = constant(_placeholder);\n\n    var unique = 0;\n    var generate$1 = function (prefix) {\n      var date = new Date();\n      var time = date.getTime();\n      var random = Math.floor(Math.random() * 1000000000);\n      unique++;\n      return prefix + '_' + random + unique + String(time);\n    };\n\n    var adt$3 = Adt.generate([\n      { required: ['data'] },\n      { external: ['data'] },\n      { optional: ['data'] },\n      { group: ['data'] }\n    ]);\n    var fFactory = defaulted$1('factory', { sketch: identity });\n    var fSchema = defaulted$1('schema', []);\n    var fName = strict$1('name');\n    var fPname = field('pname', 'pname', defaultedThunk(function (typeSpec) {\n      return '<alloy.' + generate$1(typeSpec.name) + '>';\n    }), anyValue$1());\n    var fGroupSchema = state$1('schema', function () {\n      return [option('preprocess')];\n    });\n    var fDefaults = defaulted$1('defaults', constant({}));\n    var fOverrides = defaulted$1('overrides', constant({}));\n    var requiredSpec = objOf([\n      fFactory,\n      fSchema,\n      fName,\n      fPname,\n      fDefaults,\n      fOverrides\n    ]);\n    var optionalSpec = objOf([\n      fFactory,\n      fSchema,\n      fName,\n      fPname,\n      fDefaults,\n      fOverrides\n    ]);\n    var groupSpec = objOf([\n      fFactory,\n      fGroupSchema,\n      fName,\n      strict$1('unit'),\n      fPname,\n      fDefaults,\n      fOverrides\n    ]);\n    var asNamedPart = function (part) {\n      return part.fold(Option.some, Option.none, Option.some, Option.some);\n    };\n    var name$1 = function (part) {\n      var get = function (data) {\n        return data.name;\n      };\n      return part.fold(get, get, get, get);\n    };\n    var convert = function (adtConstructor, partSchema) {\n      return function (spec) {\n        var data = asRawOrDie('Converting part type', partSchema, spec);\n        return adtConstructor(data);\n      };\n    };\n    var required = convert(adt$3.required, requiredSpec);\n    var optional = convert(adt$3.optional, optionalSpec);\n    var group = convert(adt$3.group, groupSpec);\n    var original = constant('entirety');\n\n    var combine = function (detail, data, partSpec, partValidated) {\n      return deepMerge(data.defaults(detail, partSpec, partValidated), partSpec, { uid: detail.partUids[data.name] }, data.overrides(detail, partSpec, partValidated));\n    };\n    var subs = function (owner, detail, parts) {\n      var internals = {};\n      var externals = {};\n      each$1(parts, function (part) {\n        part.fold(function (data) {\n          internals[data.pname] = single(true, function (detail, partSpec, partValidated) {\n            return data.factory.sketch(combine(detail, data, partSpec, partValidated));\n          });\n        }, function (data) {\n          var partSpec = detail.parts[data.name];\n          externals[data.name] = constant(data.factory.sketch(combine(detail, data, partSpec[original()]), partSpec));\n        }, function (data) {\n          internals[data.pname] = single(false, function (detail, partSpec, partValidated) {\n            return data.factory.sketch(combine(detail, data, partSpec, partValidated));\n          });\n        }, function (data) {\n          internals[data.pname] = multiple(true, function (detail, _partSpec, _partValidated) {\n            var units = detail[data.name];\n            return map$1(units, function (u) {\n              return data.factory.sketch(deepMerge(data.defaults(detail, u, _partValidated), u, data.overrides(detail, u)));\n            });\n          });\n        });\n      });\n      return {\n        internals: constant(internals),\n        externals: constant(externals)\n      };\n    };\n\n    var generate$2 = function (owner, parts) {\n      var r = {};\n      each$1(parts, function (part) {\n        asNamedPart(part).each(function (np) {\n          var g = doGenerateOne(owner, np.pname);\n          r[np.name] = function (config) {\n            var validated = asRawOrDie('Part: ' + np.name + ' in ' + owner, objOf(np.schema), config);\n            return __assign(__assign({}, g), {\n              config: config,\n              validated: validated\n            });\n          };\n        });\n      });\n      return r;\n    };\n    var doGenerateOne = function (owner, pname) {\n      return {\n        uiType: placeholder(),\n        owner: owner,\n        name: pname\n      };\n    };\n    var generateOne = function (owner, pname, config) {\n      return {\n        uiType: placeholder(),\n        owner: owner,\n        name: pname,\n        config: config,\n        validated: {}\n      };\n    };\n    var schemas = function (parts) {\n      return bind(parts, function (part) {\n        return part.fold(Option.none, Option.some, Option.none, Option.none).map(function (data) {\n          return strictObjOf(data.name, data.schema.concat([snapshot(original())]));\n        }).toArray();\n      });\n    };\n    var names = function (parts) {\n      return map$1(parts, name$1);\n    };\n    var substitutes = function (owner, detail, parts) {\n      return subs(owner, detail, parts);\n    };\n    var components = function (owner, detail, internals) {\n      return substitutePlaces(Option.some(owner), detail, detail.components, internals);\n    };\n    var getPart = function (component, detail, partKey) {\n      var uid = detail.partUids[partKey];\n      return component.getSystem().getByUid(uid).toOption();\n    };\n    var getPartOrDie = function (component, detail, partKey) {\n      return getPart(component, detail, partKey).getOrDie('Could not find part: ' + partKey);\n    };\n    var getAllParts = function (component, detail) {\n      var system = component.getSystem();\n      return map(detail.partUids, function (pUid, k) {\n        return constant(system.getByUid(pUid));\n      });\n    };\n    var defaultUids = function (baseUid, partTypes) {\n      var partNames = names(partTypes);\n      return wrapAll$1(map$1(partNames, function (pn) {\n        return {\n          key: pn,\n          value: baseUid + '-' + pn\n        };\n      }));\n    };\n    var defaultUidsSchema = function (partTypes) {\n      return field('partUids', 'partUids', mergeWithThunk(function (spec) {\n        return defaultUids(spec.uid, partTypes);\n      }), anyValue$1());\n    };\n\n    var premadeTag = generate$1('alloy-premade');\n    var premade = function (comp) {\n      return wrap$1(premadeTag, comp);\n    };\n    var getPremade = function (spec) {\n      return readOptFrom$1(spec, premadeTag);\n    };\n    var makeApi = function (f) {\n      return markAsSketchApi(function (component) {\n        var rest = [];\n        for (var _i = 1; _i < arguments.length; _i++) {\n          rest[_i - 1] = arguments[_i];\n        }\n        return f.apply(undefined, [component.getApis()].concat([component].concat(rest)));\n      }, f);\n    };\n\n    var prefix$1 = constant('alloy-id-');\n    var idAttr = constant('data-alloy-id');\n\n    var prefix$2 = prefix$1();\n    var idAttr$1 = idAttr();\n    var write = function (label, elem) {\n      var id = generate$1(prefix$2 + label);\n      writeOnly(elem, id);\n      return id;\n    };\n    var writeOnly = function (elem, uid) {\n      Object.defineProperty(elem.dom(), idAttr$1, {\n        value: uid,\n        writable: true\n      });\n    };\n    var read$2 = function (elem) {\n      var id = isElement(elem) ? elem.dom()[idAttr$1] : null;\n      return Option.from(id);\n    };\n    var generate$3 = function (prefix) {\n      return generate$1(prefix);\n    };\n\n    var base = function (partSchemas, partUidsSchemas) {\n      var ps = partSchemas.length > 0 ? [strictObjOf('parts', partSchemas)] : [];\n      return ps.concat([\n        strict$1('uid'),\n        defaulted$1('dom', {}),\n        defaulted$1('components', []),\n        snapshot('originalSpec'),\n        defaulted$1('debug.sketcher', {})\n      ]).concat(partUidsSchemas);\n    };\n    var asRawOrDie$1 = function (label, schema, spec, partSchemas, partUidsSchemas) {\n      var baseS = base(partSchemas, partUidsSchemas);\n      return asRawOrDie(label + ' [SpecSchema]', objOfOnly(baseS.concat(schema)), spec);\n    };\n\n    var single$1 = function (owner, schema, factory, spec) {\n      var specWithUid = supplyUid(spec);\n      var detail = asRawOrDie$1(owner, schema, specWithUid, [], []);\n      return factory(detail, specWithUid);\n    };\n    var composite = function (owner, schema, partTypes, factory, spec) {\n      var specWithUid = supplyUid(spec);\n      var partSchemas = schemas(partTypes);\n      var partUidsSchema = defaultUidsSchema(partTypes);\n      var detail = asRawOrDie$1(owner, schema, specWithUid, partSchemas, [partUidsSchema]);\n      var subs = substitutes(owner, detail, partTypes);\n      var components$1 = components(owner, detail, subs.internals());\n      return factory(detail, components$1, specWithUid, subs.externals());\n    };\n    var supplyUid = function (spec) {\n      return spec.hasOwnProperty('uid') ? spec : __assign(__assign({}, spec), { uid: generate$3('uid') });\n    };\n\n    function isSketchSpec(spec) {\n      return spec.uid !== undefined;\n    }\n    var singleSchema = objOfOnly([\n      strict$1('name'),\n      strict$1('factory'),\n      strict$1('configFields'),\n      defaulted$1('apis', {}),\n      defaulted$1('extraApis', {})\n    ]);\n    var compositeSchema = objOfOnly([\n      strict$1('name'),\n      strict$1('factory'),\n      strict$1('configFields'),\n      strict$1('partFields'),\n      defaulted$1('apis', {}),\n      defaulted$1('extraApis', {})\n    ]);\n    var single$2 = function (rawConfig) {\n      var config = asRawOrDie('Sketcher for ' + rawConfig.name, singleSchema, rawConfig);\n      var sketch = function (spec) {\n        return single$1(config.name, config.configFields, config.factory, spec);\n      };\n      var apis = map(config.apis, makeApi);\n      var extraApis = map(config.extraApis, function (f, k) {\n        return markAsExtraApi(f, k);\n      });\n      return __assign(__assign({\n        name: constant(config.name),\n        partFields: constant([]),\n        configFields: constant(config.configFields),\n        sketch: sketch\n      }, apis), extraApis);\n    };\n    var composite$1 = function (rawConfig) {\n      var config = asRawOrDie('Sketcher for ' + rawConfig.name, compositeSchema, rawConfig);\n      var sketch = function (spec) {\n        return composite(config.name, config.configFields, config.partFields, config.factory, spec);\n      };\n      var parts = generate$2(config.name, config.partFields);\n      var apis = map(config.apis, makeApi);\n      var extraApis = map(config.extraApis, function (f, k) {\n        return markAsExtraApi(f, k);\n      });\n      return __assign(__assign({\n        name: constant(config.name),\n        partFields: constant(config.partFields),\n        configFields: constant(config.configFields),\n        sketch: sketch,\n        parts: constant(parts)\n      }, apis), extraApis);\n    };\n\n    var factory = function (detail) {\n      var events = events$2(detail.action);\n      var tag = detail.dom.tag;\n      var lookupAttr = function (attr) {\n        return readOptFrom$1(detail.dom, 'attributes').bind(function (attrs) {\n          return readOptFrom$1(attrs, attr);\n        });\n      };\n      var getModAttributes = function () {\n        if (tag === 'button') {\n          var type = lookupAttr('type').getOr('button');\n          var roleAttrs = lookupAttr('role').map(function (role) {\n            return { role: role };\n          }).getOr({});\n          return __assign({ type: type }, roleAttrs);\n        } else {\n          var role = lookupAttr('role').getOr('button');\n          return { role: role };\n        }\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: detail.components,\n        events: events,\n        behaviours: SketchBehaviours.augment(detail.buttonBehaviours, [\n          Focusing.config({}),\n          Keying.config({\n            mode: 'execution',\n            useSpace: true,\n            useEnter: true\n          })\n        ]),\n        domModification: { attributes: getModAttributes() },\n        eventOrder: detail.eventOrder\n      };\n    };\n    var Button = single$2({\n      name: 'Button',\n      factory: factory,\n      configFields: [\n        defaulted$1('uid', undefined),\n        strict$1('dom'),\n        defaulted$1('components', []),\n        SketchBehaviours.field('buttonBehaviours', [\n          Focusing,\n          Keying\n        ]),\n        option('action'),\n        option('role'),\n        defaulted$1('eventOrder', {})\n      ]\n    });\n\n    var exhibit$2 = function (base, unselectConfig) {\n      return nu$5({\n        styles: {\n          '-webkit-user-select': 'none',\n          'user-select': 'none',\n          '-ms-user-select': 'none',\n          '-moz-user-select': '-moz-none'\n        },\n        attributes: { unselectable: 'on' }\n      });\n    };\n    var events$4 = function (unselectConfig) {\n      return derive([abort(selectstart(), constant(true))]);\n    };\n\n    var ActiveUnselecting = /*#__PURE__*/Object.freeze({\n        events: events$4,\n        exhibit: exhibit$2\n    });\n\n    var Unselecting = create$1({\n      fields: [],\n      name: 'unselecting',\n      active: ActiveUnselecting\n    });\n\n    var getAttrs = function (elem) {\n      var attributes = elem.dom().attributes !== undefined ? elem.dom().attributes : [];\n      return foldl(attributes, function (b, attr) {\n        var _a;\n        if (attr.name === 'class') {\n          return b;\n        } else {\n          return __assign(__assign({}, b), (_a = {}, _a[attr.name] = attr.value, _a));\n        }\n      }, {});\n    };\n    var getClasses = function (elem) {\n      return Array.prototype.slice.call(elem.dom().classList, 0);\n    };\n    var fromHtml$2 = function (html) {\n      var elem = Element.fromHtml(html);\n      var children$1 = children(elem);\n      var attrs = getAttrs(elem);\n      var classes = getClasses(elem);\n      var contents = children$1.length === 0 ? {} : { innerHtml: get$2(elem) };\n      return __assign({\n        tag: name(elem),\n        classes: classes,\n        attributes: attrs\n      }, contents);\n    };\n\n    var dom$1 = function (rawHtml) {\n      var html = supplant(rawHtml, { prefix: Styles.prefix() });\n      return fromHtml$2(html);\n    };\n    var spec = function (rawHtml) {\n      var sDom = dom$1(rawHtml);\n      return { dom: sDom };\n    };\n\n    var forToolbarCommand = function (editor, command) {\n      return forToolbar(command, function () {\n        editor.execCommand(command);\n      }, {}, editor);\n    };\n    var getToggleBehaviours = function (command) {\n      return derive$1([\n        Toggling.config({\n          toggleClass: Styles.resolve('toolbar-button-selected'),\n          toggleOnExecute: false,\n          aria: { mode: 'pressed' }\n        }),\n        Receivers.format(command, function (button, status) {\n          var toggle = status ? Toggling.on : Toggling.off;\n          toggle(button);\n        })\n      ]);\n    };\n    var forToolbarStateCommand = function (editor, command) {\n      var extraBehaviours = getToggleBehaviours(command);\n      return forToolbar(command, function () {\n        editor.execCommand(command);\n      }, extraBehaviours, editor);\n    };\n    var forToolbarStateAction = function (editor, clazz, command, action) {\n      var extraBehaviours = getToggleBehaviours(command);\n      return forToolbar(clazz, action, extraBehaviours, editor);\n    };\n    var getToolbarIconButton = function (clazz, editor) {\n      var icons = editor.ui.registry.getAll().icons;\n      var optOxideIcon = Option.from(icons[clazz]);\n      return optOxideIcon.fold(function () {\n        return dom$1('<span class=\"${prefix}-toolbar-button ${prefix}-toolbar-group-item ${prefix}-icon-' + clazz + ' ${prefix}-icon\"></span>');\n      }, function (icon) {\n        return dom$1('<span class=\"${prefix}-toolbar-button ${prefix}-toolbar-group-item\">' + icon + '</span>');\n      });\n    };\n    var forToolbar = function (clazz, action, extraBehaviours, editor) {\n      return Button.sketch({\n        dom: getToolbarIconButton(clazz, editor),\n        action: action,\n        buttonBehaviours: deepMerge(derive$1([Unselecting.config({})]), extraBehaviours)\n      });\n    };\n    var Buttons = {\n      forToolbar: forToolbar,\n      forToolbarCommand: forToolbarCommand,\n      forToolbarStateAction: forToolbarStateAction,\n      forToolbarStateCommand: forToolbarStateCommand,\n      getToolbarIconButton: getToolbarIconButton\n    };\n\n    var labelPart = optional({\n      schema: [strict$1('dom')],\n      name: 'label'\n    });\n    var edgePart = function (name) {\n      return optional({\n        name: '' + name + '-edge',\n        overrides: function (detail) {\n          var action = detail.model.manager.edgeActions[name];\n          return action.fold(function () {\n            return {};\n          }, function (a) {\n            return {\n              events: derive([\n                runActionExtra(touchstart(), a, [detail]),\n                runActionExtra(mousedown(), a, [detail]),\n                runActionExtra(mousemove(), function (l, se, det) {\n                  if (det.mouseIsDown.get()) {\n                    a(l, det);\n                  }\n                }, [detail])\n              ])\n            };\n          });\n        }\n      });\n    };\n    var tlEdgePart = edgePart('top-left');\n    var tedgePart = edgePart('top');\n    var trEdgePart = edgePart('top-right');\n    var redgePart = edgePart('right');\n    var brEdgePart = edgePart('bottom-right');\n    var bedgePart = edgePart('bottom');\n    var blEdgePart = edgePart('bottom-left');\n    var ledgePart = edgePart('left');\n    var thumbPart = required({\n      name: 'thumb',\n      defaults: constant({ dom: { styles: { position: 'absolute' } } }),\n      overrides: function (detail) {\n        return {\n          events: derive([\n            redirectToPart(touchstart(), detail, 'spectrum'),\n            redirectToPart(touchmove(), detail, 'spectrum'),\n            redirectToPart(touchend(), detail, 'spectrum'),\n            redirectToPart(mousedown(), detail, 'spectrum'),\n            redirectToPart(mousemove(), detail, 'spectrum'),\n            redirectToPart(mouseup(), detail, 'spectrum')\n          ])\n        };\n      }\n    });\n    var spectrumPart = required({\n      schema: [state$1('mouseIsDown', function () {\n          return Cell(false);\n        })],\n      name: 'spectrum',\n      overrides: function (detail) {\n        var modelDetail = detail.model;\n        var model = modelDetail.manager;\n        var setValueFrom = function (component, simulatedEvent) {\n          return model.getValueFromEvent(simulatedEvent).map(function (value) {\n            return model.setValueFrom(component, detail, value);\n          });\n        };\n        return {\n          behaviours: derive$1([\n            Keying.config({\n              mode: 'special',\n              onLeft: function (spectrum) {\n                return model.onLeft(spectrum, detail);\n              },\n              onRight: function (spectrum) {\n                return model.onRight(spectrum, detail);\n              },\n              onUp: function (spectrum) {\n                return model.onUp(spectrum, detail);\n              },\n              onDown: function (spectrum) {\n                return model.onDown(spectrum, detail);\n              }\n            }),\n            Focusing.config({})\n          ]),\n          events: derive([\n            run(touchstart(), setValueFrom),\n            run(touchmove(), setValueFrom),\n            run(mousedown(), setValueFrom),\n            run(mousemove(), function (spectrum, se) {\n              if (detail.mouseIsDown.get()) {\n                setValueFrom(spectrum, se);\n              }\n            })\n          ])\n        };\n      }\n    });\n    var SliderParts = [\n      labelPart,\n      ledgePart,\n      redgePart,\n      tedgePart,\n      bedgePart,\n      tlEdgePart,\n      trEdgePart,\n      blEdgePart,\n      brEdgePart,\n      thumbPart,\n      spectrumPart\n    ];\n\n    var onLoad$1 = function (component, repConfig, repState) {\n      repConfig.store.manager.onLoad(component, repConfig, repState);\n    };\n    var onUnload = function (component, repConfig, repState) {\n      repConfig.store.manager.onUnload(component, repConfig, repState);\n    };\n    var setValue = function (component, repConfig, repState, data) {\n      repConfig.store.manager.setValue(component, repConfig, repState, data);\n    };\n    var getValue = function (component, repConfig, repState) {\n      return repConfig.store.manager.getValue(component, repConfig, repState);\n    };\n    var getState = function (component, repConfig, repState) {\n      return repState;\n    };\n\n    var RepresentApis = /*#__PURE__*/Object.freeze({\n        onLoad: onLoad$1,\n        onUnload: onUnload,\n        setValue: setValue,\n        getValue: getValue,\n        getState: getState\n    });\n\n    var events$5 = function (repConfig, repState) {\n      var es = repConfig.resetOnDom ? [\n        runOnAttached(function (comp, se) {\n          onLoad$1(comp, repConfig, repState);\n        }),\n        runOnDetached(function (comp, se) {\n          onUnload(comp, repConfig, repState);\n        })\n      ] : [loadEvent(repConfig, repState, onLoad$1)];\n      return derive(es);\n    };\n\n    var ActiveRepresenting = /*#__PURE__*/Object.freeze({\n        events: events$5\n    });\n\n    var memory = function () {\n      var data = Cell(null);\n      var readState = function () {\n        return {\n          mode: 'memory',\n          value: data.get()\n        };\n      };\n      var isNotSet = function () {\n        return data.get() === null;\n      };\n      var clear = function () {\n        data.set(null);\n      };\n      return nu$6({\n        set: data.set,\n        get: data.get,\n        isNotSet: isNotSet,\n        clear: clear,\n        readState: readState\n      });\n    };\n    var manual = function () {\n      var readState = function () {\n      };\n      return nu$6({ readState: readState });\n    };\n    var dataset = function () {\n      var dataByValue = Cell({});\n      var dataByText = Cell({});\n      var readState = function () {\n        return {\n          mode: 'dataset',\n          dataByValue: dataByValue.get(),\n          dataByText: dataByText.get()\n        };\n      };\n      var clear = function () {\n        dataByValue.set({});\n        dataByText.set({});\n      };\n      var lookup = function (itemString) {\n        return readOptFrom$1(dataByValue.get(), itemString).orThunk(function () {\n          return readOptFrom$1(dataByText.get(), itemString);\n        });\n      };\n      var update = function (items) {\n        var currentDataByValue = dataByValue.get();\n        var currentDataByText = dataByText.get();\n        var newDataByValue = {};\n        var newDataByText = {};\n        each$1(items, function (item) {\n          newDataByValue[item.value] = item;\n          readOptFrom$1(item, 'meta').each(function (meta) {\n            readOptFrom$1(meta, 'text').each(function (text) {\n              newDataByText[text] = item;\n            });\n          });\n        });\n        dataByValue.set(__assign(__assign({}, currentDataByValue), newDataByValue));\n        dataByText.set(__assign(__assign({}, currentDataByText), newDataByText));\n      };\n      return nu$6({\n        readState: readState,\n        lookup: lookup,\n        update: update,\n        clear: clear\n      });\n    };\n    var init$1 = function (spec) {\n      return spec.store.manager.state(spec);\n    };\n\n    var RepresentState = /*#__PURE__*/Object.freeze({\n        memory: memory,\n        dataset: dataset,\n        manual: manual,\n        init: init$1\n    });\n\n    var setValue$1 = function (component, repConfig, repState, data) {\n      var store = repConfig.store;\n      repState.update([data]);\n      store.setValue(component, data);\n      repConfig.onSetValue(component, data);\n    };\n    var getValue$1 = function (component, repConfig, repState) {\n      var store = repConfig.store;\n      var key = store.getDataKey(component);\n      return repState.lookup(key).fold(function () {\n        return store.getFallbackEntry(key);\n      }, function (data) {\n        return data;\n      });\n    };\n    var onLoad$2 = function (component, repConfig, repState) {\n      var store = repConfig.store;\n      store.initialValue.each(function (data) {\n        setValue$1(component, repConfig, repState, data);\n      });\n    };\n    var onUnload$1 = function (component, repConfig, repState) {\n      repState.clear();\n    };\n    var DatasetStore = [\n      option('initialValue'),\n      strict$1('getFallbackEntry'),\n      strict$1('getDataKey'),\n      strict$1('setValue'),\n      output('manager', {\n        setValue: setValue$1,\n        getValue: getValue$1,\n        onLoad: onLoad$2,\n        onUnload: onUnload$1,\n        state: dataset\n      })\n    ];\n\n    var getValue$2 = function (component, repConfig, repState) {\n      return repConfig.store.getValue(component);\n    };\n    var setValue$2 = function (component, repConfig, repState, data) {\n      repConfig.store.setValue(component, data);\n      repConfig.onSetValue(component, data);\n    };\n    var onLoad$3 = function (component, repConfig, repState) {\n      repConfig.store.initialValue.each(function (data) {\n        repConfig.store.setValue(component, data);\n      });\n    };\n    var ManualStore = [\n      strict$1('getValue'),\n      defaulted$1('setValue', noop),\n      option('initialValue'),\n      output('manager', {\n        setValue: setValue$2,\n        getValue: getValue$2,\n        onLoad: onLoad$3,\n        onUnload: noop,\n        state: NoState.init\n      })\n    ];\n\n    var setValue$3 = function (component, repConfig, repState, data) {\n      repState.set(data);\n      repConfig.onSetValue(component, data);\n    };\n    var getValue$3 = function (component, repConfig, repState) {\n      return repState.get();\n    };\n    var onLoad$4 = function (component, repConfig, repState) {\n      repConfig.store.initialValue.each(function (initVal) {\n        if (repState.isNotSet()) {\n          repState.set(initVal);\n        }\n      });\n    };\n    var onUnload$2 = function (component, repConfig, repState) {\n      repState.clear();\n    };\n    var MemoryStore = [\n      option('initialValue'),\n      output('manager', {\n        setValue: setValue$3,\n        getValue: getValue$3,\n        onLoad: onLoad$4,\n        onUnload: onUnload$2,\n        state: memory\n      })\n    ];\n\n    var RepresentSchema = [\n      defaultedOf('store', { mode: 'memory' }, choose$1('mode', {\n        memory: MemoryStore,\n        manual: ManualStore,\n        dataset: DatasetStore\n      })),\n      onHandler('onSetValue'),\n      defaulted$1('resetOnDom', false)\n    ];\n\n    var Representing = create$1({\n      fields: RepresentSchema,\n      name: 'representing',\n      active: ActiveRepresenting,\n      apis: RepresentApis,\n      extra: {\n        setValueFrom: function (component, source) {\n          var value = Representing.getValue(source);\n          Representing.setValue(component, value);\n        }\n      },\n      state: RepresentState\n    });\n\n    var api$1 = Dimension('width', function (element) {\n      return element.dom().offsetWidth;\n    });\n    var set$4 = function (element, h) {\n      api$1.set(element, h);\n    };\n    var get$6 = function (element) {\n      return api$1.get(element);\n    };\n\n    var r = function (left, top) {\n      var translate = function (x, y) {\n        return r(left + x, top + y);\n      };\n      return {\n        left: constant(left),\n        top: constant(top),\n        translate: translate\n      };\n    };\n    var Position = r;\n\n    var _sliderChangeEvent = 'slider.change.value';\n    var sliderChangeEvent = constant(_sliderChangeEvent);\n    var isTouchEvent = function (evt) {\n      return evt.type.indexOf('touch') !== -1;\n    };\n    var getEventSource = function (simulatedEvent) {\n      var evt = simulatedEvent.event().raw();\n      if (isTouchEvent(evt)) {\n        var touchEvent = evt;\n        return touchEvent.touches !== undefined && touchEvent.touches.length === 1 ? Option.some(touchEvent.touches[0]).map(function (t) {\n          return Position(t.clientX, t.clientY);\n        }) : Option.none();\n      } else {\n        var mouseEvent = evt;\n        return mouseEvent.clientX !== undefined ? Option.some(mouseEvent).map(function (me) {\n          return Position(me.clientX, me.clientY);\n        }) : Option.none();\n      }\n    };\n\n    var t = 'top', r$1 = 'right', b = 'bottom', l = 'left';\n    var minX = function (detail) {\n      return detail.model.minX;\n    };\n    var minY = function (detail) {\n      return detail.model.minY;\n    };\n    var min1X = function (detail) {\n      return detail.model.minX - 1;\n    };\n    var min1Y = function (detail) {\n      return detail.model.minY - 1;\n    };\n    var maxX = function (detail) {\n      return detail.model.maxX;\n    };\n    var maxY = function (detail) {\n      return detail.model.maxY;\n    };\n    var max1X = function (detail) {\n      return detail.model.maxX + 1;\n    };\n    var max1Y = function (detail) {\n      return detail.model.maxY + 1;\n    };\n    var range = function (detail, max, min) {\n      return max(detail) - min(detail);\n    };\n    var xRange = function (detail) {\n      return range(detail, maxX, minX);\n    };\n    var yRange = function (detail) {\n      return range(detail, maxY, minY);\n    };\n    var halfX = function (detail) {\n      return xRange(detail) / 2;\n    };\n    var halfY = function (detail) {\n      return yRange(detail) / 2;\n    };\n    var step = function (detail) {\n      return detail.stepSize;\n    };\n    var snap = function (detail) {\n      return detail.snapToGrid;\n    };\n    var snapStart = function (detail) {\n      return detail.snapStart;\n    };\n    var rounded = function (detail) {\n      return detail.rounded;\n    };\n    var hasEdge = function (detail, edgeName) {\n      return detail[edgeName + '-edge'] !== undefined;\n    };\n    var hasLEdge = function (detail) {\n      return hasEdge(detail, l);\n    };\n    var hasREdge = function (detail) {\n      return hasEdge(detail, r$1);\n    };\n    var hasTEdge = function (detail) {\n      return hasEdge(detail, t);\n    };\n    var hasBEdge = function (detail) {\n      return hasEdge(detail, b);\n    };\n    var currentValue = function (detail) {\n      return detail.model.value.get();\n    };\n\n    var xValue = function (x) {\n      return { x: constant(x) };\n    };\n    var yValue = function (y) {\n      return { y: constant(y) };\n    };\n    var xyValue = function (x, y) {\n      return {\n        x: constant(x),\n        y: constant(y)\n      };\n    };\n    var fireSliderChange = function (component, value) {\n      emitWith(component, sliderChangeEvent(), { value: value });\n    };\n    var setToTLEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(min1X(detail), min1Y(detail)));\n    };\n    var setToTEdge = function (edge, detail) {\n      fireSliderChange(edge, yValue(min1Y(detail)));\n    };\n    var setToTEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(halfX(detail), min1Y(detail)));\n    };\n    var setToTREdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(max1X(detail), min1Y(detail)));\n    };\n    var setToREdge = function (edge, detail) {\n      fireSliderChange(edge, xValue(max1X(detail)));\n    };\n    var setToREdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(max1X(detail), halfY(detail)));\n    };\n    var setToBREdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(max1X(detail), max1Y(detail)));\n    };\n    var setToBEdge = function (edge, detail) {\n      fireSliderChange(edge, yValue(max1Y(detail)));\n    };\n    var setToBEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(halfX(detail), max1Y(detail)));\n    };\n    var setToBLEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(min1X(detail), max1Y(detail)));\n    };\n    var setToLEdge = function (edge, detail) {\n      fireSliderChange(edge, xValue(min1X(detail)));\n    };\n    var setToLEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(min1X(detail), halfY(detail)));\n    };\n\n    var reduceBy = function (value, min, max, step) {\n      if (value < min) {\n        return value;\n      } else if (value > max) {\n        return max;\n      } else if (value === min) {\n        return min - 1;\n      } else {\n        return Math.max(min, value - step);\n      }\n    };\n    var increaseBy = function (value, min, max, step) {\n      if (value > max) {\n        return value;\n      } else if (value < min) {\n        return min;\n      } else if (value === max) {\n        return max + 1;\n      } else {\n        return Math.min(max, value + step);\n      }\n    };\n    var capValue = function (value, min, max) {\n      return Math.max(min, Math.min(max, value));\n    };\n    var snapValueOf = function (value, min, max, step, snapStart) {\n      return snapStart.fold(function () {\n        var initValue = value - min;\n        var extraValue = Math.round(initValue / step) * step;\n        return capValue(min + extraValue, min - 1, max + 1);\n      }, function (start) {\n        var remainder = (value - start) % step;\n        var adjustment = Math.round(remainder / step);\n        var rawSteps = Math.floor((value - start) / step);\n        var maxSteps = Math.floor((max - start) / step);\n        var numSteps = Math.min(maxSteps, rawSteps + adjustment);\n        var r = start + numSteps * step;\n        return Math.max(start, r);\n      });\n    };\n    var findOffsetOf = function (value, min, max) {\n      return Math.min(max, Math.max(value, min)) - min;\n    };\n    var findValueOf = function (args) {\n      var min = args.min, max = args.max, range = args.range, value = args.value, step = args.step, snap = args.snap, snapStart = args.snapStart, rounded = args.rounded, hasMinEdge = args.hasMinEdge, hasMaxEdge = args.hasMaxEdge, minBound = args.minBound, maxBound = args.maxBound, screenRange = args.screenRange;\n      var capMin = hasMinEdge ? min - 1 : min;\n      var capMax = hasMaxEdge ? max + 1 : max;\n      if (value < minBound) {\n        return capMin;\n      } else if (value > maxBound) {\n        return capMax;\n      } else {\n        var offset = findOffsetOf(value, minBound, maxBound);\n        var newValue = capValue(offset / screenRange * range + min, capMin, capMax);\n        if (snap && newValue >= min && newValue <= max) {\n          return snapValueOf(newValue, min, max, step, snapStart);\n        } else if (rounded) {\n          return Math.round(newValue);\n        } else {\n          return newValue;\n        }\n      }\n    };\n    var findOffsetOfValue = function (args) {\n      var min = args.min, max = args.max, range = args.range, value = args.value, hasMinEdge = args.hasMinEdge, hasMaxEdge = args.hasMaxEdge, maxBound = args.maxBound, maxOffset = args.maxOffset, centerMinEdge = args.centerMinEdge, centerMaxEdge = args.centerMaxEdge;\n      if (value < min) {\n        return hasMinEdge ? 0 : centerMinEdge;\n      } else if (value > max) {\n        return hasMaxEdge ? maxBound : centerMaxEdge;\n      } else {\n        return (value - min) / range * maxOffset;\n      }\n    };\n\n    var top = 'top', right = 'right', bottom = 'bottom', left = 'left', width = 'width', height = 'height';\n    var getBounds = function (component) {\n      return component.element().dom().getBoundingClientRect();\n    };\n    var getBoundsProperty = function (bounds, property) {\n      return bounds[property];\n    };\n    var getMinXBounds = function (component) {\n      var bounds = getBounds(component);\n      return getBoundsProperty(bounds, left);\n    };\n    var getMaxXBounds = function (component) {\n      var bounds = getBounds(component);\n      return getBoundsProperty(bounds, right);\n    };\n    var getMinYBounds = function (component) {\n      var bounds = getBounds(component);\n      return getBoundsProperty(bounds, top);\n    };\n    var getMaxYBounds = function (component) {\n      var bounds = getBounds(component);\n      return getBoundsProperty(bounds, bottom);\n    };\n    var getXScreenRange = function (component) {\n      var bounds = getBounds(component);\n      return getBoundsProperty(bounds, width);\n    };\n    var getYScreenRange = function (component) {\n      var bounds = getBounds(component);\n      return getBoundsProperty(bounds, height);\n    };\n    var getCenterOffsetOf = function (componentMinEdge, componentMaxEdge, spectrumMinEdge) {\n      return (componentMinEdge + componentMaxEdge) / 2 - spectrumMinEdge;\n    };\n    var getXCenterOffSetOf = function (component, spectrum) {\n      var componentBounds = getBounds(component);\n      var spectrumBounds = getBounds(spectrum);\n      var componentMinEdge = getBoundsProperty(componentBounds, left);\n      var componentMaxEdge = getBoundsProperty(componentBounds, right);\n      var spectrumMinEdge = getBoundsProperty(spectrumBounds, left);\n      return getCenterOffsetOf(componentMinEdge, componentMaxEdge, spectrumMinEdge);\n    };\n    var getYCenterOffSetOf = function (component, spectrum) {\n      var componentBounds = getBounds(component);\n      var spectrumBounds = getBounds(spectrum);\n      var componentMinEdge = getBoundsProperty(componentBounds, top);\n      var componentMaxEdge = getBoundsProperty(componentBounds, bottom);\n      var spectrumMinEdge = getBoundsProperty(spectrumBounds, top);\n      return getCenterOffsetOf(componentMinEdge, componentMaxEdge, spectrumMinEdge);\n    };\n\n    var fireSliderChange$1 = function (spectrum, value) {\n      emitWith(spectrum, sliderChangeEvent(), { value: value });\n    };\n    var sliderValue = function (x) {\n      return { x: constant(x) };\n    };\n    var findValueOfOffset = function (spectrum, detail, left) {\n      var args = {\n        min: minX(detail),\n        max: maxX(detail),\n        range: xRange(detail),\n        value: left,\n        step: step(detail),\n        snap: snap(detail),\n        snapStart: snapStart(detail),\n        rounded: rounded(detail),\n        hasMinEdge: hasLEdge(detail),\n        hasMaxEdge: hasREdge(detail),\n        minBound: getMinXBounds(spectrum),\n        maxBound: getMaxXBounds(spectrum),\n        screenRange: getXScreenRange(spectrum)\n      };\n      return findValueOf(args);\n    };\n    var setValueFrom = function (spectrum, detail, value) {\n      var xValue = findValueOfOffset(spectrum, detail, value);\n      var sliderVal = sliderValue(xValue);\n      fireSliderChange$1(spectrum, sliderVal);\n      return xValue;\n    };\n    var setToMin = function (spectrum, detail) {\n      var min = minX(detail);\n      fireSliderChange$1(spectrum, sliderValue(min));\n    };\n    var setToMax = function (spectrum, detail) {\n      var max = maxX(detail);\n      fireSliderChange$1(spectrum, sliderValue(max));\n    };\n    var moveBy = function (direction, spectrum, detail) {\n      var f = direction > 0 ? increaseBy : reduceBy;\n      var xValue = f(currentValue(detail).x(), minX(detail), maxX(detail), step(detail));\n      fireSliderChange$1(spectrum, sliderValue(xValue));\n      return Option.some(xValue);\n    };\n    var handleMovement = function (direction) {\n      return function (spectrum, detail) {\n        return moveBy(direction, spectrum, detail).map(function () {\n          return true;\n        });\n      };\n    };\n    var getValueFromEvent = function (simulatedEvent) {\n      var pos = getEventSource(simulatedEvent);\n      return pos.map(function (p) {\n        return p.left();\n      });\n    };\n    var findOffsetOfValue$1 = function (spectrum, detail, value, minEdge, maxEdge) {\n      var minOffset = 0;\n      var maxOffset = getXScreenRange(spectrum);\n      var centerMinEdge = minEdge.bind(function (edge) {\n        return Option.some(getXCenterOffSetOf(edge, spectrum));\n      }).getOr(minOffset);\n      var centerMaxEdge = maxEdge.bind(function (edge) {\n        return Option.some(getXCenterOffSetOf(edge, spectrum));\n      }).getOr(maxOffset);\n      var args = {\n        min: minX(detail),\n        max: maxX(detail),\n        range: xRange(detail),\n        value: value,\n        hasMinEdge: hasLEdge(detail),\n        hasMaxEdge: hasREdge(detail),\n        minBound: getMinXBounds(spectrum),\n        minOffset: minOffset,\n        maxBound: getMaxXBounds(spectrum),\n        maxOffset: maxOffset,\n        centerMinEdge: centerMinEdge,\n        centerMaxEdge: centerMaxEdge\n      };\n      return findOffsetOfValue(args);\n    };\n    var findPositionOfValue = function (slider, spectrum, value, minEdge, maxEdge, detail) {\n      var offset = findOffsetOfValue$1(spectrum, detail, value, minEdge, maxEdge);\n      return getMinXBounds(spectrum) - getMinXBounds(slider) + offset;\n    };\n    var setPositionFromValue = function (slider, thumb, detail, edges) {\n      var value = currentValue(detail);\n      var pos = findPositionOfValue(slider, edges.getSpectrum(slider), value.x(), edges.getLeftEdge(slider), edges.getRightEdge(slider), detail);\n      var thumbRadius = get$6(thumb.element()) / 2;\n      set$3(thumb.element(), 'left', pos - thumbRadius + 'px');\n    };\n    var onLeft = handleMovement(-1);\n    var onRight = handleMovement(1);\n    var onUp = Option.none;\n    var onDown = Option.none;\n    var edgeActions = {\n      'top-left': Option.none(),\n      'top': Option.none(),\n      'top-right': Option.none(),\n      'right': Option.some(setToREdge),\n      'bottom-right': Option.none(),\n      'bottom': Option.none(),\n      'bottom-left': Option.none(),\n      'left': Option.some(setToLEdge)\n    };\n\n    var HorizontalModel = /*#__PURE__*/Object.freeze({\n        setValueFrom: setValueFrom,\n        setToMin: setToMin,\n        setToMax: setToMax,\n        findValueOfOffset: findValueOfOffset,\n        getValueFromEvent: getValueFromEvent,\n        findPositionOfValue: findPositionOfValue,\n        setPositionFromValue: setPositionFromValue,\n        onLeft: onLeft,\n        onRight: onRight,\n        onUp: onUp,\n        onDown: onDown,\n        edgeActions: edgeActions\n    });\n\n    var fireSliderChange$2 = function (spectrum, value) {\n      emitWith(spectrum, sliderChangeEvent(), { value: value });\n    };\n    var sliderValue$1 = function (y) {\n      return { y: constant(y) };\n    };\n    var findValueOfOffset$1 = function (spectrum, detail, top) {\n      var args = {\n        min: minY(detail),\n        max: maxY(detail),\n        range: yRange(detail),\n        value: top,\n        step: step(detail),\n        snap: snap(detail),\n        snapStart: snapStart(detail),\n        rounded: rounded(detail),\n        hasMinEdge: hasTEdge(detail),\n        hasMaxEdge: hasBEdge(detail),\n        minBound: getMinYBounds(spectrum),\n        maxBound: getMaxYBounds(spectrum),\n        screenRange: getYScreenRange(spectrum)\n      };\n      return findValueOf(args);\n    };\n    var setValueFrom$1 = function (spectrum, detail, value) {\n      var yValue = findValueOfOffset$1(spectrum, detail, value);\n      var sliderVal = sliderValue$1(yValue);\n      fireSliderChange$2(spectrum, sliderVal);\n      return yValue;\n    };\n    var setToMin$1 = function (spectrum, detail) {\n      var min = minY(detail);\n      fireSliderChange$2(spectrum, sliderValue$1(min));\n    };\n    var setToMax$1 = function (spectrum, detail) {\n      var max = maxY(detail);\n      fireSliderChange$2(spectrum, sliderValue$1(max));\n    };\n    var moveBy$1 = function (direction, spectrum, detail) {\n      var f = direction > 0 ? increaseBy : reduceBy;\n      var yValue = f(currentValue(detail).y(), minY(detail), maxY(detail), step(detail));\n      fireSliderChange$2(spectrum, sliderValue$1(yValue));\n      return Option.some(yValue);\n    };\n    var handleMovement$1 = function (direction) {\n      return function (spectrum, detail) {\n        return moveBy$1(direction, spectrum, detail).map(function () {\n          return true;\n        });\n      };\n    };\n    var getValueFromEvent$1 = function (simulatedEvent) {\n      var pos = getEventSource(simulatedEvent);\n      return pos.map(function (p) {\n        return p.top();\n      });\n    };\n    var findOffsetOfValue$2 = function (spectrum, detail, value, minEdge, maxEdge) {\n      var minOffset = 0;\n      var maxOffset = getYScreenRange(spectrum);\n      var centerMinEdge = minEdge.bind(function (edge) {\n        return Option.some(getYCenterOffSetOf(edge, spectrum));\n      }).getOr(minOffset);\n      var centerMaxEdge = maxEdge.bind(function (edge) {\n        return Option.some(getYCenterOffSetOf(edge, spectrum));\n      }).getOr(maxOffset);\n      var args = {\n        min: minY(detail),\n        max: maxY(detail),\n        range: yRange(detail),\n        value: value,\n        hasMinEdge: hasTEdge(detail),\n        hasMaxEdge: hasBEdge(detail),\n        minBound: getMinYBounds(spectrum),\n        minOffset: minOffset,\n        maxBound: getMaxYBounds(spectrum),\n        maxOffset: maxOffset,\n        centerMinEdge: centerMinEdge,\n        centerMaxEdge: centerMaxEdge\n      };\n      return findOffsetOfValue(args);\n    };\n    var findPositionOfValue$1 = function (slider, spectrum, value, minEdge, maxEdge, detail) {\n      var offset = findOffsetOfValue$2(spectrum, detail, value, minEdge, maxEdge);\n      return getMinYBounds(spectrum) - getMinYBounds(slider) + offset;\n    };\n    var setPositionFromValue$1 = function (slider, thumb, detail, edges) {\n      var value = currentValue(detail);\n      var pos = findPositionOfValue$1(slider, edges.getSpectrum(slider), value.y(), edges.getTopEdge(slider), edges.getBottomEdge(slider), detail);\n      var thumbRadius = get$4(thumb.element()) / 2;\n      set$3(thumb.element(), 'top', pos - thumbRadius + 'px');\n    };\n    var onLeft$1 = Option.none;\n    var onRight$1 = Option.none;\n    var onUp$1 = handleMovement$1(-1);\n    var onDown$1 = handleMovement$1(1);\n    var edgeActions$1 = {\n      'top-left': Option.none(),\n      'top': Option.some(setToTEdge),\n      'top-right': Option.none(),\n      'right': Option.none(),\n      'bottom-right': Option.none(),\n      'bottom': Option.some(setToBEdge),\n      'bottom-left': Option.none(),\n      'left': Option.none()\n    };\n\n    var VerticalModel = /*#__PURE__*/Object.freeze({\n        setValueFrom: setValueFrom$1,\n        setToMin: setToMin$1,\n        setToMax: setToMax$1,\n        findValueOfOffset: findValueOfOffset$1,\n        getValueFromEvent: getValueFromEvent$1,\n        findPositionOfValue: findPositionOfValue$1,\n        setPositionFromValue: setPositionFromValue$1,\n        onLeft: onLeft$1,\n        onRight: onRight$1,\n        onUp: onUp$1,\n        onDown: onDown$1,\n        edgeActions: edgeActions$1\n    });\n\n    var fireSliderChange$3 = function (spectrum, value) {\n      emitWith(spectrum, sliderChangeEvent(), { value: value });\n    };\n    var sliderValue$2 = function (x, y) {\n      return {\n        x: constant(x),\n        y: constant(y)\n      };\n    };\n    var setValueFrom$2 = function (spectrum, detail, value) {\n      var xValue = findValueOfOffset(spectrum, detail, value.left());\n      var yValue = findValueOfOffset$1(spectrum, detail, value.top());\n      var val = sliderValue$2(xValue, yValue);\n      fireSliderChange$3(spectrum, val);\n      return val;\n    };\n    var moveBy$2 = function (direction, isVerticalMovement, spectrum, detail) {\n      var f = direction > 0 ? increaseBy : reduceBy;\n      var xValue = isVerticalMovement ? currentValue(detail).x() : f(currentValue(detail).x(), minX(detail), maxX(detail), step(detail));\n      var yValue = !isVerticalMovement ? currentValue(detail).y() : f(currentValue(detail).y(), minY(detail), maxY(detail), step(detail));\n      fireSliderChange$3(spectrum, sliderValue$2(xValue, yValue));\n      return Option.some(xValue);\n    };\n    var handleMovement$2 = function (direction, isVerticalMovement) {\n      return function (spectrum, detail) {\n        return moveBy$2(direction, isVerticalMovement, spectrum, detail).map(function () {\n          return true;\n        });\n      };\n    };\n    var setToMin$2 = function (spectrum, detail) {\n      var mX = minX(detail);\n      var mY = minY(detail);\n      fireSliderChange$3(spectrum, sliderValue$2(mX, mY));\n    };\n    var setToMax$2 = function (spectrum, detail) {\n      var mX = maxX(detail);\n      var mY = maxY(detail);\n      fireSliderChange$3(spectrum, sliderValue$2(mX, mY));\n    };\n    var getValueFromEvent$2 = function (simulatedEvent) {\n      return getEventSource(simulatedEvent);\n    };\n    var setPositionFromValue$2 = function (slider, thumb, detail, edges) {\n      var value = currentValue(detail);\n      var xPos = findPositionOfValue(slider, edges.getSpectrum(slider), value.x(), edges.getLeftEdge(slider), edges.getRightEdge(slider), detail);\n      var yPos = findPositionOfValue$1(slider, edges.getSpectrum(slider), value.y(), edges.getTopEdge(slider), edges.getBottomEdge(slider), detail);\n      var thumbXRadius = get$6(thumb.element()) / 2;\n      var thumbYRadius = get$4(thumb.element()) / 2;\n      set$3(thumb.element(), 'left', xPos - thumbXRadius + 'px');\n      set$3(thumb.element(), 'top', yPos - thumbYRadius + 'px');\n    };\n    var onLeft$2 = handleMovement$2(-1, false);\n    var onRight$2 = handleMovement$2(1, false);\n    var onUp$2 = handleMovement$2(-1, true);\n    var onDown$2 = handleMovement$2(1, true);\n    var edgeActions$2 = {\n      'top-left': Option.some(setToTLEdgeXY),\n      'top': Option.some(setToTEdgeXY),\n      'top-right': Option.some(setToTREdgeXY),\n      'right': Option.some(setToREdgeXY),\n      'bottom-right': Option.some(setToBREdgeXY),\n      'bottom': Option.some(setToBEdgeXY),\n      'bottom-left': Option.some(setToBLEdgeXY),\n      'left': Option.some(setToLEdgeXY)\n    };\n\n    var TwoDModel = /*#__PURE__*/Object.freeze({\n        setValueFrom: setValueFrom$2,\n        setToMin: setToMin$2,\n        setToMax: setToMax$2,\n        getValueFromEvent: getValueFromEvent$2,\n        setPositionFromValue: setPositionFromValue$2,\n        onLeft: onLeft$2,\n        onRight: onRight$2,\n        onUp: onUp$2,\n        onDown: onDown$2,\n        edgeActions: edgeActions$2\n    });\n\n    var SliderSchema = [\n      defaulted$1('stepSize', 1),\n      defaulted$1('onChange', noop),\n      defaulted$1('onChoose', noop),\n      defaulted$1('onInit', noop),\n      defaulted$1('onDragStart', noop),\n      defaulted$1('onDragEnd', noop),\n      defaulted$1('snapToGrid', false),\n      defaulted$1('rounded', true),\n      option('snapStart'),\n      strictOf('model', choose$1('mode', {\n        x: [\n          defaulted$1('minX', 0),\n          defaulted$1('maxX', 100),\n          state$1('value', function (spec) {\n            return Cell(spec.mode.minX);\n          }),\n          strict$1('getInitialValue'),\n          output('manager', HorizontalModel)\n        ],\n        y: [\n          defaulted$1('minY', 0),\n          defaulted$1('maxY', 100),\n          state$1('value', function (spec) {\n            return Cell(spec.mode.minY);\n          }),\n          strict$1('getInitialValue'),\n          output('manager', VerticalModel)\n        ],\n        xy: [\n          defaulted$1('minX', 0),\n          defaulted$1('maxX', 100),\n          defaulted$1('minY', 0),\n          defaulted$1('maxY', 100),\n          state$1('value', function (spec) {\n            return Cell({\n              x: constant(spec.mode.minX),\n              y: constant(spec.mode.minY)\n            });\n          }),\n          strict$1('getInitialValue'),\n          output('manager', TwoDModel)\n        ]\n      })),\n      field$1('sliderBehaviours', [\n        Keying,\n        Representing\n      ]),\n      state$1('mouseIsDown', function () {\n        return Cell(false);\n      })\n    ];\n\n    var mouseReleased = constant('mouse.released');\n\n    var sketch = function (detail, components, _spec, _externals) {\n      var _a;\n      var getThumb = function (component) {\n        return getPartOrDie(component, detail, 'thumb');\n      };\n      var getSpectrum = function (component) {\n        return getPartOrDie(component, detail, 'spectrum');\n      };\n      var getLeftEdge = function (component) {\n        return getPart(component, detail, 'left-edge');\n      };\n      var getRightEdge = function (component) {\n        return getPart(component, detail, 'right-edge');\n      };\n      var getTopEdge = function (component) {\n        return getPart(component, detail, 'top-edge');\n      };\n      var getBottomEdge = function (component) {\n        return getPart(component, detail, 'bottom-edge');\n      };\n      var modelDetail = detail.model;\n      var model = modelDetail.manager;\n      var refresh = function (slider, thumb) {\n        model.setPositionFromValue(slider, thumb, detail, {\n          getLeftEdge: getLeftEdge,\n          getRightEdge: getRightEdge,\n          getTopEdge: getTopEdge,\n          getBottomEdge: getBottomEdge,\n          getSpectrum: getSpectrum\n        });\n      };\n      var changeValue = function (slider, newValue) {\n        modelDetail.value.set(newValue);\n        var thumb = getThumb(slider);\n        refresh(slider, thumb);\n        detail.onChange(slider, thumb, newValue);\n        return Option.some(true);\n      };\n      var resetToMin = function (slider) {\n        model.setToMin(slider, detail);\n      };\n      var resetToMax = function (slider) {\n        model.setToMax(slider, detail);\n      };\n      var choose = function (slider) {\n        var fireOnChoose = function () {\n          getPart(slider, detail, 'thumb').each(function (thumb) {\n            var value = modelDetail.value.get();\n            detail.onChoose(slider, thumb, value);\n          });\n        };\n        var wasDown = detail.mouseIsDown.get();\n        detail.mouseIsDown.set(false);\n        if (wasDown) {\n          fireOnChoose();\n        }\n      };\n      var onDragStart = function (slider, simulatedEvent) {\n        simulatedEvent.stop();\n        detail.mouseIsDown.set(true);\n        detail.onDragStart(slider, getThumb(slider));\n      };\n      var onDragEnd = function (slider, simulatedEvent) {\n        simulatedEvent.stop();\n        detail.onDragEnd(slider, getThumb(slider));\n        choose(slider);\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: augment(detail.sliderBehaviours, [\n          Keying.config({\n            mode: 'special',\n            focusIn: function (slider) {\n              return getPart(slider, detail, 'spectrum').map(Keying.focusIn).map(constant(true));\n            }\n          }),\n          Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function (_) {\n                return modelDetail.value.get();\n              }\n            }\n          }),\n          Receiving.config({ channels: (_a = {}, _a[mouseReleased()] = { onReceive: choose }, _a) })\n        ]),\n        events: derive([\n          run(sliderChangeEvent(), function (slider, simulatedEvent) {\n            changeValue(slider, simulatedEvent.event().value());\n          }),\n          runOnAttached(function (slider, simulatedEvent) {\n            var getInitial = modelDetail.getInitialValue();\n            modelDetail.value.set(getInitial);\n            var thumb = getThumb(slider);\n            refresh(slider, thumb);\n            var spectrum = getSpectrum(slider);\n            detail.onInit(slider, thumb, spectrum, modelDetail.value.get());\n          }),\n          run(touchstart(), onDragStart),\n          run(touchend(), onDragEnd),\n          run(mousedown(), onDragStart),\n          run(mouseup(), onDragEnd)\n        ]),\n        apis: {\n          resetToMin: resetToMin,\n          resetToMax: resetToMax,\n          changeValue: changeValue,\n          refresh: refresh\n        },\n        domModification: { styles: { position: 'relative' } }\n      };\n    };\n\n    var Slider = composite$1({\n      name: 'Slider',\n      configFields: SliderSchema,\n      partFields: SliderParts,\n      factory: sketch,\n      apis: {\n        resetToMin: function (apis, slider) {\n          apis.resetToMin(slider);\n        },\n        resetToMax: function (apis, slider) {\n          apis.resetToMax(slider);\n        },\n        refresh: function (apis, slider) {\n          apis.refresh(slider);\n        }\n      }\n    });\n\n    var button = function (realm, clazz, makeItems, editor) {\n      return Buttons.forToolbar(clazz, function () {\n        var items = makeItems();\n        realm.setContextToolbar([{\n            label: clazz + ' group',\n            items: items\n          }]);\n      }, {}, editor);\n    };\n\n    var BLACK = -1;\n    var makeSlider = function (spec$1) {\n      var getColor = function (hue) {\n        if (hue < 0) {\n          return 'black';\n        } else if (hue > 360) {\n          return 'white';\n        } else {\n          return 'hsl(' + hue + ', 100%, 50%)';\n        }\n      };\n      var onInit = function (slider, thumb, spectrum, value) {\n        var color = getColor(value.x());\n        set$3(thumb.element(), 'background-color', color);\n      };\n      var onChange = function (slider, thumb, value) {\n        var color = getColor(value.x());\n        set$3(thumb.element(), 'background-color', color);\n        spec$1.onChange(slider, thumb, color);\n      };\n      return Slider.sketch({\n        dom: dom$1('<div class=\"${prefix}-slider ${prefix}-hue-slider-container\"></div>'),\n        components: [\n          Slider.parts()['left-edge'](spec('<div class=\"${prefix}-hue-slider-black\"></div>')),\n          Slider.parts().spectrum({\n            dom: dom$1('<div class=\"${prefix}-slider-gradient-container\"></div>'),\n            components: [spec('<div class=\"${prefix}-slider-gradient\"></div>')],\n            behaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })])\n          }),\n          Slider.parts()['right-edge'](spec('<div class=\"${prefix}-hue-slider-white\"></div>')),\n          Slider.parts().thumb({\n            dom: dom$1('<div class=\"${prefix}-slider-thumb\"></div>'),\n            behaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })])\n          })\n        ],\n        onChange: onChange,\n        onDragStart: function (slider, thumb) {\n          Toggling.on(thumb);\n        },\n        onDragEnd: function (slider, thumb) {\n          Toggling.off(thumb);\n        },\n        onInit: onInit,\n        stepSize: 10,\n        model: {\n          mode: 'x',\n          minX: 0,\n          maxX: 360,\n          getInitialValue: function () {\n            return {\n              x: function () {\n                return spec$1.getInitialValue();\n              }\n            };\n          }\n        },\n        sliderBehaviours: derive$1([Receivers.orientation(Slider.refresh)])\n      });\n    };\n    var makeItems = function (spec) {\n      return [makeSlider(spec)];\n    };\n    var sketch$1 = function (realm, editor) {\n      var spec = {\n        onChange: function (slider, thumb, color) {\n          editor.undoManager.transact(function () {\n            editor.formatter.apply('forecolor', { value: color });\n            editor.nodeChanged();\n          });\n        },\n        getInitialValue: function () {\n          return BLACK;\n        }\n      };\n      return button(realm, 'color-levels', function () {\n        return makeItems(spec);\n      }, editor);\n    };\n    var ColorSlider = {\n      makeItems: makeItems,\n      sketch: sketch$1\n    };\n\n    var schema$7 = objOfOnly([\n      strict$1('getInitialValue'),\n      strict$1('onChange'),\n      strict$1('category'),\n      strict$1('sizes')\n    ]);\n    var sketch$2 = function (rawSpec) {\n      var spec$1 = asRawOrDie('SizeSlider', schema$7, rawSpec);\n      var isValidValue = function (valueIndex) {\n        return valueIndex >= 0 && valueIndex < spec$1.sizes.length;\n      };\n      var onChange = function (slider, thumb, valueIndex) {\n        var index = valueIndex.x();\n        if (isValidValue(index)) {\n          spec$1.onChange(index);\n        }\n      };\n      return Slider.sketch({\n        dom: {\n          tag: 'div',\n          classes: [\n            Styles.resolve('slider-' + spec$1.category + '-size-container'),\n            Styles.resolve('slider'),\n            Styles.resolve('slider-size-container')\n          ]\n        },\n        onChange: onChange,\n        onDragStart: function (slider, thumb) {\n          Toggling.on(thumb);\n        },\n        onDragEnd: function (slider, thumb) {\n          Toggling.off(thumb);\n        },\n        model: {\n          mode: 'x',\n          minX: 0,\n          maxX: spec$1.sizes.length - 1,\n          getInitialValue: function () {\n            return {\n              x: function () {\n                return spec$1.getInitialValue();\n              }\n            };\n          }\n        },\n        stepSize: 1,\n        snapToGrid: true,\n        sliderBehaviours: derive$1([Receivers.orientation(Slider.refresh)]),\n        components: [\n          Slider.parts().spectrum({\n            dom: dom$1('<div class=\"${prefix}-slider-size-container\"></div>'),\n            components: [spec('<div class=\"${prefix}-slider-size-line\"></div>')]\n          }),\n          Slider.parts().thumb({\n            dom: dom$1('<div class=\"${prefix}-slider-thumb\"></div>'),\n            behaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })])\n          })\n        ]\n      });\n    };\n    var SizeSlider = { sketch: sketch$2 };\n\n    var candidates = [\n      '9px',\n      '10px',\n      '11px',\n      '12px',\n      '14px',\n      '16px',\n      '18px',\n      '20px',\n      '24px',\n      '32px',\n      '36px'\n    ];\n    var defaultSize = 'medium';\n    var defaultIndex = 2;\n    var indexToSize = function (index) {\n      return Option.from(candidates[index]);\n    };\n    var sizeToIndex = function (size) {\n      return findIndex(candidates, function (v) {\n        return v === size;\n      });\n    };\n    var getRawOrComputed = function (isRoot, rawStart) {\n      var optStart = isElement(rawStart) ? Option.some(rawStart) : parent(rawStart).filter(isElement);\n      return optStart.map(function (start) {\n        var inline = closest(start, function (elem) {\n          return getRaw(elem, 'font-size').isSome();\n        }, isRoot).bind(function (elem) {\n          return getRaw(elem, 'font-size');\n        });\n        return inline.getOrThunk(function () {\n          return get$3(start, 'font-size');\n        });\n      }).getOr('');\n    };\n    var getSize = function (editor) {\n      var node = editor.selection.getStart();\n      var elem = Element.fromDom(node);\n      var root = Element.fromDom(editor.getBody());\n      var isRoot = function (e) {\n        return eq(root, e);\n      };\n      var elemSize = getRawOrComputed(isRoot, elem);\n      return find$2(candidates, function (size) {\n        return elemSize === size;\n      }).getOr(defaultSize);\n    };\n    var applySize = function (editor, value) {\n      var currentValue = getSize(editor);\n      if (currentValue !== value) {\n        editor.execCommand('fontSize', false, value);\n      }\n    };\n    var get$7 = function (editor) {\n      var size = getSize(editor);\n      return sizeToIndex(size).getOr(defaultIndex);\n    };\n    var apply$1 = function (editor, index) {\n      indexToSize(index).each(function (size) {\n        applySize(editor, size);\n      });\n    };\n    var FontSizes = {\n      candidates: constant(candidates),\n      get: get$7,\n      apply: apply$1\n    };\n\n    var sizes = FontSizes.candidates();\n    var makeSlider$1 = function (spec) {\n      return SizeSlider.sketch({\n        onChange: spec.onChange,\n        sizes: sizes,\n        category: 'font',\n        getInitialValue: spec.getInitialValue\n      });\n    };\n    var makeItems$1 = function (spec$1) {\n      return [\n        spec('<span class=\"${prefix}-toolbar-button ${prefix}-icon-small-font ${prefix}-icon\"></span>'),\n        makeSlider$1(spec$1),\n        spec('<span class=\"${prefix}-toolbar-button ${prefix}-icon-large-font ${prefix}-icon\"></span>')\n      ];\n    };\n    var sketch$3 = function (realm, editor) {\n      var spec = {\n        onChange: function (value) {\n          FontSizes.apply(editor, value);\n        },\n        getInitialValue: function () {\n          return FontSizes.get(editor);\n        }\n      };\n      return button(realm, 'font-size', function () {\n        return makeItems$1(spec);\n      }, editor);\n    };\n\n    var record = function (spec) {\n      var uid = isSketchSpec(spec) && hasKey$1(spec, 'uid') ? spec.uid : generate$3('memento');\n      var get = function (anyInSystem) {\n        return anyInSystem.getSystem().getByUid(uid).getOrDie();\n      };\n      var getOpt = function (anyInSystem) {\n        return anyInSystem.getSystem().getByUid(uid).toOption();\n      };\n      var asSpec = function () {\n        return __assign(__assign({}, spec), { uid: uid });\n      };\n      return {\n        get: get,\n        getOpt: getOpt,\n        asSpec: asSpec\n      };\n    };\n\n    var promise = function () {\n      var Promise = function (fn) {\n        if (typeof this !== 'object') {\n          throw new TypeError('Promises must be constructed via new');\n        }\n        if (typeof fn !== 'function') {\n          throw new TypeError('not a function');\n        }\n        this._state = null;\n        this._value = null;\n        this._deferreds = [];\n        doResolve(fn, bind(resolve, this), bind(reject, this));\n      };\n      var asap = Promise.immediateFn || typeof window.setImmediate === 'function' && window.setImmediate || function (fn) {\n        domGlobals.setTimeout(fn, 1);\n      };\n      function bind(fn, thisArg) {\n        return function () {\n          return fn.apply(thisArg, arguments);\n        };\n      }\n      var isArray = Array.isArray || function (value) {\n        return Object.prototype.toString.call(value) === '[object Array]';\n      };\n      function handle(deferred) {\n        var me = this;\n        if (this._state === null) {\n          this._deferreds.push(deferred);\n          return;\n        }\n        asap(function () {\n          var cb = me._state ? deferred.onFulfilled : deferred.onRejected;\n          if (cb === null) {\n            (me._state ? deferred.resolve : deferred.reject)(me._value);\n            return;\n          }\n          var ret;\n          try {\n            ret = cb(me._value);\n          } catch (e) {\n            deferred.reject(e);\n            return;\n          }\n          deferred.resolve(ret);\n        });\n      }\n      function resolve(newValue) {\n        try {\n          if (newValue === this) {\n            throw new TypeError('A promise cannot be resolved with itself.');\n          }\n          if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {\n            var then = newValue.then;\n            if (typeof then === 'function') {\n              doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this));\n              return;\n            }\n          }\n          this._state = true;\n          this._value = newValue;\n          finale.call(this);\n        } catch (e) {\n          reject.call(this, e);\n        }\n      }\n      function reject(newValue) {\n        this._state = false;\n        this._value = newValue;\n        finale.call(this);\n      }\n      function finale() {\n        for (var _i = 0, _a = this._deferreds; _i < _a.length; _i++) {\n          var deferred = _a[_i];\n          handle.call(this, deferred);\n        }\n        this._deferreds = [];\n      }\n      function Handler(onFulfilled, onRejected, resolve, reject) {\n        this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n        this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n        this.resolve = resolve;\n        this.reject = reject;\n      }\n      function doResolve(fn, onFulfilled, onRejected) {\n        var done = false;\n        try {\n          fn(function (value) {\n            if (done) {\n              return;\n            }\n            done = true;\n            onFulfilled(value);\n          }, function (reason) {\n            if (done) {\n              return;\n            }\n            done = true;\n            onRejected(reason);\n          });\n        } catch (ex) {\n          if (done) {\n            return;\n          }\n          done = true;\n          onRejected(ex);\n        }\n      }\n      Promise.prototype.catch = function (onRejected) {\n        return this.then(null, onRejected);\n      };\n      Promise.prototype.then = function (onFulfilled, onRejected) {\n        var me = this;\n        return new Promise(function (resolve, reject) {\n          handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject));\n        });\n      };\n      Promise.all = function () {\n        var values = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          values[_i] = arguments[_i];\n        }\n        var args = Array.prototype.slice.call(values.length === 1 && isArray(values[0]) ? values[0] : values);\n        return new Promise(function (resolve, reject) {\n          if (args.length === 0) {\n            return resolve([]);\n          }\n          var remaining = args.length;\n          function res(i, val) {\n            try {\n              if (val && (typeof val === 'object' || typeof val === 'function')) {\n                var then = val.then;\n                if (typeof then === 'function') {\n                  then.call(val, function (val) {\n                    res(i, val);\n                  }, reject);\n                  return;\n                }\n              }\n              args[i] = val;\n              if (--remaining === 0) {\n                resolve(args);\n              }\n            } catch (ex) {\n              reject(ex);\n            }\n          }\n          for (var i = 0; i < args.length; i++) {\n            res(i, args[i]);\n          }\n        });\n      };\n      Promise.resolve = function (value) {\n        if (value && typeof value === 'object' && value.constructor === Promise) {\n          return value;\n        }\n        return new Promise(function (resolve) {\n          resolve(value);\n        });\n      };\n      Promise.reject = function (reason) {\n        return new Promise(function (resolve, reject) {\n          reject(reason);\n        });\n      };\n      Promise.race = function (values) {\n        return new Promise(function (resolve, reject) {\n          for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {\n            var value = values_1[_i];\n            value.then(resolve, reject);\n          }\n        });\n      };\n      return Promise;\n    };\n    var Promise = window.Promise ? window.Promise : promise();\n\n    function blobToDataUri(blob) {\n      return new Promise(function (resolve) {\n        var reader = new domGlobals.FileReader();\n        reader.onloadend = function () {\n          resolve(reader.result);\n        };\n        reader.readAsDataURL(blob);\n      });\n    }\n    function blobToBase64(blob) {\n      return blobToDataUri(blob).then(function (dataUri) {\n        return dataUri.split(',')[1];\n      });\n    }\n\n    var blobToBase64$1 = function (blob) {\n      return blobToBase64(blob);\n    };\n\n    var addImage = function (editor, blob) {\n      blobToBase64$1(blob).then(function (base64) {\n        editor.undoManager.transact(function () {\n          var cache = editor.editorUpload.blobCache;\n          var info = cache.create(generate$1('mceu'), blob, base64);\n          cache.add(info);\n          var img = editor.dom.createHTML('img', { src: info.blobUri() });\n          editor.insertContent(img);\n        });\n      });\n    };\n    var extractBlob = function (simulatedEvent) {\n      var event = simulatedEvent.event();\n      var files = event.raw().target.files || event.raw().dataTransfer.files;\n      return Option.from(files[0]);\n    };\n    var sketch$4 = function (editor) {\n      var pickerDom = {\n        tag: 'input',\n        attributes: {\n          accept: 'image/*',\n          type: 'file',\n          title: ''\n        },\n        styles: {\n          visibility: 'hidden',\n          position: 'absolute'\n        }\n      };\n      var memPicker = record({\n        dom: pickerDom,\n        events: derive([\n          cutter(click()),\n          run(change(), function (picker, simulatedEvent) {\n            extractBlob(simulatedEvent).each(function (blob) {\n              addImage(editor, blob);\n            });\n          })\n        ])\n      });\n      return Button.sketch({\n        dom: Buttons.getToolbarIconButton('image', editor),\n        components: [memPicker.asSpec()],\n        action: function (button) {\n          var picker = memPicker.get(button);\n          picker.element().dom().click();\n        }\n      });\n    };\n\n    var get$8 = function (element) {\n      return element.dom().textContent;\n    };\n    var set$5 = function (element, value) {\n      element.dom().textContent = value;\n    };\n\n    var isNotEmpty = function (val) {\n      return val.length > 0;\n    };\n    var defaultToEmpty = function (str) {\n      return str === undefined || str === null ? '' : str;\n    };\n    var noLink = function (editor) {\n      var text = editor.selection.getContent({ format: 'text' });\n      return {\n        url: '',\n        text: text,\n        title: '',\n        target: '',\n        link: Option.none()\n      };\n    };\n    var fromLink = function (link) {\n      var text = get$8(link);\n      var url = get(link, 'href');\n      var title = get(link, 'title');\n      var target = get(link, 'target');\n      return {\n        url: defaultToEmpty(url),\n        text: text !== url ? defaultToEmpty(text) : '',\n        title: defaultToEmpty(title),\n        target: defaultToEmpty(target),\n        link: Option.some(link)\n      };\n    };\n    var getInfo = function (editor) {\n      return query(editor).fold(function () {\n        return noLink(editor);\n      }, function (link) {\n        return fromLink(link);\n      });\n    };\n    var wasSimple = function (link) {\n      var prevHref = get(link, 'href');\n      var prevText = get$8(link);\n      return prevHref === prevText;\n    };\n    var getTextToApply = function (link, url, info) {\n      return info.text.toOption().filter(isNotEmpty).fold(function () {\n        return wasSimple(link) ? Option.some(url) : Option.none();\n      }, Option.some);\n    };\n    var unlinkIfRequired = function (editor, info) {\n      var activeLink = info.link.bind(identity);\n      activeLink.each(function (link) {\n        editor.execCommand('unlink');\n      });\n    };\n    var getAttrs$1 = function (url, info) {\n      var attrs = {};\n      attrs.href = url;\n      info.title.toOption().filter(isNotEmpty).each(function (title) {\n        attrs.title = title;\n      });\n      info.target.toOption().filter(isNotEmpty).each(function (target) {\n        attrs.target = target;\n      });\n      return attrs;\n    };\n    var applyInfo = function (editor, info) {\n      info.url.toOption().filter(isNotEmpty).fold(function () {\n        unlinkIfRequired(editor, info);\n      }, function (url) {\n        var attrs = getAttrs$1(url, info);\n        var activeLink = info.link.bind(identity);\n        activeLink.fold(function () {\n          var text = info.text.toOption().filter(isNotEmpty).getOr(url);\n          editor.insertContent(editor.dom.createHTML('a', attrs, editor.dom.encode(text)));\n        }, function (link) {\n          var text = getTextToApply(link, url, info);\n          setAll(link, attrs);\n          text.each(function (newText) {\n            set$5(link, newText);\n          });\n        });\n      });\n    };\n    var query = function (editor) {\n      var start = Element.fromDom(editor.selection.getStart());\n      return closest$2(start, 'a');\n    };\n    var LinkBridge = {\n      getInfo: getInfo,\n      applyInfo: applyInfo,\n      query: query\n    };\n\n    var platform$1 = detect$3();\n    var preserve = function (f, editor) {\n      var rng = editor.selection.getRng();\n      f();\n      editor.selection.setRng(rng);\n    };\n    var forAndroid = function (editor, f) {\n      var wrapper = platform$1.os.isAndroid() ? preserve : apply;\n      wrapper(f, editor);\n    };\n    var RangePreserver = { forAndroid: forAndroid };\n\n    var events$6 = function (name, eventHandlers) {\n      var events = derive(eventHandlers);\n      return create$1({\n        fields: [strict$1('enabled')],\n        name: name,\n        active: { events: constant(events) }\n      });\n    };\n    var config = function (name, eventHandlers) {\n      var me = events$6(name, eventHandlers);\n      return {\n        key: name,\n        value: {\n          config: {},\n          me: me,\n          configAsRaw: constant({}),\n          initialConfig: {},\n          state: NoState\n        }\n      };\n    };\n\n    var getCurrent = function (component, composeConfig, composeState) {\n      return composeConfig.find(component);\n    };\n\n    var ComposeApis = /*#__PURE__*/Object.freeze({\n        getCurrent: getCurrent\n    });\n\n    var ComposeSchema = [strict$1('find')];\n\n    var Composing = create$1({\n      fields: ComposeSchema,\n      name: 'composing',\n      apis: ComposeApis\n    });\n\n    var factory$1 = function (detail) {\n      var _a = detail.dom, attributes = _a.attributes, domWithoutAttributes = __rest(_a, ['attributes']);\n      return {\n        uid: detail.uid,\n        dom: __assign({\n          tag: 'div',\n          attributes: __assign({ role: 'presentation' }, attributes)\n        }, domWithoutAttributes),\n        components: detail.components,\n        behaviours: get$5(detail.containerBehaviours),\n        events: detail.events,\n        domModification: detail.domModification,\n        eventOrder: detail.eventOrder\n      };\n    };\n    var Container = single$2({\n      name: 'Container',\n      factory: factory$1,\n      configFields: [\n        defaulted$1('components', []),\n        field$1('containerBehaviours', []),\n        defaulted$1('events', {}),\n        defaulted$1('domModification', {}),\n        defaulted$1('eventOrder', {})\n      ]\n    });\n\n    var factory$2 = function (detail) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        behaviours: SketchBehaviours.augment(detail.dataBehaviours, [\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: detail.getInitialValue()\n            }\n          }),\n          Composing.config({ find: Option.some })\n        ]),\n        events: derive([runOnAttached(function (component, simulatedEvent) {\n            Representing.setValue(component, detail.getInitialValue());\n          })])\n      };\n    };\n    var DataField = single$2({\n      name: 'DataField',\n      factory: factory$2,\n      configFields: [\n        strict$1('uid'),\n        strict$1('dom'),\n        strict$1('getInitialValue'),\n        SketchBehaviours.field('dataBehaviours', [\n          Representing,\n          Composing\n        ])\n      ]\n    });\n\n    var get$9 = function (element) {\n      return element.dom().value;\n    };\n    var set$6 = function (element, value) {\n      if (value === undefined) {\n        throw new Error('Value.set was undefined');\n      }\n      element.dom().value = value;\n    };\n\n    var schema$8 = constant([\n      option('data'),\n      defaulted$1('inputAttributes', {}),\n      defaulted$1('inputStyles', {}),\n      defaulted$1('tag', 'input'),\n      defaulted$1('inputClasses', []),\n      onHandler('onSetValue'),\n      defaulted$1('styles', {}),\n      defaulted$1('eventOrder', {}),\n      field$1('inputBehaviours', [\n        Representing,\n        Focusing\n      ]),\n      defaulted$1('selectOnFocus', true)\n    ]);\n    var focusBehaviours = function (detail) {\n      return derive$1([Focusing.config({\n          onFocus: detail.selectOnFocus === false ? noop : function (component) {\n            var input = component.element();\n            var value = get$9(input);\n            input.dom().setSelectionRange(0, value.length);\n          }\n        })]);\n    };\n    var behaviours = function (detail) {\n      return __assign(__assign({}, focusBehaviours(detail)), augment(detail.inputBehaviours, [Representing.config({\n          store: {\n            mode: 'manual',\n            initialValue: detail.data.getOr(undefined),\n            getValue: function (input) {\n              return get$9(input.element());\n            },\n            setValue: function (input, data) {\n              var current = get$9(input.element());\n              if (current !== data) {\n                set$6(input.element(), data);\n              }\n            }\n          },\n          onSetValue: detail.onSetValue\n        })]));\n    };\n    var dom$2 = function (detail) {\n      return {\n        tag: detail.tag,\n        attributes: __assign({ type: 'text' }, detail.inputAttributes),\n        styles: detail.inputStyles,\n        classes: detail.inputClasses\n      };\n    };\n\n    var factory$3 = function (detail, spec) {\n      return {\n        uid: detail.uid,\n        dom: dom$2(detail),\n        components: [],\n        behaviours: behaviours(detail),\n        eventOrder: detail.eventOrder\n      };\n    };\n    var Input = single$2({\n      name: 'Input',\n      configFields: schema$8(),\n      factory: factory$3\n    });\n\n    var exhibit$3 = function (base, tabConfig) {\n      return nu$5({\n        attributes: wrapAll$1([{\n            key: tabConfig.tabAttr,\n            value: 'true'\n          }])\n      });\n    };\n\n    var ActiveTabstopping = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$3\n    });\n\n    var TabstopSchema = [defaulted$1('tabAttr', 'data-alloy-tabstop')];\n\n    var Tabstopping = create$1({\n      fields: TabstopSchema,\n      name: 'tabstopping',\n      active: ActiveTabstopping\n    });\n\n    var global$3 = tinymce.util.Tools.resolve('tinymce.util.I18n');\n\n    var clearInputBehaviour = 'input-clearing';\n    var field$2 = function (name, placeholder) {\n      var inputSpec = record(Input.sketch({\n        inputAttributes: { placeholder: global$3.translate(placeholder) },\n        onSetValue: function (input$1, data) {\n          emit(input$1, input());\n        },\n        inputBehaviours: derive$1([\n          Composing.config({ find: Option.some }),\n          Tabstopping.config({}),\n          Keying.config({ mode: 'execution' })\n        ]),\n        selectOnFocus: false\n      }));\n      var buttonSpec = record(Button.sketch({\n        dom: dom$1('<button class=\"${prefix}-input-container-x ${prefix}-icon-cancel-circle ${prefix}-icon\"></button>'),\n        action: function (button) {\n          var input = inputSpec.get(button);\n          Representing.setValue(input, '');\n        }\n      }));\n      return {\n        name: name,\n        spec: Container.sketch({\n          dom: dom$1('<div class=\"${prefix}-input-container\"></div>'),\n          components: [\n            inputSpec.asSpec(),\n            buttonSpec.asSpec()\n          ],\n          containerBehaviours: derive$1([\n            Toggling.config({ toggleClass: Styles.resolve('input-container-empty') }),\n            Composing.config({\n              find: function (comp) {\n                return Option.some(inputSpec.get(comp));\n              }\n            }),\n            config(clearInputBehaviour, [run(input(), function (iContainer) {\n                var input = inputSpec.get(iContainer);\n                var val = Representing.getValue(input);\n                var f = val.length > 0 ? Toggling.off : Toggling.on;\n                f(iContainer);\n              })])\n          ])\n        })\n      };\n    };\n    var hidden = function (name) {\n      return {\n        name: name,\n        spec: DataField.sketch({\n          dom: {\n            tag: 'span',\n            styles: { display: 'none' }\n          },\n          getInitialValue: function () {\n            return Option.none();\n          }\n        })\n      };\n    };\n\n    var nativeDisabled = [\n      'input',\n      'button',\n      'textarea',\n      'select'\n    ];\n    var onLoad$5 = function (component, disableConfig, disableState) {\n      if (disableConfig.disabled) {\n        disable(component, disableConfig);\n      }\n    };\n    var hasNative = function (component, config) {\n      return config.useNative === true && contains(nativeDisabled, name(component.element()));\n    };\n    var nativeIsDisabled = function (component) {\n      return has$1(component.element(), 'disabled');\n    };\n    var nativeDisable = function (component) {\n      set(component.element(), 'disabled', 'disabled');\n    };\n    var nativeEnable = function (component) {\n      remove$1(component.element(), 'disabled');\n    };\n    var ariaIsDisabled = function (component) {\n      return get(component.element(), 'aria-disabled') === 'true';\n    };\n    var ariaDisable = function (component) {\n      set(component.element(), 'aria-disabled', 'true');\n    };\n    var ariaEnable = function (component) {\n      set(component.element(), 'aria-disabled', 'false');\n    };\n    var disable = function (component, disableConfig, disableState) {\n      disableConfig.disableClass.each(function (disableClass) {\n        add$2(component.element(), disableClass);\n      });\n      var f = hasNative(component, disableConfig) ? nativeDisable : ariaDisable;\n      f(component);\n      disableConfig.onDisabled(component);\n    };\n    var enable = function (component, disableConfig, disableState) {\n      disableConfig.disableClass.each(function (disableClass) {\n        remove$4(component.element(), disableClass);\n      });\n      var f = hasNative(component, disableConfig) ? nativeEnable : ariaEnable;\n      f(component);\n      disableConfig.onEnabled(component);\n    };\n    var isDisabled = function (component, disableConfig) {\n      return hasNative(component, disableConfig) ? nativeIsDisabled(component) : ariaIsDisabled(component);\n    };\n    var set$7 = function (component, disableConfig, disableState, disabled) {\n      var f = disabled ? disable : enable;\n      f(component, disableConfig, disableState);\n    };\n\n    var DisableApis = /*#__PURE__*/Object.freeze({\n        enable: enable,\n        disable: disable,\n        isDisabled: isDisabled,\n        onLoad: onLoad$5,\n        set: set$7\n    });\n\n    var exhibit$4 = function (base, disableConfig, disableState) {\n      return nu$5({ classes: disableConfig.disabled ? disableConfig.disableClass.map(pure).getOr([]) : [] });\n    };\n    var events$7 = function (disableConfig, disableState) {\n      return derive([\n        abort(execute(), function (component, simulatedEvent) {\n          return isDisabled(component, disableConfig);\n        }),\n        loadEvent(disableConfig, disableState, onLoad$5)\n      ]);\n    };\n\n    var ActiveDisable = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$4,\n        events: events$7\n    });\n\n    var DisableSchema = [\n      defaulted$1('disabled', false),\n      defaulted$1('useNative', true),\n      option('disableClass'),\n      onHandler('onDisabled'),\n      onHandler('onEnabled')\n    ];\n\n    var Disabling = create$1({\n      fields: DisableSchema,\n      name: 'disabling',\n      active: ActiveDisable,\n      apis: DisableApis\n    });\n\n    var owner$1 = 'form';\n    var schema$9 = [field$1('formBehaviours', [Representing])];\n    var getPartName = function (name) {\n      return '<alloy.field.' + name + '>';\n    };\n    var sketch$5 = function (fSpec) {\n      var parts = function () {\n        var record = [];\n        var field = function (name, config) {\n          record.push(name);\n          return generateOne(owner$1, getPartName(name), config);\n        };\n        return {\n          field: field,\n          record: function () {\n            return record;\n          }\n        };\n      }();\n      var spec = fSpec(parts);\n      var partNames = parts.record();\n      var fieldParts = map$1(partNames, function (n) {\n        return required({\n          name: n,\n          pname: getPartName(n)\n        });\n      });\n      return composite(owner$1, schema$9, fieldParts, make, spec);\n    };\n    var toResult$1 = function (o, e) {\n      return o.fold(function () {\n        return Result.error(e);\n      }, Result.value);\n    };\n    var make = function (detail, components, spec) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: augment(detail.formBehaviours, [Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function (form) {\n                var resPs = getAllParts(form, detail);\n                return map(resPs, function (resPThunk, pName) {\n                  return resPThunk().bind(function (v) {\n                    var opt = Composing.getCurrent(v);\n                    return toResult$1(opt, 'missing current');\n                  }).map(Representing.getValue);\n                });\n              },\n              setValue: function (form, values) {\n                each(values, function (newValue, key) {\n                  getPart(form, detail, key).each(function (wrapper) {\n                    Composing.getCurrent(wrapper).each(function (field) {\n                      Representing.setValue(field, newValue);\n                    });\n                  });\n                });\n              }\n            }\n          })]),\n        apis: {\n          getField: function (form, key) {\n            return getPart(form, detail, key).bind(Composing.getCurrent);\n          }\n        }\n      };\n    };\n    var Form = {\n      getField: makeApi(function (apis, component, key) {\n        return apis.getField(component, key);\n      }),\n      sketch: sketch$5\n    };\n\n    var api$2 = function () {\n      var subject = Cell(Option.none());\n      var revoke = function () {\n        subject.get().each(function (s) {\n          s.destroy();\n        });\n      };\n      var clear = function () {\n        revoke();\n        subject.set(Option.none());\n      };\n      var set = function (s) {\n        revoke();\n        subject.set(Option.some(s));\n      };\n      var run = function (f) {\n        subject.get().each(f);\n      };\n      var isSet = function () {\n        return subject.get().isSome();\n      };\n      return {\n        clear: clear,\n        isSet: isSet,\n        set: set,\n        run: run\n      };\n    };\n    var value$2 = function () {\n      var subject = Cell(Option.none());\n      var clear = function () {\n        subject.set(Option.none());\n      };\n      var set = function (s) {\n        subject.set(Option.some(s));\n      };\n      var on = function (f) {\n        subject.get().each(f);\n      };\n      var isSet = function () {\n        return subject.get().isSome();\n      };\n      return {\n        clear: clear,\n        set: set,\n        isSet: isSet,\n        on: on\n      };\n    };\n\n    var SWIPING_LEFT = 1;\n    var SWIPING_RIGHT = -1;\n    var SWIPING_NONE = 0;\n    var init$2 = function (xValue) {\n      return {\n        xValue: xValue,\n        points: []\n      };\n    };\n    var move$1 = function (model, xValue) {\n      if (xValue === model.xValue) {\n        return model;\n      }\n      var currentDirection = xValue - model.xValue > 0 ? SWIPING_LEFT : SWIPING_RIGHT;\n      var newPoint = {\n        direction: currentDirection,\n        xValue: xValue\n      };\n      var priorPoints = function () {\n        if (model.points.length === 0) {\n          return [];\n        } else {\n          var prev = model.points[model.points.length - 1];\n          return prev.direction === currentDirection ? model.points.slice(0, model.points.length - 1) : model.points;\n        }\n      }();\n      return {\n        xValue: xValue,\n        points: priorPoints.concat([newPoint])\n      };\n    };\n    var complete = function (model) {\n      if (model.points.length === 0) {\n        return SWIPING_NONE;\n      } else {\n        var firstDirection = model.points[0].direction;\n        var lastDirection = model.points[model.points.length - 1].direction;\n        return firstDirection === SWIPING_RIGHT && lastDirection === SWIPING_RIGHT ? SWIPING_RIGHT : firstDirection === SWIPING_LEFT && lastDirection === SWIPING_LEFT ? SWIPING_LEFT : SWIPING_NONE;\n      }\n    };\n    var SwipingModel = {\n      init: init$2,\n      move: move$1,\n      complete: complete\n    };\n\n    var sketch$6 = function (rawSpec) {\n      var navigateEvent = 'navigateEvent';\n      var wrapperAdhocEvents = 'serializer-wrapper-events';\n      var formAdhocEvents = 'form-events';\n      var schema = objOf([\n        strict$1('fields'),\n        defaulted$1('maxFieldIndex', rawSpec.fields.length - 1),\n        strict$1('onExecute'),\n        strict$1('getInitialValue'),\n        state$1('state', function () {\n          return {\n            dialogSwipeState: value$2(),\n            currentScreen: Cell(0)\n          };\n        })\n      ]);\n      var spec$1 = asRawOrDie('SerialisedDialog', schema, rawSpec);\n      var navigationButton = function (direction, directionName, enabled) {\n        return Button.sketch({\n          dom: dom$1('<span class=\"${prefix}-icon-' + directionName + ' ${prefix}-icon\"></span>'),\n          action: function (button) {\n            emitWith(button, navigateEvent, { direction: direction });\n          },\n          buttonBehaviours: derive$1([Disabling.config({\n              disableClass: Styles.resolve('toolbar-navigation-disabled'),\n              disabled: !enabled\n            })])\n        });\n      };\n      var reposition = function (dialog, message) {\n        descendant$1(dialog.element(), '.' + Styles.resolve('serialised-dialog-chain')).each(function (parent) {\n          set$3(parent, 'left', -spec$1.state.currentScreen.get() * message.width + 'px');\n        });\n      };\n      var navigate = function (dialog, direction) {\n        var screens = descendants(dialog.element(), '.' + Styles.resolve('serialised-dialog-screen'));\n        descendant$1(dialog.element(), '.' + Styles.resolve('serialised-dialog-chain')).each(function (parent) {\n          if (spec$1.state.currentScreen.get() + direction >= 0 && spec$1.state.currentScreen.get() + direction < screens.length) {\n            getRaw(parent, 'left').each(function (left) {\n              var currentLeft = parseInt(left, 10);\n              var w = get$6(screens[0]);\n              set$3(parent, 'left', currentLeft - direction * w + 'px');\n            });\n            spec$1.state.currentScreen.set(spec$1.state.currentScreen.get() + direction);\n          }\n        });\n      };\n      var focusInput = function (dialog) {\n        var inputs = descendants(dialog.element(), 'input');\n        var optInput = Option.from(inputs[spec$1.state.currentScreen.get()]);\n        optInput.each(function (input) {\n          dialog.getSystem().getByDom(input).each(function (inputComp) {\n            dispatchFocus(dialog, inputComp.element());\n          });\n        });\n        var dotitems = memDots.get(dialog);\n        Highlighting.highlightAt(dotitems, spec$1.state.currentScreen.get());\n      };\n      var resetState = function () {\n        spec$1.state.currentScreen.set(0);\n        spec$1.state.dialogSwipeState.clear();\n      };\n      var memForm = record(Form.sketch(function (parts) {\n        return {\n          dom: dom$1('<div class=\"${prefix}-serialised-dialog\"></div>'),\n          components: [Container.sketch({\n              dom: dom$1('<div class=\"${prefix}-serialised-dialog-chain\" style=\"left: 0px; position: absolute;\"></div>'),\n              components: map$1(spec$1.fields, function (field, i) {\n                return i <= spec$1.maxFieldIndex ? Container.sketch({\n                  dom: dom$1('<div class=\"${prefix}-serialised-dialog-screen\"></div>'),\n                  components: [\n                    navigationButton(-1, 'previous', i > 0),\n                    parts.field(field.name, field.spec),\n                    navigationButton(+1, 'next', i < spec$1.maxFieldIndex)\n                  ]\n                }) : parts.field(field.name, field.spec);\n              })\n            })],\n          formBehaviours: derive$1([\n            Receivers.orientation(function (dialog, message) {\n              reposition(dialog, message);\n            }),\n            Keying.config({\n              mode: 'special',\n              focusIn: function (dialog) {\n                focusInput(dialog);\n              },\n              onTab: function (dialog) {\n                navigate(dialog, +1);\n                return Option.some(true);\n              },\n              onShiftTab: function (dialog) {\n                navigate(dialog, -1);\n                return Option.some(true);\n              }\n            }),\n            config(formAdhocEvents, [\n              runOnAttached(function (dialog, simulatedEvent) {\n                resetState();\n                var dotitems = memDots.get(dialog);\n                Highlighting.highlightFirst(dotitems);\n                spec$1.getInitialValue(dialog).each(function (v) {\n                  Representing.setValue(dialog, v);\n                });\n              }),\n              runOnExecute(spec$1.onExecute),\n              run(transitionend(), function (dialog, simulatedEvent) {\n                var event = simulatedEvent.event();\n                if (event.raw().propertyName === 'left') {\n                  focusInput(dialog);\n                }\n              }),\n              run(navigateEvent, function (dialog, simulatedEvent) {\n                var event = simulatedEvent.event();\n                var direction = event.direction();\n                navigate(dialog, direction);\n              })\n            ])\n          ])\n        };\n      }));\n      var memDots = record({\n        dom: dom$1('<div class=\"${prefix}-dot-container\"></div>'),\n        behaviours: derive$1([Highlighting.config({\n            highlightClass: Styles.resolve('dot-active'),\n            itemClass: Styles.resolve('dot-item')\n          })]),\n        components: bind(spec$1.fields, function (_f, i) {\n          return i <= spec$1.maxFieldIndex ? [spec('<div class=\"${prefix}-dot-item ${prefix}-icon-full-dot ${prefix}-icon\"></div>')] : [];\n        })\n      });\n      return {\n        dom: dom$1('<div class=\"${prefix}-serializer-wrapper\"></div>'),\n        components: [\n          memForm.asSpec(),\n          memDots.asSpec()\n        ],\n        behaviours: derive$1([\n          Keying.config({\n            mode: 'special',\n            focusIn: function (wrapper) {\n              var form = memForm.get(wrapper);\n              Keying.focusIn(form);\n            }\n          }),\n          config(wrapperAdhocEvents, [\n            run(touchstart(), function (wrapper, simulatedEvent) {\n              var event = simulatedEvent.event();\n              spec$1.state.dialogSwipeState.set(SwipingModel.init(event.raw().touches[0].clientX));\n            }),\n            run(touchmove(), function (wrapper, simulatedEvent) {\n              var event = simulatedEvent.event();\n              spec$1.state.dialogSwipeState.on(function (state) {\n                simulatedEvent.event().prevent();\n                spec$1.state.dialogSwipeState.set(SwipingModel.move(state, event.raw().touches[0].clientX));\n              });\n            }),\n            run(touchend(), function (wrapper) {\n              spec$1.state.dialogSwipeState.on(function (state) {\n                var dialog = memForm.get(wrapper);\n                var direction = -1 * SwipingModel.complete(state);\n                navigate(dialog, direction);\n              });\n            })\n          ])\n        ])\n      };\n    };\n\n    var getGroups = cached(function (realm, editor) {\n      return [{\n          label: 'the link group',\n          items: [sketch$6({\n              fields: [\n                field$2('url', 'Type or paste URL'),\n                field$2('text', 'Link text'),\n                field$2('title', 'Link title'),\n                field$2('target', 'Link target'),\n                hidden('link')\n              ],\n              maxFieldIndex: [\n                'url',\n                'text',\n                'title',\n                'target'\n              ].length - 1,\n              getInitialValue: function () {\n                return Option.some(LinkBridge.getInfo(editor));\n              },\n              onExecute: function (dialog) {\n                var info = Representing.getValue(dialog);\n                LinkBridge.applyInfo(editor, info);\n                realm.restoreToolbar();\n                editor.focus();\n              }\n            })]\n        }];\n    });\n    var sketch$7 = function (realm, editor) {\n      return Buttons.forToolbarStateAction(editor, 'link', 'link', function () {\n        var groups = getGroups(realm, editor);\n        realm.setContextToolbar(groups);\n        RangePreserver.forAndroid(editor, function () {\n          realm.focusToolbar();\n        });\n        LinkBridge.query(editor).each(function (link) {\n          editor.selection.select(link.dom());\n        });\n      });\n    };\n\n    var DefaultStyleFormats = [\n      {\n        title: 'Headings',\n        items: [\n          {\n            title: 'Heading 1',\n            format: 'h1'\n          },\n          {\n            title: 'Heading 2',\n            format: 'h2'\n          },\n          {\n            title: 'Heading 3',\n            format: 'h3'\n          },\n          {\n            title: 'Heading 4',\n            format: 'h4'\n          },\n          {\n            title: 'Heading 5',\n            format: 'h5'\n          },\n          {\n            title: 'Heading 6',\n            format: 'h6'\n          }\n        ]\n      },\n      {\n        title: 'Inline',\n        items: [\n          {\n            title: 'Bold',\n            icon: 'bold',\n            format: 'bold'\n          },\n          {\n            title: 'Italic',\n            icon: 'italic',\n            format: 'italic'\n          },\n          {\n            title: 'Underline',\n            icon: 'underline',\n            format: 'underline'\n          },\n          {\n            title: 'Strikethrough',\n            icon: 'strikethrough',\n            format: 'strikethrough'\n          },\n          {\n            title: 'Superscript',\n            icon: 'superscript',\n            format: 'superscript'\n          },\n          {\n            title: 'Subscript',\n            icon: 'subscript',\n            format: 'subscript'\n          },\n          {\n            title: 'Code',\n            icon: 'code',\n            format: 'code'\n          }\n        ]\n      },\n      {\n        title: 'Blocks',\n        items: [\n          {\n            title: 'Paragraph',\n            format: 'p'\n          },\n          {\n            title: 'Blockquote',\n            format: 'blockquote'\n          },\n          {\n            title: 'Div',\n            format: 'div'\n          },\n          {\n            title: 'Pre',\n            format: 'pre'\n          }\n        ]\n      },\n      {\n        title: 'Alignment',\n        items: [\n          {\n            title: 'Left',\n            icon: 'alignleft',\n            format: 'alignleft'\n          },\n          {\n            title: 'Center',\n            icon: 'aligncenter',\n            format: 'aligncenter'\n          },\n          {\n            title: 'Right',\n            icon: 'alignright',\n            format: 'alignright'\n          },\n          {\n            title: 'Justify',\n            icon: 'alignjustify',\n            format: 'alignjustify'\n          }\n        ]\n      }\n    ];\n\n    var isRecursive = function (component, originator, target) {\n      return eq(originator, component.element()) && !eq(originator, target);\n    };\n    var events$8 = derive([can(focus(), function (component, simulatedEvent) {\n        var originator = simulatedEvent.event().originator();\n        var target = simulatedEvent.event().target();\n        if (isRecursive(component, originator, target)) {\n          domGlobals.console.warn(focus() + ' did not get interpreted by the desired target. ' + '\\nOriginator: ' + element(originator) + '\\nTarget: ' + element(target) + '\\nCheck the ' + focus() + ' event handlers');\n          return false;\n        } else {\n          return true;\n        }\n      })]);\n\n    var DefaultEvents = /*#__PURE__*/Object.freeze({\n        events: events$8\n    });\n\n    var make$1 = identity;\n\n    var NoContextApi = function (getComp) {\n      var fail = function (event) {\n        return function () {\n          throw new Error('The component must be in a context to send: ' + event + '\\n' + element(getComp().element()) + ' is not in context.');\n        };\n      };\n      return {\n        debugInfo: constant('fake'),\n        triggerEvent: fail('triggerEvent'),\n        triggerFocus: fail('triggerFocus'),\n        triggerEscape: fail('triggerEscape'),\n        build: fail('build'),\n        addToWorld: fail('addToWorld'),\n        removeFromWorld: fail('removeFromWorld'),\n        addToGui: fail('addToGui'),\n        removeFromGui: fail('removeFromGui'),\n        getByUid: fail('getByUid'),\n        getByDom: fail('getByDom'),\n        broadcast: fail('broadcast'),\n        broadcastOn: fail('broadcastOn'),\n        broadcastEvent: fail('broadcastEvent'),\n        isConnected: constant(false)\n      };\n    };\n    var singleton = NoContextApi();\n\n    var generateFrom = function (spec, all) {\n      var schema = map$1(all, function (a) {\n        return optionObjOf(a.name(), [\n          strict$1('config'),\n          defaulted$1('state', NoState)\n        ]);\n      });\n      var validated = asRaw('component.behaviours', objOf(schema), spec.behaviours).fold(function (errInfo) {\n        throw new Error(formatError(errInfo) + '\\nComplete spec:\\n' + JSON.stringify(spec, null, 2));\n      }, function (v) {\n        return v;\n      });\n      return {\n        list: all,\n        data: map(validated, function (optBlobThunk) {\n          var optBlob = optBlobThunk;\n          var output = optBlob.map(function (blob) {\n            return {\n              config: blob.config,\n              state: blob.state.init(blob.config)\n            };\n          });\n          return function () {\n            return output;\n          };\n        })\n      };\n    };\n    var getBehaviours = function (bData) {\n      return bData.list;\n    };\n    var getData = function (bData) {\n      return bData.data;\n    };\n\n    var byInnerKey = function (data, tuple) {\n      var r = {};\n      each(data, function (detail, key) {\n        each(detail, function (value, indexKey) {\n          var chain = readOr$1(indexKey, [])(r);\n          r[indexKey] = chain.concat([tuple(key, value)]);\n        });\n      });\n      return r;\n    };\n\n    var combine$1 = function (info, baseMod, behaviours, base) {\n      var modsByBehaviour = __assign({}, baseMod);\n      each$1(behaviours, function (behaviour) {\n        modsByBehaviour[behaviour.name()] = behaviour.exhibit(info, base);\n      });\n      var nameAndMod = function (name, modification) {\n        return {\n          name: name,\n          modification: modification\n        };\n      };\n      var byAspect = byInnerKey(modsByBehaviour, nameAndMod);\n      var combineObjects = function (objects) {\n        return foldr(objects, function (b, a) {\n          return __assign(__assign({}, a.modification), b);\n        }, {});\n      };\n      var combinedClasses = foldr(byAspect.classes, function (b, a) {\n        return a.modification.concat(b);\n      }, []);\n      var combinedAttributes = combineObjects(byAspect.attributes);\n      var combinedStyles = combineObjects(byAspect.styles);\n      return nu$5({\n        classes: combinedClasses,\n        attributes: combinedAttributes,\n        styles: combinedStyles\n      });\n    };\n\n    var sortKeys = function (label, keyName, array, order) {\n      var sliced = array.slice(0);\n      try {\n        var sorted = sliced.sort(function (a, b) {\n          var aKey = a[keyName]();\n          var bKey = b[keyName]();\n          var aIndex = order.indexOf(aKey);\n          var bIndex = order.indexOf(bKey);\n          if (aIndex === -1) {\n            throw new Error('The ordering for ' + label + ' does not have an entry for ' + aKey + '.\\nOrder specified: ' + JSON.stringify(order, null, 2));\n          }\n          if (bIndex === -1) {\n            throw new Error('The ordering for ' + label + ' does not have an entry for ' + bKey + '.\\nOrder specified: ' + JSON.stringify(order, null, 2));\n          }\n          if (aIndex < bIndex) {\n            return -1;\n          } else if (bIndex < aIndex) {\n            return 1;\n          } else {\n            return 0;\n          }\n        });\n        return Result.value(sorted);\n      } catch (err) {\n        return Result.error([err]);\n      }\n    };\n\n    var uncurried = function (handler, purpose) {\n      return {\n        handler: handler,\n        purpose: constant(purpose)\n      };\n    };\n    var curried = function (handler, purpose) {\n      return {\n        cHandler: handler,\n        purpose: constant(purpose)\n      };\n    };\n    var curryArgs = function (descHandler, extraArgs) {\n      return curried(curry.apply(undefined, [descHandler.handler].concat(extraArgs)), descHandler.purpose());\n    };\n    var getCurried = function (descHandler) {\n      return descHandler.cHandler;\n    };\n\n    var behaviourTuple = function (name, handler) {\n      return {\n        name: constant(name),\n        handler: constant(handler)\n      };\n    };\n    var nameToHandlers = function (behaviours, info) {\n      var r = {};\n      each$1(behaviours, function (behaviour) {\n        r[behaviour.name()] = behaviour.handlers(info);\n      });\n      return r;\n    };\n    var groupByEvents = function (info, behaviours, base) {\n      var behaviourEvents = __assign(__assign({}, base), nameToHandlers(behaviours, info));\n      return byInnerKey(behaviourEvents, behaviourTuple);\n    };\n    var combine$2 = function (info, eventOrder, behaviours, base) {\n      var byEventName = groupByEvents(info, behaviours, base);\n      return combineGroups(byEventName, eventOrder);\n    };\n    var assemble = function (rawHandler) {\n      var handler = read(rawHandler);\n      return function (component, simulatedEvent) {\n        var rest = [];\n        for (var _i = 2; _i < arguments.length; _i++) {\n          rest[_i - 2] = arguments[_i];\n        }\n        var args = [\n          component,\n          simulatedEvent\n        ].concat(rest);\n        if (handler.abort.apply(undefined, args)) {\n          simulatedEvent.stop();\n        } else if (handler.can.apply(undefined, args)) {\n          handler.run.apply(undefined, args);\n        }\n      };\n    };\n    var missingOrderError = function (eventName, tuples) {\n      return Result.error(['The event (' + eventName + ') has more than one behaviour that listens to it.\\nWhen this occurs, you must ' + 'specify an event ordering for the behaviours in your spec (e.g. [ \"listing\", \"toggling\" ]).\\nThe behaviours that ' + 'can trigger it are: ' + JSON.stringify(map$1(tuples, function (c) {\n          return c.name();\n        }), null, 2)]);\n    };\n    var fuse$1 = function (tuples, eventOrder, eventName) {\n      var order = eventOrder[eventName];\n      if (!order) {\n        return missingOrderError(eventName, tuples);\n      } else {\n        return sortKeys('Event: ' + eventName, 'name', tuples, order).map(function (sortedTuples) {\n          var handlers = map$1(sortedTuples, function (tuple) {\n            return tuple.handler();\n          });\n          return fuse(handlers);\n        });\n      }\n    };\n    var combineGroups = function (byEventName, eventOrder) {\n      var r = mapToArray(byEventName, function (tuples, eventName) {\n        var combined = tuples.length === 1 ? Result.value(tuples[0].handler()) : fuse$1(tuples, eventOrder, eventName);\n        return combined.map(function (handler) {\n          var assembled = assemble(handler);\n          var purpose = tuples.length > 1 ? filter(eventOrder[eventName], function (o) {\n            return exists(tuples, function (t) {\n              return t.name() === o;\n            });\n          }).join(' > ') : tuples[0].name();\n          return wrap$1(eventName, uncurried(assembled, purpose));\n        });\n      });\n      return consolidate(r, {});\n    };\n\n    var toInfo = function (spec) {\n      return asRaw('custom.definition', objOf([\n        field('dom', 'dom', strict(), objOf([\n          strict$1('tag'),\n          defaulted$1('styles', {}),\n          defaulted$1('classes', []),\n          defaulted$1('attributes', {}),\n          option('value'),\n          option('innerHtml')\n        ])),\n        strict$1('components'),\n        strict$1('uid'),\n        defaulted$1('events', {}),\n        defaulted$1('apis', {}),\n        field('eventOrder', 'eventOrder', mergeWith({\n          'alloy.execute': [\n            'disabling',\n            'alloy.base.behaviour',\n            'toggling',\n            'typeaheadevents'\n          ],\n          'alloy.focus': [\n            'alloy.base.behaviour',\n            'focusing',\n            'keying'\n          ],\n          'alloy.system.init': [\n            'alloy.base.behaviour',\n            'disabling',\n            'toggling',\n            'representing'\n          ],\n          'input': [\n            'alloy.base.behaviour',\n            'representing',\n            'streaming',\n            'invalidating'\n          ],\n          'alloy.system.detached': [\n            'alloy.base.behaviour',\n            'representing',\n            'item-events',\n            'tooltipping'\n          ],\n          'mousedown': [\n            'focusing',\n            'alloy.base.behaviour',\n            'item-type-events'\n          ],\n          'touchstart': [\n            'focusing',\n            'alloy.base.behaviour',\n            'item-type-events'\n          ],\n          'mouseover': [\n            'item-type-events',\n            'tooltipping'\n          ]\n        }), anyValue$1()),\n        option('domModification')\n      ]), spec);\n    };\n    var toDefinition = function (detail) {\n      return __assign(__assign({}, detail.dom), {\n        uid: detail.uid,\n        domChildren: map$1(detail.components, function (comp) {\n          return comp.element();\n        })\n      });\n    };\n    var toModification = function (detail) {\n      return detail.domModification.fold(function () {\n        return nu$5({});\n      }, nu$5);\n    };\n    var toEvents = function (info) {\n      return info.events;\n    };\n\n    var add$3 = function (element, classes) {\n      each$1(classes, function (x) {\n        add$2(element, x);\n      });\n    };\n    var remove$6 = function (element, classes) {\n      each$1(classes, function (x) {\n        remove$4(element, x);\n      });\n    };\n\n    var renderToDom = function (definition) {\n      var subject = Element.fromTag(definition.tag);\n      setAll(subject, definition.attributes);\n      add$3(subject, definition.classes);\n      setAll$1(subject, definition.styles);\n      definition.innerHtml.each(function (html) {\n        return set$1(subject, html);\n      });\n      var children = definition.domChildren;\n      append$1(subject, children);\n      definition.value.each(function (value) {\n        set$6(subject, value);\n      });\n      if (!definition.uid) {\n        debugger;\n      }\n      writeOnly(subject, definition.uid);\n      return subject;\n    };\n\n    var getBehaviours$1 = function (spec) {\n      var behaviours = readOr$1('behaviours', {})(spec);\n      var keys$1 = filter(keys(behaviours), function (k) {\n        return behaviours[k] !== undefined;\n      });\n      return map$1(keys$1, function (k) {\n        return behaviours[k].me;\n      });\n    };\n    var generateFrom$1 = function (spec, all) {\n      return generateFrom(spec, all);\n    };\n    var generate$4 = function (spec) {\n      var all = getBehaviours$1(spec);\n      return generateFrom$1(spec, all);\n    };\n\n    var getDomDefinition = function (info, bList, bData) {\n      var definition = toDefinition(info);\n      var infoModification = toModification(info);\n      var baseModification = { 'alloy.base.modification': infoModification };\n      var modification = bList.length > 0 ? combine$1(bData, baseModification, bList, definition) : infoModification;\n      return merge$1(definition, modification);\n    };\n    var getEvents = function (info, bList, bData) {\n      var baseEvents = { 'alloy.base.behaviour': toEvents(info) };\n      return combine$2(bData, info.eventOrder, bList, baseEvents).getOrDie();\n    };\n    var build = function (spec) {\n      var getMe = function () {\n        return me;\n      };\n      var systemApi = Cell(singleton);\n      var info = getOrDie(toInfo(spec));\n      var bBlob = generate$4(spec);\n      var bList = getBehaviours(bBlob);\n      var bData = getData(bBlob);\n      var modDefinition = getDomDefinition(info, bList, bData);\n      var item = renderToDom(modDefinition);\n      var events = getEvents(info, bList, bData);\n      var subcomponents = Cell(info.components);\n      var connect = function (newApi) {\n        systemApi.set(newApi);\n      };\n      var disconnect = function () {\n        systemApi.set(NoContextApi(getMe));\n      };\n      var syncComponents = function () {\n        var children$1 = children(item);\n        var subs = bind(children$1, function (child) {\n          return systemApi.get().getByDom(child).fold(function () {\n            return [];\n          }, function (c) {\n            return [c];\n          });\n        });\n        subcomponents.set(subs);\n      };\n      var config = function (behaviour) {\n        var b = bData;\n        var f = isFunction(b[behaviour.name()]) ? b[behaviour.name()] : function () {\n          throw new Error('Could not find ' + behaviour.name() + ' in ' + JSON.stringify(spec, null, 2));\n        };\n        return f();\n      };\n      var hasConfigured = function (behaviour) {\n        return isFunction(bData[behaviour.name()]);\n      };\n      var getApis = function () {\n        return info.apis;\n      };\n      var readState = function (behaviourName) {\n        return bData[behaviourName]().map(function (b) {\n          return b.state.readState();\n        }).getOr('not enabled');\n      };\n      var me = {\n        getSystem: systemApi.get,\n        config: config,\n        hasConfigured: hasConfigured,\n        spec: constant(spec),\n        readState: readState,\n        getApis: getApis,\n        connect: connect,\n        disconnect: disconnect,\n        element: constant(item),\n        syncComponents: syncComponents,\n        components: subcomponents.get,\n        events: constant(events)\n      };\n      return me;\n    };\n\n    var buildSubcomponents = function (spec) {\n      var components = readOr$1('components', [])(spec);\n      return map$1(components, build$1);\n    };\n    var buildFromSpec = function (userSpec) {\n      var _a = make$1(userSpec), specEvents = _a.events, spec = __rest(_a, ['events']);\n      var components = buildSubcomponents(spec);\n      var completeSpec = __assign(__assign({}, spec), {\n        events: __assign(__assign({}, DefaultEvents), specEvents),\n        components: components\n      });\n      return Result.value(build(completeSpec));\n    };\n    var text = function (textContent) {\n      var element = Element.fromText(textContent);\n      return external({ element: element });\n    };\n    var external = function (spec) {\n      var extSpec = asRawOrDie('external.component', objOfOnly([\n        strict$1('element'),\n        option('uid')\n      ]), spec);\n      var systemApi = Cell(NoContextApi());\n      var connect = function (newApi) {\n        systemApi.set(newApi);\n      };\n      var disconnect = function () {\n        systemApi.set(NoContextApi(function () {\n          return me;\n        }));\n      };\n      extSpec.uid.each(function (uid) {\n        writeOnly(extSpec.element, uid);\n      });\n      var me = {\n        getSystem: systemApi.get,\n        config: Option.none,\n        hasConfigured: constant(false),\n        connect: connect,\n        disconnect: disconnect,\n        getApis: function () {\n          return {};\n        },\n        element: constant(extSpec.element),\n        spec: constant(spec),\n        readState: constant('No state'),\n        syncComponents: noop,\n        components: constant([]),\n        events: constant({})\n      };\n      return premade(me);\n    };\n    var uids = generate$3;\n    var build$1 = function (spec) {\n      return getPremade(spec).fold(function () {\n        var userSpecWithUid = spec.hasOwnProperty('uid') ? spec : __assign({ uid: uids('') }, spec);\n        return buildFromSpec(userSpecWithUid).getOrDie();\n      }, function (prebuilt) {\n        return prebuilt;\n      });\n    };\n    var premade$1 = premade;\n\n    var hoverEvent = 'alloy.item-hover';\n    var focusEvent = 'alloy.item-focus';\n    var onHover = function (item) {\n      if (search(item.element()).isNone() || Focusing.isFocused(item)) {\n        if (!Focusing.isFocused(item)) {\n          Focusing.focus(item);\n        }\n        emitWith(item, hoverEvent, { item: item });\n      }\n    };\n    var onFocus = function (item) {\n      emitWith(item, focusEvent, { item: item });\n    };\n    var hover = constant(hoverEvent);\n    var focus$3 = constant(focusEvent);\n\n    var builder = function (detail) {\n      return {\n        dom: detail.dom,\n        domModification: __assign(__assign({}, detail.domModification), { attributes: __assign(__assign(__assign({ 'role': detail.toggling.isSome() ? 'menuitemcheckbox' : 'menuitem' }, detail.domModification.attributes), { 'aria-haspopup': detail.hasSubmenu }), detail.hasSubmenu ? { 'aria-expanded': false } : {}) }),\n        behaviours: SketchBehaviours.augment(detail.itemBehaviours, [\n          detail.toggling.fold(Toggling.revoke, function (tConfig) {\n            return Toggling.config(__assign({ aria: { mode: 'checked' } }, tConfig));\n          }),\n          Focusing.config({\n            ignore: detail.ignoreFocus,\n            stopMousedown: detail.ignoreFocus,\n            onFocus: function (component) {\n              onFocus(component);\n            }\n          }),\n          Keying.config({ mode: 'execution' }),\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: detail.data\n            }\n          }),\n          config('item-type-events', __spreadArrays(pointerEvents(), [\n            run(mouseover(), onHover),\n            run(focusItem(), Focusing.focus)\n          ]))\n        ]),\n        components: detail.components,\n        eventOrder: detail.eventOrder\n      };\n    };\n    var schema$a = [\n      strict$1('data'),\n      strict$1('components'),\n      strict$1('dom'),\n      defaulted$1('hasSubmenu', false),\n      option('toggling'),\n      SketchBehaviours.field('itemBehaviours', [\n        Toggling,\n        Focusing,\n        Keying,\n        Representing\n      ]),\n      defaulted$1('ignoreFocus', false),\n      defaulted$1('domModification', {}),\n      output('builder', builder),\n      defaulted$1('eventOrder', {})\n    ];\n\n    var builder$1 = function (detail) {\n      return {\n        dom: detail.dom,\n        components: detail.components,\n        events: derive([stopper(focusItem())])\n      };\n    };\n    var schema$b = [\n      strict$1('dom'),\n      strict$1('components'),\n      output('builder', builder$1)\n    ];\n\n    var owner$2 = function () {\n      return 'item-widget';\n    };\n    var parts = constant([required({\n        name: 'widget',\n        overrides: function (detail) {\n          return {\n            behaviours: derive$1([Representing.config({\n                store: {\n                  mode: 'manual',\n                  getValue: function (component) {\n                    return detail.data;\n                  },\n                  setValue: function () {\n                  }\n                }\n              })])\n          };\n        }\n      })]);\n\n    var builder$2 = function (detail) {\n      var subs = substitutes(owner$2(), detail, parts());\n      var components$1 = components(owner$2(), detail, subs.internals());\n      var focusWidget = function (component) {\n        return getPart(component, detail, 'widget').map(function (widget) {\n          Keying.focusIn(widget);\n          return widget;\n        });\n      };\n      var onHorizontalArrow = function (component, simulatedEvent) {\n        return inside(simulatedEvent.event().target()) ? Option.none() : function () {\n          if (detail.autofocus) {\n            simulatedEvent.setSource(component.element());\n            return Option.none();\n          } else {\n            return Option.none();\n          }\n        }();\n      };\n      return {\n        dom: detail.dom,\n        components: components$1,\n        domModification: detail.domModification,\n        events: derive([\n          runOnExecute(function (component, simulatedEvent) {\n            focusWidget(component).each(function (widget) {\n              simulatedEvent.stop();\n            });\n          }),\n          run(mouseover(), onHover),\n          run(focusItem(), function (component, simulatedEvent) {\n            if (detail.autofocus) {\n              focusWidget(component);\n            } else {\n              Focusing.focus(component);\n            }\n          })\n        ]),\n        behaviours: SketchBehaviours.augment(detail.widgetBehaviours, [\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: detail.data\n            }\n          }),\n          Focusing.config({\n            ignore: detail.ignoreFocus,\n            onFocus: function (component) {\n              onFocus(component);\n            }\n          }),\n          Keying.config({\n            mode: 'special',\n            focusIn: detail.autofocus ? function (component) {\n              focusWidget(component);\n            } : revoke(),\n            onLeft: onHorizontalArrow,\n            onRight: onHorizontalArrow,\n            onEscape: function (component, simulatedEvent) {\n              if (!Focusing.isFocused(component) && !detail.autofocus) {\n                Focusing.focus(component);\n                return Option.some(true);\n              } else if (detail.autofocus) {\n                simulatedEvent.setSource(component.element());\n                return Option.none();\n              } else {\n                return Option.none();\n              }\n            }\n          })\n        ])\n      };\n    };\n    var schema$c = [\n      strict$1('uid'),\n      strict$1('data'),\n      strict$1('components'),\n      strict$1('dom'),\n      defaulted$1('autofocus', false),\n      defaulted$1('ignoreFocus', false),\n      SketchBehaviours.field('widgetBehaviours', [\n        Representing,\n        Focusing,\n        Keying\n      ]),\n      defaulted$1('domModification', {}),\n      defaultUidsSchema(parts()),\n      output('builder', builder$2)\n    ];\n\n    var itemSchema$1 = choose$1('type', {\n      widget: schema$c,\n      item: schema$a,\n      separator: schema$b\n    });\n    var configureGrid = function (detail, movementInfo) {\n      return {\n        mode: 'flatgrid',\n        selector: '.' + detail.markers.item,\n        initSize: {\n          numColumns: movementInfo.initSize.numColumns,\n          numRows: movementInfo.initSize.numRows\n        },\n        focusManager: detail.focusManager\n      };\n    };\n    var configureMatrix = function (detail, movementInfo) {\n      return {\n        mode: 'matrix',\n        selectors: {\n          row: movementInfo.rowSelector,\n          cell: '.' + detail.markers.item\n        },\n        focusManager: detail.focusManager\n      };\n    };\n    var configureMenu = function (detail, movementInfo) {\n      return {\n        mode: 'menu',\n        selector: '.' + detail.markers.item,\n        moveOnTab: movementInfo.moveOnTab,\n        focusManager: detail.focusManager\n      };\n    };\n    var parts$1 = constant([group({\n        factory: {\n          sketch: function (spec) {\n            var itemInfo = asRawOrDie('menu.spec item', itemSchema$1, spec);\n            return itemInfo.builder(itemInfo);\n          }\n        },\n        name: 'items',\n        unit: 'item',\n        defaults: function (detail, u) {\n          return u.hasOwnProperty('uid') ? u : __assign(__assign({}, u), { uid: generate$3('item') });\n        },\n        overrides: function (detail, u) {\n          return {\n            type: u.type,\n            ignoreFocus: detail.fakeFocus,\n            domModification: { classes: [detail.markers.item] }\n          };\n        }\n      })]);\n    var schema$d = constant([\n      strict$1('value'),\n      strict$1('items'),\n      strict$1('dom'),\n      strict$1('components'),\n      defaulted$1('eventOrder', {}),\n      field$1('menuBehaviours', [\n        Highlighting,\n        Representing,\n        Composing,\n        Keying\n      ]),\n      defaultedOf('movement', {\n        mode: 'menu',\n        moveOnTab: true\n      }, choose$1('mode', {\n        grid: [\n          initSize(),\n          output('config', configureGrid)\n        ],\n        matrix: [\n          output('config', configureMatrix),\n          strict$1('rowSelector')\n        ],\n        menu: [\n          defaulted$1('moveOnTab', true),\n          output('config', configureMenu)\n        ]\n      })),\n      itemMarkers(),\n      defaulted$1('fakeFocus', false),\n      defaulted$1('focusManager', dom()),\n      onHandler('onHighlight')\n    ]);\n\n    var focus$4 = constant('alloy.menu-focus');\n\n    var make$2 = function (detail, components, spec, externals) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        markers: detail.markers,\n        behaviours: augment(detail.menuBehaviours, [\n          Highlighting.config({\n            highlightClass: detail.markers.selectedItem,\n            itemClass: detail.markers.item,\n            onHighlight: detail.onHighlight\n          }),\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: detail.value\n            }\n          }),\n          Composing.config({ find: Option.some }),\n          Keying.config(detail.movement.config(detail, detail.movement))\n        ]),\n        events: derive([\n          run(focus$3(), function (menu, simulatedEvent) {\n            var event = simulatedEvent.event();\n            menu.getSystem().getByDom(event.target()).each(function (item) {\n              Highlighting.highlight(menu, item);\n              simulatedEvent.stop();\n              emitWith(menu, focus$4(), {\n                menu: menu,\n                item: item\n              });\n            });\n          }),\n          run(hover(), function (menu, simulatedEvent) {\n            var item = simulatedEvent.event().item();\n            Highlighting.highlight(menu, item);\n          })\n        ]),\n        components: components,\n        eventOrder: detail.eventOrder,\n        domModification: { attributes: { role: 'menu' } }\n      };\n    };\n\n    var Menu = composite$1({\n      name: 'Menu',\n      configFields: schema$d(),\n      partFields: parts$1(),\n      factory: make$2\n    });\n\n    var preserve$1 = function (f, container) {\n      var ownerDoc = owner(container);\n      var refocus = active(ownerDoc).bind(function (focused) {\n        var hasFocus = function (elem) {\n          return eq(focused, elem);\n        };\n        return hasFocus(container) ? Option.some(container) : descendant(container, hasFocus);\n      });\n      var result = f(container);\n      refocus.each(function (oldFocus) {\n        active(ownerDoc).filter(function (newFocus) {\n          return eq(newFocus, oldFocus);\n        }).fold(function () {\n          focus$1(oldFocus);\n        }, noop);\n      });\n      return result;\n    };\n\n    var set$8 = function (component, replaceConfig, replaceState, data) {\n      preserve$1(function () {\n        var newChildren = map$1(data, component.getSystem().build);\n        replaceChildren(component, newChildren);\n      }, component.element());\n    };\n    var insert = function (component, replaceConfig, insertion, childSpec) {\n      var child = component.getSystem().build(childSpec);\n      attachWith(component, child, insertion);\n    };\n    var append$2 = function (component, replaceConfig, replaceState, appendee) {\n      insert(component, replaceConfig, append, appendee);\n    };\n    var prepend$1 = function (component, replaceConfig, replaceState, prependee) {\n      insert(component, replaceConfig, prepend, prependee);\n    };\n    var remove$7 = function (component, replaceConfig, replaceState, removee) {\n      var children = contents(component);\n      var foundChild = find$2(children, function (child) {\n        return eq(removee.element(), child.element());\n      });\n      foundChild.each(detach);\n    };\n    var contents = function (component, replaceConfig) {\n      return component.components();\n    };\n    var replaceAt = function (component, replaceConfig, replaceState, replaceeIndex, replacer) {\n      var children = contents(component);\n      return Option.from(children[replaceeIndex]).map(function (replacee) {\n        remove$7(component, replaceConfig, replaceState, replacee);\n        replacer.each(function (r) {\n          insert(component, replaceConfig, function (p, c) {\n            appendAt(p, c, replaceeIndex);\n          }, r);\n        });\n        return replacee;\n      });\n    };\n    var replaceBy = function (component, replaceConfig, replaceState, replaceePred, replacer) {\n      var children = contents(component);\n      return findIndex(children, replaceePred).bind(function (replaceeIndex) {\n        return replaceAt(component, replaceConfig, replaceState, replaceeIndex, replacer);\n      });\n    };\n\n    var ReplaceApis = /*#__PURE__*/Object.freeze({\n        append: append$2,\n        prepend: prepend$1,\n        remove: remove$7,\n        replaceAt: replaceAt,\n        replaceBy: replaceBy,\n        set: set$8,\n        contents: contents\n    });\n\n    var Replacing = create$1({\n      fields: [],\n      name: 'replacing',\n      apis: ReplaceApis\n    });\n\n    var transpose = function (obj) {\n      return tupleMap(obj, function (v, k) {\n        return {\n          k: v,\n          v: k\n        };\n      });\n    };\n    var trace = function (items, byItem, byMenu, finish) {\n      return readOptFrom$1(byMenu, finish).bind(function (triggerItem) {\n        return readOptFrom$1(items, triggerItem).bind(function (triggerMenu) {\n          var rest = trace(items, byItem, byMenu, triggerMenu);\n          return Option.some([triggerMenu].concat(rest));\n        });\n      }).getOr([]);\n    };\n    var generate$5 = function (menus, expansions) {\n      var items = {};\n      each(menus, function (menuItems, menu) {\n        each$1(menuItems, function (item) {\n          items[item] = menu;\n        });\n      });\n      var byItem = expansions;\n      var byMenu = transpose(expansions);\n      var menuPaths = map(byMenu, function (_triggerItem, submenu) {\n        return [submenu].concat(trace(items, byItem, byMenu, submenu));\n      });\n      return map(items, function (menu) {\n        return readOptFrom$1(menuPaths, menu).getOr([menu]);\n      });\n    };\n\n    var init$3 = function () {\n      var expansions = Cell({});\n      var menus = Cell({});\n      var paths = Cell({});\n      var primary = Cell(Option.none());\n      var directory = Cell({});\n      var clear = function () {\n        expansions.set({});\n        menus.set({});\n        paths.set({});\n        primary.set(Option.none());\n      };\n      var isClear = function () {\n        return primary.get().isNone();\n      };\n      var setMenuBuilt = function (menuName, built) {\n        var _a;\n        menus.set(__assign(__assign({}, menus.get()), (_a = {}, _a[menuName] = {\n          type: 'prepared',\n          menu: built\n        }, _a)));\n      };\n      var setContents = function (sPrimary, sMenus, sExpansions, dir) {\n        primary.set(Option.some(sPrimary));\n        expansions.set(sExpansions);\n        menus.set(sMenus);\n        directory.set(dir);\n        var sPaths = generate$5(dir, sExpansions);\n        paths.set(sPaths);\n      };\n      var getTriggeringItem = function (menuValue) {\n        return find(expansions.get(), function (v, k) {\n          return v === menuValue;\n        });\n      };\n      var getTriggerData = function (menuValue, getItemByValue, path) {\n        return getPreparedMenu(menuValue).bind(function (menu) {\n          return getTriggeringItem(menuValue).bind(function (triggeringItemValue) {\n            return getItemByValue(triggeringItemValue).map(function (triggeredItem) {\n              return {\n                triggeredMenu: menu,\n                triggeringItem: triggeredItem,\n                triggeringPath: path\n              };\n            });\n          });\n        });\n      };\n      var getTriggeringPath = function (itemValue, getItemByValue) {\n        var extraPath = filter(lookupItem(itemValue).toArray(), function (menuValue) {\n          return getPreparedMenu(menuValue).isSome();\n        });\n        return readOptFrom$1(paths.get(), itemValue).bind(function (path) {\n          var revPath = reverse(extraPath.concat(path));\n          var triggers = bind(revPath, function (menuValue, menuIndex) {\n            return getTriggerData(menuValue, getItemByValue, revPath.slice(0, menuIndex + 1)).fold(function () {\n              return primary.get().is(menuValue) ? [] : [Option.none()];\n            }, function (data) {\n              return [Option.some(data)];\n            });\n          });\n          return sequence(triggers);\n        });\n      };\n      var expand = function (itemValue) {\n        return readOptFrom$1(expansions.get(), itemValue).map(function (menu) {\n          var current = readOptFrom$1(paths.get(), itemValue).getOr([]);\n          return [menu].concat(current);\n        });\n      };\n      var collapse = function (itemValue) {\n        return readOptFrom$1(paths.get(), itemValue).bind(function (path) {\n          return path.length > 1 ? Option.some(path.slice(1)) : Option.none();\n        });\n      };\n      var refresh = function (itemValue) {\n        return readOptFrom$1(paths.get(), itemValue);\n      };\n      var getPreparedMenu = function (menuValue) {\n        return lookupMenu(menuValue).bind(extractPreparedMenu);\n      };\n      var lookupMenu = function (menuValue) {\n        return readOptFrom$1(menus.get(), menuValue);\n      };\n      var lookupItem = function (itemValue) {\n        return readOptFrom$1(expansions.get(), itemValue);\n      };\n      var otherMenus = function (path) {\n        var menuValues = directory.get();\n        return difference(keys(menuValues), path);\n      };\n      var getPrimary = function () {\n        return primary.get().bind(getPreparedMenu);\n      };\n      var getMenus = function () {\n        return menus.get();\n      };\n      return {\n        setMenuBuilt: setMenuBuilt,\n        setContents: setContents,\n        expand: expand,\n        refresh: refresh,\n        collapse: collapse,\n        lookupMenu: lookupMenu,\n        lookupItem: lookupItem,\n        otherMenus: otherMenus,\n        getPrimary: getPrimary,\n        getMenus: getMenus,\n        clear: clear,\n        isClear: isClear,\n        getTriggeringPath: getTriggeringPath\n      };\n    };\n    var extractPreparedMenu = function (prep) {\n      return prep.type === 'prepared' ? Option.some(prep.menu) : Option.none();\n    };\n    var LayeredState = {\n      init: init$3,\n      extractPreparedMenu: extractPreparedMenu\n    };\n\n    var make$3 = function (detail, rawUiSpec) {\n      var submenuParentItems = Cell(Option.none());\n      var buildMenus = function (container, primaryName, menus) {\n        return map(menus, function (spec, name) {\n          var makeSketch = function () {\n            return Menu.sketch(__assign(__assign({ dom: spec.dom }, spec), {\n              value: name,\n              items: spec.items,\n              markers: detail.markers,\n              fakeFocus: detail.fakeFocus,\n              onHighlight: detail.onHighlight,\n              focusManager: detail.fakeFocus ? highlights() : dom()\n            }));\n          };\n          return name === primaryName ? {\n            type: 'prepared',\n            menu: container.getSystem().build(makeSketch())\n          } : {\n            type: 'notbuilt',\n            nbMenu: makeSketch\n          };\n        });\n      };\n      var layeredState = LayeredState.init();\n      var setup = function (container) {\n        var componentMap = buildMenus(container, detail.data.primary, detail.data.menus);\n        var directory = toDirectory();\n        layeredState.setContents(detail.data.primary, componentMap, detail.data.expansions, directory);\n        return layeredState.getPrimary();\n      };\n      var getItemValue = function (item) {\n        return Representing.getValue(item).value;\n      };\n      var getItemByValue = function (container, menus, itemValue) {\n        return findMap(menus, function (menu) {\n          if (!menu.getSystem().isConnected()) {\n            return Option.none();\n          }\n          var candidates = Highlighting.getCandidates(menu);\n          return find$2(candidates, function (c) {\n            return getItemValue(c) === itemValue;\n          });\n        });\n      };\n      var toDirectory = function (container) {\n        return map(detail.data.menus, function (data, menuName) {\n          return bind(data.items, function (item) {\n            return item.type === 'separator' ? [] : [item.data.value];\n          });\n        });\n      };\n      var setActiveMenu = function (container, menu) {\n        Highlighting.highlight(container, menu);\n        Highlighting.getHighlighted(menu).orThunk(function () {\n          return Highlighting.getFirst(menu);\n        }).each(function (item) {\n          dispatch(container, item.element(), focusItem());\n        });\n      };\n      var getMenus = function (state, menuValues) {\n        return cat(map$1(menuValues, function (mv) {\n          return state.lookupMenu(mv).bind(function (prep) {\n            return prep.type === 'prepared' ? Option.some(prep.menu) : Option.none();\n          });\n        }));\n      };\n      var closeOthers = function (container, state, path) {\n        var others = getMenus(state, state.otherMenus(path));\n        each$1(others, function (o) {\n          remove$6(o.element(), [detail.markers.backgroundMenu]);\n          if (!detail.stayInDom) {\n            Replacing.remove(container, o);\n          }\n        });\n      };\n      var getSubmenuParents = function (container) {\n        return submenuParentItems.get().getOrThunk(function () {\n          var r = {};\n          var items = descendants(container.element(), '.' + detail.markers.item);\n          var parentItems = filter(items, function (i) {\n            return get(i, 'aria-haspopup') === 'true';\n          });\n          each$1(parentItems, function (i) {\n            container.getSystem().getByDom(i).each(function (itemComp) {\n              var key = getItemValue(itemComp);\n              r[key] = itemComp;\n            });\n          });\n          submenuParentItems.set(Option.some(r));\n          return r;\n        });\n      };\n      var updateAriaExpansions = function (container, path) {\n        var parentItems = getSubmenuParents(container);\n        each(parentItems, function (v, k) {\n          var expanded = contains(path, k);\n          set(v.element(), 'aria-expanded', expanded);\n        });\n      };\n      var updateMenuPath = function (container, state, path) {\n        return Option.from(path[0]).bind(function (latestMenuName) {\n          return state.lookupMenu(latestMenuName).bind(function (menuPrep) {\n            if (menuPrep.type === 'notbuilt') {\n              return Option.none();\n            } else {\n              var activeMenu = menuPrep.menu;\n              var rest = getMenus(state, path.slice(1));\n              each$1(rest, function (r) {\n                add$2(r.element(), detail.markers.backgroundMenu);\n              });\n              if (!inBody(activeMenu.element())) {\n                Replacing.append(container, premade$1(activeMenu));\n              }\n              remove$6(activeMenu.element(), [detail.markers.backgroundMenu]);\n              setActiveMenu(container, activeMenu);\n              closeOthers(container, state, path);\n              return Option.some(activeMenu);\n            }\n          });\n        });\n      };\n      var ExpandHighlightDecision;\n      (function (ExpandHighlightDecision) {\n        ExpandHighlightDecision[ExpandHighlightDecision['HighlightSubmenu'] = 0] = 'HighlightSubmenu';\n        ExpandHighlightDecision[ExpandHighlightDecision['HighlightParent'] = 1] = 'HighlightParent';\n      }(ExpandHighlightDecision || (ExpandHighlightDecision = {})));\n      var buildIfRequired = function (container, menuName, menuPrep) {\n        if (menuPrep.type === 'notbuilt') {\n          var menu = container.getSystem().build(menuPrep.nbMenu());\n          layeredState.setMenuBuilt(menuName, menu);\n          return menu;\n        } else {\n          return menuPrep.menu;\n        }\n      };\n      var expandRight = function (container, item, decision) {\n        if (decision === void 0) {\n          decision = ExpandHighlightDecision.HighlightSubmenu;\n        }\n        var value = getItemValue(item);\n        return layeredState.expand(value).bind(function (path) {\n          updateAriaExpansions(container, path);\n          return Option.from(path[0]).bind(function (menuName) {\n            return layeredState.lookupMenu(menuName).bind(function (activeMenuPrep) {\n              var activeMenu = buildIfRequired(container, menuName, activeMenuPrep);\n              if (!inBody(activeMenu.element())) {\n                Replacing.append(container, premade$1(activeMenu));\n              }\n              detail.onOpenSubmenu(container, item, activeMenu, reverse(path));\n              if (decision === ExpandHighlightDecision.HighlightSubmenu) {\n                Highlighting.highlightFirst(activeMenu);\n                return updateMenuPath(container, layeredState, path);\n              } else {\n                Highlighting.dehighlightAll(activeMenu);\n                return Option.some(item);\n              }\n            });\n          });\n        });\n      };\n      var collapseLeft = function (container, item) {\n        var value = getItemValue(item);\n        return layeredState.collapse(value).bind(function (path) {\n          updateAriaExpansions(container, path);\n          return updateMenuPath(container, layeredState, path).map(function (activeMenu) {\n            detail.onCollapseMenu(container, item, activeMenu);\n            return activeMenu;\n          });\n        });\n      };\n      var updateView = function (container, item) {\n        var value = getItemValue(item);\n        return layeredState.refresh(value).bind(function (path) {\n          updateAriaExpansions(container, path);\n          return updateMenuPath(container, layeredState, path);\n        });\n      };\n      var onRight = function (container, item) {\n        return inside(item.element()) ? Option.none() : expandRight(container, item, ExpandHighlightDecision.HighlightSubmenu);\n      };\n      var onLeft = function (container, item) {\n        return inside(item.element()) ? Option.none() : collapseLeft(container, item);\n      };\n      var onEscape = function (container, item) {\n        return collapseLeft(container, item).orThunk(function () {\n          return detail.onEscape(container, item).map(function () {\n            return container;\n          });\n        });\n      };\n      var keyOnItem = function (f) {\n        return function (container, simulatedEvent) {\n          return closest$2(simulatedEvent.getSource(), '.' + detail.markers.item).bind(function (target) {\n            return container.getSystem().getByDom(target).toOption().bind(function (item) {\n              return f(container, item).map(function () {\n                return true;\n              });\n            });\n          });\n        };\n      };\n      var events = derive([\n        run(focus$4(), function (sandbox, simulatedEvent) {\n          var item = simulatedEvent.event().item();\n          layeredState.lookupItem(getItemValue(item)).each(function () {\n            var menu = simulatedEvent.event().menu();\n            Highlighting.highlight(sandbox, menu);\n            var value = getItemValue(simulatedEvent.event().item());\n            layeredState.refresh(value).each(function (path) {\n              return closeOthers(sandbox, layeredState, path);\n            });\n          });\n        }),\n        runOnExecute(function (component, simulatedEvent) {\n          var target = simulatedEvent.event().target();\n          component.getSystem().getByDom(target).each(function (item) {\n            var itemValue = getItemValue(item);\n            if (itemValue.indexOf('collapse-item') === 0) {\n              collapseLeft(component, item);\n            }\n            expandRight(component, item, ExpandHighlightDecision.HighlightSubmenu).fold(function () {\n              detail.onExecute(component, item);\n            }, function () {\n            });\n          });\n        }),\n        runOnAttached(function (container, simulatedEvent) {\n          setup(container).each(function (primary) {\n            Replacing.append(container, premade$1(primary));\n            detail.onOpenMenu(container, primary);\n            if (detail.highlightImmediately) {\n              setActiveMenu(container, primary);\n            }\n          });\n        })\n      ].concat(detail.navigateOnHover ? [run(hover(), function (sandbox, simulatedEvent) {\n          var item = simulatedEvent.event().item();\n          updateView(sandbox, item);\n          expandRight(sandbox, item, ExpandHighlightDecision.HighlightParent);\n          detail.onHover(sandbox, item);\n        })] : []));\n      var getActiveItem = function (container) {\n        return Highlighting.getHighlighted(container).bind(Highlighting.getHighlighted);\n      };\n      var collapseMenuApi = function (container) {\n        getActiveItem(container).each(function (currentItem) {\n          collapseLeft(container, currentItem);\n        });\n      };\n      var highlightPrimary = function (container) {\n        layeredState.getPrimary().each(function (primary) {\n          setActiveMenu(container, primary);\n        });\n      };\n      var extractMenuFromContainer = function (container) {\n        return Option.from(container.components()[0]).filter(function (comp) {\n          return get(comp.element(), 'role') === 'menu';\n        });\n      };\n      var repositionMenus = function (container) {\n        var maybeActivePrimary = layeredState.getPrimary().bind(function (primary) {\n          return getActiveItem(container).bind(function (currentItem) {\n            var itemValue = getItemValue(currentItem);\n            var allMenus = values(layeredState.getMenus());\n            var preparedMenus = cat(map$1(allMenus, LayeredState.extractPreparedMenu));\n            return layeredState.getTriggeringPath(itemValue, function (v) {\n              return getItemByValue(container, preparedMenus, v);\n            });\n          }).map(function (triggeringPath) {\n            return {\n              primary: primary,\n              triggeringPath: triggeringPath\n            };\n          });\n        });\n        maybeActivePrimary.fold(function () {\n          extractMenuFromContainer(container).each(function (primaryMenu) {\n            detail.onRepositionMenu(container, primaryMenu, []);\n          });\n        }, function (_a) {\n          var primary = _a.primary, triggeringPath = _a.triggeringPath;\n          detail.onRepositionMenu(container, primary, triggeringPath);\n        });\n      };\n      var apis = {\n        collapseMenu: collapseMenuApi,\n        highlightPrimary: highlightPrimary,\n        repositionMenus: repositionMenus\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        markers: detail.markers,\n        behaviours: augment(detail.tmenuBehaviours, [\n          Keying.config({\n            mode: 'special',\n            onRight: keyOnItem(onRight),\n            onLeft: keyOnItem(onLeft),\n            onEscape: keyOnItem(onEscape),\n            focusIn: function (container, keyInfo) {\n              layeredState.getPrimary().each(function (primary) {\n                dispatch(container, primary.element(), focusItem());\n              });\n            }\n          }),\n          Highlighting.config({\n            highlightClass: detail.markers.selectedMenu,\n            itemClass: detail.markers.menu\n          }),\n          Composing.config({\n            find: function (container) {\n              return Highlighting.getHighlighted(container);\n            }\n          }),\n          Replacing.config({})\n        ]),\n        eventOrder: detail.eventOrder,\n        apis: apis,\n        events: events\n      };\n    };\n    var collapseItem = constant('collapse-item');\n\n    var tieredData = function (primary, menus, expansions) {\n      return {\n        primary: primary,\n        menus: menus,\n        expansions: expansions\n      };\n    };\n    var singleData = function (name, menu) {\n      return {\n        primary: name,\n        menus: wrap$1(name, menu),\n        expansions: {}\n      };\n    };\n    var collapseItem$1 = function (text) {\n      return {\n        value: generate$1(collapseItem()),\n        meta: { text: text }\n      };\n    };\n    var tieredMenu = single$2({\n      name: 'TieredMenu',\n      configFields: [\n        onStrictKeyboardHandler('onExecute'),\n        onStrictKeyboardHandler('onEscape'),\n        onStrictHandler('onOpenMenu'),\n        onStrictHandler('onOpenSubmenu'),\n        onStrictHandler('onRepositionMenu'),\n        onHandler('onCollapseMenu'),\n        defaulted$1('highlightImmediately', true),\n        strictObjOf('data', [\n          strict$1('primary'),\n          strict$1('menus'),\n          strict$1('expansions')\n        ]),\n        defaulted$1('fakeFocus', false),\n        onHandler('onHighlight'),\n        onHandler('onHover'),\n        tieredMenuMarkers(),\n        strict$1('dom'),\n        defaulted$1('navigateOnHover', true),\n        defaulted$1('stayInDom', false),\n        field$1('tmenuBehaviours', [\n          Keying,\n          Highlighting,\n          Composing,\n          Replacing\n        ]),\n        defaulted$1('eventOrder', {})\n      ],\n      apis: {\n        collapseMenu: function (apis, tmenu) {\n          apis.collapseMenu(tmenu);\n        },\n        highlightPrimary: function (apis, tmenu) {\n          apis.highlightPrimary(tmenu);\n        },\n        repositionMenus: function (apis, tmenu) {\n          apis.repositionMenus(tmenu);\n        }\n      },\n      factory: make$3,\n      extraApis: {\n        tieredData: tieredData,\n        singleData: singleData,\n        collapseItem: collapseItem$1\n      }\n    });\n\n    var findRoute = function (component, transConfig, transState, route) {\n      return readOptFrom$1(transConfig.routes, route.start).bind(function (sConfig) {\n        return readOptFrom$1(sConfig, route.destination);\n      });\n    };\n    var getTransition = function (comp, transConfig, transState) {\n      var route = getCurrentRoute(comp, transConfig);\n      return route.bind(function (r) {\n        return getTransitionOf(comp, transConfig, transState, r);\n      });\n    };\n    var getTransitionOf = function (comp, transConfig, transState, route) {\n      return findRoute(comp, transConfig, transState, route).bind(function (r) {\n        return r.transition.map(function (t) {\n          return {\n            transition: t,\n            route: r\n          };\n        });\n      });\n    };\n    var disableTransition = function (comp, transConfig, transState) {\n      getTransition(comp, transConfig, transState).each(function (routeTransition) {\n        var t = routeTransition.transition;\n        remove$4(comp.element(), t.transitionClass);\n        remove$1(comp.element(), transConfig.destinationAttr);\n      });\n    };\n    var getNewRoute = function (comp, transConfig, transState, destination) {\n      return {\n        start: get(comp.element(), transConfig.stateAttr),\n        destination: destination\n      };\n    };\n    var getCurrentRoute = function (comp, transConfig, transState) {\n      var el = comp.element();\n      return has$1(el, transConfig.destinationAttr) ? Option.some({\n        start: get(comp.element(), transConfig.stateAttr),\n        destination: get(comp.element(), transConfig.destinationAttr)\n      }) : Option.none();\n    };\n    var jumpTo = function (comp, transConfig, transState, destination) {\n      disableTransition(comp, transConfig, transState);\n      if (has$1(comp.element(), transConfig.stateAttr) && get(comp.element(), transConfig.stateAttr) !== destination) {\n        transConfig.onFinish(comp, destination);\n      }\n      set(comp.element(), transConfig.stateAttr, destination);\n    };\n    var fasttrack = function (comp, transConfig, transState, destination) {\n      if (has$1(comp.element(), transConfig.destinationAttr)) {\n        set(comp.element(), transConfig.stateAttr, get(comp.element(), transConfig.destinationAttr));\n        remove$1(comp.element(), transConfig.destinationAttr);\n      }\n    };\n    var progressTo = function (comp, transConfig, transState, destination) {\n      fasttrack(comp, transConfig);\n      var route = getNewRoute(comp, transConfig, transState, destination);\n      getTransitionOf(comp, transConfig, transState, route).fold(function () {\n        jumpTo(comp, transConfig, transState, destination);\n      }, function (routeTransition) {\n        disableTransition(comp, transConfig, transState);\n        var t = routeTransition.transition;\n        add$2(comp.element(), t.transitionClass);\n        set(comp.element(), transConfig.destinationAttr, destination);\n      });\n    };\n    var getState$1 = function (comp, transConfig, transState) {\n      var e = comp.element();\n      return has$1(e, transConfig.stateAttr) ? Option.some(get(e, transConfig.stateAttr)) : Option.none();\n    };\n\n    var TransitionApis = /*#__PURE__*/Object.freeze({\n        findRoute: findRoute,\n        disableTransition: disableTransition,\n        getCurrentRoute: getCurrentRoute,\n        jumpTo: jumpTo,\n        progressTo: progressTo,\n        getState: getState$1\n    });\n\n    var events$9 = function (transConfig, transState) {\n      return derive([\n        run(transitionend(), function (component, simulatedEvent) {\n          var raw = simulatedEvent.event().raw();\n          getCurrentRoute(component, transConfig).each(function (route) {\n            findRoute(component, transConfig, transState, route).each(function (rInfo) {\n              rInfo.transition.each(function (rTransition) {\n                if (raw.propertyName === rTransition.property) {\n                  jumpTo(component, transConfig, transState, route.destination);\n                  transConfig.onTransition(component, route);\n                }\n              });\n            });\n          });\n        }),\n        runOnAttached(function (comp, se) {\n          jumpTo(comp, transConfig, transState, transConfig.initialState);\n        })\n      ]);\n    };\n\n    var ActiveTransitioning = /*#__PURE__*/Object.freeze({\n        events: events$9\n    });\n\n    var TransitionSchema = [\n      defaulted$1('destinationAttr', 'data-transitioning-destination'),\n      defaulted$1('stateAttr', 'data-transitioning-state'),\n      strict$1('initialState'),\n      onHandler('onTransition'),\n      onHandler('onFinish'),\n      strictOf('routes', setOf$1(Result.value, setOf$1(Result.value, objOfOnly([optionObjOfOnly('transition', [\n          strict$1('property'),\n          strict$1('transitionClass')\n        ])]))))\n    ];\n\n    var createRoutes = function (routes) {\n      var r = {};\n      each(routes, function (v, k) {\n        var waypoints = k.split('<->');\n        r[waypoints[0]] = wrap$1(waypoints[1], v);\n        r[waypoints[1]] = wrap$1(waypoints[0], v);\n      });\n      return r;\n    };\n    var createBistate = function (first, second, transitions) {\n      return wrapAll$1([\n        {\n          key: first,\n          value: wrap$1(second, transitions)\n        },\n        {\n          key: second,\n          value: wrap$1(first, transitions)\n        }\n      ]);\n    };\n    var createTristate = function (first, second, third, transitions) {\n      return wrapAll$1([\n        {\n          key: first,\n          value: wrapAll$1([\n            {\n              key: second,\n              value: transitions\n            },\n            {\n              key: third,\n              value: transitions\n            }\n          ])\n        },\n        {\n          key: second,\n          value: wrapAll$1([\n            {\n              key: first,\n              value: transitions\n            },\n            {\n              key: third,\n              value: transitions\n            }\n          ])\n        },\n        {\n          key: third,\n          value: wrapAll$1([\n            {\n              key: first,\n              value: transitions\n            },\n            {\n              key: second,\n              value: transitions\n            }\n          ])\n        }\n      ]);\n    };\n    var Transitioning = create$1({\n      fields: TransitionSchema,\n      name: 'transitioning',\n      active: ActiveTransitioning,\n      apis: TransitionApis,\n      extra: {\n        createRoutes: createRoutes,\n        createBistate: createBistate,\n        createTristate: createTristate\n      }\n    });\n\n    var scrollable = Styles.resolve('scrollable');\n    var register = function (element) {\n      add$2(element, scrollable);\n    };\n    var deregister = function (element) {\n      remove$4(element, scrollable);\n    };\n    var Scrollable = {\n      register: register,\n      deregister: deregister,\n      scrollable: constant(scrollable)\n    };\n\n    var getValue$4 = function (item) {\n      return readOptFrom$1(item, 'format').getOr(item.title);\n    };\n    var convert$1 = function (formats, memMenuThunk) {\n      var mainMenu = makeMenu('Styles', [].concat(map$1(formats.items, function (k) {\n        return makeItem(getValue$4(k), k.title, k.isSelected(), k.getPreview(), hasKey$1(formats.expansions, getValue$4(k)));\n      })), memMenuThunk, false);\n      var submenus = map(formats.menus, function (menuItems, menuName) {\n        var items = map$1(menuItems, function (item) {\n          return makeItem(getValue$4(item), item.title, item.isSelected !== undefined ? item.isSelected() : false, item.getPreview !== undefined ? item.getPreview() : '', hasKey$1(formats.expansions, getValue$4(item)));\n        });\n        return makeMenu(menuName, items, memMenuThunk, true);\n      });\n      var menus = deepMerge(submenus, wrap$1('styles', mainMenu));\n      var tmenu = tieredMenu.tieredData('styles', menus, formats.expansions);\n      return { tmenu: tmenu };\n    };\n    var makeItem = function (value, text, selected, preview, isMenu) {\n      return {\n        data: {\n          value: value,\n          text: text\n        },\n        type: 'item',\n        dom: {\n          tag: 'div',\n          classes: isMenu ? [Styles.resolve('styles-item-is-menu')] : []\n        },\n        toggling: {\n          toggleOnExecute: false,\n          toggleClass: Styles.resolve('format-matches'),\n          selected: selected\n        },\n        itemBehaviours: derive$1(isMenu ? [] : [Receivers.format(value, function (comp, status) {\n            var toggle = status ? Toggling.on : Toggling.off;\n            toggle(comp);\n          })]),\n        components: [{\n            dom: {\n              tag: 'div',\n              attributes: { style: preview },\n              innerHtml: text\n            }\n          }]\n      };\n    };\n    var makeMenu = function (value, items, memMenuThunk, collapsable) {\n      return {\n        value: value,\n        dom: { tag: 'div' },\n        components: [\n          Button.sketch({\n            dom: {\n              tag: 'div',\n              classes: [Styles.resolve('styles-collapser')]\n            },\n            components: collapsable ? [\n              {\n                dom: {\n                  tag: 'span',\n                  classes: [Styles.resolve('styles-collapse-icon')]\n                }\n              },\n              text(value)\n            ] : [text(value)],\n            action: function (item) {\n              if (collapsable) {\n                var comp = memMenuThunk().get(item);\n                tieredMenu.collapseMenu(comp);\n              }\n            }\n          }),\n          {\n            dom: {\n              tag: 'div',\n              classes: [Styles.resolve('styles-menu-items-container')]\n            },\n            components: [Menu.parts().items({})],\n            behaviours: derive$1([config('adhoc-scrollable-menu', [\n                runOnAttached(function (component, simulatedEvent) {\n                  set$3(component.element(), 'overflow-y', 'auto');\n                  set$3(component.element(), '-webkit-overflow-scrolling', 'touch');\n                  Scrollable.register(component.element());\n                }),\n                runOnDetached(function (component) {\n                  remove$5(component.element(), 'overflow-y');\n                  remove$5(component.element(), '-webkit-overflow-scrolling');\n                  Scrollable.deregister(component.element());\n                })\n              ])])\n          }\n        ],\n        items: items,\n        menuBehaviours: derive$1([Transitioning.config({\n            initialState: 'after',\n            routes: Transitioning.createTristate('before', 'current', 'after', {\n              transition: {\n                property: 'transform',\n                transitionClass: 'transitioning'\n              }\n            })\n          })])\n      };\n    };\n    var sketch$8 = function (settings) {\n      var dataset = convert$1(settings.formats, function () {\n        return memMenu;\n      });\n      var memMenu = record(tieredMenu.sketch({\n        dom: {\n          tag: 'div',\n          classes: [Styles.resolve('styles-menu')]\n        },\n        components: [],\n        fakeFocus: true,\n        stayInDom: true,\n        onExecute: function (tmenu, item) {\n          var v = Representing.getValue(item);\n          settings.handle(item, v.value);\n          return Option.none();\n        },\n        onEscape: function () {\n          return Option.none();\n        },\n        onOpenMenu: function (container, menu) {\n          var w = get$6(container.element());\n          set$4(menu.element(), w);\n          Transitioning.jumpTo(menu, 'current');\n        },\n        onOpenSubmenu: function (container, item, submenu) {\n          var w = get$6(container.element());\n          var menu = ancestor$1(item.element(), '[role=\"menu\"]').getOrDie('hacky');\n          var menuComp = container.getSystem().getByDom(menu).getOrDie();\n          set$4(submenu.element(), w);\n          Transitioning.progressTo(menuComp, 'before');\n          Transitioning.jumpTo(submenu, 'after');\n          Transitioning.progressTo(submenu, 'current');\n        },\n        onCollapseMenu: function (container, item, menu) {\n          var submenu = ancestor$1(item.element(), '[role=\"menu\"]').getOrDie('hacky');\n          var submenuComp = container.getSystem().getByDom(submenu).getOrDie();\n          Transitioning.progressTo(submenuComp, 'after');\n          Transitioning.progressTo(menu, 'current');\n        },\n        navigateOnHover: false,\n        highlightImmediately: true,\n        data: dataset.tmenu,\n        markers: {\n          backgroundMenu: Styles.resolve('styles-background-menu'),\n          menu: Styles.resolve('styles-menu'),\n          selectedMenu: Styles.resolve('styles-selected-menu'),\n          item: Styles.resolve('styles-item'),\n          selectedItem: Styles.resolve('styles-selected-item')\n        }\n      }));\n      return memMenu.asSpec();\n    };\n    var StylesMenu = { sketch: sketch$8 };\n\n    var getFromExpandingItem = function (item) {\n      var newItem = deepMerge(exclude$1(item, ['items']), { menu: true });\n      var rest = expand(item.items);\n      var newMenus = deepMerge(rest.menus, wrap$1(item.title, rest.items));\n      var newExpansions = deepMerge(rest.expansions, wrap$1(item.title, item.title));\n      return {\n        item: newItem,\n        menus: newMenus,\n        expansions: newExpansions\n      };\n    };\n    var getFromItem = function (item) {\n      return hasKey$1(item, 'items') ? getFromExpandingItem(item) : {\n        item: item,\n        menus: {},\n        expansions: {}\n      };\n    };\n    var expand = function (items) {\n      return foldr(items, function (acc, item) {\n        var newData = getFromItem(item);\n        return {\n          menus: deepMerge(acc.menus, newData.menus),\n          items: [newData.item].concat(acc.items),\n          expansions: deepMerge(acc.expansions, newData.expansions)\n        };\n      }, {\n        menus: {},\n        expansions: {},\n        items: []\n      });\n    };\n    var StyleConversions = { expand: expand };\n\n    var register$1 = function (editor, settings) {\n      var isSelectedFor = function (format) {\n        return function () {\n          return editor.formatter.match(format);\n        };\n      };\n      var getPreview = function (format) {\n        return function () {\n          var styles = editor.formatter.getCssText(format);\n          return styles;\n        };\n      };\n      var enrichSupported = function (item) {\n        return deepMerge(item, {\n          isSelected: isSelectedFor(item.format),\n          getPreview: getPreview(item.format)\n        });\n      };\n      var enrichMenu = function (item) {\n        return deepMerge(item, {\n          isSelected: constant(false),\n          getPreview: constant('')\n        });\n      };\n      var enrichCustom = function (item) {\n        var formatName = generate$1(item.title);\n        var newItem = deepMerge(item, {\n          format: formatName,\n          isSelected: isSelectedFor(formatName),\n          getPreview: getPreview(formatName)\n        });\n        editor.formatter.register(formatName, newItem);\n        return newItem;\n      };\n      var formats = readOptFrom$1(settings, 'style_formats').getOr(DefaultStyleFormats);\n      var doEnrich = function (items) {\n        return map$1(items, function (item) {\n          if (hasKey$1(item, 'items')) {\n            var newItems = doEnrich(item.items);\n            return deepMerge(enrichMenu(item), { items: newItems });\n          } else if (hasKey$1(item, 'format')) {\n            return enrichSupported(item);\n          } else {\n            return enrichCustom(item);\n          }\n        });\n      };\n      return doEnrich(formats);\n    };\n    var prune = function (editor, formats) {\n      var doPrune = function (items) {\n        return bind(items, function (item) {\n          if (item.items !== undefined) {\n            var newItems = doPrune(item.items);\n            return newItems.length > 0 ? [item] : [];\n          } else {\n            var keep = hasKey$1(item, 'format') ? editor.formatter.canApply(item.format) : true;\n            return keep ? [item] : [];\n          }\n        });\n      };\n      var prunedItems = doPrune(formats);\n      return StyleConversions.expand(prunedItems);\n    };\n    var ui = function (editor, formats, onDone) {\n      var pruned = prune(editor, formats);\n      return StylesMenu.sketch({\n        formats: pruned,\n        handle: function (item, value) {\n          editor.undoManager.transact(function () {\n            if (Toggling.isOn(item)) {\n              editor.formatter.remove(value);\n            } else {\n              editor.formatter.apply(value);\n            }\n          });\n          onDone();\n        }\n      });\n    };\n    var StyleFormats = {\n      register: register$1,\n      ui: ui\n    };\n\n    var defaults = [\n      'undo',\n      'bold',\n      'italic',\n      'link',\n      'image',\n      'bullist',\n      'styleselect'\n    ];\n    var extract$1 = function (rawToolbar) {\n      var toolbar = rawToolbar.replace(/\\|/g, ' ').trim();\n      return toolbar.length > 0 ? toolbar.split(/\\s+/) : [];\n    };\n    var identifyFromArray = function (toolbar) {\n      return bind(toolbar, function (item) {\n        return isArray(item) ? identifyFromArray(item) : extract$1(item);\n      });\n    };\n    var identify = function (settings) {\n      var toolbar = settings.toolbar !== undefined ? settings.toolbar : defaults;\n      return isArray(toolbar) ? identifyFromArray(toolbar) : extract$1(toolbar);\n    };\n    var setup = function (realm, editor) {\n      var commandSketch = function (name) {\n        return function () {\n          return Buttons.forToolbarCommand(editor, name);\n        };\n      };\n      var stateCommandSketch = function (name) {\n        return function () {\n          return Buttons.forToolbarStateCommand(editor, name);\n        };\n      };\n      var actionSketch = function (name, query, action) {\n        return function () {\n          return Buttons.forToolbarStateAction(editor, name, query, action);\n        };\n      };\n      var undo = commandSketch('undo');\n      var redo = commandSketch('redo');\n      var bold = stateCommandSketch('bold');\n      var italic = stateCommandSketch('italic');\n      var underline = stateCommandSketch('underline');\n      var removeformat = commandSketch('removeformat');\n      var link = function () {\n        return sketch$7(realm, editor);\n      };\n      var unlink = actionSketch('unlink', 'link', function () {\n        editor.execCommand('unlink', null, false);\n      });\n      var image = function () {\n        return sketch$4(editor);\n      };\n      var bullist = actionSketch('unordered-list', 'ul', function () {\n        editor.execCommand('InsertUnorderedList', null, false);\n      });\n      var numlist = actionSketch('ordered-list', 'ol', function () {\n        editor.execCommand('InsertOrderedList', null, false);\n      });\n      var fontsizeselect = function () {\n        return sketch$3(realm, editor);\n      };\n      var forecolor = function () {\n        return ColorSlider.sketch(realm, editor);\n      };\n      var styleFormats = StyleFormats.register(editor, editor.settings);\n      var styleFormatsMenu = function () {\n        return StyleFormats.ui(editor, styleFormats, function () {\n          editor.fire('scrollIntoView');\n        });\n      };\n      var styleselect = function () {\n        return Buttons.forToolbar('style-formats', function (button) {\n          editor.fire('toReading');\n          realm.dropup().appear(styleFormatsMenu, Toggling.on, button);\n        }, derive$1([\n          Toggling.config({\n            toggleClass: Styles.resolve('toolbar-button-selected'),\n            toggleOnExecute: false,\n            aria: { mode: 'pressed' }\n          }),\n          Receiving.config({\n            channels: wrapAll$1([\n              Receivers.receive(TinyChannels.orientationChanged(), Toggling.off),\n              Receivers.receive(TinyChannels.dropupDismissed(), Toggling.off)\n            ])\n          })\n        ]), editor);\n      };\n      var feature = function (prereq, sketch) {\n        return {\n          isSupported: function () {\n            var buttons = editor.ui.registry.getAll().buttons;\n            return prereq.forall(function (p) {\n              return hasKey$1(buttons, p);\n            });\n          },\n          sketch: sketch\n        };\n      };\n      return {\n        undo: feature(Option.none(), undo),\n        redo: feature(Option.none(), redo),\n        bold: feature(Option.none(), bold),\n        italic: feature(Option.none(), italic),\n        underline: feature(Option.none(), underline),\n        removeformat: feature(Option.none(), removeformat),\n        link: feature(Option.none(), link),\n        unlink: feature(Option.none(), unlink),\n        image: feature(Option.none(), image),\n        bullist: feature(Option.some('bullist'), bullist),\n        numlist: feature(Option.some('numlist'), numlist),\n        fontsizeselect: feature(Option.none(), fontsizeselect),\n        forecolor: feature(Option.none(), forecolor),\n        styleselect: feature(Option.none(), styleselect)\n      };\n    };\n    var detect$4 = function (settings, features) {\n      var itemNames = identify(settings);\n      var present = {};\n      return bind(itemNames, function (iName) {\n        var r = !hasKey$1(present, iName) && hasKey$1(features, iName) && features[iName].isSupported() ? [features[iName].sketch()] : [];\n        present[iName] = true;\n        return r;\n      });\n    };\n    var Features = {\n      identify: identify,\n      setup: setup,\n      detect: detect$4\n    };\n\n    var mkEvent = function (target, x, y, stop, prevent, kill, raw) {\n      return {\n        target: constant(target),\n        x: constant(x),\n        y: constant(y),\n        stop: stop,\n        prevent: prevent,\n        kill: kill,\n        raw: constant(raw)\n      };\n    };\n    var fromRawEvent = function (rawEvent) {\n      var target = Element.fromDom(rawEvent.target);\n      var stop = function () {\n        rawEvent.stopPropagation();\n      };\n      var prevent = function () {\n        rawEvent.preventDefault();\n      };\n      var kill = compose(prevent, stop);\n      return mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent);\n    };\n    var handle = function (filter, handler) {\n      return function (rawEvent) {\n        if (!filter(rawEvent)) {\n          return;\n        }\n        handler(fromRawEvent(rawEvent));\n      };\n    };\n    var binder = function (element, event, filter, handler, useCapture) {\n      var wrapped = handle(filter, handler);\n      element.dom().addEventListener(event, wrapped, useCapture);\n      return { unbind: curry(unbind, element, event, wrapped, useCapture) };\n    };\n    var bind$2 = function (element, event, filter, handler) {\n      return binder(element, event, filter, handler, false);\n    };\n    var capture = function (element, event, filter, handler) {\n      return binder(element, event, filter, handler, true);\n    };\n    var unbind = function (element, event, handler, useCapture) {\n      element.dom().removeEventListener(event, handler, useCapture);\n    };\n\n    var filter$1 = constant(true);\n    var bind$3 = function (element, event, handler) {\n      return bind$2(element, event, filter$1, handler);\n    };\n    var capture$1 = function (element, event, handler) {\n      return capture(element, event, filter$1, handler);\n    };\n\n    var global$4 = tinymce.util.Tools.resolve('tinymce.util.Delay');\n\n    var INTERVAL = 50;\n    var INSURANCE = 1000 / INTERVAL;\n    var get$a = function (outerWindow) {\n      var isPortrait = outerWindow.matchMedia('(orientation: portrait)').matches;\n      return { isPortrait: constant(isPortrait) };\n    };\n    var getActualWidth = function (outerWindow) {\n      var isIos = detect$3().os.isiOS();\n      var isPortrait = get$a(outerWindow).isPortrait();\n      return isIos && !isPortrait ? outerWindow.screen.height : outerWindow.screen.width;\n    };\n    var onChange = function (outerWindow, listeners) {\n      var win = Element.fromDom(outerWindow);\n      var poller = null;\n      var change = function () {\n        global$4.clearInterval(poller);\n        var orientation = get$a(outerWindow);\n        listeners.onChange(orientation);\n        onAdjustment(function () {\n          listeners.onReady(orientation);\n        });\n      };\n      var orientationHandle = bind$3(win, 'orientationchange', change);\n      var onAdjustment = function (f) {\n        global$4.clearInterval(poller);\n        var flag = outerWindow.innerHeight;\n        var insurance = 0;\n        poller = global$4.setInterval(function () {\n          if (flag !== outerWindow.innerHeight) {\n            global$4.clearInterval(poller);\n            f(Option.some(outerWindow.innerHeight));\n          } else if (insurance > INSURANCE) {\n            global$4.clearInterval(poller);\n            f(Option.none());\n          }\n          insurance++;\n        }, INTERVAL);\n      };\n      var destroy = function () {\n        orientationHandle.unbind();\n      };\n      return {\n        onAdjustment: onAdjustment,\n        destroy: destroy\n      };\n    };\n    var Orientation = {\n      get: get$a,\n      onChange: onChange,\n      getActualWidth: getActualWidth\n    };\n\n    function DelayedFunction (fun, delay) {\n      var ref = null;\n      var schedule = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        ref = domGlobals.setTimeout(function () {\n          fun.apply(null, args);\n          ref = null;\n        }, delay);\n      };\n      var cancel = function () {\n        if (ref !== null) {\n          domGlobals.clearTimeout(ref);\n          ref = null;\n        }\n      };\n      return {\n        cancel: cancel,\n        schedule: schedule\n      };\n    }\n\n    var SIGNIFICANT_MOVE = 5;\n    var LONGPRESS_DELAY = 400;\n    var getTouch = function (event) {\n      var raw = event.raw();\n      if (raw.touches === undefined || raw.touches.length !== 1) {\n        return Option.none();\n      }\n      return Option.some(raw.touches[0]);\n    };\n    var isFarEnough = function (touch, data) {\n      var distX = Math.abs(touch.clientX - data.x());\n      var distY = Math.abs(touch.clientY - data.y());\n      return distX > SIGNIFICANT_MOVE || distY > SIGNIFICANT_MOVE;\n    };\n    var monitor = function (settings) {\n      var startData = Cell(Option.none());\n      var longpressFired = Cell(false);\n      var longpress$1 = DelayedFunction(function (event) {\n        settings.triggerEvent(longpress(), event);\n        longpressFired.set(true);\n      }, LONGPRESS_DELAY);\n      var handleTouchstart = function (event) {\n        getTouch(event).each(function (touch) {\n          longpress$1.cancel();\n          var data = {\n            x: constant(touch.clientX),\n            y: constant(touch.clientY),\n            target: event.target\n          };\n          longpress$1.schedule(event);\n          longpressFired.set(false);\n          startData.set(Option.some(data));\n        });\n        return Option.none();\n      };\n      var handleTouchmove = function (event) {\n        longpress$1.cancel();\n        getTouch(event).each(function (touch) {\n          startData.get().each(function (data) {\n            if (isFarEnough(touch, data)) {\n              startData.set(Option.none());\n            }\n          });\n        });\n        return Option.none();\n      };\n      var handleTouchend = function (event) {\n        longpress$1.cancel();\n        var isSame = function (data) {\n          return eq(data.target(), event.target());\n        };\n        return startData.get().filter(isSame).map(function (data) {\n          if (longpressFired.get()) {\n            event.prevent();\n            return false;\n          } else {\n            return settings.triggerEvent(tap(), event);\n          }\n        });\n      };\n      var handlers = wrapAll$1([\n        {\n          key: touchstart(),\n          value: handleTouchstart\n        },\n        {\n          key: touchmove(),\n          value: handleTouchmove\n        },\n        {\n          key: touchend(),\n          value: handleTouchend\n        }\n      ]);\n      var fireIfReady = function (event, type) {\n        return readOptFrom$1(handlers, type).bind(function (handler) {\n          return handler(event);\n        });\n      };\n      return { fireIfReady: fireIfReady };\n    };\n\n    var monitor$1 = function (editorApi) {\n      var tapEvent = monitor({\n        triggerEvent: function (type, evt) {\n          editorApi.onTapContent(evt);\n        }\n      });\n      var onTouchend = function () {\n        return bind$3(editorApi.body(), 'touchend', function (evt) {\n          tapEvent.fireIfReady(evt, 'touchend');\n        });\n      };\n      var onTouchmove = function () {\n        return bind$3(editorApi.body(), 'touchmove', function (evt) {\n          tapEvent.fireIfReady(evt, 'touchmove');\n        });\n      };\n      var fireTouchstart = function (evt) {\n        tapEvent.fireIfReady(evt, 'touchstart');\n      };\n      return {\n        fireTouchstart: fireTouchstart,\n        onTouchend: onTouchend,\n        onTouchmove: onTouchmove\n      };\n    };\n    var TappingEvent = { monitor: monitor$1 };\n\n    var isAndroid6 = detect$3().os.version.major >= 6;\n    var initEvents = function (editorApi, toolstrip, alloy) {\n      var tapping = TappingEvent.monitor(editorApi);\n      var outerDoc = owner(toolstrip);\n      var isRanged = function (sel) {\n        return !eq(sel.start(), sel.finish()) || sel.soffset() !== sel.foffset();\n      };\n      var hasRangeInUi = function () {\n        return active(outerDoc).filter(function (input) {\n          return name(input) === 'input';\n        }).exists(function (input) {\n          return input.dom().selectionStart !== input.dom().selectionEnd;\n        });\n      };\n      var updateMargin = function () {\n        var rangeInContent = editorApi.doc().dom().hasFocus() && editorApi.getSelection().exists(isRanged);\n        alloy.getByDom(toolstrip).each((rangeInContent || hasRangeInUi()) === true ? Toggling.on : Toggling.off);\n      };\n      var listeners = [\n        bind$3(editorApi.body(), 'touchstart', function (evt) {\n          editorApi.onTouchContent();\n          tapping.fireTouchstart(evt);\n        }),\n        tapping.onTouchmove(),\n        tapping.onTouchend(),\n        bind$3(toolstrip, 'touchstart', function (evt) {\n          editorApi.onTouchToolstrip();\n        }),\n        editorApi.onToReading(function () {\n          blur(editorApi.body());\n        }),\n        editorApi.onToEditing(noop),\n        editorApi.onScrollToCursor(function (tinyEvent) {\n          tinyEvent.preventDefault();\n          editorApi.getCursorBox().each(function (bounds) {\n            var cWin = editorApi.win();\n            var isOutside = bounds.top() > cWin.innerHeight || bounds.bottom() > cWin.innerHeight;\n            var cScrollBy = isOutside ? bounds.bottom() - cWin.innerHeight + 50 : 0;\n            if (cScrollBy !== 0) {\n              cWin.scrollTo(cWin.pageXOffset, cWin.pageYOffset + cScrollBy);\n            }\n          });\n        })\n      ].concat(isAndroid6 === true ? [] : [\n        bind$3(Element.fromDom(editorApi.win()), 'blur', function () {\n          alloy.getByDom(toolstrip).each(Toggling.off);\n        }),\n        bind$3(outerDoc, 'select', updateMargin),\n        bind$3(editorApi.doc(), 'selectionchange', updateMargin)\n      ]);\n      var destroy = function () {\n        each$1(listeners, function (l) {\n          l.unbind();\n        });\n      };\n      return { destroy: destroy };\n    };\n    var AndroidEvents = { initEvents: initEvents };\n\n    var safeParse = function (element, attribute) {\n      var parsed = parseInt(get(element, attribute), 10);\n      return isNaN(parsed) ? 0 : parsed;\n    };\n    var DataAttributes = { safeParse: safeParse };\n\n    function NodeValue (is, name) {\n      var get = function (element) {\n        if (!is(element)) {\n          throw new Error('Can only get ' + name + ' value of a ' + name + ' node');\n        }\n        return getOption(element).getOr('');\n      };\n      var getOption = function (element) {\n        return is(element) ? Option.from(element.dom().nodeValue) : Option.none();\n      };\n      var set = function (element, value) {\n        if (!is(element)) {\n          throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');\n        }\n        element.dom().nodeValue = value;\n      };\n      return {\n        get: get,\n        getOption: getOption,\n        set: set\n      };\n    }\n\n    var api$3 = NodeValue(isText, 'text');\n    var get$b = function (element) {\n      return api$3.get(element);\n    };\n    var getOption = function (element) {\n      return api$3.getOption(element);\n    };\n\n    var getEnd = function (element) {\n      return name(element) === 'img' ? 1 : getOption(element).fold(function () {\n        return children(element).length;\n      }, function (v) {\n        return v.length;\n      });\n    };\n    var NBSP = '\\xA0';\n    var isTextNodeWithCursorPosition = function (el) {\n      return getOption(el).filter(function (text) {\n        return text.trim().length !== 0 || text.indexOf(NBSP) > -1;\n      }).isSome();\n    };\n    var elementsWithCursorPosition = [\n      'img',\n      'br'\n    ];\n    var isCursorPosition = function (elem) {\n      var hasCursorPosition = isTextNodeWithCursorPosition(elem);\n      return hasCursorPosition || contains(elementsWithCursorPosition, name(elem));\n    };\n\n    var create$3 = Immutable('start', 'soffset', 'finish', 'foffset');\n    var SimRange = { create: create$3 };\n\n    var adt$4 = Adt.generate([\n      { before: ['element'] },\n      {\n        on: [\n          'element',\n          'offset'\n        ]\n      },\n      { after: ['element'] }\n    ]);\n    var cata = function (subject, onBefore, onOn, onAfter) {\n      return subject.fold(onBefore, onOn, onAfter);\n    };\n    var getStart = function (situ) {\n      return situ.fold(identity, identity, identity);\n    };\n    var before$1 = adt$4.before;\n    var on$1 = adt$4.on;\n    var after$1 = adt$4.after;\n    var Situ = {\n      before: before$1,\n      on: on$1,\n      after: after$1,\n      cata: cata,\n      getStart: getStart\n    };\n\n    var adt$5 = Adt.generate([\n      { domRange: ['rng'] },\n      {\n        relative: [\n          'startSitu',\n          'finishSitu'\n        ]\n      },\n      {\n        exact: [\n          'start',\n          'soffset',\n          'finish',\n          'foffset'\n        ]\n      }\n    ]);\n    var exactFromRange = function (simRange) {\n      return adt$5.exact(simRange.start(), simRange.soffset(), simRange.finish(), simRange.foffset());\n    };\n    var getStart$1 = function (selection) {\n      return selection.match({\n        domRange: function (rng) {\n          return Element.fromDom(rng.startContainer);\n        },\n        relative: function (startSitu, finishSitu) {\n          return Situ.getStart(startSitu);\n        },\n        exact: function (start, soffset, finish, foffset) {\n          return start;\n        }\n      });\n    };\n    var domRange = adt$5.domRange;\n    var relative = adt$5.relative;\n    var exact = adt$5.exact;\n    var getWin = function (selection) {\n      var start = getStart$1(selection);\n      return defaultView(start);\n    };\n    var range$1 = SimRange.create;\n    var Selection = {\n      domRange: domRange,\n      relative: relative,\n      exact: exact,\n      exactFromRange: exactFromRange,\n      getWin: getWin,\n      range: range$1\n    };\n\n    var setStart = function (rng, situ) {\n      situ.fold(function (e) {\n        rng.setStartBefore(e.dom());\n      }, function (e, o) {\n        rng.setStart(e.dom(), o);\n      }, function (e) {\n        rng.setStartAfter(e.dom());\n      });\n    };\n    var setFinish = function (rng, situ) {\n      situ.fold(function (e) {\n        rng.setEndBefore(e.dom());\n      }, function (e, o) {\n        rng.setEnd(e.dom(), o);\n      }, function (e) {\n        rng.setEndAfter(e.dom());\n      });\n    };\n    var relativeToNative = function (win, startSitu, finishSitu) {\n      var range = win.document.createRange();\n      setStart(range, startSitu);\n      setFinish(range, finishSitu);\n      return range;\n    };\n    var exactToNative = function (win, start, soffset, finish, foffset) {\n      var rng = win.document.createRange();\n      rng.setStart(start.dom(), soffset);\n      rng.setEnd(finish.dom(), foffset);\n      return rng;\n    };\n    var toRect = function (rect) {\n      return {\n        left: constant(rect.left),\n        top: constant(rect.top),\n        right: constant(rect.right),\n        bottom: constant(rect.bottom),\n        width: constant(rect.width),\n        height: constant(rect.height)\n      };\n    };\n    var getFirstRect = function (rng) {\n      var rects = rng.getClientRects();\n      var rect = rects.length > 0 ? rects[0] : rng.getBoundingClientRect();\n      return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect) : Option.none();\n    };\n\n    var adt$6 = Adt.generate([\n      {\n        ltr: [\n          'start',\n          'soffset',\n          'finish',\n          'foffset'\n        ]\n      },\n      {\n        rtl: [\n          'start',\n          'soffset',\n          'finish',\n          'foffset'\n        ]\n      }\n    ]);\n    var fromRange = function (win, type, range) {\n      return type(Element.fromDom(range.startContainer), range.startOffset, Element.fromDom(range.endContainer), range.endOffset);\n    };\n    var getRanges = function (win, selection) {\n      return selection.match({\n        domRange: function (rng) {\n          return {\n            ltr: constant(rng),\n            rtl: Option.none\n          };\n        },\n        relative: function (startSitu, finishSitu) {\n          return {\n            ltr: cached(function () {\n              return relativeToNative(win, startSitu, finishSitu);\n            }),\n            rtl: cached(function () {\n              return Option.some(relativeToNative(win, finishSitu, startSitu));\n            })\n          };\n        },\n        exact: function (start, soffset, finish, foffset) {\n          return {\n            ltr: cached(function () {\n              return exactToNative(win, start, soffset, finish, foffset);\n            }),\n            rtl: cached(function () {\n              return Option.some(exactToNative(win, finish, foffset, start, soffset));\n            })\n          };\n        }\n      });\n    };\n    var doDiagnose = function (win, ranges) {\n      var rng = ranges.ltr();\n      if (rng.collapsed) {\n        var reversed = ranges.rtl().filter(function (rev) {\n          return rev.collapsed === false;\n        });\n        return reversed.map(function (rev) {\n          return adt$6.rtl(Element.fromDom(rev.endContainer), rev.endOffset, Element.fromDom(rev.startContainer), rev.startOffset);\n        }).getOrThunk(function () {\n          return fromRange(win, adt$6.ltr, rng);\n        });\n      } else {\n        return fromRange(win, adt$6.ltr, rng);\n      }\n    };\n    var diagnose = function (win, selection) {\n      var ranges = getRanges(win, selection);\n      return doDiagnose(win, ranges);\n    };\n    var asLtrRange = function (win, selection) {\n      var diagnosis = diagnose(win, selection);\n      return diagnosis.match({\n        ltr: function (start, soffset, finish, foffset) {\n          var rng = win.document.createRange();\n          rng.setStart(start.dom(), soffset);\n          rng.setEnd(finish.dom(), foffset);\n          return rng;\n        },\n        rtl: function (start, soffset, finish, foffset) {\n          var rng = win.document.createRange();\n          rng.setStart(finish.dom(), foffset);\n          rng.setEnd(start.dom(), soffset);\n          return rng;\n        }\n      });\n    };\n\n    var searchForPoint = function (rectForOffset, x, y, maxX, length) {\n      if (length === 0) {\n        return 0;\n      } else if (x === maxX) {\n        return length - 1;\n      }\n      var xDelta = maxX;\n      for (var i = 1; i < length; i++) {\n        var rect = rectForOffset(i);\n        var curDeltaX = Math.abs(x - rect.left);\n        if (y <= rect.bottom) {\n          if (y < rect.top || curDeltaX > xDelta) {\n            return i - 1;\n          } else {\n            xDelta = curDeltaX;\n          }\n        }\n      }\n      return 0;\n    };\n    var inRect = function (rect, x, y) {\n      return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;\n    };\n\n    var locateOffset = function (doc, textnode, x, y, rect) {\n      var rangeForOffset = function (o) {\n        var r = doc.dom().createRange();\n        r.setStart(textnode.dom(), o);\n        r.collapse(true);\n        return r;\n      };\n      var rectForOffset = function (o) {\n        var r = rangeForOffset(o);\n        return r.getBoundingClientRect();\n      };\n      var length = get$b(textnode).length;\n      var offset = searchForPoint(rectForOffset, x, y, rect.right, length);\n      return rangeForOffset(offset);\n    };\n    var locate$1 = function (doc, node, x, y) {\n      var r = doc.dom().createRange();\n      r.selectNode(node.dom());\n      var rects = r.getClientRects();\n      var foundRect = findMap(rects, function (rect) {\n        return inRect(rect, x, y) ? Option.some(rect) : Option.none();\n      });\n      return foundRect.map(function (rect) {\n        return locateOffset(doc, node, x, y, rect);\n      });\n    };\n\n    var searchInChildren = function (doc, node, x, y) {\n      var r = doc.dom().createRange();\n      var nodes = children(node);\n      return findMap(nodes, function (n) {\n        r.selectNode(n.dom());\n        return inRect(r.getBoundingClientRect(), x, y) ? locateNode(doc, n, x, y) : Option.none();\n      });\n    };\n    var locateNode = function (doc, node, x, y) {\n      return isText(node) ? locate$1(doc, node, x, y) : searchInChildren(doc, node, x, y);\n    };\n    var locate$2 = function (doc, node, x, y) {\n      var r = doc.dom().createRange();\n      r.selectNode(node.dom());\n      var rect = r.getBoundingClientRect();\n      var boundedX = Math.max(rect.left, Math.min(rect.right, x));\n      var boundedY = Math.max(rect.top, Math.min(rect.bottom, y));\n      return locateNode(doc, node, boundedX, boundedY);\n    };\n\n    var first$1 = function (element) {\n      return descendant(element, isCursorPosition);\n    };\n    var last = function (element) {\n      return descendantRtl(element, isCursorPosition);\n    };\n    var descendantRtl = function (scope, predicate) {\n      var descend = function (element) {\n        var children$1 = children(element);\n        for (var i = children$1.length - 1; i >= 0; i--) {\n          var child = children$1[i];\n          if (predicate(child)) {\n            return Option.some(child);\n          }\n          var res = descend(child);\n          if (res.isSome()) {\n            return res;\n          }\n        }\n        return Option.none();\n      };\n      return descend(scope);\n    };\n\n    var COLLAPSE_TO_LEFT = true;\n    var COLLAPSE_TO_RIGHT = false;\n    var getCollapseDirection = function (rect, x) {\n      return x - rect.left < rect.right - x ? COLLAPSE_TO_LEFT : COLLAPSE_TO_RIGHT;\n    };\n    var createCollapsedNode = function (doc, target, collapseDirection) {\n      var r = doc.dom().createRange();\n      r.selectNode(target.dom());\n      r.collapse(collapseDirection);\n      return r;\n    };\n    var locateInElement = function (doc, node, x) {\n      var cursorRange = doc.dom().createRange();\n      cursorRange.selectNode(node.dom());\n      var rect = cursorRange.getBoundingClientRect();\n      var collapseDirection = getCollapseDirection(rect, x);\n      var f = collapseDirection === COLLAPSE_TO_LEFT ? first$1 : last;\n      return f(node).map(function (target) {\n        return createCollapsedNode(doc, target, collapseDirection);\n      });\n    };\n    var locateInEmpty = function (doc, node, x) {\n      var rect = node.dom().getBoundingClientRect();\n      var collapseDirection = getCollapseDirection(rect, x);\n      return Option.some(createCollapsedNode(doc, node, collapseDirection));\n    };\n    var search$1 = function (doc, node, x) {\n      var f = children(node).length === 0 ? locateInEmpty : locateInElement;\n      return f(doc, node, x);\n    };\n\n    var caretPositionFromPoint = function (doc, x, y) {\n      return Option.from(doc.dom().caretPositionFromPoint(x, y)).bind(function (pos) {\n        if (pos.offsetNode === null) {\n          return Option.none();\n        }\n        var r = doc.dom().createRange();\n        r.setStart(pos.offsetNode, pos.offset);\n        r.collapse();\n        return Option.some(r);\n      });\n    };\n    var caretRangeFromPoint = function (doc, x, y) {\n      return Option.from(doc.dom().caretRangeFromPoint(x, y));\n    };\n    var searchTextNodes = function (doc, node, x, y) {\n      var r = doc.dom().createRange();\n      r.selectNode(node.dom());\n      var rect = r.getBoundingClientRect();\n      var boundedX = Math.max(rect.left, Math.min(rect.right, x));\n      var boundedY = Math.max(rect.top, Math.min(rect.bottom, y));\n      return locate$2(doc, node, boundedX, boundedY);\n    };\n    var searchFromPoint = function (doc, x, y) {\n      return Element.fromPoint(doc, x, y).bind(function (elem) {\n        var fallback = function () {\n          return search$1(doc, elem, x);\n        };\n        return children(elem).length === 0 ? fallback() : searchTextNodes(doc, elem, x, y).orThunk(fallback);\n      });\n    };\n    var availableSearch = document.caretPositionFromPoint ? caretPositionFromPoint : document.caretRangeFromPoint ? caretRangeFromPoint : searchFromPoint;\n\n    var beforeSpecial = function (element, offset) {\n      var name$1 = name(element);\n      if ('input' === name$1) {\n        return Situ.after(element);\n      } else if (!contains([\n          'br',\n          'img'\n        ], name$1)) {\n        return Situ.on(element, offset);\n      } else {\n        return offset === 0 ? Situ.before(element) : Situ.after(element);\n      }\n    };\n    var preprocessExact = function (start, soffset, finish, foffset) {\n      var startSitu = beforeSpecial(start, soffset);\n      var finishSitu = beforeSpecial(finish, foffset);\n      return Selection.relative(startSitu, finishSitu);\n    };\n\n    var makeRange = function (start, soffset, finish, foffset) {\n      var doc = owner(start);\n      var rng = doc.dom().createRange();\n      rng.setStart(start.dom(), soffset);\n      rng.setEnd(finish.dom(), foffset);\n      return rng;\n    };\n    var after$2 = function (start, soffset, finish, foffset) {\n      var r = makeRange(start, soffset, finish, foffset);\n      var same = eq(start, finish) && soffset === foffset;\n      return r.collapsed && !same;\n    };\n\n    var doSetNativeRange = function (win, rng) {\n      Option.from(win.getSelection()).each(function (selection) {\n        selection.removeAllRanges();\n        selection.addRange(rng);\n      });\n    };\n    var doSetRange = function (win, start, soffset, finish, foffset) {\n      var rng = exactToNative(win, start, soffset, finish, foffset);\n      doSetNativeRange(win, rng);\n    };\n    var setLegacyRtlRange = function (win, selection, start, soffset, finish, foffset) {\n      selection.collapse(start.dom(), soffset);\n      selection.extend(finish.dom(), foffset);\n    };\n    var setRangeFromRelative = function (win, relative) {\n      return diagnose(win, relative).match({\n        ltr: function (start, soffset, finish, foffset) {\n          doSetRange(win, start, soffset, finish, foffset);\n        },\n        rtl: function (start, soffset, finish, foffset) {\n          var selection = win.getSelection();\n          if (selection.setBaseAndExtent) {\n            selection.setBaseAndExtent(start.dom(), soffset, finish.dom(), foffset);\n          } else if (selection.extend) {\n            try {\n              setLegacyRtlRange(win, selection, start, soffset, finish, foffset);\n            } catch (e) {\n              doSetRange(win, finish, foffset, start, soffset);\n            }\n          } else {\n            doSetRange(win, finish, foffset, start, soffset);\n          }\n        }\n      });\n    };\n    var setExact = function (win, start, soffset, finish, foffset) {\n      var relative = preprocessExact(start, soffset, finish, foffset);\n      setRangeFromRelative(win, relative);\n    };\n    var readRange = function (selection) {\n      if (selection.rangeCount > 0) {\n        var firstRng = selection.getRangeAt(0);\n        var lastRng = selection.getRangeAt(selection.rangeCount - 1);\n        return Option.some(SimRange.create(Element.fromDom(firstRng.startContainer), firstRng.startOffset, Element.fromDom(lastRng.endContainer), lastRng.endOffset));\n      } else {\n        return Option.none();\n      }\n    };\n    var doGetExact = function (selection) {\n      var anchor = Element.fromDom(selection.anchorNode);\n      var focus = Element.fromDom(selection.focusNode);\n      return after$2(anchor, selection.anchorOffset, focus, selection.focusOffset) ? Option.some(SimRange.create(anchor, selection.anchorOffset, focus, selection.focusOffset)) : readRange(selection);\n    };\n    var getExact = function (win) {\n      return Option.from(win.getSelection()).filter(function (sel) {\n        return sel.rangeCount > 0;\n      }).bind(doGetExact);\n    };\n    var get$c = function (win) {\n      return getExact(win).map(function (range) {\n        return Selection.exact(range.start(), range.soffset(), range.finish(), range.foffset());\n      });\n    };\n    var getFirstRect$1 = function (win, selection) {\n      var rng = asLtrRange(win, selection);\n      return getFirstRect(rng);\n    };\n    var clear$1 = function (win) {\n      var selection = win.getSelection();\n      selection.removeAllRanges();\n    };\n\n    var COLLAPSED_WIDTH = 2;\n    var collapsedRect = function (rect) {\n      return {\n        left: rect.left,\n        top: rect.top,\n        right: rect.right,\n        bottom: rect.bottom,\n        width: constant(COLLAPSED_WIDTH),\n        height: rect.height\n      };\n    };\n    var toRect$1 = function (rawRect) {\n      return {\n        left: constant(rawRect.left),\n        top: constant(rawRect.top),\n        right: constant(rawRect.right),\n        bottom: constant(rawRect.bottom),\n        width: constant(rawRect.width),\n        height: constant(rawRect.height)\n      };\n    };\n    var getRectsFromRange = function (range) {\n      if (!range.collapsed) {\n        return map$1(range.getClientRects(), toRect$1);\n      } else {\n        var start_1 = Element.fromDom(range.startContainer);\n        return parent(start_1).bind(function (parent) {\n          var selection = Selection.exact(start_1, range.startOffset, parent, getEnd(parent));\n          var optRect = getFirstRect$1(range.startContainer.ownerDocument.defaultView, selection);\n          return optRect.map(collapsedRect).map(pure);\n        }).getOr([]);\n      }\n    };\n    var getRectangles = function (cWin) {\n      var sel = cWin.getSelection();\n      return sel !== undefined && sel.rangeCount > 0 ? getRectsFromRange(sel.getRangeAt(0)) : [];\n    };\n    var Rectangles = { getRectangles: getRectangles };\n\n    var autocompleteHack = function () {\n      return function (f) {\n        global$4.setTimeout(function () {\n          f();\n        }, 0);\n      };\n    };\n    var resume = function (cWin) {\n      cWin.focus();\n      var iBody = Element.fromDom(cWin.document.body);\n      var inInput = active().exists(function (elem) {\n        return contains([\n          'input',\n          'textarea'\n        ], name(elem));\n      });\n      var transaction = inInput ? autocompleteHack() : apply;\n      transaction(function () {\n        active().each(blur);\n        focus$1(iBody);\n      });\n    };\n    var ResumeEditing = { resume: resume };\n\n    var EXTRA_SPACING = 50;\n    var data = 'data-' + Styles.resolve('last-outer-height');\n    var setLastHeight = function (cBody, value) {\n      set(cBody, data, value);\n    };\n    var getLastHeight = function (cBody) {\n      return DataAttributes.safeParse(cBody, data);\n    };\n    var getBoundsFrom = function (rect) {\n      return {\n        top: constant(rect.top()),\n        bottom: constant(rect.top() + rect.height())\n      };\n    };\n    var getBounds$1 = function (cWin) {\n      var rects = Rectangles.getRectangles(cWin);\n      return rects.length > 0 ? Option.some(rects[0]).map(getBoundsFrom) : Option.none();\n    };\n    var findDelta = function (outerWindow, cBody) {\n      var last = getLastHeight(cBody);\n      var current = outerWindow.innerHeight;\n      return last > current ? Option.some(last - current) : Option.none();\n    };\n    var calculate = function (cWin, bounds, delta) {\n      var isOutside = bounds.top() > cWin.innerHeight || bounds.bottom() > cWin.innerHeight;\n      return isOutside ? Math.min(delta, bounds.bottom() - cWin.innerHeight + EXTRA_SPACING) : 0;\n    };\n    var setup$1 = function (outerWindow, cWin) {\n      var cBody = Element.fromDom(cWin.document.body);\n      var toEditing = function () {\n        ResumeEditing.resume(cWin);\n      };\n      var onResize = bind$3(Element.fromDom(outerWindow), 'resize', function () {\n        findDelta(outerWindow, cBody).each(function (delta) {\n          getBounds$1(cWin).each(function (bounds) {\n            var cScrollBy = calculate(cWin, bounds, delta);\n            if (cScrollBy !== 0) {\n              cWin.scrollTo(cWin.pageXOffset, cWin.pageYOffset + cScrollBy);\n            }\n          });\n        });\n        setLastHeight(cBody, outerWindow.innerHeight);\n      });\n      setLastHeight(cBody, outerWindow.innerHeight);\n      var destroy = function () {\n        onResize.unbind();\n      };\n      return {\n        toEditing: toEditing,\n        destroy: destroy\n      };\n    };\n    var AndroidSetup = { setup: setup$1 };\n\n    var getBodyFromFrame = function (frame) {\n      return Option.some(Element.fromDom(frame.dom().contentWindow.document.body));\n    };\n    var getDocFromFrame = function (frame) {\n      return Option.some(Element.fromDom(frame.dom().contentWindow.document));\n    };\n    var getWinFromFrame = function (frame) {\n      return Option.from(frame.dom().contentWindow);\n    };\n    var getSelectionFromFrame = function (frame) {\n      var optWin = getWinFromFrame(frame);\n      return optWin.bind(getExact);\n    };\n    var getFrame = function (editor) {\n      return editor.getFrame();\n    };\n    var getOrDerive = function (name, f) {\n      return function (editor) {\n        var g = editor[name].getOrThunk(function () {\n          var frame = getFrame(editor);\n          return function () {\n            return f(frame);\n          };\n        });\n        return g();\n      };\n    };\n    var getOrListen = function (editor, doc, name, type) {\n      return editor[name].getOrThunk(function () {\n        return function (handler) {\n          return bind$3(doc, type, handler);\n        };\n      });\n    };\n    var toRect$2 = function (rect) {\n      return {\n        left: constant(rect.left),\n        top: constant(rect.top),\n        right: constant(rect.right),\n        bottom: constant(rect.bottom),\n        width: constant(rect.width),\n        height: constant(rect.height)\n      };\n    };\n    var getActiveApi = function (editor) {\n      var frame = getFrame(editor);\n      var tryFallbackBox = function (win) {\n        var isCollapsed = function (sel) {\n          return eq(sel.start(), sel.finish()) && sel.soffset() === sel.foffset();\n        };\n        var toStartRect = function (sel) {\n          var rect = sel.start().dom().getBoundingClientRect();\n          return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect$2) : Option.none();\n        };\n        return getExact(win).filter(isCollapsed).bind(toStartRect);\n      };\n      return getBodyFromFrame(frame).bind(function (body) {\n        return getDocFromFrame(frame).bind(function (doc) {\n          return getWinFromFrame(frame).map(function (win) {\n            var html = Element.fromDom(doc.dom().documentElement);\n            var getCursorBox = editor.getCursorBox.getOrThunk(function () {\n              return function () {\n                return get$c(win).bind(function (sel) {\n                  return getFirstRect$1(win, sel).orThunk(function () {\n                    return tryFallbackBox(win);\n                  });\n                });\n              };\n            });\n            var setSelection = editor.setSelection.getOrThunk(function () {\n              return function (start, soffset, finish, foffset) {\n                setExact(win, start, soffset, finish, foffset);\n              };\n            });\n            var clearSelection = editor.clearSelection.getOrThunk(function () {\n              return function () {\n                clear$1(win);\n              };\n            });\n            return {\n              body: constant(body),\n              doc: constant(doc),\n              win: constant(win),\n              html: constant(html),\n              getSelection: curry(getSelectionFromFrame, frame),\n              setSelection: setSelection,\n              clearSelection: clearSelection,\n              frame: constant(frame),\n              onKeyup: getOrListen(editor, doc, 'onKeyup', 'keyup'),\n              onNodeChanged: getOrListen(editor, doc, 'onNodeChanged', 'SelectionChange'),\n              onDomChanged: editor.onDomChanged,\n              onScrollToCursor: editor.onScrollToCursor,\n              onScrollToElement: editor.onScrollToElement,\n              onToReading: editor.onToReading,\n              onToEditing: editor.onToEditing,\n              onToolbarScrollStart: editor.onToolbarScrollStart,\n              onTouchContent: editor.onTouchContent,\n              onTapContent: editor.onTapContent,\n              onTouchToolstrip: editor.onTouchToolstrip,\n              getCursorBox: getCursorBox\n            };\n          });\n        });\n      });\n    };\n    var PlatformEditor = {\n      getBody: getOrDerive('getBody', getBodyFromFrame),\n      getDoc: getOrDerive('getDoc', getDocFromFrame),\n      getWin: getOrDerive('getWin', getWinFromFrame),\n      getSelection: getOrDerive('getSelection', getSelectionFromFrame),\n      getFrame: getFrame,\n      getActiveApi: getActiveApi\n    };\n\n    var attr = 'data-ephox-mobile-fullscreen-style';\n    var siblingStyles = 'display:none!important;';\n    var ancestorPosition = 'position:absolute!important;';\n    var ancestorStyles = 'top:0!important;left:0!important;margin:0!important;padding:0!important;width:100%!important;height:100%!important;overflow:visible!important;';\n    var bgFallback = 'background-color:rgb(255,255,255)!important;';\n    var isAndroid = detect$3().os.isAndroid();\n    var matchColor = function (editorBody) {\n      var color = get$3(editorBody, 'background-color');\n      return color !== undefined && color !== '' ? 'background-color:' + color + '!important' : bgFallback;\n    };\n    var clobberStyles = function (container, editorBody) {\n      var gatherSibilings = function (element) {\n        var siblings = siblings$2(element, '*');\n        return siblings;\n      };\n      var clobber = function (clobberStyle) {\n        return function (element) {\n          var styles = get(element, 'style');\n          var backup = styles === undefined ? 'no-styles' : styles.trim();\n          if (backup === clobberStyle) {\n            return;\n          } else {\n            set(element, attr, backup);\n            set(element, 'style', clobberStyle);\n          }\n        };\n      };\n      var ancestors = ancestors$1(container, '*');\n      var siblings = bind(ancestors, gatherSibilings);\n      var bgColor = matchColor(editorBody);\n      each$1(siblings, clobber(siblingStyles));\n      each$1(ancestors, clobber(ancestorPosition + ancestorStyles + bgColor));\n      var containerStyles = isAndroid === true ? '' : ancestorPosition;\n      clobber(containerStyles + ancestorStyles + bgColor)(container);\n    };\n    var restoreStyles = function () {\n      var clobberedEls = all$2('[' + attr + ']');\n      each$1(clobberedEls, function (element) {\n        var restore = get(element, attr);\n        if (restore !== 'no-styles') {\n          set(element, 'style', restore);\n        } else {\n          remove$1(element, 'style');\n        }\n        remove$1(element, attr);\n      });\n    };\n    var Thor = {\n      clobberStyles: clobberStyles,\n      restoreStyles: restoreStyles\n    };\n\n    var tag = function () {\n      var head = first('head').getOrDie();\n      var nu = function () {\n        var meta = Element.fromTag('meta');\n        set(meta, 'name', 'viewport');\n        append(head, meta);\n        return meta;\n      };\n      var element = first('meta[name=\"viewport\"]').getOrThunk(nu);\n      var backup = get(element, 'content');\n      var maximize = function () {\n        set(element, 'content', 'width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0');\n      };\n      var restore = function () {\n        if (backup !== undefined && backup !== null && backup.length > 0) {\n          set(element, 'content', backup);\n        } else {\n          set(element, 'content', 'user-scalable=yes');\n        }\n      };\n      return {\n        maximize: maximize,\n        restore: restore\n      };\n    };\n    var MetaViewport = { tag: tag };\n\n    var create$4 = function (platform, mask) {\n      var meta = MetaViewport.tag();\n      var androidApi = api$2();\n      var androidEvents = api$2();\n      var enter = function () {\n        mask.hide();\n        add$2(platform.container, Styles.resolve('fullscreen-maximized'));\n        add$2(platform.container, Styles.resolve('android-maximized'));\n        meta.maximize();\n        add$2(platform.body, Styles.resolve('android-scroll-reload'));\n        androidApi.set(AndroidSetup.setup(platform.win, PlatformEditor.getWin(platform.editor).getOrDie('no')));\n        PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) {\n          Thor.clobberStyles(platform.container, editorApi.body());\n          androidEvents.set(AndroidEvents.initEvents(editorApi, platform.toolstrip, platform.alloy));\n        });\n      };\n      var exit = function () {\n        meta.restore();\n        mask.show();\n        remove$4(platform.container, Styles.resolve('fullscreen-maximized'));\n        remove$4(platform.container, Styles.resolve('android-maximized'));\n        Thor.restoreStyles();\n        remove$4(platform.body, Styles.resolve('android-scroll-reload'));\n        androidEvents.clear();\n        androidApi.clear();\n      };\n      return {\n        enter: enter,\n        exit: exit\n      };\n    };\n    var AndroidMode = { create: create$4 };\n\n    var first$2 = function (fn, rate) {\n      var timer = null;\n      var cancel = function () {\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n          timer = null;\n        }\n      };\n      var throttle = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (timer === null) {\n          timer = domGlobals.setTimeout(function () {\n            fn.apply(null, args);\n            timer = null;\n          }, rate);\n        }\n      };\n      return {\n        cancel: cancel,\n        throttle: throttle\n      };\n    };\n    var last$1 = function (fn, rate) {\n      var timer = null;\n      var cancel = function () {\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n          timer = null;\n        }\n      };\n      var throttle = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n        }\n        timer = domGlobals.setTimeout(function () {\n          fn.apply(null, args);\n          timer = null;\n        }, rate);\n      };\n      return {\n        cancel: cancel,\n        throttle: throttle\n      };\n    };\n\n    var sketch$9 = function (onView, translate) {\n      var memIcon = record(Container.sketch({\n        dom: dom$1('<div aria-hidden=\"true\" class=\"${prefix}-mask-tap-icon\"></div>'),\n        containerBehaviours: derive$1([Toggling.config({\n            toggleClass: Styles.resolve('mask-tap-icon-selected'),\n            toggleOnExecute: false\n          })])\n      }));\n      var onViewThrottle = first$2(onView, 200);\n      return Container.sketch({\n        dom: dom$1('<div class=\"${prefix}-disabled-mask\"></div>'),\n        components: [Container.sketch({\n            dom: dom$1('<div class=\"${prefix}-content-container\"></div>'),\n            components: [Button.sketch({\n                dom: dom$1('<div class=\"${prefix}-content-tap-section\"></div>'),\n                components: [memIcon.asSpec()],\n                action: function (button) {\n                  onViewThrottle.throttle();\n                },\n                buttonBehaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('mask-tap-icon-selected') })])\n              })]\n          })]\n      });\n    };\n    var TapToEditMask = { sketch: sketch$9 };\n\n    var MobileSchema = objOf([\n      strictObjOf('editor', [\n        strict$1('getFrame'),\n        option('getBody'),\n        option('getDoc'),\n        option('getWin'),\n        option('getSelection'),\n        option('setSelection'),\n        option('clearSelection'),\n        option('cursorSaver'),\n        option('onKeyup'),\n        option('onNodeChanged'),\n        option('getCursorBox'),\n        strict$1('onDomChanged'),\n        defaulted$1('onTouchContent', noop),\n        defaulted$1('onTapContent', noop),\n        defaulted$1('onTouchToolstrip', noop),\n        defaulted$1('onScrollToCursor', constant({ unbind: noop })),\n        defaulted$1('onScrollToElement', constant({ unbind: noop })),\n        defaulted$1('onToEditing', constant({ unbind: noop })),\n        defaulted$1('onToReading', constant({ unbind: noop })),\n        defaulted$1('onToolbarScrollStart', identity)\n      ]),\n      strict$1('socket'),\n      strict$1('toolstrip'),\n      strict$1('dropup'),\n      strict$1('toolbar'),\n      strict$1('container'),\n      strict$1('alloy'),\n      state$1('win', function (spec) {\n        return owner(spec.socket).dom().defaultView;\n      }),\n      state$1('body', function (spec) {\n        return Element.fromDom(spec.socket.dom().ownerDocument.body);\n      }),\n      defaulted$1('translate', identity),\n      defaulted$1('setReadOnly', noop),\n      defaulted$1('readOnlyOnInit', constant(true))\n    ]);\n\n    var produce = function (raw) {\n      var mobile = asRawOrDie('Getting AndroidWebapp schema', MobileSchema, raw);\n      set$3(mobile.toolstrip, 'width', '100%');\n      var onTap = function () {\n        mobile.setReadOnly(mobile.readOnlyOnInit());\n        mode.enter();\n      };\n      var mask = build$1(TapToEditMask.sketch(onTap, mobile.translate));\n      mobile.alloy.add(mask);\n      var maskApi = {\n        show: function () {\n          mobile.alloy.add(mask);\n        },\n        hide: function () {\n          mobile.alloy.remove(mask);\n        }\n      };\n      append(mobile.container, mask.element());\n      var mode = AndroidMode.create(mobile, maskApi);\n      return {\n        setReadOnly: mobile.setReadOnly,\n        refreshStructure: noop,\n        enter: mode.enter,\n        exit: mode.exit,\n        destroy: noop\n      };\n    };\n    var AndroidWebapp = { produce: produce };\n\n    var schema$e = constant([\n      strict$1('dom'),\n      defaulted$1('shell', true),\n      field$1('toolbarBehaviours', [Replacing])\n    ]);\n    var enhanceGroups = function (detail) {\n      return { behaviours: derive$1([Replacing.config({})]) };\n    };\n    var parts$2 = constant([optional({\n        name: 'groups',\n        overrides: enhanceGroups\n      })]);\n\n    var factory$4 = function (detail, components, spec, _externals) {\n      var setGroups = function (toolbar, groups) {\n        getGroupContainer(toolbar).fold(function () {\n          domGlobals.console.error('Toolbar was defined to not be a shell, but no groups container was specified in components');\n          throw new Error('Toolbar was defined to not be a shell, but no groups container was specified in components');\n        }, function (container) {\n          Replacing.set(container, groups);\n        });\n      };\n      var getGroupContainer = function (component) {\n        return detail.shell ? Option.some(component) : getPart(component, detail, 'groups');\n      };\n      var extra = detail.shell ? {\n        behaviours: [Replacing.config({})],\n        components: []\n      } : {\n        behaviours: [],\n        components: components\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: extra.components,\n        behaviours: augment(detail.toolbarBehaviours, extra.behaviours),\n        apis: { setGroups: setGroups },\n        domModification: { attributes: { role: 'group' } }\n      };\n    };\n    var Toolbar = composite$1({\n      name: 'Toolbar',\n      configFields: schema$e(),\n      partFields: parts$2(),\n      factory: factory$4,\n      apis: {\n        setGroups: function (apis, toolbar, groups) {\n          apis.setGroups(toolbar, groups);\n        }\n      }\n    });\n\n    var schema$f = constant([\n      strict$1('items'),\n      markers(['itemSelector']),\n      field$1('tgroupBehaviours', [Keying])\n    ]);\n    var parts$3 = constant([group({\n        name: 'items',\n        unit: 'item'\n      })]);\n\n    var factory$5 = function (detail, components, spec, _externals) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: augment(detail.tgroupBehaviours, [Keying.config({\n            mode: 'flow',\n            selector: detail.markers.itemSelector\n          })]),\n        domModification: { attributes: { role: 'toolbar' } }\n      };\n    };\n    var ToolbarGroup = composite$1({\n      name: 'ToolbarGroup',\n      configFields: schema$f(),\n      partFields: parts$3(),\n      factory: factory$5\n    });\n\n    var dataHorizontal = 'data-' + Styles.resolve('horizontal-scroll');\n    var canScrollVertically = function (container) {\n      container.dom().scrollTop = 1;\n      var result = container.dom().scrollTop !== 0;\n      container.dom().scrollTop = 0;\n      return result;\n    };\n    var canScrollHorizontally = function (container) {\n      container.dom().scrollLeft = 1;\n      var result = container.dom().scrollLeft !== 0;\n      container.dom().scrollLeft = 0;\n      return result;\n    };\n    var hasVerticalScroll = function (container) {\n      return container.dom().scrollTop > 0 || canScrollVertically(container);\n    };\n    var hasHorizontalScroll = function (container) {\n      return container.dom().scrollLeft > 0 || canScrollHorizontally(container);\n    };\n    var markAsHorizontal = function (container) {\n      set(container, dataHorizontal, 'true');\n    };\n    var hasScroll = function (container) {\n      return get(container, dataHorizontal) === 'true' ? hasHorizontalScroll(container) : hasVerticalScroll(container);\n    };\n    var exclusive = function (scope, selector) {\n      return bind$3(scope, 'touchmove', function (event) {\n        closest$2(event.target(), selector).filter(hasScroll).fold(function () {\n          event.raw().preventDefault();\n        }, noop);\n      });\n    };\n    var Scrollables = {\n      exclusive: exclusive,\n      markAsHorizontal: markAsHorizontal\n    };\n\n    function ScrollingToolbar () {\n      var makeGroup = function (gSpec) {\n        var scrollClass = gSpec.scrollable === true ? '${prefix}-toolbar-scrollable-group' : '';\n        return {\n          dom: dom$1('<div aria-label=\"' + gSpec.label + '\" class=\"${prefix}-toolbar-group ' + scrollClass + '\"></div>'),\n          tgroupBehaviours: derive$1([config('adhoc-scrollable-toolbar', gSpec.scrollable === true ? [runOnInit(function (component, simulatedEvent) {\n                set$3(component.element(), 'overflow-x', 'auto');\n                Scrollables.markAsHorizontal(component.element());\n                Scrollable.register(component.element());\n              })] : [])]),\n          components: [Container.sketch({ components: [ToolbarGroup.parts().items({})] })],\n          markers: { itemSelector: '.' + Styles.resolve('toolbar-group-item') },\n          items: gSpec.items\n        };\n      };\n      var toolbar = build$1(Toolbar.sketch({\n        dom: dom$1('<div class=\"${prefix}-toolbar\"></div>'),\n        components: [Toolbar.parts().groups({})],\n        toolbarBehaviours: derive$1([\n          Toggling.config({\n            toggleClass: Styles.resolve('context-toolbar'),\n            toggleOnExecute: false,\n            aria: { mode: 'none' }\n          }),\n          Keying.config({ mode: 'cyclic' })\n        ]),\n        shell: true\n      }));\n      var wrapper = build$1(Container.sketch({\n        dom: { classes: [Styles.resolve('toolstrip')] },\n        components: [premade$1(toolbar)],\n        containerBehaviours: derive$1([Toggling.config({\n            toggleClass: Styles.resolve('android-selection-context-toolbar'),\n            toggleOnExecute: false\n          })])\n      }));\n      var resetGroups = function () {\n        Toolbar.setGroups(toolbar, initGroups.get());\n        Toggling.off(toolbar);\n      };\n      var initGroups = Cell([]);\n      var setGroups = function (gs) {\n        initGroups.set(gs);\n        resetGroups();\n      };\n      var createGroups = function (gs) {\n        return map$1(gs, compose(ToolbarGroup.sketch, makeGroup));\n      };\n      var refresh = function () {\n      };\n      var setContextToolbar = function (gs) {\n        Toggling.on(toolbar);\n        Toolbar.setGroups(toolbar, gs);\n      };\n      var restoreToolbar = function () {\n        if (Toggling.isOn(toolbar)) {\n          resetGroups();\n        }\n      };\n      var focus = function () {\n        Keying.focusIn(toolbar);\n      };\n      return {\n        wrapper: constant(wrapper),\n        toolbar: constant(toolbar),\n        createGroups: createGroups,\n        setGroups: setGroups,\n        setContextToolbar: setContextToolbar,\n        restoreToolbar: restoreToolbar,\n        refresh: refresh,\n        focus: focus\n      };\n    }\n\n    var makeEditSwitch = function (webapp) {\n      return build$1(Button.sketch({\n        dom: dom$1('<div class=\"${prefix}-mask-edit-icon ${prefix}-icon\"></div>'),\n        action: function () {\n          webapp.run(function (w) {\n            w.setReadOnly(false);\n          });\n        }\n      }));\n    };\n    var makeSocket = function () {\n      return build$1(Container.sketch({\n        dom: dom$1('<div class=\"${prefix}-editor-socket\"></div>'),\n        components: [],\n        containerBehaviours: derive$1([Replacing.config({})])\n      }));\n    };\n    var showEdit = function (socket, switchToEdit) {\n      Replacing.append(socket, premade$1(switchToEdit));\n    };\n    var hideEdit = function (socket, switchToEdit) {\n      Replacing.remove(socket, switchToEdit);\n    };\n    var updateMode = function (socket, switchToEdit, readOnly, root) {\n      var swap = readOnly === true ? Swapping.toAlpha : Swapping.toOmega;\n      swap(root);\n      var f = readOnly ? showEdit : hideEdit;\n      f(socket, switchToEdit);\n    };\n    var CommonRealm = {\n      makeEditSwitch: makeEditSwitch,\n      makeSocket: makeSocket,\n      updateMode: updateMode\n    };\n\n    var getAnimationRoot = function (component, slideConfig) {\n      return slideConfig.getAnimationRoot.fold(function () {\n        return component.element();\n      }, function (get) {\n        return get(component);\n      });\n    };\n\n    var getDimensionProperty = function (slideConfig) {\n      return slideConfig.dimension.property;\n    };\n    var getDimension = function (slideConfig, elem) {\n      return slideConfig.dimension.getDimension(elem);\n    };\n    var disableTransitions = function (component, slideConfig) {\n      var root = getAnimationRoot(component, slideConfig);\n      remove$6(root, [\n        slideConfig.shrinkingClass,\n        slideConfig.growingClass\n      ]);\n    };\n    var setShrunk = function (component, slideConfig) {\n      remove$4(component.element(), slideConfig.openClass);\n      add$2(component.element(), slideConfig.closedClass);\n      set$3(component.element(), getDimensionProperty(slideConfig), '0px');\n      reflow(component.element());\n    };\n    var setGrown = function (component, slideConfig) {\n      remove$4(component.element(), slideConfig.closedClass);\n      add$2(component.element(), slideConfig.openClass);\n      remove$5(component.element(), getDimensionProperty(slideConfig));\n    };\n    var doImmediateShrink = function (component, slideConfig, slideState, _calculatedSize) {\n      slideState.setCollapsed();\n      set$3(component.element(), getDimensionProperty(slideConfig), getDimension(slideConfig, component.element()));\n      reflow(component.element());\n      disableTransitions(component, slideConfig);\n      setShrunk(component, slideConfig);\n      slideConfig.onStartShrink(component);\n      slideConfig.onShrunk(component);\n    };\n    var doStartShrink = function (component, slideConfig, slideState, calculatedSize) {\n      var size = calculatedSize.getOrThunk(function () {\n        return getDimension(slideConfig, component.element());\n      });\n      slideState.setCollapsed();\n      set$3(component.element(), getDimensionProperty(slideConfig), size);\n      reflow(component.element());\n      var root = getAnimationRoot(component, slideConfig);\n      remove$4(root, slideConfig.growingClass);\n      add$2(root, slideConfig.shrinkingClass);\n      setShrunk(component, slideConfig);\n      slideConfig.onStartShrink(component);\n    };\n    var doStartSmartShrink = function (component, slideConfig, slideState) {\n      var size = getDimension(slideConfig, component.element());\n      var shrinker = size === '0px' ? doImmediateShrink : doStartShrink;\n      shrinker(component, slideConfig, slideState, Option.some(size));\n    };\n    var doStartGrow = function (component, slideConfig, slideState) {\n      var root = getAnimationRoot(component, slideConfig);\n      var wasShrinking = has$2(root, slideConfig.shrinkingClass);\n      var beforeSize = getDimension(slideConfig, component.element());\n      setGrown(component, slideConfig);\n      var fullSize = getDimension(slideConfig, component.element());\n      var startPartialGrow = function () {\n        set$3(component.element(), getDimensionProperty(slideConfig), beforeSize);\n        reflow(component.element());\n      };\n      var startCompleteGrow = function () {\n        setShrunk(component, slideConfig);\n      };\n      var setStartSize = wasShrinking ? startPartialGrow : startCompleteGrow;\n      setStartSize();\n      remove$4(root, slideConfig.shrinkingClass);\n      add$2(root, slideConfig.growingClass);\n      setGrown(component, slideConfig);\n      set$3(component.element(), getDimensionProperty(slideConfig), fullSize);\n      slideState.setExpanded();\n      slideConfig.onStartGrow(component);\n    };\n    var refresh = function (component, slideConfig, slideState) {\n      if (slideState.isExpanded()) {\n        remove$5(component.element(), getDimensionProperty(slideConfig));\n        var fullSize = getDimension(slideConfig, component.element());\n        set$3(component.element(), getDimensionProperty(slideConfig), fullSize);\n      }\n    };\n    var grow = function (component, slideConfig, slideState) {\n      if (!slideState.isExpanded()) {\n        doStartGrow(component, slideConfig, slideState);\n      }\n    };\n    var shrink = function (component, slideConfig, slideState) {\n      if (slideState.isExpanded()) {\n        doStartSmartShrink(component, slideConfig, slideState);\n      }\n    };\n    var immediateShrink = function (component, slideConfig, slideState) {\n      if (slideState.isExpanded()) {\n        doImmediateShrink(component, slideConfig, slideState);\n      }\n    };\n    var hasGrown = function (component, slideConfig, slideState) {\n      return slideState.isExpanded();\n    };\n    var hasShrunk = function (component, slideConfig, slideState) {\n      return slideState.isCollapsed();\n    };\n    var isGrowing = function (component, slideConfig, slideState) {\n      var root = getAnimationRoot(component, slideConfig);\n      return has$2(root, slideConfig.growingClass) === true;\n    };\n    var isShrinking = function (component, slideConfig, slideState) {\n      var root = getAnimationRoot(component, slideConfig);\n      return has$2(root, slideConfig.shrinkingClass) === true;\n    };\n    var isTransitioning = function (component, slideConfig, slideState) {\n      return isGrowing(component, slideConfig) === true || isShrinking(component, slideConfig) === true;\n    };\n    var toggleGrow = function (component, slideConfig, slideState) {\n      var f = slideState.isExpanded() ? doStartSmartShrink : doStartGrow;\n      f(component, slideConfig, slideState);\n    };\n\n    var SlidingApis = /*#__PURE__*/Object.freeze({\n        refresh: refresh,\n        grow: grow,\n        shrink: shrink,\n        immediateShrink: immediateShrink,\n        hasGrown: hasGrown,\n        hasShrunk: hasShrunk,\n        isGrowing: isGrowing,\n        isShrinking: isShrinking,\n        isTransitioning: isTransitioning,\n        toggleGrow: toggleGrow,\n        disableTransitions: disableTransitions\n    });\n\n    var exhibit$5 = function (base, slideConfig) {\n      var expanded = slideConfig.expanded;\n      return expanded ? nu$5({\n        classes: [slideConfig.openClass],\n        styles: {}\n      }) : nu$5({\n        classes: [slideConfig.closedClass],\n        styles: wrap$1(slideConfig.dimension.property, '0px')\n      });\n    };\n    var events$a = function (slideConfig, slideState) {\n      return derive([runOnSource(transitionend(), function (component, simulatedEvent) {\n          var raw = simulatedEvent.event().raw();\n          if (raw.propertyName === slideConfig.dimension.property) {\n            disableTransitions(component, slideConfig);\n            if (slideState.isExpanded()) {\n              remove$5(component.element(), slideConfig.dimension.property);\n            }\n            var notify = slideState.isExpanded() ? slideConfig.onGrown : slideConfig.onShrunk;\n            notify(component);\n          }\n        })]);\n    };\n\n    var ActiveSliding = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$5,\n        events: events$a\n    });\n\n    var SlidingSchema = [\n      strict$1('closedClass'),\n      strict$1('openClass'),\n      strict$1('shrinkingClass'),\n      strict$1('growingClass'),\n      option('getAnimationRoot'),\n      onHandler('onShrunk'),\n      onHandler('onStartShrink'),\n      onHandler('onGrown'),\n      onHandler('onStartGrow'),\n      defaulted$1('expanded', false),\n      strictOf('dimension', choose$1('property', {\n        width: [\n          output('property', 'width'),\n          output('getDimension', function (elem) {\n            return get$6(elem) + 'px';\n          })\n        ],\n        height: [\n          output('property', 'height'),\n          output('getDimension', function (elem) {\n            return get$4(elem) + 'px';\n          })\n        ]\n      }))\n    ];\n\n    var init$4 = function (spec) {\n      var state = Cell(spec.expanded);\n      var readState = function () {\n        return 'expanded: ' + state.get();\n      };\n      return nu$6({\n        isExpanded: function () {\n          return state.get() === true;\n        },\n        isCollapsed: function () {\n          return state.get() === false;\n        },\n        setCollapsed: curry(state.set, false),\n        setExpanded: curry(state.set, true),\n        readState: readState\n      });\n    };\n\n    var SlidingState = /*#__PURE__*/Object.freeze({\n        init: init$4\n    });\n\n    var Sliding = create$1({\n      fields: SlidingSchema,\n      name: 'sliding',\n      active: ActiveSliding,\n      apis: SlidingApis,\n      state: SlidingState\n    });\n\n    var build$2 = function (refresh, scrollIntoView) {\n      var dropup = build$1(Container.sketch({\n        dom: {\n          tag: 'div',\n          classes: [Styles.resolve('dropup')]\n        },\n        components: [],\n        containerBehaviours: derive$1([\n          Replacing.config({}),\n          Sliding.config({\n            closedClass: Styles.resolve('dropup-closed'),\n            openClass: Styles.resolve('dropup-open'),\n            shrinkingClass: Styles.resolve('dropup-shrinking'),\n            growingClass: Styles.resolve('dropup-growing'),\n            dimension: { property: 'height' },\n            onShrunk: function (component) {\n              refresh();\n              scrollIntoView();\n              Replacing.set(component, []);\n            },\n            onGrown: function (component) {\n              refresh();\n              scrollIntoView();\n            }\n          }),\n          Receivers.orientation(function (component, data) {\n            disappear(noop);\n          })\n        ])\n      }));\n      var appear = function (menu, update, component) {\n        if (Sliding.hasShrunk(dropup) === true && Sliding.isTransitioning(dropup) === false) {\n          domGlobals.window.requestAnimationFrame(function () {\n            update(component);\n            Replacing.set(dropup, [menu()]);\n            Sliding.grow(dropup);\n          });\n        }\n      };\n      var disappear = function (onReadyToShrink) {\n        domGlobals.window.requestAnimationFrame(function () {\n          onReadyToShrink();\n          Sliding.shrink(dropup);\n        });\n      };\n      return {\n        appear: appear,\n        disappear: disappear,\n        component: constant(dropup),\n        element: dropup.element\n      };\n    };\n\n    var closest$3 = function (scope, selector, isRoot) {\n      return closest$2(scope, selector, isRoot).isSome();\n    };\n\n    var isDangerous = function (event) {\n      var keyEv = event.raw();\n      return keyEv.which === BACKSPACE()[0] && !contains([\n        'input',\n        'textarea'\n      ], name(event.target())) && !closest$3(event.target(), '[contenteditable=\"true\"]');\n    };\n    var isFirefox = detect$3().browser.isFirefox();\n    var settingsSchema = objOfOnly([\n      strictFunction('triggerEvent'),\n      defaulted$1('stopBackspace', true)\n    ]);\n    var bindFocus = function (container, handler) {\n      if (isFirefox) {\n        return capture$1(container, 'focus', handler);\n      } else {\n        return bind$3(container, 'focusin', handler);\n      }\n    };\n    var bindBlur = function (container, handler) {\n      if (isFirefox) {\n        return capture$1(container, 'blur', handler);\n      } else {\n        return bind$3(container, 'focusout', handler);\n      }\n    };\n    var setup$2 = function (container, rawSettings) {\n      var settings = asRawOrDie('Getting GUI events settings', settingsSchema, rawSettings);\n      var pointerEvents = [\n        'touchstart',\n        'touchmove',\n        'touchend',\n        'touchcancel',\n        'gesturestart',\n        'mousedown',\n        'mouseup',\n        'mouseover',\n        'mousemove',\n        'mouseout',\n        'click'\n      ];\n      var tapEvent = monitor(settings);\n      var simpleEvents = map$1(pointerEvents.concat([\n        'selectstart',\n        'input',\n        'contextmenu',\n        'change',\n        'transitionend',\n        'drag',\n        'dragstart',\n        'dragend',\n        'dragenter',\n        'dragleave',\n        'dragover',\n        'drop',\n        'keyup'\n      ]), function (type) {\n        return bind$3(container, type, function (event) {\n          tapEvent.fireIfReady(event, type).each(function (tapStopped) {\n            if (tapStopped) {\n              event.kill();\n            }\n          });\n          var stopped = settings.triggerEvent(type, event);\n          if (stopped) {\n            event.kill();\n          }\n        });\n      });\n      var pasteTimeout = Cell(Option.none());\n      var onPaste = bind$3(container, 'paste', function (event) {\n        tapEvent.fireIfReady(event, 'paste').each(function (tapStopped) {\n          if (tapStopped) {\n            event.kill();\n          }\n        });\n        var stopped = settings.triggerEvent('paste', event);\n        if (stopped) {\n          event.kill();\n        }\n        pasteTimeout.set(Option.some(domGlobals.setTimeout(function () {\n          settings.triggerEvent(postPaste(), event);\n        }, 0)));\n      });\n      var onKeydown = bind$3(container, 'keydown', function (event) {\n        var stopped = settings.triggerEvent('keydown', event);\n        if (stopped) {\n          event.kill();\n        } else if (settings.stopBackspace === true && isDangerous(event)) {\n          event.prevent();\n        }\n      });\n      var onFocusIn = bindFocus(container, function (event) {\n        var stopped = settings.triggerEvent('focusin', event);\n        if (stopped) {\n          event.kill();\n        }\n      });\n      var focusoutTimeout = Cell(Option.none());\n      var onFocusOut = bindBlur(container, function (event) {\n        var stopped = settings.triggerEvent('focusout', event);\n        if (stopped) {\n          event.kill();\n        }\n        focusoutTimeout.set(Option.some(domGlobals.setTimeout(function () {\n          settings.triggerEvent(postBlur(), event);\n        }, 0)));\n      });\n      var unbind = function () {\n        each$1(simpleEvents, function (e) {\n          e.unbind();\n        });\n        onKeydown.unbind();\n        onFocusIn.unbind();\n        onFocusOut.unbind();\n        onPaste.unbind();\n        pasteTimeout.get().each(domGlobals.clearTimeout);\n        focusoutTimeout.get().each(domGlobals.clearTimeout);\n      };\n      return { unbind: unbind };\n    };\n\n    var derive$2 = function (rawEvent, rawTarget) {\n      var source = readOptFrom$1(rawEvent, 'target').map(function (getTarget) {\n        return getTarget();\n      }).getOr(rawTarget);\n      return Cell(source);\n    };\n\n    var fromSource = function (event, source) {\n      var stopper = Cell(false);\n      var cutter = Cell(false);\n      var stop = function () {\n        stopper.set(true);\n      };\n      var cut = function () {\n        cutter.set(true);\n      };\n      return {\n        stop: stop,\n        cut: cut,\n        isStopped: stopper.get,\n        isCut: cutter.get,\n        event: constant(event),\n        setSource: source.set,\n        getSource: source.get\n      };\n    };\n    var fromExternal = function (event) {\n      var stopper = Cell(false);\n      var stop = function () {\n        stopper.set(true);\n      };\n      return {\n        stop: stop,\n        cut: noop,\n        isStopped: stopper.get,\n        isCut: constant(false),\n        event: constant(event),\n        setSource: die('Cannot set source of a broadcasted event'),\n        getSource: die('Cannot get source of a broadcasted event')\n      };\n    };\n\n    var adt$7 = Adt.generate([\n      { stopped: [] },\n      { resume: ['element'] },\n      { complete: [] }\n    ]);\n    var doTriggerHandler = function (lookup, eventType, rawEvent, target, source, logger) {\n      var handler = lookup(eventType, target);\n      var simulatedEvent = fromSource(rawEvent, source);\n      return handler.fold(function () {\n        logger.logEventNoHandlers(eventType, target);\n        return adt$7.complete();\n      }, function (handlerInfo) {\n        var descHandler = handlerInfo.descHandler();\n        var eventHandler = getCurried(descHandler);\n        eventHandler(simulatedEvent);\n        if (simulatedEvent.isStopped()) {\n          logger.logEventStopped(eventType, handlerInfo.element(), descHandler.purpose());\n          return adt$7.stopped();\n        } else if (simulatedEvent.isCut()) {\n          logger.logEventCut(eventType, handlerInfo.element(), descHandler.purpose());\n          return adt$7.complete();\n        } else {\n          return parent(handlerInfo.element()).fold(function () {\n            logger.logNoParent(eventType, handlerInfo.element(), descHandler.purpose());\n            return adt$7.complete();\n          }, function (parent) {\n            logger.logEventResponse(eventType, handlerInfo.element(), descHandler.purpose());\n            return adt$7.resume(parent);\n          });\n        }\n      });\n    };\n    var doTriggerOnUntilStopped = function (lookup, eventType, rawEvent, rawTarget, source, logger) {\n      return doTriggerHandler(lookup, eventType, rawEvent, rawTarget, source, logger).fold(function () {\n        return true;\n      }, function (parent) {\n        return doTriggerOnUntilStopped(lookup, eventType, rawEvent, parent, source, logger);\n      }, function () {\n        return false;\n      });\n    };\n    var triggerHandler = function (lookup, eventType, rawEvent, target, logger) {\n      var source = derive$2(rawEvent, target);\n      return doTriggerHandler(lookup, eventType, rawEvent, target, source, logger);\n    };\n    var broadcast = function (listeners, rawEvent, logger) {\n      var simulatedEvent = fromExternal(rawEvent);\n      each$1(listeners, function (listener) {\n        var descHandler = listener.descHandler();\n        var handler = getCurried(descHandler);\n        handler(simulatedEvent);\n      });\n      return simulatedEvent.isStopped();\n    };\n    var triggerUntilStopped = function (lookup, eventType, rawEvent, logger) {\n      var rawTarget = rawEvent.target();\n      return triggerOnUntilStopped(lookup, eventType, rawEvent, rawTarget, logger);\n    };\n    var triggerOnUntilStopped = function (lookup, eventType, rawEvent, rawTarget, logger) {\n      var source = derive$2(rawEvent, rawTarget);\n      return doTriggerOnUntilStopped(lookup, eventType, rawEvent, rawTarget, source, logger);\n    };\n\n    var eventHandler = Immutable('element', 'descHandler');\n    var broadcastHandler = function (id, handler) {\n      return {\n        id: constant(id),\n        descHandler: constant(handler)\n      };\n    };\n    function EventRegistry () {\n      var registry = {};\n      var registerId = function (extraArgs, id, events) {\n        each(events, function (v, k) {\n          var handlers = registry[k] !== undefined ? registry[k] : {};\n          handlers[id] = curryArgs(v, extraArgs);\n          registry[k] = handlers;\n        });\n      };\n      var findHandler = function (handlers, elem) {\n        return read$2(elem).fold(function () {\n          return Option.none();\n        }, function (id) {\n          var reader = readOpt$1(id);\n          return handlers.bind(reader).map(function (descHandler) {\n            return eventHandler(elem, descHandler);\n          });\n        });\n      };\n      var filterByType = function (type) {\n        return readOptFrom$1(registry, type).map(function (handlers) {\n          return mapToArray(handlers, function (f, id) {\n            return broadcastHandler(id, f);\n          });\n        }).getOr([]);\n      };\n      var find = function (isAboveRoot, type, target) {\n        var readType = readOpt$1(type);\n        var handlers = readType(registry);\n        return closest$1(target, function (elem) {\n          return findHandler(handlers, elem);\n        }, isAboveRoot);\n      };\n      var unregisterId = function (id) {\n        each(registry, function (handlersById, eventName) {\n          if (handlersById.hasOwnProperty(id)) {\n            delete handlersById[id];\n          }\n        });\n      };\n      return {\n        registerId: registerId,\n        unregisterId: unregisterId,\n        filterByType: filterByType,\n        find: find\n      };\n    }\n\n    function Registry () {\n      var events = EventRegistry();\n      var components = {};\n      var readOrTag = function (component) {\n        var elem = component.element();\n        return read$2(elem).fold(function () {\n          return write('uid-', component.element());\n        }, function (uid) {\n          return uid;\n        });\n      };\n      var failOnDuplicate = function (component, tagId) {\n        var conflict = components[tagId];\n        if (conflict === component) {\n          unregister(component);\n        } else {\n          throw new Error('The tagId \"' + tagId + '\" is already used by: ' + element(conflict.element()) + '\\nCannot use it for: ' + element(component.element()) + '\\n' + 'The conflicting element is' + (inBody(conflict.element()) ? ' ' : ' not ') + 'already in the DOM');\n        }\n      };\n      var register = function (component) {\n        var tagId = readOrTag(component);\n        if (hasKey$1(components, tagId)) {\n          failOnDuplicate(component, tagId);\n        }\n        var extraArgs = [component];\n        events.registerId(extraArgs, tagId, component.events());\n        components[tagId] = component;\n      };\n      var unregister = function (component) {\n        read$2(component.element()).each(function (tagId) {\n          delete components[tagId];\n          events.unregisterId(tagId);\n        });\n      };\n      var filter = function (type) {\n        return events.filterByType(type);\n      };\n      var find = function (isAboveRoot, type, target) {\n        return events.find(isAboveRoot, type, target);\n      };\n      var getById = function (id) {\n        return readOpt$1(id)(components);\n      };\n      return {\n        find: find,\n        filter: filter,\n        register: register,\n        unregister: unregister,\n        getById: getById\n      };\n    }\n\n    var takeover = function (root) {\n      var isAboveRoot = function (el) {\n        return parent(root.element()).fold(function () {\n          return true;\n        }, function (parent) {\n          return eq(el, parent);\n        });\n      };\n      var registry = Registry();\n      var lookup = function (eventName, target) {\n        return registry.find(isAboveRoot, eventName, target);\n      };\n      var domEvents = setup$2(root.element(), {\n        triggerEvent: function (eventName, event) {\n          return monitorEvent(eventName, event.target(), function (logger) {\n            return triggerUntilStopped(lookup, eventName, event, logger);\n          });\n        }\n      });\n      var systemApi = {\n        debugInfo: constant('real'),\n        triggerEvent: function (eventName, target, data) {\n          monitorEvent(eventName, target, function (logger) {\n            triggerOnUntilStopped(lookup, eventName, data, target, logger);\n          });\n        },\n        triggerFocus: function (target, originator) {\n          read$2(target).fold(function () {\n            focus$1(target);\n          }, function (_alloyId) {\n            monitorEvent(focus(), target, function (logger) {\n              triggerHandler(lookup, focus(), {\n                originator: constant(originator),\n                kill: noop,\n                prevent: noop,\n                target: constant(target)\n              }, target, logger);\n            });\n          });\n        },\n        triggerEscape: function (comp, simulatedEvent) {\n          systemApi.triggerEvent('keydown', comp.element(), simulatedEvent.event());\n        },\n        getByUid: function (uid) {\n          return getByUid(uid);\n        },\n        getByDom: function (elem) {\n          return getByDom(elem);\n        },\n        build: build$1,\n        addToGui: function (c) {\n          add(c);\n        },\n        removeFromGui: function (c) {\n          remove$1(c);\n        },\n        addToWorld: function (c) {\n          addToWorld(c);\n        },\n        removeFromWorld: function (c) {\n          removeFromWorld(c);\n        },\n        broadcast: function (message) {\n          broadcast$1(message);\n        },\n        broadcastOn: function (channels, message) {\n          broadcastOn(channels, message);\n        },\n        broadcastEvent: function (eventName, event) {\n          broadcastEvent(eventName, event);\n        },\n        isConnected: constant(true)\n      };\n      var addToWorld = function (component) {\n        component.connect(systemApi);\n        if (!isText(component.element())) {\n          registry.register(component);\n          each$1(component.components(), addToWorld);\n          systemApi.triggerEvent(systemInit(), component.element(), { target: constant(component.element()) });\n        }\n      };\n      var removeFromWorld = function (component) {\n        if (!isText(component.element())) {\n          each$1(component.components(), removeFromWorld);\n          registry.unregister(component);\n        }\n        component.disconnect();\n      };\n      var add = function (component) {\n        attach$1(root, component);\n      };\n      var remove$1 = function (component) {\n        detach(component);\n      };\n      var destroy = function () {\n        domEvents.unbind();\n        remove(root.element());\n      };\n      var broadcastData = function (data) {\n        var receivers = registry.filter(receive());\n        each$1(receivers, function (receiver) {\n          var descHandler = receiver.descHandler();\n          var handler = getCurried(descHandler);\n          handler(data);\n        });\n      };\n      var broadcast$1 = function (message) {\n        broadcastData({\n          universal: constant(true),\n          data: constant(message)\n        });\n      };\n      var broadcastOn = function (channels, message) {\n        broadcastData({\n          universal: constant(false),\n          channels: constant(channels),\n          data: constant(message)\n        });\n      };\n      var broadcastEvent = function (eventName, event) {\n        var listeners = registry.filter(eventName);\n        return broadcast(listeners, event);\n      };\n      var getByUid = function (uid) {\n        return registry.getById(uid).fold(function () {\n          return Result.error(new Error('Could not find component with uid: \"' + uid + '\" in system.'));\n        }, Result.value);\n      };\n      var getByDom = function (elem) {\n        var uid = read$2(elem).getOr('not found');\n        return getByUid(uid);\n      };\n      addToWorld(root);\n      return {\n        root: constant(root),\n        element: root.element,\n        destroy: destroy,\n        add: add,\n        remove: remove$1,\n        getByUid: getByUid,\n        getByDom: getByDom,\n        addToWorld: addToWorld,\n        removeFromWorld: removeFromWorld,\n        broadcast: broadcast$1,\n        broadcastOn: broadcastOn,\n        broadcastEvent: broadcastEvent\n      };\n    };\n\n    var READ_ONLY_MODE_CLASS = constant(Styles.resolve('readonly-mode'));\n    var EDIT_MODE_CLASS = constant(Styles.resolve('edit-mode'));\n    function OuterContainer (spec) {\n      var root = build$1(Container.sketch({\n        dom: { classes: [Styles.resolve('outer-container')].concat(spec.classes) },\n        containerBehaviours: derive$1([Swapping.config({\n            alpha: READ_ONLY_MODE_CLASS(),\n            omega: EDIT_MODE_CLASS()\n          })])\n      }));\n      return takeover(root);\n    }\n\n    function AndroidRealm (scrollIntoView) {\n      var alloy = OuterContainer({ classes: [Styles.resolve('android-container')] });\n      var toolbar = ScrollingToolbar();\n      var webapp = api$2();\n      var switchToEdit = CommonRealm.makeEditSwitch(webapp);\n      var socket = CommonRealm.makeSocket();\n      var dropup = build$2(noop, scrollIntoView);\n      alloy.add(toolbar.wrapper());\n      alloy.add(socket);\n      alloy.add(dropup.component());\n      var setToolbarGroups = function (rawGroups) {\n        var groups = toolbar.createGroups(rawGroups);\n        toolbar.setGroups(groups);\n      };\n      var setContextToolbar = function (rawGroups) {\n        var groups = toolbar.createGroups(rawGroups);\n        toolbar.setContextToolbar(groups);\n      };\n      var focusToolbar = function () {\n        toolbar.focus();\n      };\n      var restoreToolbar = function () {\n        toolbar.restoreToolbar();\n      };\n      var init = function (spec) {\n        webapp.set(AndroidWebapp.produce(spec));\n      };\n      var exit = function () {\n        webapp.run(function (w) {\n          w.exit();\n          Replacing.remove(socket, switchToEdit);\n        });\n      };\n      var updateMode = function (readOnly) {\n        CommonRealm.updateMode(socket, switchToEdit, readOnly, alloy.root());\n      };\n      return {\n        system: constant(alloy),\n        element: alloy.element,\n        init: init,\n        exit: exit,\n        setToolbarGroups: setToolbarGroups,\n        setContextToolbar: setContextToolbar,\n        focusToolbar: focusToolbar,\n        restoreToolbar: restoreToolbar,\n        updateMode: updateMode,\n        socket: constant(socket),\n        dropup: constant(dropup)\n      };\n    }\n\n    var input$1 = function (parent, operation) {\n      var input = Element.fromTag('input');\n      setAll$1(input, {\n        opacity: '0',\n        position: 'absolute',\n        top: '-1000px',\n        left: '-1000px'\n      });\n      append(parent, input);\n      focus$1(input);\n      operation(input);\n      remove(input);\n    };\n    var CaptureBin = { input: input$1 };\n\n    var refreshInput = function (input) {\n      var start = input.dom().selectionStart;\n      var end = input.dom().selectionEnd;\n      var dir = input.dom().selectionDirection;\n      global$4.setTimeout(function () {\n        input.dom().setSelectionRange(start, end, dir);\n        focus$1(input);\n      }, 50);\n    };\n    var refresh$1 = function (winScope) {\n      var sel = winScope.getSelection();\n      if (sel.rangeCount > 0) {\n        var br = sel.getRangeAt(0);\n        var r = winScope.document.createRange();\n        r.setStart(br.startContainer, br.startOffset);\n        r.setEnd(br.endContainer, br.endOffset);\n        sel.removeAllRanges();\n        sel.addRange(r);\n      }\n    };\n    var CursorRefresh = {\n      refreshInput: refreshInput,\n      refresh: refresh$1\n    };\n\n    var resume$1 = function (cWin, frame) {\n      active().each(function (active) {\n        if (!eq(active, frame)) {\n          blur(active);\n        }\n      });\n      cWin.focus();\n      focus$1(Element.fromDom(cWin.document.body));\n      CursorRefresh.refresh(cWin);\n    };\n    var ResumeEditing$1 = { resume: resume$1 };\n\n    var stubborn = function (outerBody, cWin, page, frame) {\n      var toEditing = function () {\n        ResumeEditing$1.resume(cWin, frame);\n      };\n      var toReading = function () {\n        CaptureBin.input(outerBody, blur);\n      };\n      var captureInput = bind$3(page, 'keydown', function (evt) {\n        if (!contains([\n            'input',\n            'textarea'\n          ], name(evt.target()))) {\n          toEditing();\n        }\n      });\n      var onToolbarTouch = function () {\n      };\n      var destroy = function () {\n        captureInput.unbind();\n      };\n      return {\n        toReading: toReading,\n        toEditing: toEditing,\n        onToolbarTouch: onToolbarTouch,\n        destroy: destroy\n      };\n    };\n    var timid = function (outerBody, cWin, page, frame) {\n      var dismissKeyboard = function () {\n        blur(frame);\n      };\n      var onToolbarTouch = function () {\n        dismissKeyboard();\n      };\n      var toReading = function () {\n        dismissKeyboard();\n      };\n      var toEditing = function () {\n        ResumeEditing$1.resume(cWin, frame);\n      };\n      return {\n        toReading: toReading,\n        toEditing: toEditing,\n        onToolbarTouch: onToolbarTouch,\n        destroy: noop\n      };\n    };\n    var IosKeyboard = {\n      stubborn: stubborn,\n      timid: timid\n    };\n\n    var initEvents$1 = function (editorApi, iosApi, toolstrip, socket, dropup) {\n      var saveSelectionFirst = function () {\n        iosApi.run(function (api) {\n          api.highlightSelection();\n        });\n      };\n      var refreshIosSelection = function () {\n        iosApi.run(function (api) {\n          api.refreshSelection();\n        });\n      };\n      var scrollToY = function (yTop, height) {\n        var y = yTop - socket.dom().scrollTop;\n        iosApi.run(function (api) {\n          api.scrollIntoView(y, y + height);\n        });\n      };\n      var scrollToElement = function (target) {\n        scrollToY(iosApi, socket);\n      };\n      var scrollToCursor = function () {\n        editorApi.getCursorBox().each(function (box) {\n          scrollToY(box.top(), box.height());\n        });\n      };\n      var clearSelection = function () {\n        iosApi.run(function (api) {\n          api.clearSelection();\n        });\n      };\n      var clearAndRefresh = function () {\n        clearSelection();\n        refreshThrottle.throttle();\n      };\n      var refreshView = function () {\n        scrollToCursor();\n        iosApi.run(function (api) {\n          api.syncHeight();\n        });\n      };\n      var reposition = function () {\n        var toolbarHeight = get$4(toolstrip);\n        iosApi.run(function (api) {\n          api.setViewportOffset(toolbarHeight);\n        });\n        refreshIosSelection();\n        refreshView();\n      };\n      var toEditing = function () {\n        iosApi.run(function (api) {\n          api.toEditing();\n        });\n      };\n      var toReading = function () {\n        iosApi.run(function (api) {\n          api.toReading();\n        });\n      };\n      var onToolbarTouch = function (event) {\n        iosApi.run(function (api) {\n          api.onToolbarTouch(event);\n        });\n      };\n      var tapping = TappingEvent.monitor(editorApi);\n      var refreshThrottle = last$1(refreshView, 300);\n      var listeners = [\n        editorApi.onKeyup(clearAndRefresh),\n        editorApi.onNodeChanged(refreshIosSelection),\n        editorApi.onDomChanged(refreshThrottle.throttle),\n        editorApi.onDomChanged(refreshIosSelection),\n        editorApi.onScrollToCursor(function (tinyEvent) {\n          tinyEvent.preventDefault();\n          refreshThrottle.throttle();\n        }),\n        editorApi.onScrollToElement(function (event) {\n          scrollToElement(event.element());\n        }),\n        editorApi.onToEditing(toEditing),\n        editorApi.onToReading(toReading),\n        bind$3(editorApi.doc(), 'touchend', function (touchEvent) {\n          if (eq(editorApi.html(), touchEvent.target()) || eq(editorApi.body(), touchEvent.target())) ;\n        }),\n        bind$3(toolstrip, 'transitionend', function (transitionEvent) {\n          if (transitionEvent.raw().propertyName === 'height') {\n            reposition();\n          }\n        }),\n        capture$1(toolstrip, 'touchstart', function (touchEvent) {\n          saveSelectionFirst();\n          onToolbarTouch(touchEvent);\n          editorApi.onTouchToolstrip();\n        }),\n        bind$3(editorApi.body(), 'touchstart', function (evt) {\n          clearSelection();\n          editorApi.onTouchContent();\n          tapping.fireTouchstart(evt);\n        }),\n        tapping.onTouchmove(),\n        tapping.onTouchend(),\n        bind$3(editorApi.body(), 'click', function (event) {\n          event.kill();\n        }),\n        bind$3(toolstrip, 'touchmove', function () {\n          editorApi.onToolbarScrollStart();\n        })\n      ];\n      var destroy = function () {\n        each$1(listeners, function (l) {\n          l.unbind();\n        });\n      };\n      return { destroy: destroy };\n    };\n    var IosEvents = { initEvents: initEvents$1 };\n\n    function FakeSelection (win, frame) {\n      var doc = win.document;\n      var container = Element.fromTag('div');\n      add$2(container, Styles.resolve('unfocused-selections'));\n      append(Element.fromDom(doc.documentElement), container);\n      var onTouch = bind$3(container, 'touchstart', function (event) {\n        event.prevent();\n        ResumeEditing$1.resume(win, frame);\n        clear();\n      });\n      var make = function (rectangle) {\n        var span = Element.fromTag('span');\n        add$3(span, [\n          Styles.resolve('layer-editor'),\n          Styles.resolve('unfocused-selection')\n        ]);\n        setAll$1(span, {\n          left: rectangle.left() + 'px',\n          top: rectangle.top() + 'px',\n          width: rectangle.width() + 'px',\n          height: rectangle.height() + 'px'\n        });\n        return span;\n      };\n      var update = function () {\n        clear();\n        var rectangles = Rectangles.getRectangles(win);\n        var spans = map$1(rectangles, make);\n        append$1(container, spans);\n      };\n      var clear = function () {\n        empty(container);\n      };\n      var destroy = function () {\n        onTouch.unbind();\n        remove(container);\n      };\n      var isActive = function () {\n        return children(container).length > 0;\n      };\n      return {\n        update: update,\n        isActive: isActive,\n        destroy: destroy,\n        clear: clear\n      };\n    }\n\n    var exports$1 = {}, module = { exports: exports$1 };\n    (function (define, exports, module, require) {\n      (function (f) {\n        if (typeof exports === 'object' && typeof module !== 'undefined') {\n          module.exports = f();\n        } else if (typeof define === 'function' && define.amd) {\n          define([], f);\n        } else {\n          var g;\n          if (typeof window !== 'undefined') {\n            g = window;\n          } else if (typeof global !== 'undefined') {\n            g = global;\n          } else if (typeof self !== 'undefined') {\n            g = self;\n          } else {\n            g = this;\n          }\n          g.EphoxContactWrapper = f();\n        }\n      }(function () {\n        return function () {\n          function r(e, n, t) {\n            function o(i, f) {\n              if (!n[i]) {\n                if (!e[i]) {\n                  var c = 'function' == typeof require && require;\n                  if (!f && c)\n                    return c(i, !0);\n                  if (u)\n                    return u(i, !0);\n                  var a = new Error('Cannot find module \\'' + i + '\\'');\n                  throw a.code = 'MODULE_NOT_FOUND', a;\n                }\n                var p = n[i] = { exports: {} };\n                e[i][0].call(p.exports, function (r) {\n                  var n = e[i][1][r];\n                  return o(n || r);\n                }, p, p.exports, r, e, n, t);\n              }\n              return n[i].exports;\n            }\n            for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++)\n              o(t[i]);\n            return o;\n          }\n          return r;\n        }()({\n          1: [\n            function (require, module, exports) {\n              var process = module.exports = {};\n              var cachedSetTimeout;\n              var cachedClearTimeout;\n              function defaultSetTimout() {\n                throw new Error('setTimeout has not been defined');\n              }\n              function defaultClearTimeout() {\n                throw new Error('clearTimeout has not been defined');\n              }\n              (function () {\n                try {\n                  if (typeof setTimeout === 'function') {\n                    cachedSetTimeout = setTimeout;\n                  } else {\n                    cachedSetTimeout = defaultSetTimout;\n                  }\n                } catch (e) {\n                  cachedSetTimeout = defaultSetTimout;\n                }\n                try {\n                  if (typeof clearTimeout === 'function') {\n                    cachedClearTimeout = clearTimeout;\n                  } else {\n                    cachedClearTimeout = defaultClearTimeout;\n                  }\n                } catch (e) {\n                  cachedClearTimeout = defaultClearTimeout;\n                }\n              }());\n              function runTimeout(fun) {\n                if (cachedSetTimeout === setTimeout) {\n                  return setTimeout(fun, 0);\n                }\n                if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n                  cachedSetTimeout = setTimeout;\n                  return setTimeout(fun, 0);\n                }\n                try {\n                  return cachedSetTimeout(fun, 0);\n                } catch (e) {\n                  try {\n                    return cachedSetTimeout.call(null, fun, 0);\n                  } catch (e) {\n                    return cachedSetTimeout.call(this, fun, 0);\n                  }\n                }\n              }\n              function runClearTimeout(marker) {\n                if (cachedClearTimeout === clearTimeout) {\n                  return clearTimeout(marker);\n                }\n                if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n                  cachedClearTimeout = clearTimeout;\n                  return clearTimeout(marker);\n                }\n                try {\n                  return cachedClearTimeout(marker);\n                } catch (e) {\n                  try {\n                    return cachedClearTimeout.call(null, marker);\n                  } catch (e) {\n                    return cachedClearTimeout.call(this, marker);\n                  }\n                }\n              }\n              var queue = [];\n              var draining = false;\n              var currentQueue;\n              var queueIndex = -1;\n              function cleanUpNextTick() {\n                if (!draining || !currentQueue) {\n                  return;\n                }\n                draining = false;\n                if (currentQueue.length) {\n                  queue = currentQueue.concat(queue);\n                } else {\n                  queueIndex = -1;\n                }\n                if (queue.length) {\n                  drainQueue();\n                }\n              }\n              function drainQueue() {\n                if (draining) {\n                  return;\n                }\n                var timeout = runTimeout(cleanUpNextTick);\n                draining = true;\n                var len = queue.length;\n                while (len) {\n                  currentQueue = queue;\n                  queue = [];\n                  while (++queueIndex < len) {\n                    if (currentQueue) {\n                      currentQueue[queueIndex].run();\n                    }\n                  }\n                  queueIndex = -1;\n                  len = queue.length;\n                }\n                currentQueue = null;\n                draining = false;\n                runClearTimeout(timeout);\n              }\n              process.nextTick = function (fun) {\n                var args = new Array(arguments.length - 1);\n                if (arguments.length > 1) {\n                  for (var i = 1; i < arguments.length; i++) {\n                    args[i - 1] = arguments[i];\n                  }\n                }\n                queue.push(new Item(fun, args));\n                if (queue.length === 1 && !draining) {\n                  runTimeout(drainQueue);\n                }\n              };\n              function Item(fun, array) {\n                this.fun = fun;\n                this.array = array;\n              }\n              Item.prototype.run = function () {\n                this.fun.apply(null, this.array);\n              };\n              process.title = 'browser';\n              process.browser = true;\n              process.env = {};\n              process.argv = [];\n              process.version = '';\n              process.versions = {};\n              function noop() {\n              }\n              process.on = noop;\n              process.addListener = noop;\n              process.once = noop;\n              process.off = noop;\n              process.removeListener = noop;\n              process.removeAllListeners = noop;\n              process.emit = noop;\n              process.prependListener = noop;\n              process.prependOnceListener = noop;\n              process.listeners = function (name) {\n                return [];\n              };\n              process.binding = function (name) {\n                throw new Error('process.binding is not supported');\n              };\n              process.cwd = function () {\n                return '/';\n              };\n              process.chdir = function (dir) {\n                throw new Error('process.chdir is not supported');\n              };\n              process.umask = function () {\n                return 0;\n              };\n            },\n            {}\n          ],\n          2: [\n            function (require, module, exports) {\n              (function (setImmediate) {\n                (function (root) {\n                  var setTimeoutFunc = setTimeout;\n                  function noop() {\n                  }\n                  function bind(fn, thisArg) {\n                    return function () {\n                      fn.apply(thisArg, arguments);\n                    };\n                  }\n                  function Promise(fn) {\n                    if (typeof this !== 'object')\n                      throw new TypeError('Promises must be constructed via new');\n                    if (typeof fn !== 'function')\n                      throw new TypeError('not a function');\n                    this._state = 0;\n                    this._handled = false;\n                    this._value = undefined;\n                    this._deferreds = [];\n                    doResolve(fn, this);\n                  }\n                  function handle(self, deferred) {\n                    while (self._state === 3) {\n                      self = self._value;\n                    }\n                    if (self._state === 0) {\n                      self._deferreds.push(deferred);\n                      return;\n                    }\n                    self._handled = true;\n                    Promise._immediateFn(function () {\n                      var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;\n                      if (cb === null) {\n                        (self._state === 1 ? resolve : reject)(deferred.promise, self._value);\n                        return;\n                      }\n                      var ret;\n                      try {\n                        ret = cb(self._value);\n                      } catch (e) {\n                        reject(deferred.promise, e);\n                        return;\n                      }\n                      resolve(deferred.promise, ret);\n                    });\n                  }\n                  function resolve(self, newValue) {\n                    try {\n                      if (newValue === self)\n                        throw new TypeError('A promise cannot be resolved with itself.');\n                      if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {\n                        var then = newValue.then;\n                        if (newValue instanceof Promise) {\n                          self._state = 3;\n                          self._value = newValue;\n                          finale(self);\n                          return;\n                        } else if (typeof then === 'function') {\n                          doResolve(bind(then, newValue), self);\n                          return;\n                        }\n                      }\n                      self._state = 1;\n                      self._value = newValue;\n                      finale(self);\n                    } catch (e) {\n                      reject(self, e);\n                    }\n                  }\n                  function reject(self, newValue) {\n                    self._state = 2;\n                    self._value = newValue;\n                    finale(self);\n                  }\n                  function finale(self) {\n                    if (self._state === 2 && self._deferreds.length === 0) {\n                      Promise._immediateFn(function () {\n                        if (!self._handled) {\n                          Promise._unhandledRejectionFn(self._value);\n                        }\n                      });\n                    }\n                    for (var i = 0, len = self._deferreds.length; i < len; i++) {\n                      handle(self, self._deferreds[i]);\n                    }\n                    self._deferreds = null;\n                  }\n                  function Handler(onFulfilled, onRejected, promise) {\n                    this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n                    this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n                    this.promise = promise;\n                  }\n                  function doResolve(fn, self) {\n                    var done = false;\n                    try {\n                      fn(function (value) {\n                        if (done)\n                          return;\n                        done = true;\n                        resolve(self, value);\n                      }, function (reason) {\n                        if (done)\n                          return;\n                        done = true;\n                        reject(self, reason);\n                      });\n                    } catch (ex) {\n                      if (done)\n                        return;\n                      done = true;\n                      reject(self, ex);\n                    }\n                  }\n                  Promise.prototype['catch'] = function (onRejected) {\n                    return this.then(null, onRejected);\n                  };\n                  Promise.prototype.then = function (onFulfilled, onRejected) {\n                    var prom = new this.constructor(noop);\n                    handle(this, new Handler(onFulfilled, onRejected, prom));\n                    return prom;\n                  };\n                  Promise.all = function (arr) {\n                    var args = Array.prototype.slice.call(arr);\n                    return new Promise(function (resolve, reject) {\n                      if (args.length === 0)\n                        return resolve([]);\n                      var remaining = args.length;\n                      function res(i, val) {\n                        try {\n                          if (val && (typeof val === 'object' || typeof val === 'function')) {\n                            var then = val.then;\n                            if (typeof then === 'function') {\n                              then.call(val, function (val) {\n                                res(i, val);\n                              }, reject);\n                              return;\n                            }\n                          }\n                          args[i] = val;\n                          if (--remaining === 0) {\n                            resolve(args);\n                          }\n                        } catch (ex) {\n                          reject(ex);\n                        }\n                      }\n                      for (var i = 0; i < args.length; i++) {\n                        res(i, args[i]);\n                      }\n                    });\n                  };\n                  Promise.resolve = function (value) {\n                    if (value && typeof value === 'object' && value.constructor === Promise) {\n                      return value;\n                    }\n                    return new Promise(function (resolve) {\n                      resolve(value);\n                    });\n                  };\n                  Promise.reject = function (value) {\n                    return new Promise(function (resolve, reject) {\n                      reject(value);\n                    });\n                  };\n                  Promise.race = function (values) {\n                    return new Promise(function (resolve, reject) {\n                      for (var i = 0, len = values.length; i < len; i++) {\n                        values[i].then(resolve, reject);\n                      }\n                    });\n                  };\n                  Promise._immediateFn = typeof setImmediate === 'function' ? function (fn) {\n                    setImmediate(fn);\n                  } : function (fn) {\n                    setTimeoutFunc(fn, 0);\n                  };\n                  Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {\n                    if (typeof console !== 'undefined' && console) {\n                      console.warn('Possible Unhandled Promise Rejection:', err);\n                    }\n                  };\n                  Promise._setImmediateFn = function _setImmediateFn(fn) {\n                    Promise._immediateFn = fn;\n                  };\n                  Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {\n                    Promise._unhandledRejectionFn = fn;\n                  };\n                  if (typeof module !== 'undefined' && module.exports) {\n                    module.exports = Promise;\n                  } else if (!root.Promise) {\n                    root.Promise = Promise;\n                  }\n                }(this));\n              }.call(this, require('timers').setImmediate));\n            },\n            { 'timers': 3 }\n          ],\n          3: [\n            function (require, module, exports) {\n              (function (setImmediate, clearImmediate) {\n                var nextTick = require('process/browser.js').nextTick;\n                var apply = Function.prototype.apply;\n                var slice = Array.prototype.slice;\n                var immediateIds = {};\n                var nextImmediateId = 0;\n                exports.setTimeout = function () {\n                  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n                };\n                exports.setInterval = function () {\n                  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n                };\n                exports.clearTimeout = exports.clearInterval = function (timeout) {\n                  timeout.close();\n                };\n                function Timeout(id, clearFn) {\n                  this._id = id;\n                  this._clearFn = clearFn;\n                }\n                Timeout.prototype.unref = Timeout.prototype.ref = function () {\n                };\n                Timeout.prototype.close = function () {\n                  this._clearFn.call(window, this._id);\n                };\n                exports.enroll = function (item, msecs) {\n                  clearTimeout(item._idleTimeoutId);\n                  item._idleTimeout = msecs;\n                };\n                exports.unenroll = function (item) {\n                  clearTimeout(item._idleTimeoutId);\n                  item._idleTimeout = -1;\n                };\n                exports._unrefActive = exports.active = function (item) {\n                  clearTimeout(item._idleTimeoutId);\n                  var msecs = item._idleTimeout;\n                  if (msecs >= 0) {\n                    item._idleTimeoutId = setTimeout(function onTimeout() {\n                      if (item._onTimeout)\n                        item._onTimeout();\n                    }, msecs);\n                  }\n                };\n                exports.setImmediate = typeof setImmediate === 'function' ? setImmediate : function (fn) {\n                  var id = nextImmediateId++;\n                  var args = arguments.length < 2 ? false : slice.call(arguments, 1);\n                  immediateIds[id] = true;\n                  nextTick(function onNextTick() {\n                    if (immediateIds[id]) {\n                      if (args) {\n                        fn.apply(null, args);\n                      } else {\n                        fn.call(null);\n                      }\n                      exports.clearImmediate(id);\n                    }\n                  });\n                  return id;\n                };\n                exports.clearImmediate = typeof clearImmediate === 'function' ? clearImmediate : function (id) {\n                  delete immediateIds[id];\n                };\n              }.call(this, require('timers').setImmediate, require('timers').clearImmediate));\n            },\n            {\n              'process/browser.js': 1,\n              'timers': 3\n            }\n          ],\n          4: [\n            function (require, module, exports) {\n              var promisePolyfill = require('promise-polyfill');\n              var Global = function () {\n                if (typeof window !== 'undefined') {\n                  return window;\n                } else {\n                  return Function('return this;')();\n                }\n              }();\n              module.exports = { boltExport: Global.Promise || promisePolyfill };\n            },\n            { 'promise-polyfill': 2 }\n          ]\n        }, {}, [4])(4);\n      }));\n    }(undefined, exports$1, module, undefined));\n    var Promise$1 = module.exports.boltExport;\n\n    var nu$7 = function (baseFn) {\n      var data = Option.none();\n      var callbacks = [];\n      var map = function (f) {\n        return nu$7(function (nCallback) {\n          get(function (data) {\n            nCallback(f(data));\n          });\n        });\n      };\n      var get = function (nCallback) {\n        if (isReady()) {\n          call(nCallback);\n        } else {\n          callbacks.push(nCallback);\n        }\n      };\n      var set = function (x) {\n        data = Option.some(x);\n        run(callbacks);\n        callbacks = [];\n      };\n      var isReady = function () {\n        return data.isSome();\n      };\n      var run = function (cbs) {\n        each$1(cbs, call);\n      };\n      var call = function (cb) {\n        data.each(function (x) {\n          domGlobals.setTimeout(function () {\n            cb(x);\n          }, 0);\n        });\n      };\n      baseFn(set);\n      return {\n        get: get,\n        map: map,\n        isReady: isReady\n      };\n    };\n    var pure$1 = function (a) {\n      return nu$7(function (callback) {\n        callback(a);\n      });\n    };\n    var LazyValue = {\n      nu: nu$7,\n      pure: pure$1\n    };\n\n    var errorReporter = function (err) {\n      domGlobals.setTimeout(function () {\n        throw err;\n      }, 0);\n    };\n    var make$4 = function (run) {\n      var get = function (callback) {\n        run().then(callback, errorReporter);\n      };\n      var map = function (fab) {\n        return make$4(function () {\n          return run().then(fab);\n        });\n      };\n      var bind = function (aFutureB) {\n        return make$4(function () {\n          return run().then(function (v) {\n            return aFutureB(v).toPromise();\n          });\n        });\n      };\n      var anonBind = function (futureB) {\n        return make$4(function () {\n          return run().then(function () {\n            return futureB.toPromise();\n          });\n        });\n      };\n      var toLazy = function () {\n        return LazyValue.nu(get);\n      };\n      var toCached = function () {\n        var cache = null;\n        return make$4(function () {\n          if (cache === null) {\n            cache = run();\n          }\n          return cache;\n        });\n      };\n      var toPromise = run;\n      return {\n        map: map,\n        bind: bind,\n        anonBind: anonBind,\n        toLazy: toLazy,\n        toCached: toCached,\n        toPromise: toPromise,\n        get: get\n      };\n    };\n    var nu$8 = function (baseFn) {\n      return make$4(function () {\n        return new Promise$1(baseFn);\n      });\n    };\n    var pure$2 = function (a) {\n      return make$4(function () {\n        return Promise$1.resolve(a);\n      });\n    };\n    var Future = {\n      nu: nu$8,\n      pure: pure$2\n    };\n\n    var adjust = function (value, destination, amount) {\n      if (Math.abs(value - destination) <= amount) {\n        return Option.none();\n      } else if (value < destination) {\n        return Option.some(value + amount);\n      } else {\n        return Option.some(value - amount);\n      }\n    };\n    var create$5 = function () {\n      var interval = null;\n      var animate = function (getCurrent, destination, amount, increment, doFinish, rate) {\n        var finished = false;\n        var finish = function (v) {\n          finished = true;\n          doFinish(v);\n        };\n        global$4.clearInterval(interval);\n        var abort = function (v) {\n          global$4.clearInterval(interval);\n          finish(v);\n        };\n        interval = global$4.setInterval(function () {\n          var value = getCurrent();\n          adjust(value, destination, amount).fold(function () {\n            global$4.clearInterval(interval);\n            finish(destination);\n          }, function (s) {\n            increment(s, abort);\n            if (!finished) {\n              var newValue = getCurrent();\n              if (newValue !== s || Math.abs(newValue - destination) > Math.abs(value - destination)) {\n                global$4.clearInterval(interval);\n                finish(destination);\n              }\n            }\n          });\n        }, rate);\n      };\n      return { animate: animate };\n    };\n    var SmoothAnimation = {\n      create: create$5,\n      adjust: adjust\n    };\n\n    var findDevice = function (deviceWidth, deviceHeight) {\n      var devices = [\n        {\n          width: 320,\n          height: 480,\n          keyboard: {\n            portrait: 300,\n            landscape: 240\n          }\n        },\n        {\n          width: 320,\n          height: 568,\n          keyboard: {\n            portrait: 300,\n            landscape: 240\n          }\n        },\n        {\n          width: 375,\n          height: 667,\n          keyboard: {\n            portrait: 305,\n            landscape: 240\n          }\n        },\n        {\n          width: 414,\n          height: 736,\n          keyboard: {\n            portrait: 320,\n            landscape: 240\n          }\n        },\n        {\n          width: 768,\n          height: 1024,\n          keyboard: {\n            portrait: 320,\n            landscape: 400\n          }\n        },\n        {\n          width: 1024,\n          height: 1366,\n          keyboard: {\n            portrait: 380,\n            landscape: 460\n          }\n        }\n      ];\n      return findMap(devices, function (device) {\n        return someIf(deviceWidth <= device.width && deviceHeight <= device.height, device.keyboard);\n      }).getOr({\n        portrait: deviceHeight / 5,\n        landscape: deviceWidth / 4\n      });\n    };\n\n    var softKeyboardLimits = function (outerWindow) {\n      return findDevice(outerWindow.screen.width, outerWindow.screen.height);\n    };\n    var accountableKeyboardHeight = function (outerWindow) {\n      var portrait = Orientation.get(outerWindow).isPortrait();\n      var limits = softKeyboardLimits(outerWindow);\n      var keyboard = portrait ? limits.portrait : limits.landscape;\n      var visualScreenHeight = portrait ? outerWindow.screen.height : outerWindow.screen.width;\n      return visualScreenHeight - outerWindow.innerHeight > keyboard ? 0 : keyboard;\n    };\n    var getGreenzone = function (socket, dropup) {\n      var outerWindow = owner(socket).dom().defaultView;\n      var viewportHeight = get$4(socket) + get$4(dropup);\n      var acc = accountableKeyboardHeight(outerWindow);\n      return viewportHeight - acc;\n    };\n    var updatePadding = function (contentBody, socket, dropup) {\n      var greenzoneHeight = getGreenzone(socket, dropup);\n      var deltaHeight = get$4(socket) + get$4(dropup) - greenzoneHeight;\n      set$3(contentBody, 'padding-bottom', deltaHeight + 'px');\n    };\n    var DeviceZones = {\n      getGreenzone: getGreenzone,\n      updatePadding: updatePadding\n    };\n\n    var fixture = Adt.generate([\n      {\n        fixed: [\n          'element',\n          'property',\n          'offsetY'\n        ]\n      },\n      {\n        scroller: [\n          'element',\n          'offsetY'\n        ]\n      }\n    ]);\n    var yFixedData = 'data-' + Styles.resolve('position-y-fixed');\n    var yFixedProperty = 'data-' + Styles.resolve('y-property');\n    var yScrollingData = 'data-' + Styles.resolve('scrolling');\n    var windowSizeData = 'data-' + Styles.resolve('last-window-height');\n    var getYFixedData = function (element) {\n      return DataAttributes.safeParse(element, yFixedData);\n    };\n    var getYFixedProperty = function (element) {\n      return get(element, yFixedProperty);\n    };\n    var getLastWindowSize = function (element) {\n      return DataAttributes.safeParse(element, windowSizeData);\n    };\n    var classifyFixed = function (element, offsetY) {\n      var prop = getYFixedProperty(element);\n      return fixture.fixed(element, prop, offsetY);\n    };\n    var classifyScrolling = function (element, offsetY) {\n      return fixture.scroller(element, offsetY);\n    };\n    var classify = function (element) {\n      var offsetY = getYFixedData(element);\n      var classifier = get(element, yScrollingData) === 'true' ? classifyScrolling : classifyFixed;\n      return classifier(element, offsetY);\n    };\n    var findFixtures = function (container) {\n      var candidates = descendants(container, '[' + yFixedData + ']');\n      return map$1(candidates, classify);\n    };\n    var takeoverToolbar = function (toolbar) {\n      var oldToolbarStyle = get(toolbar, 'style');\n      setAll$1(toolbar, {\n        position: 'absolute',\n        top: '0px'\n      });\n      set(toolbar, yFixedData, '0px');\n      set(toolbar, yFixedProperty, 'top');\n      var restore = function () {\n        set(toolbar, 'style', oldToolbarStyle || '');\n        remove$1(toolbar, yFixedData);\n        remove$1(toolbar, yFixedProperty);\n      };\n      return { restore: restore };\n    };\n    var takeoverViewport = function (toolbarHeight, height, viewport) {\n      var oldViewportStyle = get(viewport, 'style');\n      Scrollable.register(viewport);\n      setAll$1(viewport, {\n        position: 'absolute',\n        height: height + 'px',\n        width: '100%',\n        top: toolbarHeight + 'px'\n      });\n      set(viewport, yFixedData, toolbarHeight + 'px');\n      set(viewport, yScrollingData, 'true');\n      set(viewport, yFixedProperty, 'top');\n      var restore = function () {\n        Scrollable.deregister(viewport);\n        set(viewport, 'style', oldViewportStyle || '');\n        remove$1(viewport, yFixedData);\n        remove$1(viewport, yScrollingData);\n        remove$1(viewport, yFixedProperty);\n      };\n      return { restore: restore };\n    };\n    var takeoverDropup = function (dropup, toolbarHeight, viewportHeight) {\n      var oldDropupStyle = get(dropup, 'style');\n      setAll$1(dropup, {\n        position: 'absolute',\n        bottom: '0px'\n      });\n      set(dropup, yFixedData, '0px');\n      set(dropup, yFixedProperty, 'bottom');\n      var restore = function () {\n        set(dropup, 'style', oldDropupStyle || '');\n        remove$1(dropup, yFixedData);\n        remove$1(dropup, yFixedProperty);\n      };\n      return { restore: restore };\n    };\n    var deriveViewportHeight = function (viewport, toolbarHeight, dropupHeight) {\n      var outerWindow = owner(viewport).dom().defaultView;\n      var winH = outerWindow.innerHeight;\n      set(viewport, windowSizeData, winH + 'px');\n      return winH - toolbarHeight - dropupHeight;\n    };\n    var takeover$1 = function (viewport, contentBody, toolbar, dropup) {\n      var outerWindow = owner(viewport).dom().defaultView;\n      var toolbarSetup = takeoverToolbar(toolbar);\n      var toolbarHeight = get$4(toolbar);\n      var dropupHeight = get$4(dropup);\n      var viewportHeight = deriveViewportHeight(viewport, toolbarHeight, dropupHeight);\n      var viewportSetup = takeoverViewport(toolbarHeight, viewportHeight, viewport);\n      var dropupSetup = takeoverDropup(dropup);\n      var isActive = true;\n      var restore = function () {\n        isActive = false;\n        toolbarSetup.restore();\n        viewportSetup.restore();\n        dropupSetup.restore();\n      };\n      var isExpanding = function () {\n        var currentWinHeight = outerWindow.innerHeight;\n        var lastWinHeight = getLastWindowSize(viewport);\n        return currentWinHeight > lastWinHeight;\n      };\n      var refresh = function () {\n        if (isActive) {\n          var newToolbarHeight = get$4(toolbar);\n          var dropupHeight_1 = get$4(dropup);\n          var newHeight = deriveViewportHeight(viewport, newToolbarHeight, dropupHeight_1);\n          set(viewport, yFixedData, newToolbarHeight + 'px');\n          set$3(viewport, 'height', newHeight + 'px');\n          DeviceZones.updatePadding(contentBody, viewport, dropup);\n        }\n      };\n      var setViewportOffset = function (newYOffset) {\n        var offsetPx = newYOffset + 'px';\n        set(viewport, yFixedData, offsetPx);\n        refresh();\n      };\n      DeviceZones.updatePadding(contentBody, viewport, dropup);\n      return {\n        setViewportOffset: setViewportOffset,\n        isExpanding: isExpanding,\n        isShrinking: not(isExpanding),\n        refresh: refresh,\n        restore: restore\n      };\n    };\n    var IosViewport = {\n      findFixtures: findFixtures,\n      takeover: takeover$1,\n      getYFixedData: getYFixedData\n    };\n\n    var animator = SmoothAnimation.create();\n    var ANIMATION_STEP = 15;\n    var NUM_TOP_ANIMATION_FRAMES = 10;\n    var ANIMATION_RATE = 10;\n    var lastScroll = 'data-' + Styles.resolve('last-scroll-top');\n    var getTop = function (element) {\n      var raw = getRaw(element, 'top').getOr('0');\n      return parseInt(raw, 10);\n    };\n    var getScrollTop = function (element) {\n      return parseInt(element.dom().scrollTop, 10);\n    };\n    var moveScrollAndTop = function (element, destination, finalTop) {\n      return Future.nu(function (callback) {\n        var getCurrent = curry(getScrollTop, element);\n        var update = function (newScroll) {\n          element.dom().scrollTop = newScroll;\n          set$3(element, 'top', getTop(element) + ANIMATION_STEP + 'px');\n        };\n        var finish = function () {\n          element.dom().scrollTop = destination;\n          set$3(element, 'top', finalTop + 'px');\n          callback(destination);\n        };\n        animator.animate(getCurrent, destination, ANIMATION_STEP, update, finish, ANIMATION_RATE);\n      });\n    };\n    var moveOnlyScroll = function (element, destination) {\n      return Future.nu(function (callback) {\n        var getCurrent = curry(getScrollTop, element);\n        set(element, lastScroll, getCurrent());\n        var update = function (newScroll, abort) {\n          var previous = DataAttributes.safeParse(element, lastScroll);\n          if (previous !== element.dom().scrollTop) {\n            abort(element.dom().scrollTop);\n          } else {\n            element.dom().scrollTop = newScroll;\n            set(element, lastScroll, newScroll);\n          }\n        };\n        var finish = function () {\n          element.dom().scrollTop = destination;\n          set(element, lastScroll, destination);\n          callback(destination);\n        };\n        var distance = Math.abs(destination - getCurrent());\n        var step = Math.ceil(distance / NUM_TOP_ANIMATION_FRAMES);\n        animator.animate(getCurrent, destination, step, update, finish, ANIMATION_RATE);\n      });\n    };\n    var moveOnlyTop = function (element, destination) {\n      return Future.nu(function (callback) {\n        var getCurrent = curry(getTop, element);\n        var update = function (newTop) {\n          set$3(element, 'top', newTop + 'px');\n        };\n        var finish = function () {\n          update(destination);\n          callback(destination);\n        };\n        var distance = Math.abs(destination - getCurrent());\n        var step = Math.ceil(distance / NUM_TOP_ANIMATION_FRAMES);\n        animator.animate(getCurrent, destination, step, update, finish, ANIMATION_RATE);\n      });\n    };\n    var updateTop = function (element, amount) {\n      var newTop = amount + IosViewport.getYFixedData(element) + 'px';\n      set$3(element, 'top', newTop);\n    };\n    var moveWindowScroll = function (toolbar, viewport, destY) {\n      var outerWindow = owner(toolbar).dom().defaultView;\n      return Future.nu(function (callback) {\n        updateTop(toolbar, destY);\n        updateTop(viewport, destY);\n        outerWindow.scrollTo(0, destY);\n        callback(destY);\n      });\n    };\n    var IosScrolling = {\n      moveScrollAndTop: moveScrollAndTop,\n      moveOnlyScroll: moveOnlyScroll,\n      moveOnlyTop: moveOnlyTop,\n      moveWindowScroll: moveWindowScroll\n    };\n\n    function BackgroundActivity (doAction) {\n      var action = Cell(LazyValue.pure({}));\n      var start = function (value) {\n        var future = LazyValue.nu(function (callback) {\n          return doAction(value).get(callback);\n        });\n        action.set(future);\n      };\n      var idle = function (g) {\n        action.get().get(function () {\n          g();\n        });\n      };\n      return {\n        start: start,\n        idle: idle\n      };\n    }\n\n    var scrollIntoView = function (cWin, socket, dropup, top, bottom) {\n      var greenzone = DeviceZones.getGreenzone(socket, dropup);\n      var refreshCursor = curry(CursorRefresh.refresh, cWin);\n      if (top > greenzone || bottom > greenzone) {\n        IosScrolling.moveOnlyScroll(socket, socket.dom().scrollTop - greenzone + bottom).get(refreshCursor);\n      } else if (top < 0) {\n        IosScrolling.moveOnlyScroll(socket, socket.dom().scrollTop + top).get(refreshCursor);\n      }\n    };\n    var Greenzone = { scrollIntoView: scrollIntoView };\n\n    var par = function (asyncValues, nu) {\n      return nu(function (callback) {\n        var r = [];\n        var count = 0;\n        var cb = function (i) {\n          return function (value) {\n            r[i] = value;\n            count++;\n            if (count >= asyncValues.length) {\n              callback(r);\n            }\n          };\n        };\n        if (asyncValues.length === 0) {\n          callback([]);\n        } else {\n          each$1(asyncValues, function (asyncValue, i) {\n            asyncValue.get(cb(i));\n          });\n        }\n      });\n    };\n\n    var par$1 = function (futures) {\n      return par(futures, Future.nu);\n    };\n\n    var updateFixed = function (element, property, winY, offsetY) {\n      var destination = winY + offsetY;\n      set$3(element, property, destination + 'px');\n      return Future.pure(offsetY);\n    };\n    var updateScrollingFixed = function (element, winY, offsetY) {\n      var destTop = winY + offsetY;\n      var oldProp = getRaw(element, 'top').getOr(offsetY);\n      var delta = destTop - parseInt(oldProp, 10);\n      var destScroll = element.dom().scrollTop + delta;\n      return IosScrolling.moveScrollAndTop(element, destScroll, destTop);\n    };\n    var updateFixture = function (fixture, winY) {\n      return fixture.fold(function (element, property, offsetY) {\n        return updateFixed(element, property, winY, offsetY);\n      }, function (element, offsetY) {\n        return updateScrollingFixed(element, winY, offsetY);\n      });\n    };\n    var updatePositions = function (container, winY) {\n      var fixtures = IosViewport.findFixtures(container);\n      var updates = map$1(fixtures, function (fixture) {\n        return updateFixture(fixture, winY);\n      });\n      return par$1(updates);\n    };\n    var IosUpdates = { updatePositions: updatePositions };\n\n    var VIEW_MARGIN = 5;\n    var register$2 = function (toolstrip, socket, container, outerWindow, structure, cWin) {\n      var scroller = BackgroundActivity(function (y) {\n        return IosScrolling.moveWindowScroll(toolstrip, socket, y);\n      });\n      var scrollBounds = function () {\n        var rects = Rectangles.getRectangles(cWin);\n        return Option.from(rects[0]).bind(function (rect) {\n          var viewTop = rect.top() - socket.dom().scrollTop;\n          var outside = viewTop > outerWindow.innerHeight + VIEW_MARGIN || viewTop < -VIEW_MARGIN;\n          return outside ? Option.some({\n            top: constant(viewTop),\n            bottom: constant(viewTop + rect.height())\n          }) : Option.none();\n        });\n      };\n      var scrollThrottle = last$1(function () {\n        scroller.idle(function () {\n          IosUpdates.updatePositions(container, outerWindow.pageYOffset).get(function () {\n            var extraScroll = scrollBounds();\n            extraScroll.each(function (extra) {\n              socket.dom().scrollTop = socket.dom().scrollTop + extra.top();\n            });\n            scroller.start(0);\n            structure.refresh();\n          });\n        });\n      }, 1000);\n      var onScroll = bind$3(Element.fromDom(outerWindow), 'scroll', function () {\n        if (outerWindow.pageYOffset < 0) {\n          return;\n        }\n        scrollThrottle.throttle();\n      });\n      IosUpdates.updatePositions(container, outerWindow.pageYOffset).get(identity);\n      return { unbind: onScroll.unbind };\n    };\n    var setup$3 = function (bag) {\n      var cWin = bag.cWin();\n      var ceBody = bag.ceBody();\n      var socket = bag.socket();\n      var toolstrip = bag.toolstrip();\n      var toolbar = bag.toolbar();\n      var contentElement = bag.contentElement();\n      var keyboardType = bag.keyboardType();\n      var outerWindow = bag.outerWindow();\n      var dropup = bag.dropup();\n      var structure = IosViewport.takeover(socket, ceBody, toolstrip, dropup);\n      var keyboardModel = keyboardType(bag.outerBody(), cWin, body(), contentElement, toolstrip, toolbar);\n      var toEditing = function () {\n        keyboardModel.toEditing();\n        clearSelection();\n      };\n      var toReading = function () {\n        keyboardModel.toReading();\n      };\n      var onToolbarTouch = function (event) {\n        keyboardModel.onToolbarTouch(event);\n      };\n      var onOrientation = Orientation.onChange(outerWindow, {\n        onChange: noop,\n        onReady: structure.refresh\n      });\n      onOrientation.onAdjustment(function () {\n        structure.refresh();\n      });\n      var onResize = bind$3(Element.fromDom(outerWindow), 'resize', function () {\n        if (structure.isExpanding()) {\n          structure.refresh();\n        }\n      });\n      var onScroll = register$2(toolstrip, socket, bag.outerBody(), outerWindow, structure, cWin);\n      var unfocusedSelection = FakeSelection(cWin, contentElement);\n      var refreshSelection = function () {\n        if (unfocusedSelection.isActive()) {\n          unfocusedSelection.update();\n        }\n      };\n      var highlightSelection = function () {\n        unfocusedSelection.update();\n      };\n      var clearSelection = function () {\n        unfocusedSelection.clear();\n      };\n      var scrollIntoView = function (top, bottom) {\n        Greenzone.scrollIntoView(cWin, socket, dropup, top, bottom);\n      };\n      var syncHeight = function () {\n        set$3(contentElement, 'height', contentElement.dom().contentWindow.document.body.scrollHeight + 'px');\n      };\n      var setViewportOffset = function (newYOffset) {\n        structure.setViewportOffset(newYOffset);\n        IosScrolling.moveOnlyTop(socket, newYOffset).get(identity);\n      };\n      var destroy = function () {\n        structure.restore();\n        onOrientation.destroy();\n        onScroll.unbind();\n        onResize.unbind();\n        keyboardModel.destroy();\n        unfocusedSelection.destroy();\n        CaptureBin.input(body(), blur);\n      };\n      return {\n        toEditing: toEditing,\n        toReading: toReading,\n        onToolbarTouch: onToolbarTouch,\n        refreshSelection: refreshSelection,\n        clearSelection: clearSelection,\n        highlightSelection: highlightSelection,\n        scrollIntoView: scrollIntoView,\n        updateToolbarPadding: noop,\n        setViewportOffset: setViewportOffset,\n        syncHeight: syncHeight,\n        refreshStructure: structure.refresh,\n        destroy: destroy\n      };\n    };\n    var IosSetup = { setup: setup$3 };\n\n    var create$6 = function (platform, mask) {\n      var meta = MetaViewport.tag();\n      var priorState = value$2();\n      var scrollEvents = value$2();\n      var iosApi = api$2();\n      var iosEvents = api$2();\n      var enter = function () {\n        mask.hide();\n        var doc = Element.fromDom(domGlobals.document);\n        PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) {\n          priorState.set({\n            socketHeight: getRaw(platform.socket, 'height'),\n            iframeHeight: getRaw(editorApi.frame(), 'height'),\n            outerScroll: domGlobals.document.body.scrollTop\n          });\n          scrollEvents.set({ exclusives: Scrollables.exclusive(doc, '.' + Scrollable.scrollable()) });\n          add$2(platform.container, Styles.resolve('fullscreen-maximized'));\n          Thor.clobberStyles(platform.container, editorApi.body());\n          meta.maximize();\n          set$3(platform.socket, 'overflow', 'scroll');\n          set$3(platform.socket, '-webkit-overflow-scrolling', 'touch');\n          focus$1(editorApi.body());\n          var setupBag = MixedBag([\n            'cWin',\n            'ceBody',\n            'socket',\n            'toolstrip',\n            'toolbar',\n            'dropup',\n            'contentElement',\n            'cursor',\n            'keyboardType',\n            'isScrolling',\n            'outerWindow',\n            'outerBody'\n          ], []);\n          iosApi.set(IosSetup.setup(setupBag({\n            cWin: editorApi.win(),\n            ceBody: editorApi.body(),\n            socket: platform.socket,\n            toolstrip: platform.toolstrip,\n            toolbar: platform.toolbar,\n            dropup: platform.dropup.element(),\n            contentElement: editorApi.frame(),\n            cursor: noop,\n            outerBody: platform.body,\n            outerWindow: platform.win,\n            keyboardType: IosKeyboard.stubborn,\n            isScrolling: function () {\n              var scrollValue = scrollEvents;\n              return scrollValue.get().exists(function (s) {\n                return s.socket.isScrolling();\n              });\n            }\n          })));\n          iosApi.run(function (api) {\n            api.syncHeight();\n          });\n          iosEvents.set(IosEvents.initEvents(editorApi, iosApi, platform.toolstrip, platform.socket, platform.dropup));\n        });\n      };\n      var exit = function () {\n        meta.restore();\n        iosEvents.clear();\n        iosApi.clear();\n        mask.show();\n        priorState.on(function (s) {\n          s.socketHeight.each(function (h) {\n            set$3(platform.socket, 'height', h);\n          });\n          s.iframeHeight.each(function (h) {\n            set$3(platform.editor.getFrame(), 'height', h);\n          });\n          domGlobals.document.body.scrollTop = s.scrollTop;\n        });\n        priorState.clear();\n        scrollEvents.on(function (s) {\n          s.exclusives.unbind();\n        });\n        scrollEvents.clear();\n        remove$4(platform.container, Styles.resolve('fullscreen-maximized'));\n        Thor.restoreStyles();\n        Scrollable.deregister(platform.toolbar);\n        remove$5(platform.socket, 'overflow');\n        remove$5(platform.socket, '-webkit-overflow-scrolling');\n        blur(platform.editor.getFrame());\n        PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) {\n          editorApi.clearSelection();\n        });\n      };\n      var refreshStructure = function () {\n        iosApi.run(function (api) {\n          api.refreshStructure();\n        });\n      };\n      return {\n        enter: enter,\n        refreshStructure: refreshStructure,\n        exit: exit\n      };\n    };\n    var IosMode = { create: create$6 };\n\n    var produce$1 = function (raw) {\n      var mobile = asRawOrDie('Getting IosWebapp schema', MobileSchema, raw);\n      set$3(mobile.toolstrip, 'width', '100%');\n      set$3(mobile.container, 'position', 'relative');\n      var onView = function () {\n        mobile.setReadOnly(mobile.readOnlyOnInit());\n        mode.enter();\n      };\n      var mask = build$1(TapToEditMask.sketch(onView, mobile.translate));\n      mobile.alloy.add(mask);\n      var maskApi = {\n        show: function () {\n          mobile.alloy.add(mask);\n        },\n        hide: function () {\n          mobile.alloy.remove(mask);\n        }\n      };\n      var mode = IosMode.create(mobile, maskApi);\n      return {\n        setReadOnly: mobile.setReadOnly,\n        refreshStructure: mode.refreshStructure,\n        enter: mode.enter,\n        exit: mode.exit,\n        destroy: noop\n      };\n    };\n    var IosWebapp = { produce: produce$1 };\n\n    function IosRealm (scrollIntoView) {\n      var alloy = OuterContainer({ classes: [Styles.resolve('ios-container')] });\n      var toolbar = ScrollingToolbar();\n      var webapp = api$2();\n      var switchToEdit = CommonRealm.makeEditSwitch(webapp);\n      var socket = CommonRealm.makeSocket();\n      var dropup = build$2(function () {\n        webapp.run(function (w) {\n          w.refreshStructure();\n        });\n      }, scrollIntoView);\n      alloy.add(toolbar.wrapper());\n      alloy.add(socket);\n      alloy.add(dropup.component());\n      var setToolbarGroups = function (rawGroups) {\n        var groups = toolbar.createGroups(rawGroups);\n        toolbar.setGroups(groups);\n      };\n      var setContextToolbar = function (rawGroups) {\n        var groups = toolbar.createGroups(rawGroups);\n        toolbar.setContextToolbar(groups);\n      };\n      var focusToolbar = function () {\n        toolbar.focus();\n      };\n      var restoreToolbar = function () {\n        toolbar.restoreToolbar();\n      };\n      var init = function (spec) {\n        webapp.set(IosWebapp.produce(spec));\n      };\n      var exit = function () {\n        webapp.run(function (w) {\n          Replacing.remove(socket, switchToEdit);\n          w.exit();\n        });\n      };\n      var updateMode = function (readOnly) {\n        CommonRealm.updateMode(socket, switchToEdit, readOnly, alloy.root());\n      };\n      return {\n        system: constant(alloy),\n        element: alloy.element,\n        init: init,\n        exit: exit,\n        setToolbarGroups: setToolbarGroups,\n        setContextToolbar: setContextToolbar,\n        focusToolbar: focusToolbar,\n        restoreToolbar: restoreToolbar,\n        updateMode: updateMode,\n        socket: constant(socket),\n        dropup: constant(dropup)\n      };\n    }\n\n    var global$5 = tinymce.util.Tools.resolve('tinymce.EditorManager');\n\n    var derive$3 = function (editor) {\n      var base = readOptFrom$1(editor.settings, 'skin_url').fold(function () {\n        return global$5.baseURL + '/skins/ui/oxide';\n      }, function (url) {\n        return url;\n      });\n      return {\n        content: base + '/content.mobile.min.css',\n        ui: base + '/skin.mobile.min.css'\n      };\n    };\n    var CssUrls = { derive: derive$3 };\n\n    var fontSizes = [\n      'x-small',\n      'small',\n      'medium',\n      'large',\n      'x-large'\n    ];\n    var fireChange = function (realm, command, state) {\n      realm.system().broadcastOn([TinyChannels.formatChanged()], {\n        command: command,\n        state: state\n      });\n    };\n    var init$5 = function (realm, editor) {\n      var allFormats = keys(editor.formatter.get());\n      each$1(allFormats, function (command) {\n        editor.formatter.formatChanged(command, function (state) {\n          fireChange(realm, command, state);\n        });\n      });\n      each$1([\n        'ul',\n        'ol'\n      ], function (command) {\n        editor.selection.selectorChanged(command, function (state, data) {\n          fireChange(realm, command, state);\n        });\n      });\n    };\n    var FormatChangers = {\n      init: init$5,\n      fontSizes: constant(fontSizes)\n    };\n\n    var fireSkinLoaded = function (editor) {\n      var done = function () {\n        editor._skinLoaded = true;\n        editor.fire('SkinLoaded');\n      };\n      return function () {\n        if (editor.initialized) {\n          done();\n        } else {\n          editor.on('init', done);\n        }\n      };\n    };\n    var SkinLoaded = { fireSkinLoaded: fireSkinLoaded };\n\n    var READING = constant('toReading');\n    var EDITING = constant('toEditing');\n    var renderMobileTheme = function (editor) {\n      var renderUI = function () {\n        var targetNode = editor.getElement();\n        var cssUrls = CssUrls.derive(editor);\n        if (isSkinDisabled(editor) === false) {\n          editor.contentCSS.push(cssUrls.content);\n          global$1.DOM.styleSheetLoader.load(cssUrls.ui, SkinLoaded.fireSkinLoaded(editor));\n        } else {\n          SkinLoaded.fireSkinLoaded(editor)();\n        }\n        var doScrollIntoView = function () {\n          editor.fire('ScrollIntoView');\n        };\n        var realm = detect$3().os.isAndroid() ? AndroidRealm(doScrollIntoView) : IosRealm(doScrollIntoView);\n        var original = Element.fromDom(targetNode);\n        attachSystemAfter(original, realm.system());\n        var findFocusIn = function (elem) {\n          return search(elem).bind(function (focused) {\n            return realm.system().getByDom(focused).toOption();\n          });\n        };\n        var outerWindow = targetNode.ownerDocument.defaultView;\n        var orientation = Orientation.onChange(outerWindow, {\n          onChange: function () {\n            var alloy = realm.system();\n            alloy.broadcastOn([TinyChannels.orientationChanged()], { width: Orientation.getActualWidth(outerWindow) });\n          },\n          onReady: noop\n        });\n        var setReadOnly = function (dynamicGroup, readOnlyGroups, mainGroups, ro) {\n          if (ro === false) {\n            editor.selection.collapse();\n          }\n          var toolbars = configureToolbar(dynamicGroup, readOnlyGroups, mainGroups);\n          realm.setToolbarGroups(ro === true ? toolbars.readOnly : toolbars.main);\n          editor.setMode(ro === true ? 'readonly' : 'design');\n          editor.fire(ro === true ? READING() : EDITING());\n          realm.updateMode(ro);\n        };\n        var configureToolbar = function (dynamicGroup, readOnlyGroups, mainGroups) {\n          var dynamic = dynamicGroup.get();\n          var toolbars = {\n            readOnly: dynamic.backToMask.concat(readOnlyGroups.get()),\n            main: dynamic.backToMask.concat(mainGroups.get())\n          };\n          return toolbars;\n        };\n        var bindHandler = function (label, handler) {\n          editor.on(label, handler);\n          return {\n            unbind: function () {\n              editor.off(label);\n            }\n          };\n        };\n        editor.on('init', function () {\n          realm.init({\n            editor: {\n              getFrame: function () {\n                return Element.fromDom(editor.contentAreaContainer.querySelector('iframe'));\n              },\n              onDomChanged: function () {\n                return { unbind: noop };\n              },\n              onToReading: function (handler) {\n                return bindHandler(READING(), handler);\n              },\n              onToEditing: function (handler) {\n                return bindHandler(EDITING(), handler);\n              },\n              onScrollToCursor: function (handler) {\n                editor.on('ScrollIntoView', function (tinyEvent) {\n                  handler(tinyEvent);\n                });\n                var unbind = function () {\n                  editor.off('ScrollIntoView');\n                  orientation.destroy();\n                };\n                return { unbind: unbind };\n              },\n              onTouchToolstrip: function () {\n                hideDropup();\n              },\n              onTouchContent: function () {\n                var toolbar = Element.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolbar')));\n                findFocusIn(toolbar).each(emitExecute);\n                realm.restoreToolbar();\n                hideDropup();\n              },\n              onTapContent: function (evt) {\n                var target = evt.target();\n                if (name(target) === 'img') {\n                  editor.selection.select(target.dom());\n                  evt.kill();\n                } else if (name(target) === 'a') {\n                  var component = realm.system().getByDom(Element.fromDom(editor.editorContainer));\n                  component.each(function (container) {\n                    if (Swapping.isAlpha(container)) {\n                      TinyCodeDupe.openLink(target.dom());\n                    }\n                  });\n                }\n              }\n            },\n            container: Element.fromDom(editor.editorContainer),\n            socket: Element.fromDom(editor.contentAreaContainer),\n            toolstrip: Element.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolstrip'))),\n            toolbar: Element.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolbar'))),\n            dropup: realm.dropup(),\n            alloy: realm.system(),\n            translate: noop,\n            setReadOnly: function (ro) {\n              setReadOnly(dynamicGroup, readOnlyGroups, mainGroups, ro);\n            },\n            readOnlyOnInit: function () {\n              return readOnlyOnInit();\n            }\n          });\n          var hideDropup = function () {\n            realm.dropup().disappear(function () {\n              realm.system().broadcastOn([TinyChannels.dropupDismissed()], {});\n            });\n          };\n          var backToMaskGroup = {\n            label: 'The first group',\n            scrollable: false,\n            items: [Buttons.forToolbar('back', function () {\n                editor.selection.collapse();\n                realm.exit();\n              }, {}, editor)]\n          };\n          var backToReadOnlyGroup = {\n            label: 'Back to read only',\n            scrollable: false,\n            items: [Buttons.forToolbar('readonly-back', function () {\n                setReadOnly(dynamicGroup, readOnlyGroups, mainGroups, true);\n              }, {}, editor)]\n          };\n          var readOnlyGroup = {\n            label: 'The read only mode group',\n            scrollable: true,\n            items: []\n          };\n          var features = Features.setup(realm, editor);\n          var items = Features.detect(editor.settings, features);\n          var actionGroup = {\n            label: 'the action group',\n            scrollable: true,\n            items: items\n          };\n          var extraGroup = {\n            label: 'The extra group',\n            scrollable: false,\n            items: []\n          };\n          var mainGroups = Cell([\n            actionGroup,\n            extraGroup\n          ]);\n          var readOnlyGroups = Cell([\n            readOnlyGroup,\n            extraGroup\n          ]);\n          var dynamicGroup = Cell({\n            backToMask: [backToMaskGroup],\n            backToReadOnly: [backToReadOnlyGroup]\n          });\n          FormatChangers.init(realm, editor);\n        });\n        editor.on('remove', function () {\n          realm.exit();\n        });\n        editor.on('detach', function () {\n          detachSystem(realm.system());\n          realm.system().destroy();\n        });\n        return {\n          iframeContainer: realm.socket().element().dom(),\n          editorContainer: realm.element().dom()\n        };\n      };\n      return {\n        getNotificationManagerImpl: function () {\n          return {\n            open: constant({\n              progressBar: { value: noop },\n              close: noop,\n              text: noop,\n              getEl: constant(null),\n              moveTo: noop,\n              moveRel: noop,\n              settings: {}\n            }),\n            close: noop,\n            reposition: noop,\n            getArgs: constant({})\n          };\n        },\n        renderUI: renderUI\n      };\n    };\n    function Theme () {\n      global$2.add('mobile', renderMobileTheme);\n    }\n\n    Theme();\n\n}(window));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack:///./node_modules/tinymce/themes/mobile/theme.js?");

/***/ }),

/***/ "./node_modules/tinymce/themes/silver/theme.js":
/*!*****************************************************!*\
  !*** ./node_modules/tinymce/themes/silver/theme.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Copyright (c) Tiny Technologies, Inc. All rights reserved.\n * Licensed under the LGPL or a commercial license.\n * For LGPL see License.txt in the project root for license information.\n * For commercial licenses see https://www.tiny.cloud/\n *\n * Version: 5.1.5 (2019-12-19)\n */\n(function (domGlobals) {\n    'use strict';\n\n    var noop = function () {\n    };\n    var noarg = function (f) {\n      return function () {\n        return f();\n      };\n    };\n    var compose = function (fa, fb) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return fa(fb.apply(null, args));\n      };\n    };\n    var constant = function (value) {\n      return function () {\n        return value;\n      };\n    };\n    var identity = function (x) {\n      return x;\n    };\n    function curry(fn) {\n      var initialArgs = [];\n      for (var _i = 1; _i < arguments.length; _i++) {\n        initialArgs[_i - 1] = arguments[_i];\n      }\n      return function () {\n        var restArgs = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          restArgs[_i] = arguments[_i];\n        }\n        var all = initialArgs.concat(restArgs);\n        return fn.apply(null, all);\n      };\n    }\n    var not = function (f) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return !f.apply(null, args);\n      };\n    };\n    var die = function (msg) {\n      return function () {\n        throw new Error(msg);\n      };\n    };\n    var never = constant(false);\n    var always = constant(true);\n\n    var global$1 = tinymce.util.Tools.resolve('tinymce.ThemeManager');\n\n    var __assign = function () {\n      __assign = Object.assign || function __assign(t) {\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\n          s = arguments[i];\n          for (var p in s)\n            if (Object.prototype.hasOwnProperty.call(s, p))\n              t[p] = s[p];\n        }\n        return t;\n      };\n      return __assign.apply(this, arguments);\n    };\n    function __rest(s, e) {\n      var t = {};\n      for (var p in s)\n        if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n          t[p] = s[p];\n      if (s != null && typeof Object.getOwnPropertySymbols === 'function')\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n          if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n            t[p[i]] = s[p[i]];\n        }\n      return t;\n    }\n    function __spreadArrays() {\n      for (var s = 0, i = 0, il = arguments.length; i < il; i++)\n        s += arguments[i].length;\n      for (var r = Array(s), k = 0, i = 0; i < il; i++)\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n          r[k] = a[j];\n      return r;\n    }\n\n    var none = function () {\n      return NONE;\n    };\n    var NONE = function () {\n      var eq = function (o) {\n        return o.isNone();\n      };\n      var call = function (thunk) {\n        return thunk();\n      };\n      var id = function (n) {\n        return n;\n      };\n      var me = {\n        fold: function (n, s) {\n          return n();\n        },\n        is: never,\n        isSome: never,\n        isNone: always,\n        getOr: id,\n        getOrThunk: call,\n        getOrDie: function (msg) {\n          throw new Error(msg || 'error: getOrDie called on none.');\n        },\n        getOrNull: constant(null),\n        getOrUndefined: constant(undefined),\n        or: id,\n        orThunk: call,\n        map: none,\n        each: noop,\n        bind: none,\n        exists: never,\n        forall: always,\n        filter: none,\n        equals: eq,\n        equals_: eq,\n        toArray: function () {\n          return [];\n        },\n        toString: constant('none()')\n      };\n      if (Object.freeze) {\n        Object.freeze(me);\n      }\n      return me;\n    }();\n    var some = function (a) {\n      var constant_a = constant(a);\n      var self = function () {\n        return me;\n      };\n      var bind = function (f) {\n        return f(a);\n      };\n      var me = {\n        fold: function (n, s) {\n          return s(a);\n        },\n        is: function (v) {\n          return a === v;\n        },\n        isSome: always,\n        isNone: never,\n        getOr: constant_a,\n        getOrThunk: constant_a,\n        getOrDie: constant_a,\n        getOrNull: constant_a,\n        getOrUndefined: constant_a,\n        or: self,\n        orThunk: self,\n        map: function (f) {\n          return some(f(a));\n        },\n        each: function (f) {\n          f(a);\n        },\n        bind: bind,\n        exists: bind,\n        forall: bind,\n        filter: function (f) {\n          return f(a) ? me : NONE;\n        },\n        toArray: function () {\n          return [a];\n        },\n        toString: function () {\n          return 'some(' + a + ')';\n        },\n        equals: function (o) {\n          return o.is(a);\n        },\n        equals_: function (o, elementEq) {\n          return o.fold(never, function (b) {\n            return elementEq(a, b);\n          });\n        }\n      };\n      return me;\n    };\n    var from = function (value) {\n      return value === null || value === undefined ? NONE : some(value);\n    };\n    var Option = {\n      some: some,\n      none: none,\n      from: from\n    };\n\n    var value = function (o) {\n      var is = function (v) {\n        return o === v;\n      };\n      var or = function (opt) {\n        return value(o);\n      };\n      var orThunk = function (f) {\n        return value(o);\n      };\n      var map = function (f) {\n        return value(f(o));\n      };\n      var mapError = function (f) {\n        return value(o);\n      };\n      var each = function (f) {\n        f(o);\n      };\n      var bind = function (f) {\n        return f(o);\n      };\n      var fold = function (_, onValue) {\n        return onValue(o);\n      };\n      var exists = function (f) {\n        return f(o);\n      };\n      var forall = function (f) {\n        return f(o);\n      };\n      var toOption = function () {\n        return Option.some(o);\n      };\n      return {\n        is: is,\n        isValue: always,\n        isError: never,\n        getOr: constant(o),\n        getOrThunk: constant(o),\n        getOrDie: constant(o),\n        or: or,\n        orThunk: orThunk,\n        fold: fold,\n        map: map,\n        mapError: mapError,\n        each: each,\n        bind: bind,\n        exists: exists,\n        forall: forall,\n        toOption: toOption\n      };\n    };\n    var error = function (message) {\n      var getOrThunk = function (f) {\n        return f();\n      };\n      var getOrDie = function () {\n        return die(String(message))();\n      };\n      var or = function (opt) {\n        return opt;\n      };\n      var orThunk = function (f) {\n        return f();\n      };\n      var map = function (f) {\n        return error(message);\n      };\n      var mapError = function (f) {\n        return error(f(message));\n      };\n      var bind = function (f) {\n        return error(message);\n      };\n      var fold = function (onError, _) {\n        return onError(message);\n      };\n      return {\n        is: never,\n        isValue: never,\n        isError: always,\n        getOr: identity,\n        getOrThunk: getOrThunk,\n        getOrDie: getOrDie,\n        or: or,\n        orThunk: orThunk,\n        fold: fold,\n        map: map,\n        mapError: mapError,\n        each: noop,\n        bind: bind,\n        exists: never,\n        forall: always,\n        toOption: Option.none\n      };\n    };\n    var fromOption = function (opt, err) {\n      return opt.fold(function () {\n        return error(err);\n      }, value);\n    };\n    var Result = {\n      value: value,\n      error: error,\n      fromOption: fromOption\n    };\n\n    var typeOf = function (x) {\n      if (x === null) {\n        return 'null';\n      }\n      var t = typeof x;\n      if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {\n        return 'array';\n      }\n      if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {\n        return 'string';\n      }\n      return t;\n    };\n    var isType = function (type) {\n      return function (value) {\n        return typeOf(value) === type;\n      };\n    };\n    var isString = isType('string');\n    var isObject = isType('object');\n    var isArray = isType('array');\n    var isBoolean = isType('boolean');\n    var isFunction = isType('function');\n    var isNumber = isType('number');\n    var isArrayOf = function (value, pred) {\n      if (isArray(value)) {\n        for (var i = 0, len = value.length; i < len; ++i) {\n          if (pred(value[i]) !== true) {\n            return false;\n          }\n        }\n        return true;\n      }\n      return false;\n    };\n\n    var nativeSlice = Array.prototype.slice;\n    var nativeIndexOf = Array.prototype.indexOf;\n    var nativePush = Array.prototype.push;\n    var rawIndexOf = function (ts, t) {\n      return nativeIndexOf.call(ts, t);\n    };\n    var indexOf = function (xs, x) {\n      var r = rawIndexOf(xs, x);\n      return r === -1 ? Option.none() : Option.some(r);\n    };\n    var contains = function (xs, x) {\n      return rawIndexOf(xs, x) > -1;\n    };\n    var exists = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return true;\n        }\n      }\n      return false;\n    };\n    var range = function (num, f) {\n      var r = [];\n      for (var i = 0; i < num; i++) {\n        r.push(f(i));\n      }\n      return r;\n    };\n    var chunk = function (array, size) {\n      var r = [];\n      for (var i = 0; i < array.length; i += size) {\n        var s = nativeSlice.call(array, i, i + size);\n        r.push(s);\n      }\n      return r;\n    };\n    var map = function (xs, f) {\n      var len = xs.length;\n      var r = new Array(len);\n      for (var i = 0; i < len; i++) {\n        var x = xs[i];\n        r[i] = f(x, i);\n      }\n      return r;\n    };\n    var each = function (xs, f) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        f(x, i);\n      }\n    };\n    var eachr = function (xs, f) {\n      for (var i = xs.length - 1; i >= 0; i--) {\n        var x = xs[i];\n        f(x, i);\n      }\n    };\n    var partition = function (xs, pred) {\n      var pass = [];\n      var fail = [];\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        var arr = pred(x, i) ? pass : fail;\n        arr.push(x);\n      }\n      return {\n        pass: pass,\n        fail: fail\n      };\n    };\n    var filter = function (xs, pred) {\n      var r = [];\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          r.push(x);\n        }\n      }\n      return r;\n    };\n    var foldr = function (xs, f, acc) {\n      eachr(xs, function (x) {\n        acc = f(acc, x);\n      });\n      return acc;\n    };\n    var foldl = function (xs, f, acc) {\n      each(xs, function (x) {\n        acc = f(acc, x);\n      });\n      return acc;\n    };\n    var find = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return Option.some(x);\n        }\n      }\n      return Option.none();\n    };\n    var findIndex = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return Option.some(i);\n        }\n      }\n      return Option.none();\n    };\n    var flatten = function (xs) {\n      var r = [];\n      for (var i = 0, len = xs.length; i < len; ++i) {\n        if (!isArray(xs[i])) {\n          throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);\n        }\n        nativePush.apply(r, xs[i]);\n      }\n      return r;\n    };\n    var bind = function (xs, f) {\n      var output = map(xs, f);\n      return flatten(output);\n    };\n    var forall = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; ++i) {\n        var x = xs[i];\n        if (pred(x, i) !== true) {\n          return false;\n        }\n      }\n      return true;\n    };\n    var reverse = function (xs) {\n      var r = nativeSlice.call(xs, 0);\n      r.reverse();\n      return r;\n    };\n    var difference = function (a1, a2) {\n      return filter(a1, function (x) {\n        return !contains(a2, x);\n      });\n    };\n    var pure = function (x) {\n      return [x];\n    };\n    var sort = function (xs, comparator) {\n      var copy = nativeSlice.call(xs, 0);\n      copy.sort(comparator);\n      return copy;\n    };\n    var head = function (xs) {\n      return xs.length === 0 ? Option.none() : Option.some(xs[0]);\n    };\n    var last = function (xs) {\n      return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]);\n    };\n    var from$1 = isFunction(Array.from) ? Array.from : function (x) {\n      return nativeSlice.call(x);\n    };\n\n    var keys = Object.keys;\n    var hasOwnProperty = Object.hasOwnProperty;\n    var each$1 = function (obj, f) {\n      var props = keys(obj);\n      for (var k = 0, len = props.length; k < len; k++) {\n        var i = props[k];\n        var x = obj[i];\n        f(x, i);\n      }\n    };\n    var map$1 = function (obj, f) {\n      return tupleMap(obj, function (x, i) {\n        return {\n          k: i,\n          v: f(x, i)\n        };\n      });\n    };\n    var tupleMap = function (obj, f) {\n      var r = {};\n      each$1(obj, function (x, i) {\n        var tuple = f(x, i);\n        r[tuple.k] = tuple.v;\n      });\n      return r;\n    };\n    var mapToArray = function (obj, f) {\n      var r = [];\n      each$1(obj, function (value, name) {\n        r.push(f(value, name));\n      });\n      return r;\n    };\n    var find$1 = function (obj, pred) {\n      var props = keys(obj);\n      for (var k = 0, len = props.length; k < len; k++) {\n        var i = props[k];\n        var x = obj[i];\n        if (pred(x, i, obj)) {\n          return Option.some(x);\n        }\n      }\n      return Option.none();\n    };\n    var values = function (obj) {\n      return mapToArray(obj, function (v) {\n        return v;\n      });\n    };\n    var get = function (obj, key) {\n      return has(obj, key) ? Option.from(obj[key]) : Option.none();\n    };\n    var has = function (obj, key) {\n      return hasOwnProperty.call(obj, key);\n    };\n\n    var generate = function (cases) {\n      if (!isArray(cases)) {\n        throw new Error('cases must be an array');\n      }\n      if (cases.length === 0) {\n        throw new Error('there must be at least one case');\n      }\n      var constructors = [];\n      var adt = {};\n      each(cases, function (acase, count) {\n        var keys$1 = keys(acase);\n        if (keys$1.length !== 1) {\n          throw new Error('one and only one name per case');\n        }\n        var key = keys$1[0];\n        var value = acase[key];\n        if (adt[key] !== undefined) {\n          throw new Error('duplicate key detected:' + key);\n        } else if (key === 'cata') {\n          throw new Error('cannot have a case named cata (sorry)');\n        } else if (!isArray(value)) {\n          throw new Error('case arguments must be an array');\n        }\n        constructors.push(key);\n        adt[key] = function () {\n          var argLength = arguments.length;\n          if (argLength !== value.length) {\n            throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);\n          }\n          var args = new Array(argLength);\n          for (var i = 0; i < args.length; i++) {\n            args[i] = arguments[i];\n          }\n          var match = function (branches) {\n            var branchKeys = keys(branches);\n            if (constructors.length !== branchKeys.length) {\n              throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\\nActual: ' + branchKeys.join(','));\n            }\n            var allReqd = forall(constructors, function (reqKey) {\n              return contains(branchKeys, reqKey);\n            });\n            if (!allReqd) {\n              throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\\nRequired: ' + constructors.join(', '));\n            }\n            return branches[key].apply(null, args);\n          };\n          return {\n            fold: function () {\n              if (arguments.length !== cases.length) {\n                throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length);\n              }\n              var target = arguments[count];\n              return target.apply(null, args);\n            },\n            match: match,\n            log: function (label) {\n              domGlobals.console.log(label, {\n                constructors: constructors,\n                constructor: key,\n                params: args\n              });\n            }\n          };\n        };\n      });\n      return adt;\n    };\n    var Adt = { generate: generate };\n\n    var hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n    var shallow = function (old, nu) {\n      return nu;\n    };\n    var deep = function (old, nu) {\n      var bothObjects = isObject(old) && isObject(nu);\n      return bothObjects ? deepMerge(old, nu) : nu;\n    };\n    var baseMerge = function (merger) {\n      return function () {\n        var objects = new Array(arguments.length);\n        for (var i = 0; i < objects.length; i++) {\n          objects[i] = arguments[i];\n        }\n        if (objects.length === 0) {\n          throw new Error('Can\\'t merge zero objects');\n        }\n        var ret = {};\n        for (var j = 0; j < objects.length; j++) {\n          var curObject = objects[j];\n          for (var key in curObject) {\n            if (hasOwnProperty$1.call(curObject, key)) {\n              ret[key] = merger(ret[key], curObject[key]);\n            }\n          }\n        }\n        return ret;\n      };\n    };\n    var deepMerge = baseMerge(deep);\n    var merge = baseMerge(shallow);\n\n    var cached = function (f) {\n      var called = false;\n      var r;\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (!called) {\n          called = true;\n          r = f.apply(null, args);\n        }\n        return r;\n      };\n    };\n\n    var adt = Adt.generate([\n      { strict: [] },\n      { defaultedThunk: ['fallbackThunk'] },\n      { asOption: [] },\n      { asDefaultedOptionThunk: ['fallbackThunk'] },\n      { mergeWithThunk: ['baseThunk'] }\n    ]);\n    var defaulted = function (fallback) {\n      return adt.defaultedThunk(constant(fallback));\n    };\n    var mergeWith = function (base) {\n      return adt.mergeWithThunk(constant(base));\n    };\n    var strict = adt.strict;\n    var asOption = adt.asOption;\n    var defaultedThunk = adt.defaultedThunk;\n    var mergeWithThunk = adt.mergeWithThunk;\n\n    var exclude = function (obj, fields) {\n      var r = {};\n      each$1(obj, function (v, k) {\n        if (!contains(fields, k)) {\n          r[k] = v;\n        }\n      });\n      return r;\n    };\n\n    var readOpt = function (key) {\n      return function (obj) {\n        return has(obj, key) ? Option.from(obj[key]) : Option.none();\n      };\n    };\n    var readOr = function (key, fallback) {\n      return function (obj) {\n        return has(obj, key) ? obj[key] : fallback;\n      };\n    };\n    var readOptFrom = function (obj, key) {\n      return readOpt(key)(obj);\n    };\n    var hasKey = function (obj, key) {\n      return has(obj, key) && obj[key] !== undefined && obj[key] !== null;\n    };\n\n    var wrap = function (key, value) {\n      var r = {};\n      r[key] = value;\n      return r;\n    };\n    var wrapAll = function (keyvalues) {\n      var r = {};\n      each(keyvalues, function (kv) {\n        r[kv.key] = kv.value;\n      });\n      return r;\n    };\n\n    var comparison = Adt.generate([\n      {\n        bothErrors: [\n          'error1',\n          'error2'\n        ]\n      },\n      {\n        firstError: [\n          'error1',\n          'value2'\n        ]\n      },\n      {\n        secondError: [\n          'value1',\n          'error2'\n        ]\n      },\n      {\n        bothValues: [\n          'value1',\n          'value2'\n        ]\n      }\n    ]);\n    var partition$1 = function (results) {\n      var errors = [];\n      var values = [];\n      each(results, function (result) {\n        result.fold(function (err) {\n          errors.push(err);\n        }, function (value) {\n          values.push(value);\n        });\n      });\n      return {\n        errors: errors,\n        values: values\n      };\n    };\n\n    var exclude$1 = function (obj, fields) {\n      return exclude(obj, fields);\n    };\n    var readOpt$1 = function (key) {\n      return readOpt(key);\n    };\n    var readOr$1 = function (key, fallback) {\n      return readOr(key, fallback);\n    };\n    var readOptFrom$1 = function (obj, key) {\n      return readOptFrom(obj, key);\n    };\n    var wrap$1 = function (key, value) {\n      return wrap(key, value);\n    };\n    var wrapAll$1 = function (keyvalues) {\n      return wrapAll(keyvalues);\n    };\n    var mergeValues = function (values, base) {\n      return values.length === 0 ? Result.value(base) : Result.value(deepMerge(base, merge.apply(undefined, values)));\n    };\n    var mergeErrors = function (errors) {\n      return Result.error(flatten(errors));\n    };\n    var consolidate = function (objs, base) {\n      var partitions = partition$1(objs);\n      return partitions.errors.length > 0 ? mergeErrors(partitions.errors) : mergeValues(partitions.values, base);\n    };\n    var hasKey$1 = function (obj, key) {\n      return hasKey(obj, key);\n    };\n\n    var SimpleResultType;\n    (function (SimpleResultType) {\n      SimpleResultType[SimpleResultType['Error'] = 0] = 'Error';\n      SimpleResultType[SimpleResultType['Value'] = 1] = 'Value';\n    }(SimpleResultType || (SimpleResultType = {})));\n    var fold = function (res, onError, onValue) {\n      return res.stype === SimpleResultType.Error ? onError(res.serror) : onValue(res.svalue);\n    };\n    var partition$2 = function (results) {\n      var values = [];\n      var errors = [];\n      each(results, function (obj) {\n        fold(obj, function (err) {\n          return errors.push(err);\n        }, function (val) {\n          return values.push(val);\n        });\n      });\n      return {\n        values: values,\n        errors: errors\n      };\n    };\n    var mapError = function (res, f) {\n      if (res.stype === SimpleResultType.Error) {\n        return {\n          stype: SimpleResultType.Error,\n          serror: f(res.serror)\n        };\n      } else {\n        return res;\n      }\n    };\n    var map$2 = function (res, f) {\n      if (res.stype === SimpleResultType.Value) {\n        return {\n          stype: SimpleResultType.Value,\n          svalue: f(res.svalue)\n        };\n      } else {\n        return res;\n      }\n    };\n    var bind$1 = function (res, f) {\n      if (res.stype === SimpleResultType.Value) {\n        return f(res.svalue);\n      } else {\n        return res;\n      }\n    };\n    var bindError = function (res, f) {\n      if (res.stype === SimpleResultType.Error) {\n        return f(res.serror);\n      } else {\n        return res;\n      }\n    };\n    var svalue = function (v) {\n      return {\n        stype: SimpleResultType.Value,\n        svalue: v\n      };\n    };\n    var serror = function (e) {\n      return {\n        stype: SimpleResultType.Error,\n        serror: e\n      };\n    };\n    var toResult = function (res) {\n      return fold(res, Result.error, Result.value);\n    };\n    var fromResult = function (res) {\n      return res.fold(serror, svalue);\n    };\n    var SimpleResult = {\n      fromResult: fromResult,\n      toResult: toResult,\n      svalue: svalue,\n      partition: partition$2,\n      serror: serror,\n      bind: bind$1,\n      bindError: bindError,\n      map: map$2,\n      mapError: mapError,\n      fold: fold\n    };\n\n    var mergeValues$1 = function (values, base) {\n      return values.length > 0 ? SimpleResult.svalue(deepMerge(base, merge.apply(undefined, values))) : SimpleResult.svalue(base);\n    };\n    var mergeErrors$1 = function (errors) {\n      return compose(SimpleResult.serror, flatten)(errors);\n    };\n    var consolidateObj = function (objects, base) {\n      var partition = SimpleResult.partition(objects);\n      return partition.errors.length > 0 ? mergeErrors$1(partition.errors) : mergeValues$1(partition.values, base);\n    };\n    var consolidateArr = function (objects) {\n      var partitions = SimpleResult.partition(objects);\n      return partitions.errors.length > 0 ? mergeErrors$1(partitions.errors) : SimpleResult.svalue(partitions.values);\n    };\n    var ResultCombine = {\n      consolidateObj: consolidateObj,\n      consolidateArr: consolidateArr\n    };\n\n    var typeAdt = Adt.generate([\n      {\n        setOf: [\n          'validator',\n          'valueType'\n        ]\n      },\n      { arrOf: ['valueType'] },\n      { objOf: ['fields'] },\n      { itemOf: ['validator'] },\n      {\n        choiceOf: [\n          'key',\n          'branches'\n        ]\n      },\n      { thunk: ['description'] },\n      {\n        func: [\n          'args',\n          'outputSchema'\n        ]\n      }\n    ]);\n    var fieldAdt = Adt.generate([\n      {\n        field: [\n          'name',\n          'presence',\n          'type'\n        ]\n      },\n      { state: ['name'] }\n    ]);\n\n    var formatObj = function (input) {\n      return isObject(input) && keys(input).length > 100 ? ' removed due to size' : JSON.stringify(input, null, 2);\n    };\n    var formatErrors = function (errors) {\n      var es = errors.length > 10 ? errors.slice(0, 10).concat([{\n          path: [],\n          getErrorInfo: function () {\n            return '... (only showing first ten failures)';\n          }\n        }]) : errors;\n      return map(es, function (e) {\n        return 'Failed path: (' + e.path.join(' > ') + ')\\n' + e.getErrorInfo();\n      });\n    };\n\n    var nu = function (path, getErrorInfo) {\n      return SimpleResult.serror([{\n          path: path,\n          getErrorInfo: getErrorInfo\n        }]);\n    };\n    var missingStrict = function (path, key, obj) {\n      return nu(path, function () {\n        return 'Could not find valid *strict* value for \"' + key + '\" in ' + formatObj(obj);\n      });\n    };\n    var missingKey = function (path, key) {\n      return nu(path, function () {\n        return 'Choice schema did not contain choice key: \"' + key + '\"';\n      });\n    };\n    var missingBranch = function (path, branches, branch) {\n      return nu(path, function () {\n        return 'The chosen schema: \"' + branch + '\" did not exist in branches: ' + formatObj(branches);\n      });\n    };\n    var unsupportedFields = function (path, unsupported) {\n      return nu(path, function () {\n        return 'There are unsupported fields: [' + unsupported.join(', ') + '] specified';\n      });\n    };\n    var custom = function (path, err) {\n      return nu(path, function () {\n        return err;\n      });\n    };\n\n    var adt$1 = Adt.generate([\n      {\n        field: [\n          'key',\n          'okey',\n          'presence',\n          'prop'\n        ]\n      },\n      {\n        state: [\n          'okey',\n          'instantiator'\n        ]\n      }\n    ]);\n    var strictAccess = function (path, obj, key) {\n      return readOptFrom(obj, key).fold(function () {\n        return missingStrict(path, key, obj);\n      }, SimpleResult.svalue);\n    };\n    var fallbackAccess = function (obj, key, fallbackThunk) {\n      var v = readOptFrom(obj, key).fold(function () {\n        return fallbackThunk(obj);\n      }, identity);\n      return SimpleResult.svalue(v);\n    };\n    var optionAccess = function (obj, key) {\n      return SimpleResult.svalue(readOptFrom(obj, key));\n    };\n    var optionDefaultedAccess = function (obj, key, fallback) {\n      var opt = readOptFrom(obj, key).map(function (val) {\n        return val === true ? fallback(obj) : val;\n      });\n      return SimpleResult.svalue(opt);\n    };\n    var cExtractOne = function (path, obj, field, strength) {\n      return field.fold(function (key, okey, presence, prop) {\n        var bundle = function (av) {\n          var result = prop.extract(path.concat([key]), strength, av);\n          return SimpleResult.map(result, function (res) {\n            return wrap(okey, strength(res));\n          });\n        };\n        var bundleAsOption = function (optValue) {\n          return optValue.fold(function () {\n            var outcome = wrap(okey, strength(Option.none()));\n            return SimpleResult.svalue(outcome);\n          }, function (ov) {\n            var result = prop.extract(path.concat([key]), strength, ov);\n            return SimpleResult.map(result, function (res) {\n              return wrap(okey, strength(Option.some(res)));\n            });\n          });\n        };\n        return function () {\n          return presence.fold(function () {\n            return SimpleResult.bind(strictAccess(path, obj, key), bundle);\n          }, function (fallbackThunk) {\n            return SimpleResult.bind(fallbackAccess(obj, key, fallbackThunk), bundle);\n          }, function () {\n            return SimpleResult.bind(optionAccess(obj, key), bundleAsOption);\n          }, function (fallbackThunk) {\n            return SimpleResult.bind(optionDefaultedAccess(obj, key, fallbackThunk), bundleAsOption);\n          }, function (baseThunk) {\n            var base = baseThunk(obj);\n            var result = SimpleResult.map(fallbackAccess(obj, key, constant({})), function (v) {\n              return deepMerge(base, v);\n            });\n            return SimpleResult.bind(result, bundle);\n          });\n        }();\n      }, function (okey, instantiator) {\n        var state = instantiator(obj);\n        return SimpleResult.svalue(wrap(okey, strength(state)));\n      });\n    };\n    var cExtract = function (path, obj, fields, strength) {\n      var results = map(fields, function (field) {\n        return cExtractOne(path, obj, field, strength);\n      });\n      return ResultCombine.consolidateObj(results, {});\n    };\n    var valueThunk = function (getDelegate) {\n      var extract = function (path, strength, val) {\n        return getDelegate().extract(path, strength, val);\n      };\n      var toString = function () {\n        return getDelegate().toString();\n      };\n      var toDsl = function () {\n        return getDelegate().toDsl();\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var value$1 = function (validator) {\n      var extract = function (path, strength, val) {\n        return SimpleResult.bindError(validator(val, strength), function (err) {\n          return custom(path, err);\n        });\n      };\n      var toString = function () {\n        return 'val';\n      };\n      var toDsl = function () {\n        return typeAdt.itemOf(validator);\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var getSetKeys = function (obj) {\n      var keys$1 = keys(obj);\n      return filter(keys$1, function (k) {\n        return hasKey$1(obj, k);\n      });\n    };\n    var objOfOnly = function (fields) {\n      var delegate = objOf(fields);\n      var fieldNames = foldr(fields, function (acc, f) {\n        return f.fold(function (key) {\n          return deepMerge(acc, wrap$1(key, true));\n        }, constant(acc));\n      }, {});\n      var extract = function (path, strength, o) {\n        var keys = isBoolean(o) ? [] : getSetKeys(o);\n        var extra = filter(keys, function (k) {\n          return !hasKey$1(fieldNames, k);\n        });\n        return extra.length === 0 ? delegate.extract(path, strength, o) : unsupportedFields(path, extra);\n      };\n      return {\n        extract: extract,\n        toString: delegate.toString,\n        toDsl: delegate.toDsl\n      };\n    };\n    var objOf = function (fields) {\n      var extract = function (path, strength, o) {\n        return cExtract(path, o, fields, strength);\n      };\n      var toString = function () {\n        var fieldStrings = map(fields, function (field) {\n          return field.fold(function (key, okey, presence, prop) {\n            return key + ' -> ' + prop.toString();\n          }, function (okey, instantiator) {\n            return 'state(' + okey + ')';\n          });\n        });\n        return 'obj{\\n' + fieldStrings.join('\\n') + '}';\n      };\n      var toDsl = function () {\n        return typeAdt.objOf(map(fields, function (f) {\n          return f.fold(function (key, okey, presence, prop) {\n            return fieldAdt.field(key, presence, prop);\n          }, function (okey, instantiator) {\n            return fieldAdt.state(okey);\n          });\n        }));\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var arrOf = function (prop) {\n      var extract = function (path, strength, array) {\n        var results = map(array, function (a, i) {\n          return prop.extract(path.concat(['[' + i + ']']), strength, a);\n        });\n        return ResultCombine.consolidateArr(results);\n      };\n      var toString = function () {\n        return 'array(' + prop.toString() + ')';\n      };\n      var toDsl = function () {\n        return typeAdt.arrOf(prop);\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var setOf = function (validator, prop) {\n      var validateKeys = function (path, keys) {\n        return arrOf(value$1(validator)).extract(path, identity, keys);\n      };\n      var extract = function (path, strength, o) {\n        var keys$1 = keys(o);\n        var validatedKeys = validateKeys(path, keys$1);\n        return SimpleResult.bind(validatedKeys, function (validKeys) {\n          var schema = map(validKeys, function (vk) {\n            return adt$1.field(vk, vk, strict(), prop);\n          });\n          return objOf(schema).extract(path, strength, o);\n        });\n      };\n      var toString = function () {\n        return 'setOf(' + prop.toString() + ')';\n      };\n      var toDsl = function () {\n        return typeAdt.setOf(validator, prop);\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n    var anyValue = constant(value$1(SimpleResult.svalue));\n    var arrOfObj = compose(arrOf, objOf);\n    var state = adt$1.state;\n    var field = adt$1.field;\n\n    var chooseFrom = function (path, strength, input, branches, ch) {\n      var fields = readOptFrom$1(branches, ch);\n      return fields.fold(function () {\n        return missingBranch(path, branches, ch);\n      }, function (vp) {\n        return vp.extract(path.concat(['branch: ' + ch]), strength, input);\n      });\n    };\n    var choose = function (key, branches) {\n      var extract = function (path, strength, input) {\n        var choice = readOptFrom$1(input, key);\n        return choice.fold(function () {\n          return missingKey(path, key);\n        }, function (chosen) {\n          return chooseFrom(path, strength, input, branches, chosen);\n        });\n      };\n      var toString = function () {\n        return 'chooseOn(' + key + '). Possible values: ' + keys(branches);\n      };\n      var toDsl = function () {\n        return typeAdt.choiceOf(key, branches);\n      };\n      return {\n        extract: extract,\n        toString: toString,\n        toDsl: toDsl\n      };\n    };\n\n    var _anyValue = value$1(SimpleResult.svalue);\n    var arrOfObj$1 = function (objFields) {\n      return arrOfObj(objFields);\n    };\n    var arrOfVal = function () {\n      return arrOf(_anyValue);\n    };\n    var valueThunkOf = valueThunk;\n    var valueOf = function (validator) {\n      return value$1(function (v) {\n        return validator(v).fold(SimpleResult.serror, SimpleResult.svalue);\n      });\n    };\n    var setOf$1 = function (validator, prop) {\n      return setOf(function (v) {\n        return SimpleResult.fromResult(validator(v));\n      }, prop);\n    };\n    var extract = function (label, prop, strength, obj) {\n      var res = prop.extract([label], strength, obj);\n      return SimpleResult.mapError(res, function (errs) {\n        return {\n          input: obj,\n          errors: errs\n        };\n      });\n    };\n    var asRaw = function (label, prop, obj) {\n      return SimpleResult.toResult(extract(label, prop, identity, obj));\n    };\n    var getOrDie = function (extraction) {\n      return extraction.fold(function (errInfo) {\n        throw new Error(formatError(errInfo));\n      }, identity);\n    };\n    var asRawOrDie = function (label, prop, obj) {\n      return getOrDie(asRaw(label, prop, obj));\n    };\n    var formatError = function (errInfo) {\n      return 'Errors: \\n' + formatErrors(errInfo.errors) + '\\n\\nInput object: ' + formatObj(errInfo.input);\n    };\n    var chooseProcessor = function (key, branches) {\n      return choose(key, branches);\n    };\n    var choose$1 = function (key, branches) {\n      return choose(key, map$1(branches, objOf));\n    };\n    var anyValue$1 = constant(_anyValue);\n    var typedValue = function (validator, expectedType) {\n      return value$1(function (a) {\n        var actualType = typeof a;\n        return validator(a) ? SimpleResult.svalue(a) : SimpleResult.serror('Expected type: ' + expectedType + ' but got: ' + actualType);\n      });\n    };\n    var number = typedValue(isNumber, 'number');\n    var string = typedValue(isString, 'string');\n    var boolean = typedValue(isBoolean, 'boolean');\n    var functionProcessor = typedValue(isFunction, 'function');\n    var isPostMessageable = function (val) {\n      var every = function (iter, callbackFn) {\n        var result = iter.next();\n        while (!result.done) {\n          if (!callbackFn(result.value)) {\n            return false;\n          }\n          result = iter.next();\n        }\n        return true;\n      };\n      if (Object(val) !== val) {\n        return true;\n      }\n      switch ({}.toString.call(val).slice(8, -1)) {\n      case 'Boolean':\n      case 'Number':\n      case 'String':\n      case 'Date':\n      case 'RegExp':\n      case 'Blob':\n      case 'FileList':\n      case 'ImageData':\n      case 'ImageBitmap':\n      case 'ArrayBuffer':\n        return true;\n      case 'Array':\n      case 'Object':\n        return Object.keys(val).every(function (prop) {\n          return isPostMessageable(val[prop]);\n        });\n      case 'Map':\n        return every(val.keys(), isPostMessageable) && every(val.values(), isPostMessageable);\n      case 'Set':\n        return every(val.keys(), isPostMessageable);\n      default:\n        return false;\n      }\n    };\n    var postMessageable = value$1(function (a) {\n      return isPostMessageable(a) ? SimpleResult.svalue(a) : SimpleResult.serror('Expected value to be acceptable for sending via postMessage');\n    });\n\n    var validateEnum = function (values) {\n      return valueOf(function (value) {\n        return contains(values, value) ? Result.value(value) : Result.error('Unsupported value: \"' + value + '\", choose one of \"' + values.join(', ') + '\".');\n      });\n    };\n    var strict$1 = function (key) {\n      return field(key, key, strict(), anyValue());\n    };\n    var strictOf = function (key, schema) {\n      return field(key, key, strict(), schema);\n    };\n    var strictNumber = function (key) {\n      return strictOf(key, number);\n    };\n    var strictString = function (key) {\n      return strictOf(key, string);\n    };\n    var strictStringEnum = function (key, values) {\n      return field(key, key, strict(), validateEnum(values));\n    };\n    var strictBoolean = function (key) {\n      return strictOf(key, boolean);\n    };\n    var strictFunction = function (key) {\n      return strictOf(key, functionProcessor);\n    };\n    var forbid = function (key, message) {\n      return field(key, key, asOption(), value$1(function (v) {\n        return SimpleResult.serror('The field: ' + key + ' is forbidden. ' + message);\n      }));\n    };\n    var strictObjOf = function (key, objSchema) {\n      return field(key, key, strict(), objOf(objSchema));\n    };\n    var strictArrayOfObj = function (key, objFields) {\n      return field(key, key, strict(), arrOfObj(objFields));\n    };\n    var strictArrayOf = function (key, schema) {\n      return field(key, key, strict(), arrOf(schema));\n    };\n    var option = function (key) {\n      return field(key, key, asOption(), anyValue());\n    };\n    var optionOf = function (key, schema) {\n      return field(key, key, asOption(), schema);\n    };\n    var optionNumber = function (key) {\n      return optionOf(key, number);\n    };\n    var optionString = function (key) {\n      return optionOf(key, string);\n    };\n    var optionFunction = function (key) {\n      return optionOf(key, functionProcessor);\n    };\n    var optionArrayOf = function (key, schema) {\n      return optionOf(key, arrOf(schema));\n    };\n    var optionObjOf = function (key, objSchema) {\n      return optionOf(key, objOf(objSchema));\n    };\n    var optionObjOfOnly = function (key, objSchema) {\n      return optionOf(key, objOfOnly(objSchema));\n    };\n    var defaulted$1 = function (key, fallback) {\n      return field(key, key, defaulted(fallback), anyValue());\n    };\n    var defaultedOf = function (key, fallback, schema) {\n      return field(key, key, defaulted(fallback), schema);\n    };\n    var defaultedNumber = function (key, fallback) {\n      return defaultedOf(key, fallback, number);\n    };\n    var defaultedString = function (key, fallback) {\n      return defaultedOf(key, fallback, string);\n    };\n    var defaultedStringEnum = function (key, fallback, values) {\n      return defaultedOf(key, fallback, validateEnum(values));\n    };\n    var defaultedBoolean = function (key, fallback) {\n      return defaultedOf(key, fallback, boolean);\n    };\n    var defaultedFunction = function (key, fallback) {\n      return defaultedOf(key, fallback, functionProcessor);\n    };\n    var defaultedPostMsg = function (key, fallback) {\n      return defaultedOf(key, fallback, postMessageable);\n    };\n    var defaultedArrayOf = function (key, fallback, schema) {\n      return defaultedOf(key, fallback, arrOf(schema));\n    };\n    var defaultedObjOf = function (key, fallback, objSchema) {\n      return defaultedOf(key, fallback, objOf(objSchema));\n    };\n    var state$1 = function (okey, instantiator) {\n      return state(okey, instantiator);\n    };\n\n    var Cell = function (initial) {\n      var value = initial;\n      var get = function () {\n        return value;\n      };\n      var set = function (v) {\n        value = v;\n      };\n      var clone = function () {\n        return Cell(get());\n      };\n      return {\n        get: get,\n        set: set,\n        clone: clone\n      };\n    };\n\n    var fromHtml = function (html, scope) {\n      var doc = scope || domGlobals.document;\n      var div = doc.createElement('div');\n      div.innerHTML = html;\n      if (!div.hasChildNodes() || div.childNodes.length > 1) {\n        domGlobals.console.error('HTML does not have a single root node', html);\n        throw new Error('HTML must have a single root node');\n      }\n      return fromDom(div.childNodes[0]);\n    };\n    var fromTag = function (tag, scope) {\n      var doc = scope || domGlobals.document;\n      var node = doc.createElement(tag);\n      return fromDom(node);\n    };\n    var fromText = function (text, scope) {\n      var doc = scope || domGlobals.document;\n      var node = doc.createTextNode(text);\n      return fromDom(node);\n    };\n    var fromDom = function (node) {\n      if (node === null || node === undefined) {\n        throw new Error('Node cannot be null or undefined');\n      }\n      return { dom: constant(node) };\n    };\n    var fromPoint = function (docElm, x, y) {\n      var doc = docElm.dom();\n      return Option.from(doc.elementFromPoint(x, y)).map(fromDom);\n    };\n    var Element = {\n      fromHtml: fromHtml,\n      fromTag: fromTag,\n      fromText: fromText,\n      fromDom: fromDom,\n      fromPoint: fromPoint\n    };\n\n    var compareDocumentPosition = function (a, b, match) {\n      return (a.compareDocumentPosition(b) & match) !== 0;\n    };\n    var documentPositionPreceding = function (a, b) {\n      return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_PRECEDING);\n    };\n    var documentPositionContainedBy = function (a, b) {\n      return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_CONTAINED_BY);\n    };\n    var Node = {\n      documentPositionPreceding: documentPositionPreceding,\n      documentPositionContainedBy: documentPositionContainedBy\n    };\n\n    var firstMatch = function (regexes, s) {\n      for (var i = 0; i < regexes.length; i++) {\n        var x = regexes[i];\n        if (x.test(s)) {\n          return x;\n        }\n      }\n      return undefined;\n    };\n    var find$2 = function (regexes, agent) {\n      var r = firstMatch(regexes, agent);\n      if (!r) {\n        return {\n          major: 0,\n          minor: 0\n        };\n      }\n      var group = function (i) {\n        return Number(agent.replace(r, '$' + i));\n      };\n      return nu$1(group(1), group(2));\n    };\n    var detect = function (versionRegexes, agent) {\n      var cleanedAgent = String(agent).toLowerCase();\n      if (versionRegexes.length === 0) {\n        return unknown();\n      }\n      return find$2(versionRegexes, cleanedAgent);\n    };\n    var unknown = function () {\n      return nu$1(0, 0);\n    };\n    var nu$1 = function (major, minor) {\n      return {\n        major: major,\n        minor: minor\n      };\n    };\n    var Version = {\n      nu: nu$1,\n      detect: detect,\n      unknown: unknown\n    };\n\n    var edge = 'Edge';\n    var chrome = 'Chrome';\n    var ie = 'IE';\n    var opera = 'Opera';\n    var firefox = 'Firefox';\n    var safari = 'Safari';\n    var isBrowser = function (name, current) {\n      return function () {\n        return current === name;\n      };\n    };\n    var unknown$1 = function () {\n      return nu$2({\n        current: undefined,\n        version: Version.unknown()\n      });\n    };\n    var nu$2 = function (info) {\n      var current = info.current;\n      var version = info.version;\n      return {\n        current: current,\n        version: version,\n        isEdge: isBrowser(edge, current),\n        isChrome: isBrowser(chrome, current),\n        isIE: isBrowser(ie, current),\n        isOpera: isBrowser(opera, current),\n        isFirefox: isBrowser(firefox, current),\n        isSafari: isBrowser(safari, current)\n      };\n    };\n    var Browser = {\n      unknown: unknown$1,\n      nu: nu$2,\n      edge: constant(edge),\n      chrome: constant(chrome),\n      ie: constant(ie),\n      opera: constant(opera),\n      firefox: constant(firefox),\n      safari: constant(safari)\n    };\n\n    var windows = 'Windows';\n    var ios = 'iOS';\n    var android = 'Android';\n    var linux = 'Linux';\n    var osx = 'OSX';\n    var solaris = 'Solaris';\n    var freebsd = 'FreeBSD';\n    var isOS = function (name, current) {\n      return function () {\n        return current === name;\n      };\n    };\n    var unknown$2 = function () {\n      return nu$3({\n        current: undefined,\n        version: Version.unknown()\n      });\n    };\n    var nu$3 = function (info) {\n      var current = info.current;\n      var version = info.version;\n      return {\n        current: current,\n        version: version,\n        isWindows: isOS(windows, current),\n        isiOS: isOS(ios, current),\n        isAndroid: isOS(android, current),\n        isOSX: isOS(osx, current),\n        isLinux: isOS(linux, current),\n        isSolaris: isOS(solaris, current),\n        isFreeBSD: isOS(freebsd, current)\n      };\n    };\n    var OperatingSystem = {\n      unknown: unknown$2,\n      nu: nu$3,\n      windows: constant(windows),\n      ios: constant(ios),\n      android: constant(android),\n      linux: constant(linux),\n      osx: constant(osx),\n      solaris: constant(solaris),\n      freebsd: constant(freebsd)\n    };\n\n    var DeviceType = function (os, browser, userAgent, mediaMatch) {\n      var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;\n      var isiPhone = os.isiOS() && !isiPad;\n      var isMobile = os.isiOS() || os.isAndroid();\n      var isTouch = isMobile || mediaMatch('(pointer:coarse)');\n      var isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');\n      var isPhone = isiPhone || isMobile && !isTablet;\n      var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;\n      var isDesktop = !isPhone && !isTablet && !iOSwebview;\n      return {\n        isiPad: constant(isiPad),\n        isiPhone: constant(isiPhone),\n        isTablet: constant(isTablet),\n        isPhone: constant(isPhone),\n        isTouch: constant(isTouch),\n        isAndroid: os.isAndroid,\n        isiOS: os.isiOS,\n        isWebView: constant(iOSwebview),\n        isDesktop: constant(isDesktop)\n      };\n    };\n\n    var detect$1 = function (candidates, userAgent) {\n      var agent = String(userAgent).toLowerCase();\n      return find(candidates, function (candidate) {\n        return candidate.search(agent);\n      });\n    };\n    var detectBrowser = function (browsers, userAgent) {\n      return detect$1(browsers, userAgent).map(function (browser) {\n        var version = Version.detect(browser.versionRegexes, userAgent);\n        return {\n          current: browser.name,\n          version: version\n        };\n      });\n    };\n    var detectOs = function (oses, userAgent) {\n      return detect$1(oses, userAgent).map(function (os) {\n        var version = Version.detect(os.versionRegexes, userAgent);\n        return {\n          current: os.name,\n          version: version\n        };\n      });\n    };\n    var UaString = {\n      detectBrowser: detectBrowser,\n      detectOs: detectOs\n    };\n\n    var checkRange = function (str, substr, start) {\n      if (substr === '') {\n        return true;\n      }\n      if (str.length < substr.length) {\n        return false;\n      }\n      var x = str.substr(start, start + substr.length);\n      return x === substr;\n    };\n    var contains$1 = function (str, substr) {\n      return str.indexOf(substr) !== -1;\n    };\n    var endsWith = function (str, suffix) {\n      return checkRange(str, suffix, str.length - suffix.length);\n    };\n    var trim = function (str) {\n      return str.replace(/^\\s+|\\s+$/g, '');\n    };\n\n    var normalVersionRegex = /.*?version\\/\\ ?([0-9]+)\\.([0-9]+).*/;\n    var checkContains = function (target) {\n      return function (uastring) {\n        return contains$1(uastring, target);\n      };\n    };\n    var browsers = [\n      {\n        name: 'Edge',\n        versionRegexes: [/.*?edge\\/ ?([0-9]+)\\.([0-9]+)$/],\n        search: function (uastring) {\n          return contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit');\n        }\n      },\n      {\n        name: 'Chrome',\n        versionRegexes: [\n          /.*?chrome\\/([0-9]+)\\.([0-9]+).*/,\n          normalVersionRegex\n        ],\n        search: function (uastring) {\n          return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe');\n        }\n      },\n      {\n        name: 'IE',\n        versionRegexes: [\n          /.*?msie\\ ?([0-9]+)\\.([0-9]+).*/,\n          /.*?rv:([0-9]+)\\.([0-9]+).*/\n        ],\n        search: function (uastring) {\n          return contains$1(uastring, 'msie') || contains$1(uastring, 'trident');\n        }\n      },\n      {\n        name: 'Opera',\n        versionRegexes: [\n          normalVersionRegex,\n          /.*?opera\\/([0-9]+)\\.([0-9]+).*/\n        ],\n        search: checkContains('opera')\n      },\n      {\n        name: 'Firefox',\n        versionRegexes: [/.*?firefox\\/\\ ?([0-9]+)\\.([0-9]+).*/],\n        search: checkContains('firefox')\n      },\n      {\n        name: 'Safari',\n        versionRegexes: [\n          normalVersionRegex,\n          /.*?cpu os ([0-9]+)_([0-9]+).*/\n        ],\n        search: function (uastring) {\n          return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit');\n        }\n      }\n    ];\n    var oses = [\n      {\n        name: 'Windows',\n        search: checkContains('win'),\n        versionRegexes: [/.*?windows\\ nt\\ ?([0-9]+)\\.([0-9]+).*/]\n      },\n      {\n        name: 'iOS',\n        search: function (uastring) {\n          return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad');\n        },\n        versionRegexes: [\n          /.*?version\\/\\ ?([0-9]+)\\.([0-9]+).*/,\n          /.*cpu os ([0-9]+)_([0-9]+).*/,\n          /.*cpu iphone os ([0-9]+)_([0-9]+).*/\n        ]\n      },\n      {\n        name: 'Android',\n        search: checkContains('android'),\n        versionRegexes: [/.*?android\\ ?([0-9]+)\\.([0-9]+).*/]\n      },\n      {\n        name: 'OSX',\n        search: checkContains('os x'),\n        versionRegexes: [/.*?os\\ x\\ ?([0-9]+)_([0-9]+).*/]\n      },\n      {\n        name: 'Linux',\n        search: checkContains('linux'),\n        versionRegexes: []\n      },\n      {\n        name: 'Solaris',\n        search: checkContains('sunos'),\n        versionRegexes: []\n      },\n      {\n        name: 'FreeBSD',\n        search: checkContains('freebsd'),\n        versionRegexes: []\n      }\n    ];\n    var PlatformInfo = {\n      browsers: constant(browsers),\n      oses: constant(oses)\n    };\n\n    var detect$2 = function (userAgent, mediaMatch) {\n      var browsers = PlatformInfo.browsers();\n      var oses = PlatformInfo.oses();\n      var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);\n      var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);\n      var deviceType = DeviceType(os, browser, userAgent, mediaMatch);\n      return {\n        browser: browser,\n        os: os,\n        deviceType: deviceType\n      };\n    };\n    var PlatformDetection = { detect: detect$2 };\n\n    var mediaMatch = function (query) {\n      return domGlobals.window.matchMedia(query).matches;\n    };\n    var platform = Cell(PlatformDetection.detect(domGlobals.navigator.userAgent, mediaMatch));\n    var detect$3 = function () {\n      return platform.get();\n    };\n\n    var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;\n    var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;\n    var COMMENT = domGlobals.Node.COMMENT_NODE;\n    var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;\n    var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;\n    var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;\n    var ELEMENT = domGlobals.Node.ELEMENT_NODE;\n    var TEXT = domGlobals.Node.TEXT_NODE;\n    var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;\n    var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;\n    var ENTITY = domGlobals.Node.ENTITY_NODE;\n    var NOTATION = domGlobals.Node.NOTATION_NODE;\n\n    var ELEMENT$1 = ELEMENT;\n    var DOCUMENT$1 = DOCUMENT;\n    var is = function (element, selector) {\n      var dom = element.dom();\n      if (dom.nodeType !== ELEMENT$1) {\n        return false;\n      } else {\n        var elem = dom;\n        if (elem.matches !== undefined) {\n          return elem.matches(selector);\n        } else if (elem.msMatchesSelector !== undefined) {\n          return elem.msMatchesSelector(selector);\n        } else if (elem.webkitMatchesSelector !== undefined) {\n          return elem.webkitMatchesSelector(selector);\n        } else if (elem.mozMatchesSelector !== undefined) {\n          return elem.mozMatchesSelector(selector);\n        } else {\n          throw new Error('Browser lacks native selectors');\n        }\n      }\n    };\n    var bypassSelector = function (dom) {\n      return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0;\n    };\n    var all = function (selector, scope) {\n      var base = scope === undefined ? domGlobals.document : scope.dom();\n      return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom);\n    };\n    var one = function (selector, scope) {\n      var base = scope === undefined ? domGlobals.document : scope.dom();\n      return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom);\n    };\n\n    var eq = function (e1, e2) {\n      return e1.dom() === e2.dom();\n    };\n    var regularContains = function (e1, e2) {\n      var d1 = e1.dom();\n      var d2 = e2.dom();\n      return d1 === d2 ? false : d1.contains(d2);\n    };\n    var ieContains = function (e1, e2) {\n      return Node.documentPositionContainedBy(e1.dom(), e2.dom());\n    };\n    var browser = detect$3().browser;\n    var contains$2 = browser.isIE() ? ieContains : regularContains;\n\n    var isSource = function (component, simulatedEvent) {\n      return eq(component.element(), simulatedEvent.event().target());\n    };\n\n    function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {\n      return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot);\n    }\n\n    var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();\n\n    var name = function (element) {\n      var r = element.dom().nodeName;\n      return r.toLowerCase();\n    };\n    var type = function (element) {\n      return element.dom().nodeType;\n    };\n    var isType$1 = function (t) {\n      return function (element) {\n        return type(element) === t;\n      };\n    };\n    var isElement = isType$1(ELEMENT);\n    var isText = isType$1(TEXT);\n\n    var inBody = function (element) {\n      var dom = isText(element) ? element.dom().parentNode : element.dom();\n      return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom);\n    };\n    var body = cached(function () {\n      return getBody(Element.fromDom(domGlobals.document));\n    });\n    var getBody = function (doc) {\n      var b = doc.dom().body;\n      if (b === null || b === undefined) {\n        throw new Error('Body is not available yet');\n      }\n      return Element.fromDom(b);\n    };\n\n    var ancestor = function (scope, predicate, isRoot) {\n      var element = scope.dom();\n      var stop = isFunction(isRoot) ? isRoot : constant(false);\n      while (element.parentNode) {\n        element = element.parentNode;\n        var el = Element.fromDom(element);\n        if (predicate(el)) {\n          return Option.some(el);\n        } else if (stop(el)) {\n          break;\n        }\n      }\n      return Option.none();\n    };\n    var closest = function (scope, predicate, isRoot) {\n      var is = function (s, test) {\n        return test(s);\n      };\n      return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);\n    };\n    var descendant = function (scope, predicate) {\n      var descend = function (node) {\n        for (var i = 0; i < node.childNodes.length; i++) {\n          var child_1 = Element.fromDom(node.childNodes[i]);\n          if (predicate(child_1)) {\n            return Option.some(child_1);\n          }\n          var res = descend(node.childNodes[i]);\n          if (res.isSome()) {\n            return res;\n          }\n        }\n        return Option.none();\n      };\n      return descend(scope.dom());\n    };\n\n    var closest$1 = function (target, transform, isRoot) {\n      var delegate = closest(target, function (elem) {\n        return transform(elem).isSome();\n      }, isRoot);\n      return delegate.bind(transform);\n    };\n\n    var nu$4 = function (parts) {\n      if (!hasKey$1(parts, 'can') && !hasKey$1(parts, 'abort') && !hasKey$1(parts, 'run')) {\n        throw new Error('EventHandler defined by: ' + JSON.stringify(parts, null, 2) + ' does not have can, abort, or run!');\n      }\n      return asRawOrDie('Extracting event.handler', objOfOnly([\n        defaulted$1('can', constant(true)),\n        defaulted$1('abort', constant(false)),\n        defaulted$1('run', noop)\n      ]), parts);\n    };\n    var all$1 = function (handlers, f) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return foldl(handlers, function (acc, handler) {\n          return acc && f(handler).apply(undefined, args);\n        }, true);\n      };\n    };\n    var any = function (handlers, f) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return foldl(handlers, function (acc, handler) {\n          return acc || f(handler).apply(undefined, args);\n        }, false);\n      };\n    };\n    var read = function (handler) {\n      return isFunction(handler) ? {\n        can: constant(true),\n        abort: constant(false),\n        run: handler\n      } : handler;\n    };\n    var fuse = function (handlers) {\n      var can = all$1(handlers, function (handler) {\n        return handler.can;\n      });\n      var abort = any(handlers, function (handler) {\n        return handler.abort;\n      });\n      var run = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        each(handlers, function (handler) {\n          handler.run.apply(undefined, args);\n        });\n      };\n      return nu$4({\n        can: can,\n        abort: abort,\n        run: run\n      });\n    };\n\n    var touchstart = constant('touchstart');\n    var touchmove = constant('touchmove');\n    var touchend = constant('touchend');\n    var touchcancel = constant('touchcancel');\n    var mousedown = constant('mousedown');\n    var mousemove = constant('mousemove');\n    var mouseout = constant('mouseout');\n    var mouseup = constant('mouseup');\n    var mouseover = constant('mouseover');\n    var focusin = constant('focusin');\n    var focusout = constant('focusout');\n    var keydown = constant('keydown');\n    var keyup = constant('keyup');\n    var input = constant('input');\n    var change = constant('change');\n    var click = constant('click');\n    var transitionend = constant('transitionend');\n    var selectstart = constant('selectstart');\n\n    var alloy = { tap: constant('alloy.tap') };\n    var focus = constant('alloy.focus');\n    var postBlur = constant('alloy.blur.post');\n    var postPaste = constant('alloy.paste.post');\n    var receive = constant('alloy.receive');\n    var execute = constant('alloy.execute');\n    var focusItem = constant('alloy.focus.item');\n    var tap = alloy.tap;\n    var longpress = constant('alloy.longpress');\n    var sandboxClose = constant('alloy.sandbox.close');\n    var typeaheadCancel = constant('alloy.typeahead.cancel');\n    var systemInit = constant('alloy.system.init');\n    var documentTouchmove = constant('alloy.system.touchmove');\n    var documentTouchend = constant('alloy.system.touchend');\n    var windowScroll = constant('alloy.system.scroll');\n    var windowResize = constant('alloy.system.resize');\n    var attachedToDom = constant('alloy.system.attached');\n    var detachedFromDom = constant('alloy.system.detached');\n    var dismissRequested = constant('alloy.system.dismissRequested');\n    var repositionRequested = constant('alloy.system.repositionRequested');\n    var focusShifted = constant('alloy.focusmanager.shifted');\n    var slotVisibility = constant('alloy.slotcontainer.visibility');\n    var changeTab = constant('alloy.change.tab');\n    var dismissTab = constant('alloy.dismiss.tab');\n    var highlight = constant('alloy.highlight');\n    var dehighlight = constant('alloy.dehighlight');\n\n    var emit = function (component, event) {\n      dispatchWith(component, component.element(), event, {});\n    };\n    var emitWith = function (component, event, properties) {\n      dispatchWith(component, component.element(), event, properties);\n    };\n    var emitExecute = function (component) {\n      emit(component, execute());\n    };\n    var dispatch = function (component, target, event) {\n      dispatchWith(component, target, event, {});\n    };\n    var dispatchWith = function (component, target, event, properties) {\n      var data = __assign({ target: target }, properties);\n      component.getSystem().triggerEvent(event, target, map$1(data, constant));\n    };\n    var dispatchEvent = function (component, target, event, simulatedEvent) {\n      component.getSystem().triggerEvent(event, target, simulatedEvent.event());\n    };\n\n    var derive = function (configs) {\n      return wrapAll$1(configs);\n    };\n    var abort = function (name, predicate) {\n      return {\n        key: name,\n        value: nu$4({ abort: predicate })\n      };\n    };\n    var can = function (name, predicate) {\n      return {\n        key: name,\n        value: nu$4({ can: predicate })\n      };\n    };\n    var preventDefault = function (name) {\n      return {\n        key: name,\n        value: nu$4({\n          run: function (component, simulatedEvent) {\n            simulatedEvent.event().prevent();\n          }\n        })\n      };\n    };\n    var run = function (name, handler) {\n      return {\n        key: name,\n        value: nu$4({ run: handler })\n      };\n    };\n    var runActionExtra = function (name, action, extra) {\n      return {\n        key: name,\n        value: nu$4({\n          run: function (component, simulatedEvent) {\n            action.apply(undefined, [\n              component,\n              simulatedEvent\n            ].concat(extra));\n          }\n        })\n      };\n    };\n    var runOnName = function (name) {\n      return function (handler) {\n        return run(name, handler);\n      };\n    };\n    var runOnSourceName = function (name) {\n      return function (handler) {\n        return {\n          key: name,\n          value: nu$4({\n            run: function (component, simulatedEvent) {\n              if (isSource(component, simulatedEvent)) {\n                handler(component, simulatedEvent);\n              }\n            }\n          })\n        };\n      };\n    };\n    var redirectToUid = function (name, uid) {\n      return run(name, function (component, simulatedEvent) {\n        component.getSystem().getByUid(uid).each(function (redirectee) {\n          dispatchEvent(redirectee, redirectee.element(), name, simulatedEvent);\n        });\n      });\n    };\n    var redirectToPart = function (name, detail, partName) {\n      var uid = detail.partUids[partName];\n      return redirectToUid(name, uid);\n    };\n    var runWithTarget = function (name, f) {\n      return run(name, function (component, simulatedEvent) {\n        var ev = simulatedEvent.event();\n        var target = component.getSystem().getByDom(ev.target()).fold(function () {\n          var closest = closest$1(ev.target(), function (el) {\n            return component.getSystem().getByDom(el).toOption();\n          }, constant(false));\n          return closest.getOr(component);\n        }, function (c) {\n          return c;\n        });\n        f(component, target, simulatedEvent);\n      });\n    };\n    var cutter = function (name) {\n      return run(name, function (component, simulatedEvent) {\n        simulatedEvent.cut();\n      });\n    };\n    var stopper = function (name) {\n      return run(name, function (component, simulatedEvent) {\n        simulatedEvent.stop();\n      });\n    };\n    var runOnSource = function (name, f) {\n      return runOnSourceName(name)(f);\n    };\n    var runOnAttached = runOnSourceName(attachedToDom());\n    var runOnDetached = runOnSourceName(detachedFromDom());\n    var runOnInit = runOnSourceName(systemInit());\n    var runOnExecute = runOnName(execute());\n\n    var Immutable = function () {\n      var fields = [];\n      for (var _i = 0; _i < arguments.length; _i++) {\n        fields[_i] = arguments[_i];\n      }\n      return function () {\n        var values = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          values[_i] = arguments[_i];\n        }\n        if (fields.length !== values.length) {\n          throw new Error('Wrong number of arguments to struct. Expected \"[' + fields.length + ']\", got ' + values.length + ' arguments');\n        }\n        var struct = {};\n        each(fields, function (name, i) {\n          struct[name] = constant(values[i]);\n        });\n        return struct;\n      };\n    };\n\n    var sort$1 = function (arr) {\n      return arr.slice(0).sort();\n    };\n    var reqMessage = function (required, keys) {\n      throw new Error('All required keys (' + sort$1(required).join(', ') + ') were not specified. Specified keys were: ' + sort$1(keys).join(', ') + '.');\n    };\n    var unsuppMessage = function (unsupported) {\n      throw new Error('Unsupported keys for object: ' + sort$1(unsupported).join(', '));\n    };\n    var validateStrArr = function (label, array) {\n      if (!isArray(array)) {\n        throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.');\n      }\n      each(array, function (a) {\n        if (!isString(a)) {\n          throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.');\n        }\n      });\n    };\n    var checkDupes = function (everything) {\n      var sorted = sort$1(everything);\n      var dupe = find(sorted, function (s, i) {\n        return i < sorted.length - 1 && s === sorted[i + 1];\n      });\n      dupe.each(function (d) {\n        throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].');\n      });\n    };\n\n    var MixedBag = function (required, optional) {\n      var everything = required.concat(optional);\n      if (everything.length === 0) {\n        throw new Error('You must specify at least one required or optional field.');\n      }\n      validateStrArr('required', required);\n      validateStrArr('optional', optional);\n      checkDupes(everything);\n      return function (obj) {\n        var keys$1 = keys(obj);\n        var allReqd = forall(required, function (req) {\n          return contains(keys$1, req);\n        });\n        if (!allReqd) {\n          reqMessage(required, keys$1);\n        }\n        var unsupported = filter(keys$1, function (key) {\n          return !contains(everything, key);\n        });\n        if (unsupported.length > 0) {\n          unsuppMessage(unsupported);\n        }\n        var r = {};\n        each(required, function (req) {\n          r[req] = constant(obj[req]);\n        });\n        each(optional, function (opt) {\n          r[opt] = constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]) : Option.none());\n        });\n        return r;\n      };\n    };\n\n    var owner = function (element) {\n      return Element.fromDom(element.dom().ownerDocument);\n    };\n    var documentElement = function (element) {\n      return Element.fromDom(element.dom().ownerDocument.documentElement);\n    };\n    var defaultView = function (element) {\n      return Element.fromDom(element.dom().ownerDocument.defaultView);\n    };\n    var parent = function (element) {\n      return Option.from(element.dom().parentNode).map(Element.fromDom);\n    };\n    var offsetParent = function (element) {\n      return Option.from(element.dom().offsetParent).map(Element.fromDom);\n    };\n    var nextSibling = function (element) {\n      return Option.from(element.dom().nextSibling).map(Element.fromDom);\n    };\n    var children = function (element) {\n      return map(element.dom().childNodes, Element.fromDom);\n    };\n    var child = function (element, index) {\n      var cs = element.dom().childNodes;\n      return Option.from(cs[index]).map(Element.fromDom);\n    };\n    var firstChild = function (element) {\n      return child(element, 0);\n    };\n    var spot = Immutable('element', 'offset');\n\n    var fromHtml$1 = function (html, scope) {\n      var doc = scope || domGlobals.document;\n      var div = doc.createElement('div');\n      div.innerHTML = html;\n      return children(Element.fromDom(div));\n    };\n\n    var before = function (marker, element) {\n      var parent$1 = parent(marker);\n      parent$1.each(function (v) {\n        v.dom().insertBefore(element.dom(), marker.dom());\n      });\n    };\n    var after = function (marker, element) {\n      var sibling = nextSibling(marker);\n      sibling.fold(function () {\n        var parent$1 = parent(marker);\n        parent$1.each(function (v) {\n          append(v, element);\n        });\n      }, function (v) {\n        before(v, element);\n      });\n    };\n    var prepend = function (parent, element) {\n      var firstChild$1 = firstChild(parent);\n      firstChild$1.fold(function () {\n        append(parent, element);\n      }, function (v) {\n        parent.dom().insertBefore(element.dom(), v.dom());\n      });\n    };\n    var append = function (parent, element) {\n      parent.dom().appendChild(element.dom());\n    };\n    var appendAt = function (parent, element, index) {\n      child(parent, index).fold(function () {\n        append(parent, element);\n      }, function (v) {\n        before(v, element);\n      });\n    };\n\n    var before$1 = function (marker, elements) {\n      each(elements, function (x) {\n        before(marker, x);\n      });\n    };\n    var append$1 = function (parent, elements) {\n      each(elements, function (x) {\n        append(parent, x);\n      });\n    };\n\n    var empty = function (element) {\n      element.dom().textContent = '';\n      each(children(element), function (rogue) {\n        remove(rogue);\n      });\n    };\n    var remove = function (element) {\n      var dom = element.dom();\n      if (dom.parentNode !== null) {\n        dom.parentNode.removeChild(dom);\n      }\n    };\n    var unwrap = function (wrapper) {\n      var children$1 = children(wrapper);\n      if (children$1.length > 0) {\n        before$1(wrapper, children$1);\n      }\n      remove(wrapper);\n    };\n\n    var get$1 = function (element) {\n      return element.dom().innerHTML;\n    };\n    var set = function (element, content) {\n      var owner$1 = owner(element);\n      var docDom = owner$1.dom();\n      var fragment = Element.fromDom(docDom.createDocumentFragment());\n      var contentElements = fromHtml$1(content, docDom);\n      append$1(fragment, contentElements);\n      empty(element);\n      append(element, fragment);\n    };\n    var getOuter = function (element) {\n      var container = Element.fromTag('div');\n      var clone = Element.fromDom(element.dom().cloneNode(true));\n      append(container, clone);\n      return get$1(container);\n    };\n\n    var rawSet = function (dom, key, value) {\n      if (isString(value) || isBoolean(value) || isNumber(value)) {\n        dom.setAttribute(key, value + '');\n      } else {\n        domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom);\n        throw new Error('Attribute value was not simple');\n      }\n    };\n    var set$1 = function (element, key, value) {\n      rawSet(element.dom(), key, value);\n    };\n    var setAll = function (element, attrs) {\n      var dom = element.dom();\n      each$1(attrs, function (v, k) {\n        rawSet(dom, k, v);\n      });\n    };\n    var get$2 = function (element, key) {\n      var v = element.dom().getAttribute(key);\n      return v === null ? undefined : v;\n    };\n    var has$1 = function (element, key) {\n      var dom = element.dom();\n      return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;\n    };\n    var remove$1 = function (element, key) {\n      element.dom().removeAttribute(key);\n    };\n\n    var clone = function (original, isDeep) {\n      return Element.fromDom(original.dom().cloneNode(isDeep));\n    };\n    var shallow$1 = function (original) {\n      return clone(original, false);\n    };\n\n    var getHtml = function (element) {\n      var clone = shallow$1(element);\n      return getOuter(clone);\n    };\n\n    var element = function (elem) {\n      return getHtml(elem);\n    };\n\n    var isRecursive = function (component, originator, target) {\n      return eq(originator, component.element()) && !eq(originator, target);\n    };\n    var events = derive([can(focus(), function (component, simulatedEvent) {\n        var originator = simulatedEvent.event().originator();\n        var target = simulatedEvent.event().target();\n        if (isRecursive(component, originator, target)) {\n          domGlobals.console.warn(focus() + ' did not get interpreted by the desired target. ' + '\\nOriginator: ' + element(originator) + '\\nTarget: ' + element(target) + '\\nCheck the ' + focus() + ' event handlers');\n          return false;\n        } else {\n          return true;\n        }\n      })]);\n\n    var DefaultEvents = /*#__PURE__*/Object.freeze({\n        events: events\n    });\n\n    var unique = 0;\n    var generate$1 = function (prefix) {\n      var date = new Date();\n      var time = date.getTime();\n      var random = Math.floor(Math.random() * 1000000000);\n      unique++;\n      return prefix + '_' + random + unique + String(time);\n    };\n\n    var prefix = constant('alloy-id-');\n    var idAttr = constant('data-alloy-id');\n\n    var prefix$1 = prefix();\n    var idAttr$1 = idAttr();\n    var write = function (label, elem) {\n      var id = generate$1(prefix$1 + label);\n      writeOnly(elem, id);\n      return id;\n    };\n    var writeOnly = function (elem, uid) {\n      Object.defineProperty(elem.dom(), idAttr$1, {\n        value: uid,\n        writable: true\n      });\n    };\n    var read$1 = function (elem) {\n      var id = isElement(elem) ? elem.dom()[idAttr$1] : null;\n      return Option.from(id);\n    };\n    var generate$2 = function (prefix) {\n      return generate$1(prefix);\n    };\n\n    var make = identity;\n\n    var NoContextApi = function (getComp) {\n      var fail = function (event) {\n        return function () {\n          throw new Error('The component must be in a context to send: ' + event + '\\n' + element(getComp().element()) + ' is not in context.');\n        };\n      };\n      return {\n        debugInfo: constant('fake'),\n        triggerEvent: fail('triggerEvent'),\n        triggerFocus: fail('triggerFocus'),\n        triggerEscape: fail('triggerEscape'),\n        build: fail('build'),\n        addToWorld: fail('addToWorld'),\n        removeFromWorld: fail('removeFromWorld'),\n        addToGui: fail('addToGui'),\n        removeFromGui: fail('removeFromGui'),\n        getByUid: fail('getByUid'),\n        getByDom: fail('getByDom'),\n        broadcast: fail('broadcast'),\n        broadcastOn: fail('broadcastOn'),\n        broadcastEvent: fail('broadcastEvent'),\n        isConnected: constant(false)\n      };\n    };\n    var singleton = NoContextApi();\n\n    var markAsBehaviourApi = function (f, apiName, apiFunction) {\n      var delegate = apiFunction.toString();\n      var endIndex = delegate.indexOf(')') + 1;\n      var openBracketIndex = delegate.indexOf('(');\n      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\\s*/);\n      f.toFunctionAnnotation = function () {\n        return {\n          name: apiName,\n          parameters: cleanParameters(parameters.slice(0, 1).concat(parameters.slice(3)))\n        };\n      };\n      return f;\n    };\n    var cleanParameters = function (parameters) {\n      return map(parameters, function (p) {\n        return endsWith(p, '/*') ? p.substring(0, p.length - '/*'.length) : p;\n      });\n    };\n    var markAsExtraApi = function (f, extraName) {\n      var delegate = f.toString();\n      var endIndex = delegate.indexOf(')') + 1;\n      var openBracketIndex = delegate.indexOf('(');\n      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\\s*/);\n      f.toFunctionAnnotation = function () {\n        return {\n          name: extraName,\n          parameters: cleanParameters(parameters)\n        };\n      };\n      return f;\n    };\n    var markAsSketchApi = function (f, apiFunction) {\n      var delegate = apiFunction.toString();\n      var endIndex = delegate.indexOf(')') + 1;\n      var openBracketIndex = delegate.indexOf('(');\n      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\\s*/);\n      f.toFunctionAnnotation = function () {\n        return {\n          name: 'OVERRIDE',\n          parameters: cleanParameters(parameters.slice(1))\n        };\n      };\n      return f;\n    };\n\n    var premadeTag = generate$1('alloy-premade');\n    var premade = function (comp) {\n      return wrap$1(premadeTag, comp);\n    };\n    var getPremade = function (spec) {\n      return readOptFrom$1(spec, premadeTag);\n    };\n    var makeApi = function (f) {\n      return markAsSketchApi(function (component) {\n        var rest = [];\n        for (var _i = 1; _i < arguments.length; _i++) {\n          rest[_i - 1] = arguments[_i];\n        }\n        return f.apply(undefined, [component.getApis()].concat([component].concat(rest)));\n      }, f);\n    };\n\n    var NoState = {\n      init: function () {\n        return nu$5({\n          readState: function () {\n            return 'No State required';\n          }\n        });\n      }\n    };\n    var nu$5 = function (spec) {\n      return spec;\n    };\n\n    var generateFrom = function (spec, all) {\n      var schema = map(all, function (a) {\n        return optionObjOf(a.name(), [\n          strict$1('config'),\n          defaulted$1('state', NoState)\n        ]);\n      });\n      var validated = asRaw('component.behaviours', objOf(schema), spec.behaviours).fold(function (errInfo) {\n        throw new Error(formatError(errInfo) + '\\nComplete spec:\\n' + JSON.stringify(spec, null, 2));\n      }, function (v) {\n        return v;\n      });\n      return {\n        list: all,\n        data: map$1(validated, function (optBlobThunk) {\n          var optBlob = optBlobThunk;\n          var output = optBlob.map(function (blob) {\n            return {\n              config: blob.config,\n              state: blob.state.init(blob.config)\n            };\n          });\n          return function () {\n            return output;\n          };\n        })\n      };\n    };\n    var getBehaviours = function (bData) {\n      return bData.list;\n    };\n    var getData = function (bData) {\n      return bData.data;\n    };\n\n    var byInnerKey = function (data, tuple) {\n      var r = {};\n      each$1(data, function (detail, key) {\n        each$1(detail, function (value, indexKey) {\n          var chain = readOr$1(indexKey, [])(r);\n          r[indexKey] = chain.concat([tuple(key, value)]);\n        });\n      });\n      return r;\n    };\n\n    var nu$6 = function (s) {\n      return {\n        classes: s.classes !== undefined ? s.classes : [],\n        attributes: s.attributes !== undefined ? s.attributes : {},\n        styles: s.styles !== undefined ? s.styles : {}\n      };\n    };\n    var merge$1 = function (defnA, mod) {\n      return __assign(__assign({}, defnA), {\n        attributes: __assign(__assign({}, defnA.attributes), mod.attributes),\n        styles: __assign(__assign({}, defnA.styles), mod.styles),\n        classes: defnA.classes.concat(mod.classes)\n      });\n    };\n\n    var combine = function (info, baseMod, behaviours, base) {\n      var modsByBehaviour = __assign({}, baseMod);\n      each(behaviours, function (behaviour) {\n        modsByBehaviour[behaviour.name()] = behaviour.exhibit(info, base);\n      });\n      var nameAndMod = function (name, modification) {\n        return {\n          name: name,\n          modification: modification\n        };\n      };\n      var byAspect = byInnerKey(modsByBehaviour, nameAndMod);\n      var combineObjects = function (objects) {\n        return foldr(objects, function (b, a) {\n          return __assign(__assign({}, a.modification), b);\n        }, {});\n      };\n      var combinedClasses = foldr(byAspect.classes, function (b, a) {\n        return a.modification.concat(b);\n      }, []);\n      var combinedAttributes = combineObjects(byAspect.attributes);\n      var combinedStyles = combineObjects(byAspect.styles);\n      return nu$6({\n        classes: combinedClasses,\n        attributes: combinedAttributes,\n        styles: combinedStyles\n      });\n    };\n\n    var sortKeys = function (label, keyName, array, order) {\n      var sliced = array.slice(0);\n      try {\n        var sorted = sliced.sort(function (a, b) {\n          var aKey = a[keyName]();\n          var bKey = b[keyName]();\n          var aIndex = order.indexOf(aKey);\n          var bIndex = order.indexOf(bKey);\n          if (aIndex === -1) {\n            throw new Error('The ordering for ' + label + ' does not have an entry for ' + aKey + '.\\nOrder specified: ' + JSON.stringify(order, null, 2));\n          }\n          if (bIndex === -1) {\n            throw new Error('The ordering for ' + label + ' does not have an entry for ' + bKey + '.\\nOrder specified: ' + JSON.stringify(order, null, 2));\n          }\n          if (aIndex < bIndex) {\n            return -1;\n          } else if (bIndex < aIndex) {\n            return 1;\n          } else {\n            return 0;\n          }\n        });\n        return Result.value(sorted);\n      } catch (err) {\n        return Result.error([err]);\n      }\n    };\n\n    var uncurried = function (handler, purpose) {\n      return {\n        handler: handler,\n        purpose: constant(purpose)\n      };\n    };\n    var curried = function (handler, purpose) {\n      return {\n        cHandler: handler,\n        purpose: constant(purpose)\n      };\n    };\n    var curryArgs = function (descHandler, extraArgs) {\n      return curried(curry.apply(undefined, [descHandler.handler].concat(extraArgs)), descHandler.purpose());\n    };\n    var getCurried = function (descHandler) {\n      return descHandler.cHandler;\n    };\n\n    var behaviourTuple = function (name, handler) {\n      return {\n        name: constant(name),\n        handler: constant(handler)\n      };\n    };\n    var nameToHandlers = function (behaviours, info) {\n      var r = {};\n      each(behaviours, function (behaviour) {\n        r[behaviour.name()] = behaviour.handlers(info);\n      });\n      return r;\n    };\n    var groupByEvents = function (info, behaviours, base) {\n      var behaviourEvents = __assign(__assign({}, base), nameToHandlers(behaviours, info));\n      return byInnerKey(behaviourEvents, behaviourTuple);\n    };\n    var combine$1 = function (info, eventOrder, behaviours, base) {\n      var byEventName = groupByEvents(info, behaviours, base);\n      return combineGroups(byEventName, eventOrder);\n    };\n    var assemble = function (rawHandler) {\n      var handler = read(rawHandler);\n      return function (component, simulatedEvent) {\n        var rest = [];\n        for (var _i = 2; _i < arguments.length; _i++) {\n          rest[_i - 2] = arguments[_i];\n        }\n        var args = [\n          component,\n          simulatedEvent\n        ].concat(rest);\n        if (handler.abort.apply(undefined, args)) {\n          simulatedEvent.stop();\n        } else if (handler.can.apply(undefined, args)) {\n          handler.run.apply(undefined, args);\n        }\n      };\n    };\n    var missingOrderError = function (eventName, tuples) {\n      return Result.error(['The event (' + eventName + ') has more than one behaviour that listens to it.\\nWhen this occurs, you must ' + 'specify an event ordering for the behaviours in your spec (e.g. [ \"listing\", \"toggling\" ]).\\nThe behaviours that ' + 'can trigger it are: ' + JSON.stringify(map(tuples, function (c) {\n          return c.name();\n        }), null, 2)]);\n    };\n    var fuse$1 = function (tuples, eventOrder, eventName) {\n      var order = eventOrder[eventName];\n      if (!order) {\n        return missingOrderError(eventName, tuples);\n      } else {\n        return sortKeys('Event: ' + eventName, 'name', tuples, order).map(function (sortedTuples) {\n          var handlers = map(sortedTuples, function (tuple) {\n            return tuple.handler();\n          });\n          return fuse(handlers);\n        });\n      }\n    };\n    var combineGroups = function (byEventName, eventOrder) {\n      var r = mapToArray(byEventName, function (tuples, eventName) {\n        var combined = tuples.length === 1 ? Result.value(tuples[0].handler()) : fuse$1(tuples, eventOrder, eventName);\n        return combined.map(function (handler) {\n          var assembled = assemble(handler);\n          var purpose = tuples.length > 1 ? filter(eventOrder[eventName], function (o) {\n            return exists(tuples, function (t) {\n              return t.name() === o;\n            });\n          }).join(' > ') : tuples[0].name();\n          return wrap$1(eventName, uncurried(assembled, purpose));\n        });\n      });\n      return consolidate(r, {});\n    };\n\n    var toInfo = function (spec) {\n      return asRaw('custom.definition', objOf([\n        field('dom', 'dom', strict(), objOf([\n          strict$1('tag'),\n          defaulted$1('styles', {}),\n          defaulted$1('classes', []),\n          defaulted$1('attributes', {}),\n          option('value'),\n          option('innerHtml')\n        ])),\n        strict$1('components'),\n        strict$1('uid'),\n        defaulted$1('events', {}),\n        defaulted$1('apis', {}),\n        field('eventOrder', 'eventOrder', mergeWith({\n          'alloy.execute': [\n            'disabling',\n            'alloy.base.behaviour',\n            'toggling',\n            'typeaheadevents'\n          ],\n          'alloy.focus': [\n            'alloy.base.behaviour',\n            'focusing',\n            'keying'\n          ],\n          'alloy.system.init': [\n            'alloy.base.behaviour',\n            'disabling',\n            'toggling',\n            'representing'\n          ],\n          'input': [\n            'alloy.base.behaviour',\n            'representing',\n            'streaming',\n            'invalidating'\n          ],\n          'alloy.system.detached': [\n            'alloy.base.behaviour',\n            'representing',\n            'item-events',\n            'tooltipping'\n          ],\n          'mousedown': [\n            'focusing',\n            'alloy.base.behaviour',\n            'item-type-events'\n          ],\n          'touchstart': [\n            'focusing',\n            'alloy.base.behaviour',\n            'item-type-events'\n          ],\n          'mouseover': [\n            'item-type-events',\n            'tooltipping'\n          ]\n        }), anyValue$1()),\n        option('domModification')\n      ]), spec);\n    };\n    var toDefinition = function (detail) {\n      return __assign(__assign({}, detail.dom), {\n        uid: detail.uid,\n        domChildren: map(detail.components, function (comp) {\n          return comp.element();\n        })\n      });\n    };\n    var toModification = function (detail) {\n      return detail.domModification.fold(function () {\n        return nu$6({});\n      }, nu$6);\n    };\n    var toEvents = function (info) {\n      return info.events;\n    };\n\n    var read$2 = function (element, attr) {\n      var value = get$2(element, attr);\n      return value === undefined || value === '' ? [] : value.split(' ');\n    };\n    var add = function (element, attr, id) {\n      var old = read$2(element, attr);\n      var nu = old.concat([id]);\n      set$1(element, attr, nu.join(' '));\n      return true;\n    };\n    var remove$2 = function (element, attr, id) {\n      var nu = filter(read$2(element, attr), function (v) {\n        return v !== id;\n      });\n      if (nu.length > 0) {\n        set$1(element, attr, nu.join(' '));\n      } else {\n        remove$1(element, attr);\n      }\n      return false;\n    };\n\n    var supports = function (element) {\n      return element.dom().classList !== undefined;\n    };\n    var get$3 = function (element) {\n      return read$2(element, 'class');\n    };\n    var add$1 = function (element, clazz) {\n      return add(element, 'class', clazz);\n    };\n    var remove$3 = function (element, clazz) {\n      return remove$2(element, 'class', clazz);\n    };\n\n    var add$2 = function (element, clazz) {\n      if (supports(element)) {\n        element.dom().classList.add(clazz);\n      } else {\n        add$1(element, clazz);\n      }\n    };\n    var cleanClass = function (element) {\n      var classList = supports(element) ? element.dom().classList : get$3(element);\n      if (classList.length === 0) {\n        remove$1(element, 'class');\n      }\n    };\n    var remove$4 = function (element, clazz) {\n      if (supports(element)) {\n        var classList = element.dom().classList;\n        classList.remove(clazz);\n      } else {\n        remove$3(element, clazz);\n      }\n      cleanClass(element);\n    };\n    var has$2 = function (element, clazz) {\n      return supports(element) && element.dom().classList.contains(clazz);\n    };\n\n    var add$3 = function (element, classes) {\n      each(classes, function (x) {\n        add$2(element, x);\n      });\n    };\n    var remove$5 = function (element, classes) {\n      each(classes, function (x) {\n        remove$4(element, x);\n      });\n    };\n\n    var isSupported = function (dom) {\n      return dom.style !== undefined && isFunction(dom.style.getPropertyValue);\n    };\n\n    var internalSet = function (dom, property, value) {\n      if (!isString(value)) {\n        domGlobals.console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);\n        throw new Error('CSS value must be a string: ' + value);\n      }\n      if (isSupported(dom)) {\n        dom.style.setProperty(property, value);\n      }\n    };\n    var internalRemove = function (dom, property) {\n      if (isSupported(dom)) {\n        dom.style.removeProperty(property);\n      }\n    };\n    var set$2 = function (element, property, value) {\n      var dom = element.dom();\n      internalSet(dom, property, value);\n    };\n    var setAll$1 = function (element, css) {\n      var dom = element.dom();\n      each$1(css, function (v, k) {\n        internalSet(dom, k, v);\n      });\n    };\n    var setOptions = function (element, css) {\n      var dom = element.dom();\n      each$1(css, function (v, k) {\n        v.fold(function () {\n          internalRemove(dom, k);\n        }, function (value) {\n          internalSet(dom, k, value);\n        });\n      });\n    };\n    var get$4 = function (element, property) {\n      var dom = element.dom();\n      var styles = domGlobals.window.getComputedStyle(dom);\n      var r = styles.getPropertyValue(property);\n      var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;\n      return v === null ? undefined : v;\n    };\n    var getUnsafeProperty = function (dom, property) {\n      return isSupported(dom) ? dom.style.getPropertyValue(property) : '';\n    };\n    var getRaw = function (element, property) {\n      var dom = element.dom();\n      var raw = getUnsafeProperty(dom, property);\n      return Option.from(raw).filter(function (r) {\n        return r.length > 0;\n      });\n    };\n    var isValidValue = function (tag, property, value) {\n      var element = Element.fromTag(tag);\n      set$2(element, property, value);\n      var style = getRaw(element, property);\n      return style.isSome();\n    };\n    var remove$6 = function (element, property) {\n      var dom = element.dom();\n      internalRemove(dom, property);\n      if (has$1(element, 'style') && trim(get$2(element, 'style')) === '') {\n        remove$1(element, 'style');\n      }\n    };\n    var reflow = function (e) {\n      return e.dom().offsetWidth;\n    };\n\n    var get$5 = function (element) {\n      return element.dom().value;\n    };\n    var set$3 = function (element, value) {\n      if (value === undefined) {\n        throw new Error('Value.set was undefined');\n      }\n      element.dom().value = value;\n    };\n\n    var renderToDom = function (definition) {\n      var subject = Element.fromTag(definition.tag);\n      setAll(subject, definition.attributes);\n      add$3(subject, definition.classes);\n      setAll$1(subject, definition.styles);\n      definition.innerHtml.each(function (html) {\n        return set(subject, html);\n      });\n      var children = definition.domChildren;\n      append$1(subject, children);\n      definition.value.each(function (value) {\n        set$3(subject, value);\n      });\n      if (!definition.uid) {\n        debugger;\n      }\n      writeOnly(subject, definition.uid);\n      return subject;\n    };\n\n    var getBehaviours$1 = function (spec) {\n      var behaviours = readOr$1('behaviours', {})(spec);\n      var keys$1 = filter(keys(behaviours), function (k) {\n        return behaviours[k] !== undefined;\n      });\n      return map(keys$1, function (k) {\n        return behaviours[k].me;\n      });\n    };\n    var generateFrom$1 = function (spec, all) {\n      return generateFrom(spec, all);\n    };\n    var generate$3 = function (spec) {\n      var all = getBehaviours$1(spec);\n      return generateFrom$1(spec, all);\n    };\n\n    var getDomDefinition = function (info, bList, bData) {\n      var definition = toDefinition(info);\n      var infoModification = toModification(info);\n      var baseModification = { 'alloy.base.modification': infoModification };\n      var modification = bList.length > 0 ? combine(bData, baseModification, bList, definition) : infoModification;\n      return merge$1(definition, modification);\n    };\n    var getEvents = function (info, bList, bData) {\n      var baseEvents = { 'alloy.base.behaviour': toEvents(info) };\n      return combine$1(bData, info.eventOrder, bList, baseEvents).getOrDie();\n    };\n    var build = function (spec) {\n      var getMe = function () {\n        return me;\n      };\n      var systemApi = Cell(singleton);\n      var info = getOrDie(toInfo(spec));\n      var bBlob = generate$3(spec);\n      var bList = getBehaviours(bBlob);\n      var bData = getData(bBlob);\n      var modDefinition = getDomDefinition(info, bList, bData);\n      var item = renderToDom(modDefinition);\n      var events = getEvents(info, bList, bData);\n      var subcomponents = Cell(info.components);\n      var connect = function (newApi) {\n        systemApi.set(newApi);\n      };\n      var disconnect = function () {\n        systemApi.set(NoContextApi(getMe));\n      };\n      var syncComponents = function () {\n        var children$1 = children(item);\n        var subs = bind(children$1, function (child) {\n          return systemApi.get().getByDom(child).fold(function () {\n            return [];\n          }, function (c) {\n            return [c];\n          });\n        });\n        subcomponents.set(subs);\n      };\n      var config = function (behaviour) {\n        var b = bData;\n        var f = isFunction(b[behaviour.name()]) ? b[behaviour.name()] : function () {\n          throw new Error('Could not find ' + behaviour.name() + ' in ' + JSON.stringify(spec, null, 2));\n        };\n        return f();\n      };\n      var hasConfigured = function (behaviour) {\n        return isFunction(bData[behaviour.name()]);\n      };\n      var getApis = function () {\n        return info.apis;\n      };\n      var readState = function (behaviourName) {\n        return bData[behaviourName]().map(function (b) {\n          return b.state.readState();\n        }).getOr('not enabled');\n      };\n      var me = {\n        getSystem: systemApi.get,\n        config: config,\n        hasConfigured: hasConfigured,\n        spec: constant(spec),\n        readState: readState,\n        getApis: getApis,\n        connect: connect,\n        disconnect: disconnect,\n        element: constant(item),\n        syncComponents: syncComponents,\n        components: subcomponents.get,\n        events: constant(events)\n      };\n      return me;\n    };\n\n    var buildSubcomponents = function (spec) {\n      var components = readOr$1('components', [])(spec);\n      return map(components, build$1);\n    };\n    var buildFromSpec = function (userSpec) {\n      var _a = make(userSpec), specEvents = _a.events, spec = __rest(_a, ['events']);\n      var components = buildSubcomponents(spec);\n      var completeSpec = __assign(__assign({}, spec), {\n        events: __assign(__assign({}, DefaultEvents), specEvents),\n        components: components\n      });\n      return Result.value(build(completeSpec));\n    };\n    var text = function (textContent) {\n      var element = Element.fromText(textContent);\n      return external({ element: element });\n    };\n    var external = function (spec) {\n      var extSpec = asRawOrDie('external.component', objOfOnly([\n        strict$1('element'),\n        option('uid')\n      ]), spec);\n      var systemApi = Cell(NoContextApi());\n      var connect = function (newApi) {\n        systemApi.set(newApi);\n      };\n      var disconnect = function () {\n        systemApi.set(NoContextApi(function () {\n          return me;\n        }));\n      };\n      extSpec.uid.each(function (uid) {\n        writeOnly(extSpec.element, uid);\n      });\n      var me = {\n        getSystem: systemApi.get,\n        config: Option.none,\n        hasConfigured: constant(false),\n        connect: connect,\n        disconnect: disconnect,\n        getApis: function () {\n          return {};\n        },\n        element: constant(extSpec.element),\n        spec: constant(spec),\n        readState: constant('No state'),\n        syncComponents: noop,\n        components: constant([]),\n        events: constant({})\n      };\n      return premade(me);\n    };\n    var uids = generate$2;\n    var build$1 = function (spec) {\n      return getPremade(spec).fold(function () {\n        var userSpecWithUid = spec.hasOwnProperty('uid') ? spec : __assign({ uid: uids('') }, spec);\n        return buildFromSpec(userSpecWithUid).getOrDie();\n      }, function (prebuilt) {\n        return prebuilt;\n      });\n    };\n    var premade$1 = premade;\n\n    function Dimension (name, getOffset) {\n      var set = function (element, h) {\n        if (!isNumber(h) && !h.match(/^[0-9]+$/)) {\n          throw new Error(name + '.set accepts only positive integer values. Value was ' + h);\n        }\n        var dom = element.dom();\n        if (isSupported(dom)) {\n          dom.style[name] = h + 'px';\n        }\n      };\n      var get = function (element) {\n        var r = getOffset(element);\n        if (r <= 0 || r === null) {\n          var css = get$4(element, name);\n          return parseFloat(css) || 0;\n        }\n        return r;\n      };\n      var getOuter = get;\n      var aggregate = function (element, properties) {\n        return foldl(properties, function (acc, property) {\n          var val = get$4(element, property);\n          var value = val === undefined ? 0 : parseInt(val, 10);\n          return isNaN(value) ? acc : acc + value;\n        }, 0);\n      };\n      var max = function (element, value, properties) {\n        var cumulativeInclusions = aggregate(element, properties);\n        var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;\n        return absoluteMax;\n      };\n      return {\n        set: set,\n        get: get,\n        getOuter: getOuter,\n        aggregate: aggregate,\n        max: max\n      };\n    }\n\n    var api = Dimension('height', function (element) {\n      var dom = element.dom();\n      return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;\n    });\n    var get$6 = function (element) {\n      return api.get(element);\n    };\n    var getOuter$1 = function (element) {\n      return api.getOuter(element);\n    };\n    var setMax = function (element, value) {\n      var inclusions = [\n        'margin-top',\n        'border-top-width',\n        'padding-top',\n        'padding-bottom',\n        'border-bottom-width',\n        'margin-bottom'\n      ];\n      var absMax = api.max(element, value, inclusions);\n      set$2(element, 'max-height', absMax + 'px');\n    };\n\n    var r = function (left, top) {\n      var translate = function (x, y) {\n        return r(left + x, top + y);\n      };\n      return {\n        left: constant(left),\n        top: constant(top),\n        translate: translate\n      };\n    };\n    var Position = r;\n\n    var boxPosition = function (dom) {\n      var box = dom.getBoundingClientRect();\n      return Position(box.left, box.top);\n    };\n    var firstDefinedOrZero = function (a, b) {\n      return a !== undefined ? a : b !== undefined ? b : 0;\n    };\n    var absolute = function (element) {\n      var doc = element.dom().ownerDocument;\n      var body = doc.body;\n      var win = doc.defaultView;\n      var html = doc.documentElement;\n      if (body === element.dom()) {\n        return Position(body.offsetLeft, body.offsetTop);\n      }\n      var scrollTop = firstDefinedOrZero(win.pageYOffset, html.scrollTop);\n      var scrollLeft = firstDefinedOrZero(win.pageXOffset, html.scrollLeft);\n      var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);\n      var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);\n      return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);\n    };\n    var viewport = function (element) {\n      var dom = element.dom();\n      var doc = dom.ownerDocument;\n      var body = doc.body;\n      if (body === dom) {\n        return Position(body.offsetLeft, body.offsetTop);\n      }\n      if (!inBody(element)) {\n        return Position(0, 0);\n      }\n      return boxPosition(dom);\n    };\n\n    var api$1 = Dimension('width', function (element) {\n      return element.dom().offsetWidth;\n    });\n    var set$4 = function (element, h) {\n      api$1.set(element, h);\n    };\n    var get$7 = function (element) {\n      return api$1.get(element);\n    };\n    var getOuter$2 = function (element) {\n      return api$1.getOuter(element);\n    };\n    var setMax$1 = function (element, value) {\n      var inclusions = [\n        'margin-left',\n        'border-left-width',\n        'padding-left',\n        'padding-right',\n        'border-right-width',\n        'margin-right'\n      ];\n      var absMax = api$1.max(element, value, inclusions);\n      set$2(element, 'max-width', absMax + 'px');\n    };\n\n    var isSafari = detect$3().browser.isSafari();\n    var get$8 = function (_DOC) {\n      var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document;\n      var x = doc.body.scrollLeft || doc.documentElement.scrollLeft;\n      var y = doc.body.scrollTop || doc.documentElement.scrollTop;\n      return Position(x, y);\n    };\n\n    var bounds = function (x, y, width, height) {\n      return {\n        x: constant(x),\n        y: constant(y),\n        width: constant(width),\n        height: constant(height),\n        right: constant(x + width),\n        bottom: constant(y + height)\n      };\n    };\n    var getBounds = function (_win) {\n      var win = _win === undefined ? domGlobals.window : _win;\n      var doc = win.document;\n      var scroll = get$8(Element.fromDom(doc));\n      var visualViewport = win['visualViewport'];\n      if (visualViewport !== undefined) {\n        return bounds(Math.max(visualViewport.pageLeft, scroll.left()), Math.max(visualViewport.pageTop, scroll.top()), visualViewport.width, visualViewport.height);\n      } else {\n        var html = doc.documentElement;\n        var width = html.clientWidth;\n        var height = html.clientHeight;\n        return bounds(scroll.left(), scroll.top(), width, height);\n      }\n    };\n\n    var walkUp = function (navigation, doc) {\n      var frame = navigation.view(doc);\n      return frame.fold(constant([]), function (f) {\n        var parent = navigation.owner(f);\n        var rest = walkUp(navigation, parent);\n        return [f].concat(rest);\n      });\n    };\n    var pathTo = function (element, navigation) {\n      var d = navigation.owner(element);\n      var paths = walkUp(navigation, d);\n      return Option.some(paths);\n    };\n\n    var view = function (doc) {\n      var element = doc.dom() === domGlobals.document ? Option.none() : Option.from(doc.dom().defaultView.frameElement);\n      return element.map(Element.fromDom);\n    };\n    var owner$1 = function (element) {\n      return owner(element);\n    };\n\n    var Navigation = /*#__PURE__*/Object.freeze({\n        view: view,\n        owner: owner$1\n    });\n\n    var find$3 = function (element) {\n      var doc = Element.fromDom(domGlobals.document);\n      var scroll = get$8(doc);\n      var path = pathTo(element, Navigation);\n      return path.fold(curry(absolute, element), function (frames) {\n        var offset = viewport(element);\n        var r = foldr(frames, function (b, a) {\n          var loc = viewport(a);\n          return {\n            left: b.left + loc.left(),\n            top: b.top + loc.top()\n          };\n        }, {\n          left: 0,\n          top: 0\n        });\n        return Position(r.left + offset.left() + scroll.left(), r.top + offset.top() + scroll.top());\n      });\n    };\n\n    var pointed = Immutable('point', 'width', 'height');\n    var rect = Immutable('x', 'y', 'width', 'height');\n    var bounds$1 = function (x, y, width, height) {\n      return {\n        x: constant(x),\n        y: constant(y),\n        width: constant(width),\n        height: constant(height),\n        right: constant(x + width),\n        bottom: constant(y + height)\n      };\n    };\n    var box = function (element) {\n      var xy = absolute(element);\n      var w = getOuter$2(element);\n      var h = getOuter$1(element);\n      return bounds$1(xy.left(), xy.top(), w, h);\n    };\n    var absolute$1 = function (element) {\n      var position = find$3(element);\n      var width = getOuter$2(element);\n      var height = getOuter$1(element);\n      return bounds$1(position.left(), position.top(), width, height);\n    };\n    var win = function () {\n      return getBounds(domGlobals.window);\n    };\n\n    var closest$2 = function (scope, predicate, isRoot) {\n      return closest(scope, predicate, isRoot).isSome();\n    };\n\n    var ancestor$1 = function (scope, selector, isRoot) {\n      return ancestor(scope, function (e) {\n        return is(e, selector);\n      }, isRoot);\n    };\n    var descendant$1 = function (scope, selector) {\n      return one(selector, scope);\n    };\n    var closest$3 = function (scope, selector, isRoot) {\n      return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot);\n    };\n\n    var find$4 = function (queryElem) {\n      var dependent = closest(queryElem, function (elem) {\n        if (!isElement(elem)) {\n          return false;\n        }\n        var id = get$2(elem, 'id');\n        return id !== undefined && id.indexOf('aria-owns') > -1;\n      });\n      return dependent.bind(function (dep) {\n        var id = get$2(dep, 'id');\n        var doc = owner(dep);\n        return descendant$1(doc, '[aria-owns=\"' + id + '\"]');\n      });\n    };\n    var manager = function () {\n      var ariaId = generate$1('aria-owns');\n      var link = function (elem) {\n        set$1(elem, 'aria-owns', ariaId);\n      };\n      var unlink = function (elem) {\n        remove$1(elem, 'aria-owns');\n      };\n      return {\n        id: constant(ariaId),\n        link: link,\n        unlink: unlink\n      };\n    };\n\n    var isAriaPartOf = function (component, queryElem) {\n      return find$4(queryElem).exists(function (owner) {\n        return isPartOf(component, owner);\n      });\n    };\n    var isPartOf = function (component, queryElem) {\n      return closest$2(queryElem, function (el) {\n        return eq(el, component.element());\n      }, constant(false)) || isAriaPartOf(component, queryElem);\n    };\n\n    var cat = function (arr) {\n      var r = [];\n      var push = function (x) {\n        r.push(x);\n      };\n      for (var i = 0; i < arr.length; i++) {\n        arr[i].each(push);\n      }\n      return r;\n    };\n    var sequence = function (arr) {\n      var r = [];\n      for (var i = 0; i < arr.length; i++) {\n        var x = arr[i];\n        if (x.isSome()) {\n          r.push(x.getOrDie());\n        } else {\n          return Option.none();\n        }\n      }\n      return Option.some(r);\n    };\n    var findMap = function (arr, f) {\n      for (var i = 0; i < arr.length; i++) {\n        var r = f(arr[i], i);\n        if (r.isSome()) {\n          return r;\n        }\n      }\n      return Option.none();\n    };\n    var lift2 = function (oa, ob, f) {\n      return oa.isSome() && ob.isSome() ? Option.some(f(oa.getOrDie(), ob.getOrDie())) : Option.none();\n    };\n    var lift3 = function (oa, ob, oc, f) {\n      return oa.isSome() && ob.isSome() && oc.isSome() ? Option.some(f(oa.getOrDie(), ob.getOrDie(), oc.getOrDie())) : Option.none();\n    };\n\n    var unknown$3 = 'unknown';\n    var EventConfiguration;\n    (function (EventConfiguration) {\n      EventConfiguration[EventConfiguration['STOP'] = 0] = 'STOP';\n      EventConfiguration[EventConfiguration['NORMAL'] = 1] = 'NORMAL';\n      EventConfiguration[EventConfiguration['LOGGING'] = 2] = 'LOGGING';\n    }(EventConfiguration || (EventConfiguration = {})));\n    var eventConfig = Cell({});\n    var makeEventLogger = function (eventName, initialTarget) {\n      var sequence = [];\n      var startTime = new Date().getTime();\n      return {\n        logEventCut: function (name, target, purpose) {\n          sequence.push({\n            outcome: 'cut',\n            target: target,\n            purpose: purpose\n          });\n        },\n        logEventStopped: function (name, target, purpose) {\n          sequence.push({\n            outcome: 'stopped',\n            target: target,\n            purpose: purpose\n          });\n        },\n        logNoParent: function (name, target, purpose) {\n          sequence.push({\n            outcome: 'no-parent',\n            target: target,\n            purpose: purpose\n          });\n        },\n        logEventNoHandlers: function (name, target) {\n          sequence.push({\n            outcome: 'no-handlers-left',\n            target: target\n          });\n        },\n        logEventResponse: function (name, target, purpose) {\n          sequence.push({\n            outcome: 'response',\n            purpose: purpose,\n            target: target\n          });\n        },\n        write: function () {\n          var finishTime = new Date().getTime();\n          if (contains([\n              'mousemove',\n              'mouseover',\n              'mouseout',\n              systemInit()\n            ], eventName)) {\n            return;\n          }\n          domGlobals.console.log(eventName, {\n            event: eventName,\n            time: finishTime - startTime,\n            target: initialTarget.dom(),\n            sequence: map(sequence, function (s) {\n              if (!contains([\n                  'cut',\n                  'stopped',\n                  'response'\n                ], s.outcome)) {\n                return s.outcome;\n              } else {\n                return '{' + s.purpose + '} ' + s.outcome + ' at (' + element(s.target) + ')';\n              }\n            })\n          });\n        }\n      };\n    };\n    var processEvent = function (eventName, initialTarget, f) {\n      var status = readOptFrom$1(eventConfig.get(), eventName).orThunk(function () {\n        var patterns = keys(eventConfig.get());\n        return findMap(patterns, function (p) {\n          return eventName.indexOf(p) > -1 ? Option.some(eventConfig.get()[p]) : Option.none();\n        });\n      }).getOr(EventConfiguration.NORMAL);\n      switch (status) {\n      case EventConfiguration.NORMAL:\n        return f(noLogger());\n      case EventConfiguration.LOGGING: {\n          var logger = makeEventLogger(eventName, initialTarget);\n          var output = f(logger);\n          logger.write();\n          return output;\n        }\n      case EventConfiguration.STOP:\n        return true;\n      }\n    };\n    var path = [\n      'alloy/data/Fields',\n      'alloy/debugging/Debugging'\n    ];\n    var getTrace = function () {\n      var err = new Error();\n      if (err.stack !== undefined) {\n        var lines = err.stack.split('\\n');\n        return find(lines, function (line) {\n          return line.indexOf('alloy') > 0 && !exists(path, function (p) {\n            return line.indexOf(p) > -1;\n          });\n        }).getOr(unknown$3);\n      } else {\n        return unknown$3;\n      }\n    };\n    var ignoreEvent = {\n      logEventCut: noop,\n      logEventStopped: noop,\n      logNoParent: noop,\n      logEventNoHandlers: noop,\n      logEventResponse: noop,\n      write: noop\n    };\n    var monitorEvent = function (eventName, initialTarget, f) {\n      return processEvent(eventName, initialTarget, f);\n    };\n    var noLogger = constant(ignoreEvent);\n\n    var menuFields = constant([\n      strict$1('menu'),\n      strict$1('selectedMenu')\n    ]);\n    var itemFields = constant([\n      strict$1('item'),\n      strict$1('selectedItem')\n    ]);\n    var schema = constant(objOf(itemFields().concat(menuFields())));\n    var itemSchema = constant(objOf(itemFields()));\n\n    var _initSize = strictObjOf('initSize', [\n      strict$1('numColumns'),\n      strict$1('numRows')\n    ]);\n    var itemMarkers = function () {\n      return strictOf('markers', itemSchema());\n    };\n    var tieredMenuMarkers = function () {\n      return strictObjOf('markers', [strict$1('backgroundMenu')].concat(menuFields()).concat(itemFields()));\n    };\n    var markers = function (required) {\n      return strictObjOf('markers', map(required, strict$1));\n    };\n    var onPresenceHandler = function (label, fieldName, presence) {\n      var trace = getTrace();\n      return field(fieldName, fieldName, presence, valueOf(function (f) {\n        return Result.value(function () {\n          var args = [];\n          for (var _i = 0; _i < arguments.length; _i++) {\n            args[_i] = arguments[_i];\n          }\n          return f.apply(undefined, args);\n        });\n      }));\n    };\n    var onHandler = function (fieldName) {\n      return onPresenceHandler('onHandler', fieldName, defaulted(noop));\n    };\n    var onKeyboardHandler = function (fieldName) {\n      return onPresenceHandler('onKeyboardHandler', fieldName, defaulted(Option.none));\n    };\n    var onStrictHandler = function (fieldName) {\n      return onPresenceHandler('onHandler', fieldName, strict());\n    };\n    var onStrictKeyboardHandler = function (fieldName) {\n      return onPresenceHandler('onKeyboardHandler', fieldName, strict());\n    };\n    var output = function (name, value) {\n      return state$1(name, constant(value));\n    };\n    var snapshot = function (name) {\n      return state$1(name, identity);\n    };\n    var initSize = constant(_initSize);\n\n    var nu$7 = Immutable('x', 'y', 'bubble', 'direction', 'label');\n\n    var adt$2 = Adt.generate([\n      { southeast: [] },\n      { southwest: [] },\n      { northeast: [] },\n      { northwest: [] },\n      { south: [] },\n      { north: [] },\n      { east: [] },\n      { west: [] }\n    ]);\n    var cata = function (subject, southeast, southwest, northeast, northwest, south, north, east, west) {\n      return subject.fold(southeast, southwest, northeast, northwest, south, north, east, west);\n    };\n    var cataVertical = function (subject, south, middle, north) {\n      return subject.fold(south, south, north, north, south, north, middle, middle);\n    };\n    var cataHorizontal = function (subject, east, middle, west) {\n      return subject.fold(east, west, east, west, middle, middle, east, west);\n    };\n    var southeast = adt$2.southeast;\n    var southwest = adt$2.southwest;\n    var northeast = adt$2.northeast;\n    var northwest = adt$2.northwest;\n    var south = adt$2.south;\n    var north = adt$2.north;\n    var east = adt$2.east;\n    var west = adt$2.west;\n\n    var eastX = function (anchor) {\n      return anchor.x();\n    };\n    var middleX = function (anchor, element) {\n      return anchor.x() + anchor.width() / 2 - element.width() / 2;\n    };\n    var westX = function (anchor, element) {\n      return anchor.x() + anchor.width() - element.width();\n    };\n    var northY = function (anchor, element) {\n      return anchor.y() - element.height();\n    };\n    var southY = function (anchor) {\n      return anchor.y() + anchor.height();\n    };\n    var centreY = function (anchor, element) {\n      return anchor.y() + anchor.height() / 2 - element.height() / 2;\n    };\n    var eastEdgeX = function (anchor) {\n      return anchor.x() + anchor.width();\n    };\n    var westEdgeX = function (anchor, element) {\n      return anchor.x() - element.width();\n    };\n    var southeast$1 = function (anchor, element, bubbles) {\n      return nu$7(eastX(anchor), southY(anchor), bubbles.southeast(), southeast(), 'layout-se');\n    };\n    var southwest$1 = function (anchor, element, bubbles) {\n      return nu$7(westX(anchor, element), southY(anchor), bubbles.southwest(), southwest(), 'layout-sw');\n    };\n    var northeast$1 = function (anchor, element, bubbles) {\n      return nu$7(eastX(anchor), northY(anchor, element), bubbles.northeast(), northeast(), 'layout-ne');\n    };\n    var northwest$1 = function (anchor, element, bubbles) {\n      return nu$7(westX(anchor, element), northY(anchor, element), bubbles.northwest(), northwest(), 'layout-nw');\n    };\n    var north$1 = function (anchor, element, bubbles) {\n      return nu$7(middleX(anchor, element), northY(anchor, element), bubbles.north(), north(), 'layout-n');\n    };\n    var south$1 = function (anchor, element, bubbles) {\n      return nu$7(middleX(anchor, element), southY(anchor), bubbles.south(), south(), 'layout-s');\n    };\n    var east$1 = function (anchor, element, bubbles) {\n      return nu$7(eastEdgeX(anchor), centreY(anchor, element), bubbles.east(), east(), 'layout-e');\n    };\n    var west$1 = function (anchor, element, bubbles) {\n      return nu$7(westEdgeX(anchor, element), centreY(anchor, element), bubbles.west(), west(), 'layout-w');\n    };\n    var all$2 = function () {\n      return [\n        southeast$1,\n        southwest$1,\n        northeast$1,\n        northwest$1,\n        south$1,\n        north$1,\n        east$1,\n        west$1\n      ];\n    };\n    var allRtl = function () {\n      return [\n        southwest$1,\n        southeast$1,\n        northwest$1,\n        northeast$1,\n        south$1,\n        north$1,\n        east$1,\n        west$1\n      ];\n    };\n    var belowOrAbove = function () {\n      return [\n        southeast$1,\n        southwest$1,\n        northeast$1,\n        northwest$1,\n        south$1,\n        north$1\n      ];\n    };\n    var belowOrAboveRtl = function () {\n      return [\n        southwest$1,\n        southeast$1,\n        northwest$1,\n        northeast$1,\n        south$1,\n        north$1\n      ];\n    };\n\n    var executeEvent = function (bConfig, bState, executor) {\n      return runOnExecute(function (component) {\n        executor(component, bConfig, bState);\n      });\n    };\n    var loadEvent = function (bConfig, bState, f) {\n      return runOnInit(function (component, simulatedEvent) {\n        f(component, bConfig, bState);\n      });\n    };\n    var create = function (schema, name, active, apis, extra, state) {\n      var configSchema = objOfOnly(schema);\n      var schemaSchema = optionObjOf(name, [optionObjOfOnly('config', schema)]);\n      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);\n    };\n    var createModes = function (modes, name, active, apis, extra, state) {\n      var configSchema = modes;\n      var schemaSchema = optionObjOf(name, [optionOf('config', modes)]);\n      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);\n    };\n    var wrapApi = function (bName, apiFunction, apiName) {\n      var f = function (component) {\n        var rest = [];\n        for (var _i = 1; _i < arguments.length; _i++) {\n          rest[_i - 1] = arguments[_i];\n        }\n        var args = [component].concat(rest);\n        return component.config({ name: constant(bName) }).fold(function () {\n          throw new Error('We could not find any behaviour configuration for: ' + bName + '. Using API: ' + apiName);\n        }, function (info) {\n          var rest = Array.prototype.slice.call(args, 1);\n          return apiFunction.apply(undefined, [\n            component,\n            info.config,\n            info.state\n          ].concat(rest));\n        });\n      };\n      return markAsBehaviourApi(f, apiName, apiFunction);\n    };\n    var revokeBehaviour = function (name) {\n      return {\n        key: name,\n        value: undefined\n      };\n    };\n    var doCreate = function (configSchema, schemaSchema, name, active, apis, extra, state) {\n      var getConfig = function (info) {\n        return hasKey$1(info, name) ? info[name]() : Option.none();\n      };\n      var wrappedApis = map$1(apis, function (apiF, apiName) {\n        return wrapApi(name, apiF, apiName);\n      });\n      var wrappedExtra = map$1(extra, function (extraF, extraName) {\n        return markAsExtraApi(extraF, extraName);\n      });\n      var me = __assign(__assign(__assign({}, wrappedExtra), wrappedApis), {\n        revoke: curry(revokeBehaviour, name),\n        config: function (spec) {\n          var prepared = asRawOrDie(name + '-config', configSchema, spec);\n          return {\n            key: name,\n            value: {\n              config: prepared,\n              me: me,\n              configAsRaw: cached(function () {\n                return asRawOrDie(name + '-config', configSchema, spec);\n              }),\n              initialConfig: spec,\n              state: state\n            }\n          };\n        },\n        schema: function () {\n          return schemaSchema;\n        },\n        exhibit: function (info, base) {\n          return getConfig(info).bind(function (behaviourInfo) {\n            return readOptFrom$1(active, 'exhibit').map(function (exhibitor) {\n              return exhibitor(base, behaviourInfo.config, behaviourInfo.state);\n            });\n          }).getOr(nu$6({}));\n        },\n        name: function () {\n          return name;\n        },\n        handlers: function (info) {\n          return getConfig(info).map(function (behaviourInfo) {\n            var getEvents = readOr$1('events', function (a, b) {\n              return {};\n            })(active);\n            return getEvents(behaviourInfo.config, behaviourInfo.state);\n          }).getOr({});\n        }\n      });\n      return me;\n    };\n\n    var derive$1 = function (capabilities) {\n      return wrapAll$1(capabilities);\n    };\n    var simpleSchema = objOfOnly([\n      strict$1('fields'),\n      strict$1('name'),\n      defaulted$1('active', {}),\n      defaulted$1('apis', {}),\n      defaulted$1('state', NoState),\n      defaulted$1('extra', {})\n    ]);\n    var create$1 = function (data) {\n      var value = asRawOrDie('Creating behaviour: ' + data.name, simpleSchema, data);\n      return create(value.fields, value.name, value.active, value.apis, value.extra, value.state);\n    };\n    var modeSchema = objOfOnly([\n      strict$1('branchKey'),\n      strict$1('branches'),\n      strict$1('name'),\n      defaulted$1('active', {}),\n      defaulted$1('apis', {}),\n      defaulted$1('state', NoState),\n      defaulted$1('extra', {})\n    ]);\n    var createModes$1 = function (data) {\n      var value = asRawOrDie('Creating behaviour: ' + data.name, modeSchema, data);\n      return createModes(choose$1(value.branchKey, value.branches), value.name, value.active, value.apis, value.extra, value.state);\n    };\n    var revoke = constant(undefined);\n\n    var chooseChannels = function (channels, message) {\n      return message.universal() ? channels : filter(channels, function (ch) {\n        return contains(message.channels(), ch);\n      });\n    };\n    var events$1 = function (receiveConfig) {\n      return derive([run(receive(), function (component, message) {\n          var channelMap = receiveConfig.channels;\n          var channels = keys(channelMap);\n          var targetChannels = chooseChannels(channels, message);\n          each(targetChannels, function (ch) {\n            var channelInfo = channelMap[ch];\n            var channelSchema = channelInfo.schema;\n            var data = asRawOrDie('channel[' + ch + '] data\\nReceiver: ' + element(component.element()), channelSchema, message.data());\n            channelInfo.onReceive(component, data);\n          });\n        })]);\n    };\n\n    var ActiveReceiving = /*#__PURE__*/Object.freeze({\n        events: events$1\n    });\n\n    var ReceivingSchema = [strictOf('channels', setOf$1(Result.value, objOfOnly([\n        onStrictHandler('onReceive'),\n        defaulted$1('schema', anyValue$1())\n      ])))];\n\n    var Receiving = create$1({\n      fields: ReceivingSchema,\n      name: 'receiving',\n      active: ActiveReceiving\n    });\n\n    var exhibit = function (base, posConfig) {\n      return nu$6({\n        classes: [],\n        styles: posConfig.useFixed() ? {} : { position: 'relative' }\n      });\n    };\n\n    var ActivePosition = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit\n    });\n\n    var focus$1 = function (element) {\n      element.dom().focus();\n    };\n    var blur = function (element) {\n      element.dom().blur();\n    };\n    var hasFocus = function (element) {\n      var doc = owner(element).dom();\n      return element.dom() === doc.activeElement;\n    };\n    var active = function (_doc) {\n      var doc = _doc !== undefined ? _doc.dom() : domGlobals.document;\n      return Option.from(doc.activeElement).map(Element.fromDom);\n    };\n    var search = function (element) {\n      return active(owner(element)).filter(function (e) {\n        return element.dom().contains(e.dom());\n      });\n    };\n\n    var preserve = function (f, container) {\n      var ownerDoc = owner(container);\n      var refocus = active(ownerDoc).bind(function (focused) {\n        var hasFocus = function (elem) {\n          return eq(focused, elem);\n        };\n        return hasFocus(container) ? Option.some(container) : descendant(container, hasFocus);\n      });\n      var result = f(container);\n      refocus.each(function (oldFocus) {\n        active(ownerDoc).filter(function (newFocus) {\n          return eq(newFocus, oldFocus);\n        }).fold(function () {\n          focus$1(oldFocus);\n        }, noop);\n      });\n      return result;\n    };\n\n    var allAlignments = [\n      'valignCentre',\n      'alignLeft',\n      'alignRight',\n      'alignCentre',\n      'top',\n      'bottom',\n      'left',\n      'right'\n    ];\n    var nu$8 = function (width, yoffset, classes) {\n      var getClasses = function (prop) {\n        return readOptFrom$1(classes, prop).getOr([]);\n      };\n      var make = function (xDelta, yDelta, alignmentsOn) {\n        var alignmentsOff = difference(allAlignments, alignmentsOn);\n        return {\n          offset: function () {\n            return Position(xDelta, yDelta);\n          },\n          classesOn: function () {\n            return bind(alignmentsOn, getClasses);\n          },\n          classesOff: function () {\n            return bind(alignmentsOff, getClasses);\n          }\n        };\n      };\n      return {\n        southeast: function () {\n          return make(-width, yoffset, [\n            'top',\n            'alignLeft'\n          ]);\n        },\n        southwest: function () {\n          return make(width, yoffset, [\n            'top',\n            'alignRight'\n          ]);\n        },\n        south: function () {\n          return make(-width / 2, yoffset, [\n            'top',\n            'alignCentre'\n          ]);\n        },\n        northeast: function () {\n          return make(-width, -yoffset, [\n            'bottom',\n            'alignLeft'\n          ]);\n        },\n        northwest: function () {\n          return make(width, -yoffset, [\n            'bottom',\n            'alignRight'\n          ]);\n        },\n        north: function () {\n          return make(-width / 2, -yoffset, [\n            'bottom',\n            'alignCentre'\n          ]);\n        },\n        east: function () {\n          return make(width, -yoffset / 2, [\n            'valignCentre',\n            'left'\n          ]);\n        },\n        west: function () {\n          return make(-width, -yoffset / 2, [\n            'valignCentre',\n            'right'\n          ]);\n        },\n        innerNorthwest: function () {\n          return make(-width, yoffset, [\n            'top',\n            'alignRight'\n          ]);\n        },\n        innerNortheast: function () {\n          return make(width, yoffset, [\n            'top',\n            'alignLeft'\n          ]);\n        },\n        innerNorth: function () {\n          return make(-width / 2, yoffset, [\n            'top',\n            'alignCentre'\n          ]);\n        },\n        innerSouthwest: function () {\n          return make(-width, -yoffset, [\n            'bottom',\n            'alignRight'\n          ]);\n        },\n        innerSoutheast: function () {\n          return make(width, -yoffset, [\n            'bottom',\n            'alignLeft'\n          ]);\n        },\n        innerSouth: function () {\n          return make(-width / 2, -yoffset, [\n            'bottom',\n            'alignCentre'\n          ]);\n        },\n        innerWest: function () {\n          return make(width, -yoffset / 2, [\n            'valignCentre',\n            'right'\n          ]);\n        },\n        innerEast: function () {\n          return make(-width, -yoffset / 2, [\n            'valignCentre',\n            'left'\n          ]);\n        }\n      };\n    };\n    var fallback = function () {\n      return nu$8(0, 0, {});\n    };\n\n    var decision = MixedBag([\n      'x',\n      'y',\n      'width',\n      'height',\n      'maxHeight',\n      'maxWidth',\n      'direction',\n      'classes',\n      'label',\n      'candidateYforTest'\n    ], []);\n    var css = Immutable('position', 'left', 'top', 'right', 'bottom');\n\n    var adt$3 = Adt.generate([\n      { none: [] },\n      {\n        relative: [\n          'x',\n          'y',\n          'width',\n          'height'\n        ]\n      },\n      {\n        fixed: [\n          'x',\n          'y',\n          'width',\n          'height'\n        ]\n      }\n    ]);\n    var positionWithDirection = function (posName, decision, x, y, width, height) {\n      var decisionX = decision.x() - x;\n      var decisionY = decision.y() - y;\n      var decisionWidth = decision.width();\n      var decisionHeight = decision.height();\n      var decisionRight = width - (decisionX + decisionWidth);\n      var decisionBottom = height - (decisionY + decisionHeight);\n      var left = Option.some(decisionX);\n      var top = Option.some(decisionY);\n      var right = Option.some(decisionRight);\n      var bottom = Option.some(decisionBottom);\n      var none = Option.none();\n      return cata(decision.direction(), function () {\n        return css(posName, left, top, none, none);\n      }, function () {\n        return css(posName, none, top, right, none);\n      }, function () {\n        return css(posName, left, none, none, bottom);\n      }, function () {\n        return css(posName, none, none, right, bottom);\n      }, function () {\n        return css(posName, left, top, none, none);\n      }, function () {\n        return css(posName, left, none, none, bottom);\n      }, function () {\n        return css(posName, left, top, none, none);\n      }, function () {\n        return css(posName, none, top, right, none);\n      });\n    };\n    var reposition = function (origin, decision) {\n      return origin.fold(function () {\n        return css('absolute', Option.some(decision.x()), Option.some(decision.y()), Option.none(), Option.none());\n      }, function (x, y, width, height) {\n        return positionWithDirection('absolute', decision, x, y, width, height);\n      }, function (x, y, width, height) {\n        return positionWithDirection('fixed', decision, x, y, width, height);\n      });\n    };\n    var toBox = function (origin, element) {\n      var rel = curry(find$3, element);\n      var position = origin.fold(rel, rel, function () {\n        var scroll = get$8();\n        return find$3(element).translate(-scroll.left(), -scroll.top());\n      });\n      var width = getOuter$2(element);\n      var height = getOuter$1(element);\n      return bounds$1(position.left(), position.top(), width, height);\n    };\n    var viewport$1 = function (origin, getBounds) {\n      return getBounds.fold(function () {\n        return origin.fold(win, win, bounds$1);\n      }, function (b) {\n        return origin.fold(b, b, function () {\n          var bounds = b();\n          var pos = translate(origin, bounds.x(), bounds.y());\n          return bounds$1(pos.left(), pos.top(), bounds.width(), bounds.height());\n        });\n      });\n    };\n    var translate = function (origin, x, y) {\n      var pos = Position(x, y);\n      var removeScroll = function () {\n        var outerScroll = get$8();\n        return pos.translate(-outerScroll.left(), -outerScroll.top());\n      };\n      return origin.fold(constant(pos), constant(pos), removeScroll);\n    };\n    var cata$1 = function (subject, onNone, onRelative, onFixed) {\n      return subject.fold(onNone, onRelative, onFixed);\n    };\n    var relative = adt$3.relative;\n    var fixed = adt$3.fixed;\n\n    var nu$9 = function (x) {\n      return x;\n    };\n\n    var onDirection = function (isLtr, isRtl) {\n      return function (element) {\n        return getDirection(element) === 'rtl' ? isRtl : isLtr;\n      };\n    };\n    var getDirection = function (element) {\n      return get$4(element, 'direction') === 'rtl' ? 'rtl' : 'ltr';\n    };\n\n    var schema$1 = function () {\n      return optionObjOf('layouts', [\n        strict$1('onLtr'),\n        strict$1('onRtl')\n      ]);\n    };\n    var get$9 = function (elem, info, defaultLtr, defaultRtl) {\n      var ltr = info.layouts.map(function (ls) {\n        return ls.onLtr(elem);\n      }).getOr(defaultLtr);\n      var rtl = info.layouts.map(function (ls) {\n        return ls.onRtl(elem);\n      }).getOr(defaultRtl);\n      var f = onDirection(ltr, rtl);\n      return f(elem);\n    };\n\n    var placement = function (component, anchorInfo, origin) {\n      var hotspot = anchorInfo.hotspot;\n      var anchorBox = toBox(origin, hotspot.element());\n      var layouts = get$9(component.element(), anchorInfo, belowOrAbove(), belowOrAboveRtl());\n      return Option.some(nu$9({\n        anchorBox: anchorBox,\n        bubble: anchorInfo.bubble.getOr(fallback()),\n        overrides: anchorInfo.overrides,\n        layouts: layouts,\n        placer: Option.none()\n      }));\n    };\n    var HotspotAnchor = [\n      strict$1('hotspot'),\n      option('bubble'),\n      defaulted$1('overrides', {}),\n      schema$1(),\n      output('placement', placement)\n    ];\n\n    var placement$1 = function (component, anchorInfo, origin) {\n      var pos = translate(origin, anchorInfo.x, anchorInfo.y);\n      var anchorBox = bounds$1(pos.left(), pos.top(), anchorInfo.width, anchorInfo.height);\n      var layouts = get$9(component.element(), anchorInfo, all$2(), allRtl());\n      return Option.some(nu$9({\n        anchorBox: anchorBox,\n        bubble: anchorInfo.bubble,\n        overrides: anchorInfo.overrides,\n        layouts: layouts,\n        placer: Option.none()\n      }));\n    };\n    var MakeshiftAnchor = [\n      strict$1('x'),\n      strict$1('y'),\n      defaulted$1('height', 0),\n      defaulted$1('width', 0),\n      defaulted$1('bubble', fallback()),\n      defaulted$1('overrides', {}),\n      schema$1(),\n      output('placement', placement$1)\n    ];\n\n    var zeroWidth = function () {\n      return '\\uFEFF';\n    };\n\n    var create$2 = Immutable('start', 'soffset', 'finish', 'foffset');\n    var SimRange = { create: create$2 };\n\n    var adt$4 = Adt.generate([\n      { before: ['element'] },\n      {\n        on: [\n          'element',\n          'offset'\n        ]\n      },\n      { after: ['element'] }\n    ]);\n    var cata$2 = function (subject, onBefore, onOn, onAfter) {\n      return subject.fold(onBefore, onOn, onAfter);\n    };\n    var getStart = function (situ) {\n      return situ.fold(identity, identity, identity);\n    };\n    var before$2 = adt$4.before;\n    var on = adt$4.on;\n    var after$1 = adt$4.after;\n    var Situ = {\n      before: before$2,\n      on: on,\n      after: after$1,\n      cata: cata$2,\n      getStart: getStart\n    };\n\n    var adt$5 = Adt.generate([\n      { domRange: ['rng'] },\n      {\n        relative: [\n          'startSitu',\n          'finishSitu'\n        ]\n      },\n      {\n        exact: [\n          'start',\n          'soffset',\n          'finish',\n          'foffset'\n        ]\n      }\n    ]);\n    var exactFromRange = function (simRange) {\n      return adt$5.exact(simRange.start(), simRange.soffset(), simRange.finish(), simRange.foffset());\n    };\n    var getStart$1 = function (selection) {\n      return selection.match({\n        domRange: function (rng) {\n          return Element.fromDom(rng.startContainer);\n        },\n        relative: function (startSitu, finishSitu) {\n          return Situ.getStart(startSitu);\n        },\n        exact: function (start, soffset, finish, foffset) {\n          return start;\n        }\n      });\n    };\n    var domRange = adt$5.domRange;\n    var relative$1 = adt$5.relative;\n    var exact = adt$5.exact;\n    var getWin = function (selection) {\n      var start = getStart$1(selection);\n      return defaultView(start);\n    };\n    var range$1 = SimRange.create;\n    var Selection = {\n      domRange: domRange,\n      relative: relative$1,\n      exact: exact,\n      exactFromRange: exactFromRange,\n      getWin: getWin,\n      range: range$1\n    };\n\n    var setStart = function (rng, situ) {\n      situ.fold(function (e) {\n        rng.setStartBefore(e.dom());\n      }, function (e, o) {\n        rng.setStart(e.dom(), o);\n      }, function (e) {\n        rng.setStartAfter(e.dom());\n      });\n    };\n    var setFinish = function (rng, situ) {\n      situ.fold(function (e) {\n        rng.setEndBefore(e.dom());\n      }, function (e, o) {\n        rng.setEnd(e.dom(), o);\n      }, function (e) {\n        rng.setEndAfter(e.dom());\n      });\n    };\n    var relativeToNative = function (win, startSitu, finishSitu) {\n      var range = win.document.createRange();\n      setStart(range, startSitu);\n      setFinish(range, finishSitu);\n      return range;\n    };\n    var exactToNative = function (win, start, soffset, finish, foffset) {\n      var rng = win.document.createRange();\n      rng.setStart(start.dom(), soffset);\n      rng.setEnd(finish.dom(), foffset);\n      return rng;\n    };\n    var toRect = function (rect) {\n      return {\n        left: constant(rect.left),\n        top: constant(rect.top),\n        right: constant(rect.right),\n        bottom: constant(rect.bottom),\n        width: constant(rect.width),\n        height: constant(rect.height)\n      };\n    };\n    var getFirstRect = function (rng) {\n      var rects = rng.getClientRects();\n      var rect = rects.length > 0 ? rects[0] : rng.getBoundingClientRect();\n      return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect) : Option.none();\n    };\n\n    var adt$6 = Adt.generate([\n      {\n        ltr: [\n          'start',\n          'soffset',\n          'finish',\n          'foffset'\n        ]\n      },\n      {\n        rtl: [\n          'start',\n          'soffset',\n          'finish',\n          'foffset'\n        ]\n      }\n    ]);\n    var fromRange = function (win, type, range) {\n      return type(Element.fromDom(range.startContainer), range.startOffset, Element.fromDom(range.endContainer), range.endOffset);\n    };\n    var getRanges = function (win, selection) {\n      return selection.match({\n        domRange: function (rng) {\n          return {\n            ltr: constant(rng),\n            rtl: Option.none\n          };\n        },\n        relative: function (startSitu, finishSitu) {\n          return {\n            ltr: cached(function () {\n              return relativeToNative(win, startSitu, finishSitu);\n            }),\n            rtl: cached(function () {\n              return Option.some(relativeToNative(win, finishSitu, startSitu));\n            })\n          };\n        },\n        exact: function (start, soffset, finish, foffset) {\n          return {\n            ltr: cached(function () {\n              return exactToNative(win, start, soffset, finish, foffset);\n            }),\n            rtl: cached(function () {\n              return Option.some(exactToNative(win, finish, foffset, start, soffset));\n            })\n          };\n        }\n      });\n    };\n    var doDiagnose = function (win, ranges) {\n      var rng = ranges.ltr();\n      if (rng.collapsed) {\n        var reversed = ranges.rtl().filter(function (rev) {\n          return rev.collapsed === false;\n        });\n        return reversed.map(function (rev) {\n          return adt$6.rtl(Element.fromDom(rev.endContainer), rev.endOffset, Element.fromDom(rev.startContainer), rev.startOffset);\n        }).getOrThunk(function () {\n          return fromRange(win, adt$6.ltr, rng);\n        });\n      } else {\n        return fromRange(win, adt$6.ltr, rng);\n      }\n    };\n    var diagnose = function (win, selection) {\n      var ranges = getRanges(win, selection);\n      return doDiagnose(win, ranges);\n    };\n    var asLtrRange = function (win, selection) {\n      var diagnosis = diagnose(win, selection);\n      return diagnosis.match({\n        ltr: function (start, soffset, finish, foffset) {\n          var rng = win.document.createRange();\n          rng.setStart(start.dom(), soffset);\n          rng.setEnd(finish.dom(), foffset);\n          return rng;\n        },\n        rtl: function (start, soffset, finish, foffset) {\n          var rng = win.document.createRange();\n          rng.setStart(finish.dom(), foffset);\n          rng.setEnd(start.dom(), soffset);\n          return rng;\n        }\n      });\n    };\n\n    var searchForPoint = function (rectForOffset, x, y, maxX, length) {\n      if (length === 0) {\n        return 0;\n      } else if (x === maxX) {\n        return length - 1;\n      }\n      var xDelta = maxX;\n      for (var i = 1; i < length; i++) {\n        var rect = rectForOffset(i);\n        var curDeltaX = Math.abs(x - rect.left);\n        if (y <= rect.bottom) {\n          if (y < rect.top || curDeltaX > xDelta) {\n            return i - 1;\n          } else {\n            xDelta = curDeltaX;\n          }\n        }\n      }\n      return 0;\n    };\n    var inRect = function (rect, x, y) {\n      return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;\n    };\n\n    function NodeValue (is, name) {\n      var get = function (element) {\n        if (!is(element)) {\n          throw new Error('Can only get ' + name + ' value of a ' + name + ' node');\n        }\n        return getOption(element).getOr('');\n      };\n      var getOption = function (element) {\n        return is(element) ? Option.from(element.dom().nodeValue) : Option.none();\n      };\n      var set = function (element, value) {\n        if (!is(element)) {\n          throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');\n        }\n        element.dom().nodeValue = value;\n      };\n      return {\n        get: get,\n        getOption: getOption,\n        set: set\n      };\n    }\n\n    var api$2 = NodeValue(isText, 'text');\n    var get$a = function (element) {\n      return api$2.get(element);\n    };\n    var getOption = function (element) {\n      return api$2.getOption(element);\n    };\n\n    var locateOffset = function (doc, textnode, x, y, rect) {\n      var rangeForOffset = function (o) {\n        var r = doc.dom().createRange();\n        r.setStart(textnode.dom(), o);\n        r.collapse(true);\n        return r;\n      };\n      var rectForOffset = function (o) {\n        var r = rangeForOffset(o);\n        return r.getBoundingClientRect();\n      };\n      var length = get$a(textnode).length;\n      var offset = searchForPoint(rectForOffset, x, y, rect.right, length);\n      return rangeForOffset(offset);\n    };\n    var locate = function (doc, node, x, y) {\n      var r = doc.dom().createRange();\n      r.selectNode(node.dom());\n      var rects = r.getClientRects();\n      var foundRect = findMap(rects, function (rect) {\n        return inRect(rect, x, y) ? Option.some(rect) : Option.none();\n      });\n      return foundRect.map(function (rect) {\n        return locateOffset(doc, node, x, y, rect);\n      });\n    };\n\n    var searchInChildren = function (doc, node, x, y) {\n      var r = doc.dom().createRange();\n      var nodes = children(node);\n      return findMap(nodes, function (n) {\n        r.selectNode(n.dom());\n        return inRect(r.getBoundingClientRect(), x, y) ? locateNode(doc, n, x, y) : Option.none();\n      });\n    };\n    var locateNode = function (doc, node, x, y) {\n      return isText(node) ? locate(doc, node, x, y) : searchInChildren(doc, node, x, y);\n    };\n    var locate$1 = function (doc, node, x, y) {\n      var r = doc.dom().createRange();\n      r.selectNode(node.dom());\n      var rect = r.getBoundingClientRect();\n      var boundedX = Math.max(rect.left, Math.min(rect.right, x));\n      var boundedY = Math.max(rect.top, Math.min(rect.bottom, y));\n      return locateNode(doc, node, boundedX, boundedY);\n    };\n\n    var getEnd = function (element) {\n      return name(element) === 'img' ? 1 : getOption(element).fold(function () {\n        return children(element).length;\n      }, function (v) {\n        return v.length;\n      });\n    };\n    var NBSP = '\\xA0';\n    var isTextNodeWithCursorPosition = function (el) {\n      return getOption(el).filter(function (text) {\n        return text.trim().length !== 0 || text.indexOf(NBSP) > -1;\n      }).isSome();\n    };\n    var elementsWithCursorPosition = [\n      'img',\n      'br'\n    ];\n    var isCursorPosition = function (elem) {\n      var hasCursorPosition = isTextNodeWithCursorPosition(elem);\n      return hasCursorPosition || contains(elementsWithCursorPosition, name(elem));\n    };\n\n    var first = function (element) {\n      return descendant(element, isCursorPosition);\n    };\n    var last$1 = function (element) {\n      return descendantRtl(element, isCursorPosition);\n    };\n    var descendantRtl = function (scope, predicate) {\n      var descend = function (element) {\n        var children$1 = children(element);\n        for (var i = children$1.length - 1; i >= 0; i--) {\n          var child = children$1[i];\n          if (predicate(child)) {\n            return Option.some(child);\n          }\n          var res = descend(child);\n          if (res.isSome()) {\n            return res;\n          }\n        }\n        return Option.none();\n      };\n      return descend(scope);\n    };\n\n    var COLLAPSE_TO_LEFT = true;\n    var COLLAPSE_TO_RIGHT = false;\n    var getCollapseDirection = function (rect, x) {\n      return x - rect.left < rect.right - x ? COLLAPSE_TO_LEFT : COLLAPSE_TO_RIGHT;\n    };\n    var createCollapsedNode = function (doc, target, collapseDirection) {\n      var r = doc.dom().createRange();\n      r.selectNode(target.dom());\n      r.collapse(collapseDirection);\n      return r;\n    };\n    var locateInElement = function (doc, node, x) {\n      var cursorRange = doc.dom().createRange();\n      cursorRange.selectNode(node.dom());\n      var rect = cursorRange.getBoundingClientRect();\n      var collapseDirection = getCollapseDirection(rect, x);\n      var f = collapseDirection === COLLAPSE_TO_LEFT ? first : last$1;\n      return f(node).map(function (target) {\n        return createCollapsedNode(doc, target, collapseDirection);\n      });\n    };\n    var locateInEmpty = function (doc, node, x) {\n      var rect = node.dom().getBoundingClientRect();\n      var collapseDirection = getCollapseDirection(rect, x);\n      return Option.some(createCollapsedNode(doc, node, collapseDirection));\n    };\n    var search$1 = function (doc, node, x) {\n      var f = children(node).length === 0 ? locateInEmpty : locateInElement;\n      return f(doc, node, x);\n    };\n\n    var caretPositionFromPoint = function (doc, x, y) {\n      return Option.from(doc.dom().caretPositionFromPoint(x, y)).bind(function (pos) {\n        if (pos.offsetNode === null) {\n          return Option.none();\n        }\n        var r = doc.dom().createRange();\n        r.setStart(pos.offsetNode, pos.offset);\n        r.collapse();\n        return Option.some(r);\n      });\n    };\n    var caretRangeFromPoint = function (doc, x, y) {\n      return Option.from(doc.dom().caretRangeFromPoint(x, y));\n    };\n    var searchTextNodes = function (doc, node, x, y) {\n      var r = doc.dom().createRange();\n      r.selectNode(node.dom());\n      var rect = r.getBoundingClientRect();\n      var boundedX = Math.max(rect.left, Math.min(rect.right, x));\n      var boundedY = Math.max(rect.top, Math.min(rect.bottom, y));\n      return locate$1(doc, node, boundedX, boundedY);\n    };\n    var searchFromPoint = function (doc, x, y) {\n      return Element.fromPoint(doc, x, y).bind(function (elem) {\n        var fallback = function () {\n          return search$1(doc, elem, x);\n        };\n        return children(elem).length === 0 ? fallback() : searchTextNodes(doc, elem, x, y).orThunk(fallback);\n      });\n    };\n    var availableSearch = document.caretPositionFromPoint ? caretPositionFromPoint : document.caretRangeFromPoint ? caretRangeFromPoint : searchFromPoint;\n\n    var descendants = function (scope, selector) {\n      return all(selector, scope);\n    };\n\n    var makeRange = function (start, soffset, finish, foffset) {\n      var doc = owner(start);\n      var rng = doc.dom().createRange();\n      rng.setStart(start.dom(), soffset);\n      rng.setEnd(finish.dom(), foffset);\n      return rng;\n    };\n    var after$2 = function (start, soffset, finish, foffset) {\n      var r = makeRange(start, soffset, finish, foffset);\n      var same = eq(start, finish) && soffset === foffset;\n      return r.collapsed && !same;\n    };\n\n    var readRange = function (selection) {\n      if (selection.rangeCount > 0) {\n        var firstRng = selection.getRangeAt(0);\n        var lastRng = selection.getRangeAt(selection.rangeCount - 1);\n        return Option.some(SimRange.create(Element.fromDom(firstRng.startContainer), firstRng.startOffset, Element.fromDom(lastRng.endContainer), lastRng.endOffset));\n      } else {\n        return Option.none();\n      }\n    };\n    var doGetExact = function (selection) {\n      var anchor = Element.fromDom(selection.anchorNode);\n      var focus = Element.fromDom(selection.focusNode);\n      return after$2(anchor, selection.anchorOffset, focus, selection.focusOffset) ? Option.some(SimRange.create(anchor, selection.anchorOffset, focus, selection.focusOffset)) : readRange(selection);\n    };\n    var getExact = function (win) {\n      return Option.from(win.getSelection()).filter(function (sel) {\n        return sel.rangeCount > 0;\n      }).bind(doGetExact);\n    };\n    var getFirstRect$1 = function (win, selection) {\n      var rng = asLtrRange(win, selection);\n      return getFirstRect(rng);\n    };\n\n    var point = Immutable('element', 'offset');\n    var descendOnce = function (element, offset) {\n      var children$1 = children(element);\n      if (children$1.length === 0) {\n        return point(element, offset);\n      } else if (offset < children$1.length) {\n        return point(children$1[offset], 0);\n      } else {\n        var last = children$1[children$1.length - 1];\n        var len = isText(last) ? get$a(last).length : children(last).length;\n        return point(last, len);\n      }\n    };\n\n    var adt$7 = Adt.generate([\n      { screen: ['point'] },\n      {\n        absolute: [\n          'point',\n          'scrollLeft',\n          'scrollTop'\n        ]\n      }\n    ]);\n    var toFixed = function (pos) {\n      return pos.fold(function (point) {\n        return point;\n      }, function (point, scrollLeft, scrollTop) {\n        return point.translate(-scrollLeft, -scrollTop);\n      });\n    };\n    var toAbsolute = function (pos) {\n      return pos.fold(function (point) {\n        return point;\n      }, function (point, scrollLeft, scrollTop) {\n        return point;\n      });\n    };\n    var sum = function (points) {\n      return foldl(points, function (b, a) {\n        return b.translate(a.left(), a.top());\n      }, Position(0, 0));\n    };\n    var sumAsFixed = function (positions) {\n      var points = map(positions, toFixed);\n      return sum(points);\n    };\n    var sumAsAbsolute = function (positions) {\n      var points = map(positions, toAbsolute);\n      return sum(points);\n    };\n    var screen = adt$7.screen;\n    var absolute$2 = adt$7.absolute;\n\n    var getOffset = function (component, origin, anchorInfo) {\n      var win = defaultView(anchorInfo.root).dom();\n      var hasSameOwner = function (frame) {\n        var frameOwner = owner(frame);\n        var compOwner = owner(component.element());\n        return eq(frameOwner, compOwner);\n      };\n      return Option.from(win.frameElement).map(Element.fromDom).filter(hasSameOwner).map(absolute);\n    };\n    var getRootPoint = function (component, origin, anchorInfo) {\n      var doc = owner(component.element());\n      var outerScroll = get$8(doc);\n      var offset = getOffset(component, origin, anchorInfo).getOr(outerScroll);\n      return absolute$2(offset, outerScroll.left(), outerScroll.top());\n    };\n\n    var capRect = function (left, top, width, height) {\n      var newLeft = left, newTop = top, newWidth = width, newHeight = height;\n      if (left < 0) {\n        newLeft = 0;\n        newWidth = width + left;\n      }\n      if (top < 0) {\n        newTop = 0;\n        newHeight = height + top;\n      }\n      var point = screen(Position(newLeft, newTop));\n      return Option.some(pointed(point, newWidth, newHeight));\n    };\n    var calcNewAnchor = function (optBox, rootPoint, anchorInfo, origin, elem) {\n      return optBox.map(function (box) {\n        var points = [\n          rootPoint,\n          box.point()\n        ];\n        var topLeft = cata$1(origin, function () {\n          return sumAsAbsolute(points);\n        }, function () {\n          return sumAsAbsolute(points);\n        }, function () {\n          return sumAsFixed(points);\n        });\n        var anchorBox = rect(topLeft.left(), topLeft.top(), box.width(), box.height());\n        var layoutsLtr = function () {\n          return anchorInfo.showAbove ? [\n            northeast$1,\n            northwest$1,\n            southeast$1,\n            southwest$1,\n            north$1,\n            south$1\n          ] : [\n            southeast$1,\n            southwest$1,\n            northeast$1,\n            northwest$1,\n            south$1,\n            south$1\n          ];\n        };\n        var layoutsRtl = function () {\n          return anchorInfo.showAbove ? [\n            northwest$1,\n            northeast$1,\n            southwest$1,\n            southeast$1,\n            north$1,\n            south$1\n          ] : [\n            southwest$1,\n            southeast$1,\n            northwest$1,\n            northeast$1,\n            south$1,\n            north$1\n          ];\n        };\n        var layouts = get$9(elem, anchorInfo, layoutsLtr(), layoutsRtl());\n        return nu$9({\n          anchorBox: anchorBox,\n          bubble: anchorInfo.bubble.getOr(fallback()),\n          overrides: anchorInfo.overrides,\n          layouts: layouts,\n          placer: Option.none()\n        });\n      });\n    };\n    var ContentAnchorCommon = {\n      capRect: capRect,\n      calcNewAnchor: calcNewAnchor\n    };\n\n    var point$1 = Immutable('element', 'offset');\n    var descendOnce$1 = function (element, offset) {\n      return isText(element) ? point$1(element, offset) : descendOnce(element, offset);\n    };\n    var getAnchorSelection = function (win, anchorInfo) {\n      var getSelection = anchorInfo.getSelection.getOrThunk(function () {\n        return function () {\n          return getExact(win);\n        };\n      });\n      return getSelection().map(function (sel) {\n        var modStart = descendOnce$1(sel.start(), sel.soffset());\n        var modFinish = descendOnce$1(sel.finish(), sel.foffset());\n        return Selection.range(modStart.element(), modStart.offset(), modFinish.element(), modFinish.offset());\n      });\n    };\n    var placement$2 = function (component, anchorInfo, origin) {\n      var win = defaultView(anchorInfo.root).dom();\n      var rootPoint = getRootPoint(component, origin, anchorInfo);\n      var selectionBox = getAnchorSelection(win, anchorInfo).bind(function (sel) {\n        var optRect = getFirstRect$1(win, Selection.exactFromRange(sel)).orThunk(function () {\n          var x = Element.fromText(zeroWidth());\n          before(sel.start(), x);\n          return getFirstRect$1(win, Selection.exact(x, 0, x, 1)).map(function (rect) {\n            remove(x);\n            return rect;\n          });\n        });\n        return optRect.bind(function (rawRect) {\n          return ContentAnchorCommon.capRect(rawRect.left(), rawRect.top(), rawRect.width(), rawRect.height());\n        });\n      });\n      var targetElement = getAnchorSelection(win, anchorInfo).bind(function (sel) {\n        return isElement(sel.start()) ? Option.some(sel.start()) : parent(sel.start());\n      });\n      var elem = targetElement.getOr(component.element());\n      return ContentAnchorCommon.calcNewAnchor(selectionBox, rootPoint, anchorInfo, origin, elem);\n    };\n    var SelectionAnchor = [\n      option('getSelection'),\n      strict$1('root'),\n      option('bubble'),\n      schema$1(),\n      defaulted$1('overrides', {}),\n      defaulted$1('showAbove', false),\n      output('placement', placement$2)\n    ];\n\n    var placement$3 = function (component, anchorInfo, origin) {\n      var rootPoint = getRootPoint(component, origin, anchorInfo);\n      return anchorInfo.node.bind(function (target) {\n        var rect = target.dom().getBoundingClientRect();\n        var nodeBox = ContentAnchorCommon.capRect(rect.left, rect.top, rect.width, rect.height);\n        var elem = anchorInfo.node.getOr(component.element());\n        return ContentAnchorCommon.calcNewAnchor(nodeBox, rootPoint, anchorInfo, origin, elem);\n      });\n    };\n    var NodeAnchor = [\n      strict$1('node'),\n      strict$1('root'),\n      option('bubble'),\n      schema$1(),\n      defaulted$1('overrides', {}),\n      defaulted$1('showAbove', false),\n      output('placement', placement$3)\n    ];\n\n    var eastX$1 = function (anchor) {\n      return anchor.x() + anchor.width();\n    };\n    var westX$1 = function (anchor, element) {\n      return anchor.x() - element.width();\n    };\n    var northY$1 = function (anchor, element) {\n      return anchor.y() - element.height() + anchor.height();\n    };\n    var southY$1 = function (anchor) {\n      return anchor.y();\n    };\n    var southeast$2 = function (anchor, element, bubbles) {\n      return nu$7(eastX$1(anchor), southY$1(anchor), bubbles.southeast(), southeast(), 'link-layout-se');\n    };\n    var southwest$2 = function (anchor, element, bubbles) {\n      return nu$7(westX$1(anchor, element), southY$1(anchor), bubbles.southwest(), southwest(), 'link-layout-sw');\n    };\n    var northeast$2 = function (anchor, element, bubbles) {\n      return nu$7(eastX$1(anchor), northY$1(anchor, element), bubbles.northeast(), northeast(), 'link-layout-ne');\n    };\n    var northwest$2 = function (anchor, element, bubbles) {\n      return nu$7(westX$1(anchor, element), northY$1(anchor, element), bubbles.northwest(), northwest(), 'link-layout-nw');\n    };\n    var all$3 = function () {\n      return [\n        southeast$2,\n        southwest$2,\n        northeast$2,\n        northwest$2\n      ];\n    };\n    var allRtl$1 = function () {\n      return [\n        southwest$2,\n        southeast$2,\n        northwest$2,\n        northeast$2\n      ];\n    };\n\n    var placement$4 = function (component, submenuInfo, origin) {\n      var anchorBox = toBox(origin, submenuInfo.item.element());\n      var layouts = get$9(component.element(), submenuInfo, all$3(), allRtl$1());\n      return Option.some(nu$9({\n        anchorBox: anchorBox,\n        bubble: fallback(),\n        overrides: submenuInfo.overrides,\n        layouts: layouts,\n        placer: Option.none()\n      }));\n    };\n    var SubmenuAnchor = [\n      strict$1('item'),\n      schema$1(),\n      defaulted$1('overrides', {}),\n      output('placement', placement$4)\n    ];\n\n    var AnchorSchema = choose$1('anchor', {\n      selection: SelectionAnchor,\n      node: NodeAnchor,\n      hotspot: HotspotAnchor,\n      submenu: SubmenuAnchor,\n      makeshift: MakeshiftAnchor\n    });\n\n    var anchor = Immutable('anchorBox', 'origin');\n    var box$1 = function (anchorBox, origin) {\n      return anchor(anchorBox, origin);\n    };\n\n    var cycleBy = function (value, delta, min, max) {\n      var r = value + delta;\n      if (r > max) {\n        return min;\n      } else {\n        return r < min ? max : r;\n      }\n    };\n    var cap = function (value, min, max) {\n      if (value <= min) {\n        return min;\n      } else {\n        return value >= max ? max : value;\n      }\n    };\n\n    var adt$8 = Adt.generate([\n      { fit: ['reposition'] },\n      {\n        nofit: [\n          'reposition',\n          'deltaW',\n          'deltaH'\n        ]\n      }\n    ]);\n    var calcReposition = function (newX, newY, width, height, bounds) {\n      var boundsX = bounds.x();\n      var boundsY = bounds.y();\n      var boundsWidth = bounds.width();\n      var boundsHeight = bounds.height();\n      var xInBounds = newX >= boundsX;\n      var yInBounds = newY >= boundsY;\n      var originInBounds = xInBounds && yInBounds;\n      var xFit = newX + width <= boundsX + boundsWidth;\n      var yFit = newY + height <= boundsY + boundsHeight;\n      var sizeInBounds = xFit && yFit;\n      var deltaW = Math.abs(Math.min(width, xInBounds ? boundsX + boundsWidth - newX : boundsX - (newX + width)));\n      var deltaH = Math.abs(Math.min(height, yInBounds ? boundsY + boundsHeight - newY : boundsY - (newY + height)));\n      var limitX = cap(newX, bounds.x(), bounds.right());\n      var limitY = cap(newY, bounds.y(), bounds.bottom());\n      return {\n        originInBounds: originInBounds,\n        sizeInBounds: sizeInBounds,\n        limitX: limitX,\n        limitY: limitY,\n        deltaW: deltaW,\n        deltaH: deltaH\n      };\n    };\n    var attempt = function (candidate, width, height, bounds) {\n      var candidateX = candidate.x();\n      var candidateY = candidate.y();\n      var bubbleLeft = candidate.bubble().offset().left();\n      var bubbleTop = candidate.bubble().offset().top();\n      var boundsY = bounds.y();\n      var boundsBottom = bounds.bottom();\n      var boundsX = bounds.x();\n      var boundsRight = bounds.right();\n      var newX = candidateX + bubbleLeft;\n      var newY = candidateY + bubbleTop;\n      var _a = calcReposition(newX, newY, width, height, bounds), originInBounds = _a.originInBounds, sizeInBounds = _a.sizeInBounds, limitX = _a.limitX, limitY = _a.limitY, deltaW = _a.deltaW, deltaH = _a.deltaH;\n      var upAvailable = constant(limitY + deltaH - boundsY);\n      var downAvailable = constant(boundsBottom - limitY);\n      var maxHeight = cataVertical(candidate.direction(), downAvailable, downAvailable, upAvailable);\n      var westAvailable = constant(limitX + deltaW - boundsX);\n      var eastAvailable = constant(boundsRight - limitX);\n      var maxWidth = cataHorizontal(candidate.direction(), eastAvailable, eastAvailable, westAvailable);\n      var reposition = decision({\n        x: limitX,\n        y: limitY,\n        width: deltaW,\n        height: deltaH,\n        maxHeight: maxHeight,\n        maxWidth: maxWidth,\n        direction: candidate.direction(),\n        classes: {\n          on: candidate.bubble().classesOn(),\n          off: candidate.bubble().classesOff()\n        },\n        label: candidate.label(),\n        candidateYforTest: newY\n      });\n      return originInBounds && sizeInBounds ? adt$8.fit(reposition) : adt$8.nofit(reposition, deltaW, deltaH);\n    };\n    var attempts = function (candidates, anchorBox, elementBox, bubbles, bounds) {\n      var panelWidth = elementBox.width();\n      var panelHeight = elementBox.height();\n      var attemptBestFit = function (layout, reposition, deltaW, deltaH) {\n        var next = layout(anchorBox, elementBox, bubbles);\n        var attemptLayout = attempt(next, panelWidth, panelHeight, bounds);\n        return attemptLayout.fold(adt$8.fit, function (newReposition, newDeltaW, newDeltaH) {\n          var improved = newDeltaH > deltaH || newDeltaW > deltaW;\n          return improved ? adt$8.nofit(newReposition, newDeltaW, newDeltaH) : adt$8.nofit(reposition, deltaW, deltaH);\n        });\n      };\n      var abc = foldl(candidates, function (b, a) {\n        var bestNext = curry(attemptBestFit, a);\n        return b.fold(adt$8.fit, bestNext);\n      }, adt$8.nofit(decision({\n        x: anchorBox.x(),\n        y: anchorBox.y(),\n        width: elementBox.width(),\n        height: elementBox.height(),\n        maxHeight: elementBox.height(),\n        maxWidth: elementBox.width(),\n        direction: southeast(),\n        classes: {\n          on: [],\n          off: []\n        },\n        label: 'none',\n        candidateYforTest: anchorBox.y()\n      }), -1, -1));\n      return abc.fold(identity, identity);\n    };\n\n    var elementSize = function (p) {\n      return {\n        width: constant(getOuter$2(p)),\n        height: constant(getOuter$1(p))\n      };\n    };\n    var layout = function (anchorBox, element, bubbles, options) {\n      remove$6(element, 'max-height');\n      remove$6(element, 'max-width');\n      var elementBox = elementSize(element);\n      return attempts(options.preference(), anchorBox, elementBox, bubbles, options.bounds());\n    };\n    var setClasses = function (element, decision) {\n      var classInfo = decision.classes();\n      remove$5(element, classInfo.off);\n      add$3(element, classInfo.on);\n    };\n    var setHeight = function (element, decision, options) {\n      var maxHeightFunction = options.maxHeightFunction();\n      maxHeightFunction(element, decision.maxHeight());\n    };\n    var setWidth = function (element, decision, options) {\n      var maxWidthFunction = options.maxWidthFunction();\n      maxWidthFunction(element, decision.maxWidth());\n    };\n    var position = function (element, decision, options) {\n      var addPx = function (num) {\n        return num + 'px';\n      };\n      var newPosition = reposition(options.origin(), decision);\n      setOptions(element, {\n        position: Option.some(newPosition.position()),\n        left: newPosition.left().map(addPx),\n        top: newPosition.top().map(addPx),\n        right: newPosition.right().map(addPx),\n        bottom: newPosition.bottom().map(addPx)\n      });\n    };\n\n    var setMaxHeight = function (element, maxHeight) {\n      setMax(element, Math.floor(maxHeight));\n    };\n    var anchored = constant(function (element, available) {\n      setMaxHeight(element, available);\n      setAll$1(element, {\n        'overflow-x': 'hidden',\n        'overflow-y': 'auto'\n      });\n    });\n    var expandable = constant(function (element, available) {\n      setMaxHeight(element, available);\n    });\n\n    var reparteeOptions = MixedBag([\n      'bounds',\n      'origin',\n      'preference',\n      'maxHeightFunction',\n      'maxWidthFunction'\n    ], []);\n    var defaultOr = function (options, key, dephault) {\n      return options[key] === undefined ? dephault : options[key];\n    };\n    var simple = function (anchor, element, bubble, layouts, getBounds, overrideOptions) {\n      var maxHeightFunction = defaultOr(overrideOptions, 'maxHeightFunction', anchored());\n      var maxWidthFunction = defaultOr(overrideOptions, 'maxWidthFunction', noop);\n      var anchorBox = anchor.anchorBox();\n      var origin = anchor.origin();\n      var options = reparteeOptions({\n        bounds: viewport$1(origin, getBounds),\n        origin: origin,\n        preference: layouts,\n        maxHeightFunction: maxHeightFunction,\n        maxWidthFunction: maxWidthFunction\n      });\n      go(anchorBox, element, bubble, options);\n    };\n    var go = function (anchorBox, element, bubble, options) {\n      var decision = layout(anchorBox, element, bubble, options);\n      position(element, decision, options);\n      setClasses(element, decision);\n      setHeight(element, decision, options);\n      setWidth(element, decision, options);\n    };\n\n    var getFixedOrigin = function () {\n      var html = domGlobals.document.documentElement;\n      return fixed(0, 0, html.clientWidth, html.clientHeight);\n    };\n    var getRelativeOrigin = function (component) {\n      var position = absolute(component.element());\n      var bounds = component.element().dom().getBoundingClientRect();\n      return relative(position.left(), position.top(), bounds.width, bounds.height);\n    };\n    var place = function (component, origin, anchoring, getBounds, placee) {\n      var anchor = box$1(anchoring.anchorBox, origin);\n      simple(anchor, placee.element(), anchoring.bubble, anchoring.layouts, getBounds, anchoring.overrides);\n    };\n    var position$1 = function (component, posConfig, posState, anchor, placee) {\n      positionWithin(component, posConfig, posState, anchor, placee, Option.none());\n    };\n    var positionWithin = function (component, posConfig, posState, anchor, placee, boxElement) {\n      var boundsBox = boxElement.map(box);\n      return positionWithinBounds(component, posConfig, posState, anchor, placee, boundsBox);\n    };\n    var positionWithinBounds = function (component, posConfig, posState, anchor, placee, bounds) {\n      var anchorage = asRawOrDie('positioning anchor.info', AnchorSchema, anchor);\n      preserve(function () {\n        set$2(placee.element(), 'position', 'fixed');\n        var oldVisibility = getRaw(placee.element(), 'visibility');\n        set$2(placee.element(), 'visibility', 'hidden');\n        var origin = posConfig.useFixed() ? getFixedOrigin() : getRelativeOrigin(component);\n        var placer = anchorage.placement;\n        var getBounds = bounds.map(constant).or(posConfig.getBounds);\n        placer(component, anchorage, origin).each(function (anchoring) {\n          var doPlace = anchoring.placer.getOr(place);\n          doPlace(component, origin, anchoring, getBounds, placee);\n        });\n        oldVisibility.fold(function () {\n          remove$6(placee.element(), 'visibility');\n        }, function (vis) {\n          set$2(placee.element(), 'visibility', vis);\n        });\n        if (getRaw(placee.element(), 'left').isNone() && getRaw(placee.element(), 'top').isNone() && getRaw(placee.element(), 'right').isNone() && getRaw(placee.element(), 'bottom').isNone() && getRaw(placee.element(), 'position').is('fixed')) {\n          remove$6(placee.element(), 'position');\n        }\n      }, placee.element());\n    };\n    var getMode = function (component, pConfig, pState) {\n      return pConfig.useFixed() ? 'fixed' : 'absolute';\n    };\n\n    var PositionApis = /*#__PURE__*/Object.freeze({\n        position: position$1,\n        positionWithin: positionWithin,\n        positionWithinBounds: positionWithinBounds,\n        getMode: getMode\n    });\n\n    var PositionSchema = [\n      defaulted$1('useFixed', never),\n      option('getBounds')\n    ];\n\n    var Positioning = create$1({\n      fields: PositionSchema,\n      name: 'positioning',\n      active: ActivePosition,\n      apis: PositionApis\n    });\n\n    var fireDetaching = function (component) {\n      emit(component, detachedFromDom());\n      var children = component.components();\n      each(children, fireDetaching);\n    };\n    var fireAttaching = function (component) {\n      var children = component.components();\n      each(children, fireAttaching);\n      emit(component, attachedToDom());\n    };\n    var attach = function (parent, child) {\n      append(parent.element(), child.element());\n    };\n    var detachChildren = function (component) {\n      each(component.components(), function (childComp) {\n        return remove(childComp.element());\n      });\n      empty(component.element());\n      component.syncComponents();\n    };\n    var replaceChildren = function (component, newChildren) {\n      var subs = component.components();\n      detachChildren(component);\n      var deleted = difference(subs, newChildren);\n      each(deleted, function (comp) {\n        fireDetaching(comp);\n        component.getSystem().removeFromWorld(comp);\n      });\n      each(newChildren, function (childComp) {\n        if (!childComp.getSystem().isConnected()) {\n          component.getSystem().addToWorld(childComp);\n          attach(component, childComp);\n          if (inBody(component.element())) {\n            fireAttaching(childComp);\n          }\n        } else {\n          attach(component, childComp);\n        }\n        component.syncComponents();\n      });\n    };\n\n    var attach$1 = function (parent, child) {\n      attachWith(parent, child, append);\n    };\n    var attachWith = function (parent, child, insertion) {\n      parent.getSystem().addToWorld(child);\n      insertion(parent.element(), child.element());\n      if (inBody(parent.element())) {\n        fireAttaching(child);\n      }\n      parent.syncComponents();\n    };\n    var doDetach = function (component) {\n      fireDetaching(component);\n      remove(component.element());\n      component.getSystem().removeFromWorld(component);\n    };\n    var detach = function (component) {\n      var parent$1 = parent(component.element()).bind(function (p) {\n        return component.getSystem().getByDom(p).toOption();\n      });\n      doDetach(component);\n      parent$1.each(function (p) {\n        p.syncComponents();\n      });\n    };\n    var detachChildren$1 = function (component) {\n      var subs = component.components();\n      each(subs, doDetach);\n      empty(component.element());\n      component.syncComponents();\n    };\n    var attachSystem = function (element, guiSystem) {\n      attachSystemWith(element, guiSystem, append);\n    };\n    var attachSystemAfter = function (element, guiSystem) {\n      attachSystemWith(element, guiSystem, after);\n    };\n    var attachSystemWith = function (element, guiSystem, inserter) {\n      inserter(element, guiSystem.element());\n      var children$1 = children(guiSystem.element());\n      each(children$1, function (child) {\n        guiSystem.getByDom(child).each(fireAttaching);\n      });\n    };\n    var detachSystem = function (guiSystem) {\n      var children$1 = children(guiSystem.element());\n      each(children$1, function (child) {\n        guiSystem.getByDom(child).each(fireDetaching);\n      });\n      remove(guiSystem.element());\n    };\n\n    var rebuild = function (sandbox, sConfig, sState, data) {\n      sState.get().each(function (data) {\n        detachChildren$1(sandbox);\n      });\n      var point = sConfig.getAttachPoint(sandbox);\n      attach$1(point, sandbox);\n      var built = sandbox.getSystem().build(data);\n      attach$1(sandbox, built);\n      sState.set(built);\n      return built;\n    };\n    var open = function (sandbox, sConfig, sState, data) {\n      var newState = rebuild(sandbox, sConfig, sState, data);\n      sConfig.onOpen(sandbox, newState);\n      return newState;\n    };\n    var setContent = function (sandbox, sConfig, sState, data) {\n      return sState.get().map(function () {\n        return rebuild(sandbox, sConfig, sState, data);\n      });\n    };\n    var openWhileCloaked = function (sandbox, sConfig, sState, data, transaction) {\n      cloak(sandbox, sConfig);\n      open(sandbox, sConfig, sState, data);\n      transaction();\n      decloak(sandbox, sConfig);\n    };\n    var close = function (sandbox, sConfig, sState) {\n      sState.get().each(function (data) {\n        detachChildren$1(sandbox);\n        detach(sandbox);\n        sConfig.onClose(sandbox, data);\n        sState.clear();\n      });\n    };\n    var isOpen = function (sandbox, sConfig, sState) {\n      return sState.isOpen();\n    };\n    var isPartOf$1 = function (sandbox, sConfig, sState, queryElem) {\n      return isOpen(sandbox, sConfig, sState) && sState.get().exists(function (data) {\n        return sConfig.isPartOf(sandbox, data, queryElem);\n      });\n    };\n    var getState = function (sandbox, sConfig, sState) {\n      return sState.get();\n    };\n    var store = function (sandbox, cssKey, attr, newValue) {\n      getRaw(sandbox.element(), cssKey).fold(function () {\n        remove$1(sandbox.element(), attr);\n      }, function (v) {\n        set$1(sandbox.element(), attr, v);\n      });\n      set$2(sandbox.element(), cssKey, newValue);\n    };\n    var restore = function (sandbox, cssKey, attr) {\n      if (has$1(sandbox.element(), attr)) {\n        var oldValue = get$2(sandbox.element(), attr);\n        set$2(sandbox.element(), cssKey, oldValue);\n      } else {\n        remove$6(sandbox.element(), cssKey);\n      }\n    };\n    var cloak = function (sandbox, sConfig, sState) {\n      var sink = sConfig.getAttachPoint(sandbox);\n      set$2(sandbox.element(), 'position', Positioning.getMode(sink));\n      store(sandbox, 'visibility', sConfig.cloakVisibilityAttr, 'hidden');\n    };\n    var hasPosition = function (element) {\n      return exists([\n        'top',\n        'left',\n        'right',\n        'bottom'\n      ], function (pos) {\n        return getRaw(element, pos).isSome();\n      });\n    };\n    var decloak = function (sandbox, sConfig, sState) {\n      if (!hasPosition(sandbox.element())) {\n        remove$6(sandbox.element(), 'position');\n      }\n      restore(sandbox, 'visibility', sConfig.cloakVisibilityAttr);\n    };\n\n    var SandboxApis = /*#__PURE__*/Object.freeze({\n        cloak: cloak,\n        decloak: decloak,\n        open: open,\n        openWhileCloaked: openWhileCloaked,\n        close: close,\n        isOpen: isOpen,\n        isPartOf: isPartOf$1,\n        getState: getState,\n        setContent: setContent\n    });\n\n    var events$2 = function (sandboxConfig, sandboxState) {\n      return derive([run(sandboxClose(), function (sandbox, simulatedEvent) {\n          close(sandbox, sandboxConfig, sandboxState);\n        })]);\n    };\n\n    var ActiveSandbox = /*#__PURE__*/Object.freeze({\n        events: events$2\n    });\n\n    var SandboxSchema = [\n      onHandler('onOpen'),\n      onHandler('onClose'),\n      strict$1('isPartOf'),\n      strict$1('getAttachPoint'),\n      defaulted$1('cloakVisibilityAttr', 'data-precloak-visibility')\n    ];\n\n    var init = function () {\n      var contents = Cell(Option.none());\n      var readState = constant('not-implemented');\n      var isOpen = function () {\n        return contents.get().isSome();\n      };\n      var set = function (c) {\n        contents.set(Option.some(c));\n      };\n      var get = function (c) {\n        return contents.get();\n      };\n      var clear = function () {\n        contents.set(Option.none());\n      };\n      return nu$5({\n        readState: readState,\n        isOpen: isOpen,\n        clear: clear,\n        set: set,\n        get: get\n      });\n    };\n\n    var SandboxState = /*#__PURE__*/Object.freeze({\n        init: init\n    });\n\n    var Sandboxing = create$1({\n      fields: SandboxSchema,\n      name: 'sandboxing',\n      active: ActiveSandbox,\n      apis: SandboxApis,\n      state: SandboxState\n    });\n\n    var dismissPopups = constant('dismiss.popups');\n    var repositionPopups = constant('reposition.popups');\n    var mouseReleased = constant('mouse.released');\n\n    var schema$2 = objOfOnly([\n      defaulted$1('isExtraPart', constant(false)),\n      optionObjOf('fireEventInstead', [defaulted$1('event', dismissRequested())])\n    ]);\n    var receivingChannel = function (rawSpec) {\n      var _a;\n      var detail = asRawOrDie('Dismissal', schema$2, rawSpec);\n      return _a = {}, _a[dismissPopups()] = {\n        schema: objOfOnly([strict$1('target')]),\n        onReceive: function (sandbox, data) {\n          if (Sandboxing.isOpen(sandbox)) {\n            var isPart = Sandboxing.isPartOf(sandbox, data.target) || detail.isExtraPart(sandbox, data.target);\n            if (!isPart) {\n              detail.fireEventInstead.fold(function () {\n                return Sandboxing.close(sandbox);\n              }, function (fe) {\n                return emit(sandbox, fe.event);\n              });\n            }\n          }\n        }\n      }, _a;\n    };\n\n    var schema$3 = objOfOnly([\n      defaulted$1('isExtraPart', constant(false)),\n      optionObjOf('fireEventInstead', [defaulted$1('event', repositionRequested())]),\n      strictFunction('doReposition')\n    ]);\n    var receivingChannel$1 = function (rawSpec) {\n      var _a;\n      var detail = asRawOrDie('Reposition', schema$3, rawSpec);\n      return _a = {}, _a[repositionPopups()] = {\n        onReceive: function (sandbox) {\n          if (Sandboxing.isOpen(sandbox)) {\n            detail.fireEventInstead.fold(function () {\n              return detail.doReposition(sandbox);\n            }, function (fe) {\n              return emit(sandbox, fe.event);\n            });\n          }\n        }\n      }, _a;\n    };\n\n    var onLoad = function (component, repConfig, repState) {\n      repConfig.store.manager.onLoad(component, repConfig, repState);\n    };\n    var onUnload = function (component, repConfig, repState) {\n      repConfig.store.manager.onUnload(component, repConfig, repState);\n    };\n    var setValue = function (component, repConfig, repState, data) {\n      repConfig.store.manager.setValue(component, repConfig, repState, data);\n    };\n    var getValue = function (component, repConfig, repState) {\n      return repConfig.store.manager.getValue(component, repConfig, repState);\n    };\n    var getState$1 = function (component, repConfig, repState) {\n      return repState;\n    };\n\n    var RepresentApis = /*#__PURE__*/Object.freeze({\n        onLoad: onLoad,\n        onUnload: onUnload,\n        setValue: setValue,\n        getValue: getValue,\n        getState: getState$1\n    });\n\n    var events$3 = function (repConfig, repState) {\n      var es = repConfig.resetOnDom ? [\n        runOnAttached(function (comp, se) {\n          onLoad(comp, repConfig, repState);\n        }),\n        runOnDetached(function (comp, se) {\n          onUnload(comp, repConfig, repState);\n        })\n      ] : [loadEvent(repConfig, repState, onLoad)];\n      return derive(es);\n    };\n\n    var ActiveRepresenting = /*#__PURE__*/Object.freeze({\n        events: events$3\n    });\n\n    var memory = function () {\n      var data = Cell(null);\n      var readState = function () {\n        return {\n          mode: 'memory',\n          value: data.get()\n        };\n      };\n      var isNotSet = function () {\n        return data.get() === null;\n      };\n      var clear = function () {\n        data.set(null);\n      };\n      return nu$5({\n        set: data.set,\n        get: data.get,\n        isNotSet: isNotSet,\n        clear: clear,\n        readState: readState\n      });\n    };\n    var manual = function () {\n      var readState = function () {\n      };\n      return nu$5({ readState: readState });\n    };\n    var dataset = function () {\n      var dataByValue = Cell({});\n      var dataByText = Cell({});\n      var readState = function () {\n        return {\n          mode: 'dataset',\n          dataByValue: dataByValue.get(),\n          dataByText: dataByText.get()\n        };\n      };\n      var clear = function () {\n        dataByValue.set({});\n        dataByText.set({});\n      };\n      var lookup = function (itemString) {\n        return readOptFrom$1(dataByValue.get(), itemString).orThunk(function () {\n          return readOptFrom$1(dataByText.get(), itemString);\n        });\n      };\n      var update = function (items) {\n        var currentDataByValue = dataByValue.get();\n        var currentDataByText = dataByText.get();\n        var newDataByValue = {};\n        var newDataByText = {};\n        each(items, function (item) {\n          newDataByValue[item.value] = item;\n          readOptFrom$1(item, 'meta').each(function (meta) {\n            readOptFrom$1(meta, 'text').each(function (text) {\n              newDataByText[text] = item;\n            });\n          });\n        });\n        dataByValue.set(__assign(__assign({}, currentDataByValue), newDataByValue));\n        dataByText.set(__assign(__assign({}, currentDataByText), newDataByText));\n      };\n      return nu$5({\n        readState: readState,\n        lookup: lookup,\n        update: update,\n        clear: clear\n      });\n    };\n    var init$1 = function (spec) {\n      return spec.store.manager.state(spec);\n    };\n\n    var RepresentState = /*#__PURE__*/Object.freeze({\n        memory: memory,\n        dataset: dataset,\n        manual: manual,\n        init: init$1\n    });\n\n    var setValue$1 = function (component, repConfig, repState, data) {\n      var store = repConfig.store;\n      repState.update([data]);\n      store.setValue(component, data);\n      repConfig.onSetValue(component, data);\n    };\n    var getValue$1 = function (component, repConfig, repState) {\n      var store = repConfig.store;\n      var key = store.getDataKey(component);\n      return repState.lookup(key).fold(function () {\n        return store.getFallbackEntry(key);\n      }, function (data) {\n        return data;\n      });\n    };\n    var onLoad$1 = function (component, repConfig, repState) {\n      var store = repConfig.store;\n      store.initialValue.each(function (data) {\n        setValue$1(component, repConfig, repState, data);\n      });\n    };\n    var onUnload$1 = function (component, repConfig, repState) {\n      repState.clear();\n    };\n    var DatasetStore = [\n      option('initialValue'),\n      strict$1('getFallbackEntry'),\n      strict$1('getDataKey'),\n      strict$1('setValue'),\n      output('manager', {\n        setValue: setValue$1,\n        getValue: getValue$1,\n        onLoad: onLoad$1,\n        onUnload: onUnload$1,\n        state: dataset\n      })\n    ];\n\n    var getValue$2 = function (component, repConfig, repState) {\n      return repConfig.store.getValue(component);\n    };\n    var setValue$2 = function (component, repConfig, repState, data) {\n      repConfig.store.setValue(component, data);\n      repConfig.onSetValue(component, data);\n    };\n    var onLoad$2 = function (component, repConfig, repState) {\n      repConfig.store.initialValue.each(function (data) {\n        repConfig.store.setValue(component, data);\n      });\n    };\n    var ManualStore = [\n      strict$1('getValue'),\n      defaulted$1('setValue', noop),\n      option('initialValue'),\n      output('manager', {\n        setValue: setValue$2,\n        getValue: getValue$2,\n        onLoad: onLoad$2,\n        onUnload: noop,\n        state: NoState.init\n      })\n    ];\n\n    var setValue$3 = function (component, repConfig, repState, data) {\n      repState.set(data);\n      repConfig.onSetValue(component, data);\n    };\n    var getValue$3 = function (component, repConfig, repState) {\n      return repState.get();\n    };\n    var onLoad$3 = function (component, repConfig, repState) {\n      repConfig.store.initialValue.each(function (initVal) {\n        if (repState.isNotSet()) {\n          repState.set(initVal);\n        }\n      });\n    };\n    var onUnload$2 = function (component, repConfig, repState) {\n      repState.clear();\n    };\n    var MemoryStore = [\n      option('initialValue'),\n      output('manager', {\n        setValue: setValue$3,\n        getValue: getValue$3,\n        onLoad: onLoad$3,\n        onUnload: onUnload$2,\n        state: memory\n      })\n    ];\n\n    var RepresentSchema = [\n      defaultedOf('store', { mode: 'memory' }, choose$1('mode', {\n        memory: MemoryStore,\n        manual: ManualStore,\n        dataset: DatasetStore\n      })),\n      onHandler('onSetValue'),\n      defaulted$1('resetOnDom', false)\n    ];\n\n    var Representing = create$1({\n      fields: RepresentSchema,\n      name: 'representing',\n      active: ActiveRepresenting,\n      apis: RepresentApis,\n      extra: {\n        setValueFrom: function (component, source) {\n          var value = Representing.getValue(source);\n          Representing.setValue(component, value);\n        }\n      },\n      state: RepresentState\n    });\n\n    var field$1 = function (name, forbidden) {\n      return defaultedObjOf(name, {}, map(forbidden, function (f) {\n        return forbid(f.name(), 'Cannot configure ' + f.name() + ' for ' + name);\n      }).concat([state$1('dump', identity)]));\n    };\n    var get$b = function (data) {\n      return data.dump;\n    };\n    var augment = function (data, original) {\n      return __assign(__assign({}, data.dump), derive$1(original));\n    };\n    var SketchBehaviours = {\n      field: field$1,\n      augment: augment,\n      get: get$b\n    };\n\n    var _placeholder = 'placeholder';\n    var adt$9 = Adt.generate([\n      {\n        single: [\n          'required',\n          'valueThunk'\n        ]\n      },\n      {\n        multiple: [\n          'required',\n          'valueThunks'\n        ]\n      }\n    ]);\n    var subPlaceholder = function (owner, detail, compSpec, placeholders) {\n      if (owner.exists(function (o) {\n          return o !== compSpec.owner;\n        })) {\n        return adt$9.single(true, constant(compSpec));\n      }\n      return readOptFrom$1(placeholders, compSpec.name).fold(function () {\n        throw new Error('Unknown placeholder component: ' + compSpec.name + '\\nKnown: [' + keys(placeholders) + ']\\nNamespace: ' + owner.getOr('none') + '\\nSpec: ' + JSON.stringify(compSpec, null, 2));\n      }, function (newSpec) {\n        return newSpec.replace();\n      });\n    };\n    var scan = function (owner, detail, compSpec, placeholders) {\n      if (compSpec.uiType === _placeholder) {\n        return subPlaceholder(owner, detail, compSpec, placeholders);\n      } else {\n        return adt$9.single(false, constant(compSpec));\n      }\n    };\n    var substitute = function (owner, detail, compSpec, placeholders) {\n      var base = scan(owner, detail, compSpec, placeholders);\n      return base.fold(function (req, valueThunk) {\n        var value = valueThunk(detail, compSpec.config, compSpec.validated);\n        var childSpecs = readOptFrom$1(value, 'components').getOr([]);\n        var substituted = bind(childSpecs, function (c) {\n          return substitute(owner, detail, c, placeholders);\n        });\n        return [__assign(__assign({}, value), { components: substituted })];\n      }, function (req, valuesThunk) {\n        var values = valuesThunk(detail, compSpec.config, compSpec.validated);\n        var preprocessor = compSpec.validated.preprocess.getOr(identity);\n        return preprocessor(values);\n      });\n    };\n    var substituteAll = function (owner, detail, components, placeholders) {\n      return bind(components, function (c) {\n        return substitute(owner, detail, c, placeholders);\n      });\n    };\n    var oneReplace = function (label, replacements) {\n      var called = false;\n      var used = function () {\n        return called;\n      };\n      var replace = function () {\n        if (called === true) {\n          throw new Error('Trying to use the same placeholder more than once: ' + label);\n        }\n        called = true;\n        return replacements;\n      };\n      var required = function () {\n        return replacements.fold(function (req, _) {\n          return req;\n        }, function (req, _) {\n          return req;\n        });\n      };\n      return {\n        name: constant(label),\n        required: required,\n        used: used,\n        replace: replace\n      };\n    };\n    var substitutePlaces = function (owner, detail, components, placeholders) {\n      var ps = map$1(placeholders, function (ph, name) {\n        return oneReplace(name, ph);\n      });\n      var outcome = substituteAll(owner, detail, components, ps);\n      each$1(ps, function (p) {\n        if (p.used() === false && p.required()) {\n          throw new Error('Placeholder: ' + p.name() + ' was not found in components list\\nNamespace: ' + owner.getOr('none') + '\\nComponents: ' + JSON.stringify(detail.components, null, 2));\n        }\n      });\n      return outcome;\n    };\n    var single = adt$9.single;\n    var multiple = adt$9.multiple;\n    var placeholder = constant(_placeholder);\n\n    var adt$a = Adt.generate([\n      { required: ['data'] },\n      { external: ['data'] },\n      { optional: ['data'] },\n      { group: ['data'] }\n    ]);\n    var fFactory = defaulted$1('factory', { sketch: identity });\n    var fSchema = defaulted$1('schema', []);\n    var fName = strict$1('name');\n    var fPname = field('pname', 'pname', defaultedThunk(function (typeSpec) {\n      return '<alloy.' + generate$1(typeSpec.name) + '>';\n    }), anyValue$1());\n    var fGroupSchema = state$1('schema', function () {\n      return [option('preprocess')];\n    });\n    var fDefaults = defaulted$1('defaults', constant({}));\n    var fOverrides = defaulted$1('overrides', constant({}));\n    var requiredSpec = objOf([\n      fFactory,\n      fSchema,\n      fName,\n      fPname,\n      fDefaults,\n      fOverrides\n    ]);\n    var externalSpec = objOf([\n      fFactory,\n      fSchema,\n      fName,\n      fDefaults,\n      fOverrides\n    ]);\n    var optionalSpec = objOf([\n      fFactory,\n      fSchema,\n      fName,\n      fPname,\n      fDefaults,\n      fOverrides\n    ]);\n    var groupSpec = objOf([\n      fFactory,\n      fGroupSchema,\n      fName,\n      strict$1('unit'),\n      fPname,\n      fDefaults,\n      fOverrides\n    ]);\n    var asNamedPart = function (part) {\n      return part.fold(Option.some, Option.none, Option.some, Option.some);\n    };\n    var name$1 = function (part) {\n      var get = function (data) {\n        return data.name;\n      };\n      return part.fold(get, get, get, get);\n    };\n    var asCommon = function (part) {\n      return part.fold(identity, identity, identity, identity);\n    };\n    var convert = function (adtConstructor, partSchema) {\n      return function (spec) {\n        var data = asRawOrDie('Converting part type', partSchema, spec);\n        return adtConstructor(data);\n      };\n    };\n    var required = convert(adt$a.required, requiredSpec);\n    var external$1 = convert(adt$a.external, externalSpec);\n    var optional = convert(adt$a.optional, optionalSpec);\n    var group = convert(adt$a.group, groupSpec);\n    var original = constant('entirety');\n\n    var PartType = /*#__PURE__*/Object.freeze({\n        required: required,\n        external: external$1,\n        optional: optional,\n        group: group,\n        asNamedPart: asNamedPart,\n        name: name$1,\n        asCommon: asCommon,\n        original: original\n    });\n\n    var combine$2 = function (detail, data, partSpec, partValidated) {\n      return deepMerge(data.defaults(detail, partSpec, partValidated), partSpec, { uid: detail.partUids[data.name] }, data.overrides(detail, partSpec, partValidated));\n    };\n    var subs = function (owner, detail, parts) {\n      var internals = {};\n      var externals = {};\n      each(parts, function (part) {\n        part.fold(function (data) {\n          internals[data.pname] = single(true, function (detail, partSpec, partValidated) {\n            return data.factory.sketch(combine$2(detail, data, partSpec, partValidated));\n          });\n        }, function (data) {\n          var partSpec = detail.parts[data.name];\n          externals[data.name] = constant(data.factory.sketch(combine$2(detail, data, partSpec[original()]), partSpec));\n        }, function (data) {\n          internals[data.pname] = single(false, function (detail, partSpec, partValidated) {\n            return data.factory.sketch(combine$2(detail, data, partSpec, partValidated));\n          });\n        }, function (data) {\n          internals[data.pname] = multiple(true, function (detail, _partSpec, _partValidated) {\n            var units = detail[data.name];\n            return map(units, function (u) {\n              return data.factory.sketch(deepMerge(data.defaults(detail, u, _partValidated), u, data.overrides(detail, u)));\n            });\n          });\n        });\n      });\n      return {\n        internals: constant(internals),\n        externals: constant(externals)\n      };\n    };\n\n    var generate$4 = function (owner, parts) {\n      var r = {};\n      each(parts, function (part) {\n        asNamedPart(part).each(function (np) {\n          var g = doGenerateOne(owner, np.pname);\n          r[np.name] = function (config) {\n            var validated = asRawOrDie('Part: ' + np.name + ' in ' + owner, objOf(np.schema), config);\n            return __assign(__assign({}, g), {\n              config: config,\n              validated: validated\n            });\n          };\n        });\n      });\n      return r;\n    };\n    var doGenerateOne = function (owner, pname) {\n      return {\n        uiType: placeholder(),\n        owner: owner,\n        name: pname\n      };\n    };\n    var generateOne = function (owner, pname, config) {\n      return {\n        uiType: placeholder(),\n        owner: owner,\n        name: pname,\n        config: config,\n        validated: {}\n      };\n    };\n    var schemas = function (parts) {\n      return bind(parts, function (part) {\n        return part.fold(Option.none, Option.some, Option.none, Option.none).map(function (data) {\n          return strictObjOf(data.name, data.schema.concat([snapshot(original())]));\n        }).toArray();\n      });\n    };\n    var names = function (parts) {\n      return map(parts, name$1);\n    };\n    var substitutes = function (owner, detail, parts) {\n      return subs(owner, detail, parts);\n    };\n    var components = function (owner, detail, internals) {\n      return substitutePlaces(Option.some(owner), detail, detail.components, internals);\n    };\n    var getPart = function (component, detail, partKey) {\n      var uid = detail.partUids[partKey];\n      return component.getSystem().getByUid(uid).toOption();\n    };\n    var getPartOrDie = function (component, detail, partKey) {\n      return getPart(component, detail, partKey).getOrDie('Could not find part: ' + partKey);\n    };\n    var getParts = function (component, detail, partKeys) {\n      var r = {};\n      var uids = detail.partUids;\n      var system = component.getSystem();\n      each(partKeys, function (pk) {\n        r[pk] = constant(system.getByUid(uids[pk]));\n      });\n      return r;\n    };\n    var getAllParts = function (component, detail) {\n      var system = component.getSystem();\n      return map$1(detail.partUids, function (pUid, k) {\n        return constant(system.getByUid(pUid));\n      });\n    };\n    var getAllPartNames = function (detail) {\n      return keys(detail.partUids);\n    };\n    var getPartsOrDie = function (component, detail, partKeys) {\n      var r = {};\n      var uids = detail.partUids;\n      var system = component.getSystem();\n      each(partKeys, function (pk) {\n        r[pk] = constant(system.getByUid(uids[pk]).getOrDie());\n      });\n      return r;\n    };\n    var defaultUids = function (baseUid, partTypes) {\n      var partNames = names(partTypes);\n      return wrapAll$1(map(partNames, function (pn) {\n        return {\n          key: pn,\n          value: baseUid + '-' + pn\n        };\n      }));\n    };\n    var defaultUidsSchema = function (partTypes) {\n      return field('partUids', 'partUids', mergeWithThunk(function (spec) {\n        return defaultUids(spec.uid, partTypes);\n      }), anyValue$1());\n    };\n\n    var AlloyParts = /*#__PURE__*/Object.freeze({\n        generate: generate$4,\n        generateOne: generateOne,\n        schemas: schemas,\n        names: names,\n        substitutes: substitutes,\n        components: components,\n        defaultUids: defaultUids,\n        defaultUidsSchema: defaultUidsSchema,\n        getAllParts: getAllParts,\n        getAllPartNames: getAllPartNames,\n        getPart: getPart,\n        getPartOrDie: getPartOrDie,\n        getParts: getParts,\n        getPartsOrDie: getPartsOrDie\n    });\n\n    var base = function (partSchemas, partUidsSchemas) {\n      var ps = partSchemas.length > 0 ? [strictObjOf('parts', partSchemas)] : [];\n      return ps.concat([\n        strict$1('uid'),\n        defaulted$1('dom', {}),\n        defaulted$1('components', []),\n        snapshot('originalSpec'),\n        defaulted$1('debug.sketcher', {})\n      ]).concat(partUidsSchemas);\n    };\n    var asRawOrDie$1 = function (label, schema, spec, partSchemas, partUidsSchemas) {\n      var baseS = base(partSchemas, partUidsSchemas);\n      return asRawOrDie(label + ' [SpecSchema]', objOfOnly(baseS.concat(schema)), spec);\n    };\n\n    var single$1 = function (owner, schema, factory, spec) {\n      var specWithUid = supplyUid(spec);\n      var detail = asRawOrDie$1(owner, schema, specWithUid, [], []);\n      return factory(detail, specWithUid);\n    };\n    var composite = function (owner, schema, partTypes, factory, spec) {\n      var specWithUid = supplyUid(spec);\n      var partSchemas = schemas(partTypes);\n      var partUidsSchema = defaultUidsSchema(partTypes);\n      var detail = asRawOrDie$1(owner, schema, specWithUid, partSchemas, [partUidsSchema]);\n      var subs = substitutes(owner, detail, partTypes);\n      var components$1 = components(owner, detail, subs.internals());\n      return factory(detail, components$1, specWithUid, subs.externals());\n    };\n    var supplyUid = function (spec) {\n      return spec.hasOwnProperty('uid') ? spec : __assign(__assign({}, spec), { uid: generate$2('uid') });\n    };\n\n    function isSketchSpec(spec) {\n      return spec.uid !== undefined;\n    }\n    var singleSchema = objOfOnly([\n      strict$1('name'),\n      strict$1('factory'),\n      strict$1('configFields'),\n      defaulted$1('apis', {}),\n      defaulted$1('extraApis', {})\n    ]);\n    var compositeSchema = objOfOnly([\n      strict$1('name'),\n      strict$1('factory'),\n      strict$1('configFields'),\n      strict$1('partFields'),\n      defaulted$1('apis', {}),\n      defaulted$1('extraApis', {})\n    ]);\n    var single$2 = function (rawConfig) {\n      var config = asRawOrDie('Sketcher for ' + rawConfig.name, singleSchema, rawConfig);\n      var sketch = function (spec) {\n        return single$1(config.name, config.configFields, config.factory, spec);\n      };\n      var apis = map$1(config.apis, makeApi);\n      var extraApis = map$1(config.extraApis, function (f, k) {\n        return markAsExtraApi(f, k);\n      });\n      return __assign(__assign({\n        name: constant(config.name),\n        partFields: constant([]),\n        configFields: constant(config.configFields),\n        sketch: sketch\n      }, apis), extraApis);\n    };\n    var composite$1 = function (rawConfig) {\n      var config = asRawOrDie('Sketcher for ' + rawConfig.name, compositeSchema, rawConfig);\n      var sketch = function (spec) {\n        return composite(config.name, config.configFields, config.partFields, config.factory, spec);\n      };\n      var parts = generate$4(config.name, config.partFields);\n      var apis = map$1(config.apis, makeApi);\n      var extraApis = map$1(config.extraApis, function (f, k) {\n        return markAsExtraApi(f, k);\n      });\n      return __assign(__assign({\n        name: constant(config.name),\n        partFields: constant(config.partFields),\n        configFields: constant(config.configFields),\n        sketch: sketch,\n        parts: constant(parts)\n      }, apis), extraApis);\n    };\n\n    var inside = function (target) {\n      return name(target) === 'input' && get$2(target, 'type') !== 'radio' || name(target) === 'textarea';\n    };\n\n    var getCurrent = function (component, composeConfig, composeState) {\n      return composeConfig.find(component);\n    };\n\n    var ComposeApis = /*#__PURE__*/Object.freeze({\n        getCurrent: getCurrent\n    });\n\n    var ComposeSchema = [strict$1('find')];\n\n    var Composing = create$1({\n      fields: ComposeSchema,\n      name: 'composing',\n      apis: ComposeApis\n    });\n\n    var dehighlightAllExcept = function (component, hConfig, hState, skip) {\n      var highlighted = descendants(component.element(), '.' + hConfig.highlightClass);\n      each(highlighted, function (h) {\n        if (!exists(skip, function (skipComp) {\n            return skipComp.element() === h;\n          })) {\n          remove$4(h, hConfig.highlightClass);\n          component.getSystem().getByDom(h).each(function (target) {\n            hConfig.onDehighlight(component, target);\n            emit(target, dehighlight());\n          });\n        }\n      });\n    };\n    var dehighlightAll = function (component, hConfig, hState) {\n      return dehighlightAllExcept(component, hConfig, hState, []);\n    };\n    var dehighlight$1 = function (component, hConfig, hState, target) {\n      if (isHighlighted(component, hConfig, hState, target)) {\n        remove$4(target.element(), hConfig.highlightClass);\n        hConfig.onDehighlight(component, target);\n        emit(target, dehighlight());\n      }\n    };\n    var highlight$1 = function (component, hConfig, hState, target) {\n      dehighlightAllExcept(component, hConfig, hState, [target]);\n      if (!isHighlighted(component, hConfig, hState, target)) {\n        add$2(target.element(), hConfig.highlightClass);\n        hConfig.onHighlight(component, target);\n        emit(target, highlight());\n      }\n    };\n    var highlightFirst = function (component, hConfig, hState) {\n      getFirst(component, hConfig).each(function (firstComp) {\n        highlight$1(component, hConfig, hState, firstComp);\n      });\n    };\n    var highlightLast = function (component, hConfig, hState) {\n      getLast(component, hConfig).each(function (lastComp) {\n        highlight$1(component, hConfig, hState, lastComp);\n      });\n    };\n    var highlightAt = function (component, hConfig, hState, index) {\n      getByIndex(component, hConfig, hState, index).fold(function (err) {\n        throw new Error(err);\n      }, function (firstComp) {\n        highlight$1(component, hConfig, hState, firstComp);\n      });\n    };\n    var highlightBy = function (component, hConfig, hState, predicate) {\n      var candidates = getCandidates(component, hConfig);\n      var targetComp = find(candidates, predicate);\n      targetComp.each(function (c) {\n        highlight$1(component, hConfig, hState, c);\n      });\n    };\n    var isHighlighted = function (component, hConfig, hState, queryTarget) {\n      return has$2(queryTarget.element(), hConfig.highlightClass);\n    };\n    var getHighlighted = function (component, hConfig, hState) {\n      return descendant$1(component.element(), '.' + hConfig.highlightClass).bind(function (e) {\n        return component.getSystem().getByDom(e).toOption();\n      });\n    };\n    var getByIndex = function (component, hConfig, hState, index) {\n      var items = descendants(component.element(), '.' + hConfig.itemClass);\n      return Option.from(items[index]).fold(function () {\n        return Result.error('No element found with index ' + index);\n      }, component.getSystem().getByDom);\n    };\n    var getFirst = function (component, hConfig, hState) {\n      return descendant$1(component.element(), '.' + hConfig.itemClass).bind(function (e) {\n        return component.getSystem().getByDom(e).toOption();\n      });\n    };\n    var getLast = function (component, hConfig, hState) {\n      var items = descendants(component.element(), '.' + hConfig.itemClass);\n      var last = items.length > 0 ? Option.some(items[items.length - 1]) : Option.none();\n      return last.bind(function (c) {\n        return component.getSystem().getByDom(c).toOption();\n      });\n    };\n    var getDelta = function (component, hConfig, hState, delta) {\n      var items = descendants(component.element(), '.' + hConfig.itemClass);\n      var current = findIndex(items, function (item) {\n        return has$2(item, hConfig.highlightClass);\n      });\n      return current.bind(function (selected) {\n        var dest = cycleBy(selected, delta, 0, items.length - 1);\n        return component.getSystem().getByDom(items[dest]).toOption();\n      });\n    };\n    var getPrevious = function (component, hConfig, hState) {\n      return getDelta(component, hConfig, hState, -1);\n    };\n    var getNext = function (component, hConfig, hState) {\n      return getDelta(component, hConfig, hState, +1);\n    };\n    var getCandidates = function (component, hConfig, hState) {\n      var items = descendants(component.element(), '.' + hConfig.itemClass);\n      return cat(map(items, function (i) {\n        return component.getSystem().getByDom(i).toOption();\n      }));\n    };\n\n    var HighlightApis = /*#__PURE__*/Object.freeze({\n        dehighlightAll: dehighlightAll,\n        dehighlight: dehighlight$1,\n        highlight: highlight$1,\n        highlightFirst: highlightFirst,\n        highlightLast: highlightLast,\n        highlightAt: highlightAt,\n        highlightBy: highlightBy,\n        isHighlighted: isHighlighted,\n        getHighlighted: getHighlighted,\n        getFirst: getFirst,\n        getLast: getLast,\n        getPrevious: getPrevious,\n        getNext: getNext,\n        getCandidates: getCandidates\n    });\n\n    var HighlightSchema = [\n      strict$1('highlightClass'),\n      strict$1('itemClass'),\n      onHandler('onHighlight'),\n      onHandler('onDehighlight')\n    ];\n\n    var Highlighting = create$1({\n      fields: HighlightSchema,\n      name: 'highlighting',\n      apis: HighlightApis\n    });\n\n    var BACKSPACE = function () {\n      return [8];\n    };\n    var TAB = function () {\n      return [9];\n    };\n    var ENTER = function () {\n      return [13];\n    };\n    var ESCAPE = function () {\n      return [27];\n    };\n    var SPACE = function () {\n      return [32];\n    };\n    var LEFT = function () {\n      return [37];\n    };\n    var UP = function () {\n      return [38];\n    };\n    var RIGHT = function () {\n      return [39];\n    };\n    var DOWN = function () {\n      return [40];\n    };\n\n    var cyclePrev = function (values, index, predicate) {\n      var before = reverse(values.slice(0, index));\n      var after = reverse(values.slice(index + 1));\n      return find(before.concat(after), predicate);\n    };\n    var tryPrev = function (values, index, predicate) {\n      var before = reverse(values.slice(0, index));\n      return find(before, predicate);\n    };\n    var cycleNext = function (values, index, predicate) {\n      var before = values.slice(0, index);\n      var after = values.slice(index + 1);\n      return find(after.concat(before), predicate);\n    };\n    var tryNext = function (values, index, predicate) {\n      var after = values.slice(index + 1);\n      return find(after, predicate);\n    };\n\n    var inSet = function (keys) {\n      return function (event) {\n        var raw = event.raw();\n        return contains(keys, raw.which);\n      };\n    };\n    var and = function (preds) {\n      return function (event) {\n        return forall(preds, function (pred) {\n          return pred(event);\n        });\n      };\n    };\n    var isShift = function (event) {\n      var raw = event.raw();\n      return raw.shiftKey === true;\n    };\n    var isControl = function (event) {\n      var raw = event.raw();\n      return raw.ctrlKey === true;\n    };\n    var isNotShift = not(isShift);\n\n    var rule = function (matches, action) {\n      return {\n        matches: matches,\n        classification: action\n      };\n    };\n    var choose$2 = function (transitions, event) {\n      var transition = find(transitions, function (t) {\n        return t.matches(event);\n      });\n      return transition.map(function (t) {\n        return t.classification;\n      });\n    };\n\n    var reportFocusShifting = function (component, prevFocus, newFocus) {\n      var noChange = prevFocus.exists(function (p) {\n        return newFocus.exists(function (n) {\n          return eq(n, p);\n        });\n      });\n      if (!noChange) {\n        emitWith(component, focusShifted(), {\n          prevFocus: prevFocus,\n          newFocus: newFocus\n        });\n      }\n    };\n    var dom = function () {\n      var get = function (component) {\n        return search(component.element());\n      };\n      var set = function (component, focusee) {\n        var prevFocus = get(component);\n        component.getSystem().triggerFocus(focusee, component.element());\n        var newFocus = get(component);\n        reportFocusShifting(component, prevFocus, newFocus);\n      };\n      return {\n        get: get,\n        set: set\n      };\n    };\n    var highlights = function () {\n      var get = function (component) {\n        return Highlighting.getHighlighted(component).map(function (item) {\n          return item.element();\n        });\n      };\n      var set = function (component, element) {\n        var prevFocus = get(component);\n        component.getSystem().getByDom(element).fold(noop, function (item) {\n          Highlighting.highlight(component, item);\n        });\n        var newFocus = get(component);\n        reportFocusShifting(component, prevFocus, newFocus);\n      };\n      return {\n        get: get,\n        set: set\n      };\n    };\n\n    var FocusInsideModes;\n    (function (FocusInsideModes) {\n      FocusInsideModes['OnFocusMode'] = 'onFocus';\n      FocusInsideModes['OnEnterOrSpaceMode'] = 'onEnterOrSpace';\n      FocusInsideModes['OnApiMode'] = 'onApi';\n    }(FocusInsideModes || (FocusInsideModes = {})));\n\n    var typical = function (infoSchema, stateInit, getKeydownRules, getKeyupRules, optFocusIn) {\n      var schema = function () {\n        return infoSchema.concat([\n          defaulted$1('focusManager', dom()),\n          defaultedOf('focusInside', 'onFocus', valueOf(function (val) {\n            return contains([\n              'onFocus',\n              'onEnterOrSpace',\n              'onApi'\n            ], val) ? Result.value(val) : Result.error('Invalid value for focusInside');\n          })),\n          output('handler', me),\n          output('state', stateInit),\n          output('sendFocusIn', optFocusIn)\n        ]);\n      };\n      var processKey = function (component, simulatedEvent, getRules, keyingConfig, keyingState) {\n        var rules = getRules(component, simulatedEvent, keyingConfig, keyingState);\n        return choose$2(rules, simulatedEvent.event()).bind(function (rule) {\n          return rule(component, simulatedEvent, keyingConfig, keyingState);\n        });\n      };\n      var toEvents = function (keyingConfig, keyingState) {\n        var onFocusHandler = keyingConfig.focusInside !== FocusInsideModes.OnFocusMode ? Option.none() : optFocusIn(keyingConfig).map(function (focusIn) {\n          return run(focus(), function (component, simulatedEvent) {\n            focusIn(component, keyingConfig, keyingState);\n            simulatedEvent.stop();\n          });\n        });\n        var tryGoInsideComponent = function (component, simulatedEvent) {\n          var isEnterOrSpace = inSet(SPACE().concat(ENTER()))(simulatedEvent.event());\n          if (keyingConfig.focusInside === FocusInsideModes.OnEnterOrSpaceMode && isEnterOrSpace && isSource(component, simulatedEvent)) {\n            optFocusIn(keyingConfig).each(function (focusIn) {\n              focusIn(component, keyingConfig, keyingState);\n              simulatedEvent.stop();\n            });\n          }\n        };\n        return derive(onFocusHandler.toArray().concat([\n          run(keydown(), function (component, simulatedEvent) {\n            processKey(component, simulatedEvent, getKeydownRules, keyingConfig, keyingState).fold(function () {\n              tryGoInsideComponent(component, simulatedEvent);\n            }, function (_) {\n              simulatedEvent.stop();\n            });\n          }),\n          run(keyup(), function (component, simulatedEvent) {\n            processKey(component, simulatedEvent, getKeyupRules, keyingConfig, keyingState).each(function (_) {\n              simulatedEvent.stop();\n            });\n          })\n        ]));\n      };\n      var me = {\n        schema: schema,\n        processKey: processKey,\n        toEvents: toEvents\n      };\n      return me;\n    };\n\n    var create$3 = function (cyclicField) {\n      var schema = [\n        option('onEscape'),\n        option('onEnter'),\n        defaulted$1('selector', '[data-alloy-tabstop=\"true\"]:not(:disabled)'),\n        defaulted$1('firstTabstop', 0),\n        defaulted$1('useTabstopAt', constant(true)),\n        option('visibilitySelector')\n      ].concat([cyclicField]);\n      var isVisible = function (tabbingConfig, element) {\n        var target = tabbingConfig.visibilitySelector.bind(function (sel) {\n          return closest$3(element, sel);\n        }).getOr(element);\n        return get$6(target) > 0;\n      };\n      var findInitial = function (component, tabbingConfig) {\n        var tabstops = descendants(component.element(), tabbingConfig.selector);\n        var visibles = filter(tabstops, function (elem) {\n          return isVisible(tabbingConfig, elem);\n        });\n        return Option.from(visibles[tabbingConfig.firstTabstop]);\n      };\n      var findCurrent = function (component, tabbingConfig) {\n        return tabbingConfig.focusManager.get(component).bind(function (elem) {\n          return closest$3(elem, tabbingConfig.selector);\n        });\n      };\n      var isTabstop = function (tabbingConfig, element) {\n        return isVisible(tabbingConfig, element) && tabbingConfig.useTabstopAt(element);\n      };\n      var focusIn = function (component, tabbingConfig) {\n        findInitial(component, tabbingConfig).each(function (target) {\n          tabbingConfig.focusManager.set(component, target);\n        });\n      };\n      var goFromTabstop = function (component, tabstops, stopIndex, tabbingConfig, cycle) {\n        return cycle(tabstops, stopIndex, function (elem) {\n          return isTabstop(tabbingConfig, elem);\n        }).fold(function () {\n          return tabbingConfig.cyclic ? Option.some(true) : Option.none();\n        }, function (target) {\n          tabbingConfig.focusManager.set(component, target);\n          return Option.some(true);\n        });\n      };\n      var go = function (component, simulatedEvent, tabbingConfig, cycle) {\n        var tabstops = descendants(component.element(), tabbingConfig.selector);\n        return findCurrent(component, tabbingConfig).bind(function (tabstop) {\n          var optStopIndex = findIndex(tabstops, curry(eq, tabstop));\n          return optStopIndex.bind(function (stopIndex) {\n            return goFromTabstop(component, tabstops, stopIndex, tabbingConfig, cycle);\n          });\n        });\n      };\n      var goBackwards = function (component, simulatedEvent, tabbingConfig, tabbingState) {\n        var navigate = tabbingConfig.cyclic ? cyclePrev : tryPrev;\n        return go(component, simulatedEvent, tabbingConfig, navigate);\n      };\n      var goForwards = function (component, simulatedEvent, tabbingConfig, tabbingState) {\n        var navigate = tabbingConfig.cyclic ? cycleNext : tryNext;\n        return go(component, simulatedEvent, tabbingConfig, navigate);\n      };\n      var execute = function (component, simulatedEvent, tabbingConfig, tabbingState) {\n        return tabbingConfig.onEnter.bind(function (f) {\n          return f(component, simulatedEvent);\n        });\n      };\n      var exit = function (component, simulatedEvent, tabbingConfig, tabbingState) {\n        return tabbingConfig.onEscape.bind(function (f) {\n          return f(component, simulatedEvent);\n        });\n      };\n      var getKeydownRules = constant([\n        rule(and([\n          isShift,\n          inSet(TAB())\n        ]), goBackwards),\n        rule(inSet(TAB()), goForwards),\n        rule(inSet(ESCAPE()), exit),\n        rule(and([\n          isNotShift,\n          inSet(ENTER())\n        ]), execute)\n      ]);\n      var getKeyupRules = constant([]);\n      return typical(schema, NoState.init, getKeydownRules, getKeyupRules, function () {\n        return Option.some(focusIn);\n      });\n    };\n\n    var AcyclicType = create$3(state$1('cyclic', constant(false)));\n\n    var CyclicType = create$3(state$1('cyclic', constant(true)));\n\n    var doDefaultExecute = function (component, simulatedEvent, focused) {\n      dispatch(component, focused, execute());\n      return Option.some(true);\n    };\n    var defaultExecute = function (component, simulatedEvent, focused) {\n      return inside(focused) && inSet(SPACE())(simulatedEvent.event()) ? Option.none() : doDefaultExecute(component, simulatedEvent, focused);\n    };\n    var stopEventForFirefox = function (component, simulatedEvent) {\n      return Option.some(true);\n    };\n\n    var schema$4 = [\n      defaulted$1('execute', defaultExecute),\n      defaulted$1('useSpace', false),\n      defaulted$1('useEnter', true),\n      defaulted$1('useControlEnter', false),\n      defaulted$1('useDown', false)\n    ];\n    var execute$1 = function (component, simulatedEvent, executeConfig) {\n      return executeConfig.execute(component, simulatedEvent, component.element());\n    };\n    var getKeydownRules = function (component, simulatedEvent, executeConfig, executeState) {\n      var spaceExec = executeConfig.useSpace && !inside(component.element()) ? SPACE() : [];\n      var enterExec = executeConfig.useEnter ? ENTER() : [];\n      var downExec = executeConfig.useDown ? DOWN() : [];\n      var execKeys = spaceExec.concat(enterExec).concat(downExec);\n      return [rule(inSet(execKeys), execute$1)].concat(executeConfig.useControlEnter ? [rule(and([\n          isControl,\n          inSet(ENTER())\n        ]), execute$1)] : []);\n    };\n    var getKeyupRules = function (component, simulatedEvent, executeConfig, executeState) {\n      return executeConfig.useSpace && !inside(component.element()) ? [rule(inSet(SPACE()), stopEventForFirefox)] : [];\n    };\n    var ExecutionType = typical(schema$4, NoState.init, getKeydownRules, getKeyupRules, function () {\n      return Option.none();\n    });\n\n    var flatgrid = function (spec) {\n      var dimensions = Cell(Option.none());\n      var setGridSize = function (numRows, numColumns) {\n        dimensions.set(Option.some({\n          numRows: constant(numRows),\n          numColumns: constant(numColumns)\n        }));\n      };\n      var getNumRows = function () {\n        return dimensions.get().map(function (d) {\n          return d.numRows();\n        });\n      };\n      var getNumColumns = function () {\n        return dimensions.get().map(function (d) {\n          return d.numColumns();\n        });\n      };\n      return nu$5({\n        readState: function () {\n          return dimensions.get().map(function (d) {\n            return {\n              numRows: d.numRows(),\n              numColumns: d.numColumns()\n            };\n          }).getOr({\n            numRows: '?',\n            numColumns: '?'\n          });\n        },\n        setGridSize: setGridSize,\n        getNumRows: getNumRows,\n        getNumColumns: getNumColumns\n      });\n    };\n    var init$2 = function (spec) {\n      return spec.state(spec);\n    };\n\n    var KeyingState = /*#__PURE__*/Object.freeze({\n        flatgrid: flatgrid,\n        init: init$2\n    });\n\n    var useH = function (movement) {\n      return function (component, simulatedEvent, config, state) {\n        var move = movement(component.element());\n        return use(move, component, simulatedEvent, config, state);\n      };\n    };\n    var west$2 = function (moveLeft, moveRight) {\n      var movement = onDirection(moveLeft, moveRight);\n      return useH(movement);\n    };\n    var east$2 = function (moveLeft, moveRight) {\n      var movement = onDirection(moveRight, moveLeft);\n      return useH(movement);\n    };\n    var useV = function (move) {\n      return function (component, simulatedEvent, config, state) {\n        return use(move, component, simulatedEvent, config, state);\n      };\n    };\n    var use = function (move, component, simulatedEvent, config, state) {\n      var outcome = config.focusManager.get(component).bind(function (focused) {\n        return move(component.element(), focused, config, state);\n      });\n      return outcome.map(function (newFocus) {\n        config.focusManager.set(component, newFocus);\n        return true;\n      });\n    };\n    var north$2 = useV;\n    var south$2 = useV;\n    var move = useV;\n\n    var isHidden = function (dom) {\n      return dom.offsetWidth <= 0 && dom.offsetHeight <= 0;\n    };\n    var isVisible = function (element) {\n      var dom = element.dom();\n      return !isHidden(dom);\n    };\n\n    var indexInfo = MixedBag([\n      'index',\n      'candidates'\n    ], []);\n    var locate$2 = function (candidates, predicate) {\n      return findIndex(candidates, predicate).map(function (index) {\n        return indexInfo({\n          index: index,\n          candidates: candidates\n        });\n      });\n    };\n\n    var locateVisible = function (container, current, selector) {\n      var predicate = curry(eq, current);\n      var candidates = descendants(container, selector);\n      var visible = filter(candidates, isVisible);\n      return locate$2(visible, predicate);\n    };\n    var findIndex$1 = function (elements, target) {\n      return findIndex(elements, function (elem) {\n        return eq(target, elem);\n      });\n    };\n\n    var withGrid = function (values, index, numCols, f) {\n      var oldRow = Math.floor(index / numCols);\n      var oldColumn = index % numCols;\n      return f(oldRow, oldColumn).bind(function (address) {\n        var newIndex = address.row() * numCols + address.column();\n        return newIndex >= 0 && newIndex < values.length ? Option.some(values[newIndex]) : Option.none();\n      });\n    };\n    var cycleHorizontal = function (values, index, numRows, numCols, delta) {\n      return withGrid(values, index, numCols, function (oldRow, oldColumn) {\n        var onLastRow = oldRow === numRows - 1;\n        var colsInRow = onLastRow ? values.length - oldRow * numCols : numCols;\n        var newColumn = cycleBy(oldColumn, delta, 0, colsInRow - 1);\n        return Option.some({\n          row: constant(oldRow),\n          column: constant(newColumn)\n        });\n      });\n    };\n    var cycleVertical = function (values, index, numRows, numCols, delta) {\n      return withGrid(values, index, numCols, function (oldRow, oldColumn) {\n        var newRow = cycleBy(oldRow, delta, 0, numRows - 1);\n        var onLastRow = newRow === numRows - 1;\n        var colsInRow = onLastRow ? values.length - newRow * numCols : numCols;\n        var newCol = cap(oldColumn, 0, colsInRow - 1);\n        return Option.some({\n          row: constant(newRow),\n          column: constant(newCol)\n        });\n      });\n    };\n    var cycleRight = function (values, index, numRows, numCols) {\n      return cycleHorizontal(values, index, numRows, numCols, +1);\n    };\n    var cycleLeft = function (values, index, numRows, numCols) {\n      return cycleHorizontal(values, index, numRows, numCols, -1);\n    };\n    var cycleUp = function (values, index, numRows, numCols) {\n      return cycleVertical(values, index, numRows, numCols, -1);\n    };\n    var cycleDown = function (values, index, numRows, numCols) {\n      return cycleVertical(values, index, numRows, numCols, +1);\n    };\n\n    var schema$5 = [\n      strict$1('selector'),\n      defaulted$1('execute', defaultExecute),\n      onKeyboardHandler('onEscape'),\n      defaulted$1('captureTab', false),\n      initSize()\n    ];\n    var focusIn = function (component, gridConfig, gridState) {\n      descendant$1(component.element(), gridConfig.selector).each(function (first) {\n        gridConfig.focusManager.set(component, first);\n      });\n    };\n    var findCurrent = function (component, gridConfig) {\n      return gridConfig.focusManager.get(component).bind(function (elem) {\n        return closest$3(elem, gridConfig.selector);\n      });\n    };\n    var execute$2 = function (component, simulatedEvent, gridConfig, gridState) {\n      return findCurrent(component, gridConfig).bind(function (focused) {\n        return gridConfig.execute(component, simulatedEvent, focused);\n      });\n    };\n    var doMove = function (cycle) {\n      return function (element, focused, gridConfig, gridState) {\n        return locateVisible(element, focused, gridConfig.selector).bind(function (identified) {\n          return cycle(identified.candidates(), identified.index(), gridState.getNumRows().getOr(gridConfig.initSize.numRows), gridState.getNumColumns().getOr(gridConfig.initSize.numColumns));\n        });\n      };\n    };\n    var handleTab = function (component, simulatedEvent, gridConfig, gridState) {\n      return gridConfig.captureTab ? Option.some(true) : Option.none();\n    };\n    var doEscape = function (component, simulatedEvent, gridConfig, gridState) {\n      return gridConfig.onEscape(component, simulatedEvent);\n    };\n    var moveLeft = doMove(cycleLeft);\n    var moveRight = doMove(cycleRight);\n    var moveNorth = doMove(cycleUp);\n    var moveSouth = doMove(cycleDown);\n    var getKeydownRules$1 = constant([\n      rule(inSet(LEFT()), west$2(moveLeft, moveRight)),\n      rule(inSet(RIGHT()), east$2(moveLeft, moveRight)),\n      rule(inSet(UP()), north$2(moveNorth)),\n      rule(inSet(DOWN()), south$2(moveSouth)),\n      rule(and([\n        isShift,\n        inSet(TAB())\n      ]), handleTab),\n      rule(and([\n        isNotShift,\n        inSet(TAB())\n      ]), handleTab),\n      rule(inSet(ESCAPE()), doEscape),\n      rule(inSet(SPACE().concat(ENTER())), execute$2)\n    ]);\n    var getKeyupRules$1 = constant([rule(inSet(SPACE()), stopEventForFirefox)]);\n    var FlatgridType = typical(schema$5, flatgrid, getKeydownRules$1, getKeyupRules$1, function () {\n      return Option.some(focusIn);\n    });\n\n    var horizontal = function (container, selector, current, delta) {\n      var isDisabledButton = function (candidate) {\n        return name(candidate) === 'button' && get$2(candidate, 'disabled') === 'disabled';\n      };\n      var tryCycle = function (initial, index, candidates) {\n        var newIndex = cycleBy(index, delta, 0, candidates.length - 1);\n        if (newIndex === initial) {\n          return Option.none();\n        } else {\n          return isDisabledButton(candidates[newIndex]) ? tryCycle(initial, newIndex, candidates) : Option.from(candidates[newIndex]);\n        }\n      };\n      return locateVisible(container, current, selector).bind(function (identified) {\n        var index = identified.index();\n        var candidates = identified.candidates();\n        return tryCycle(index, index, candidates);\n      });\n    };\n\n    var schema$6 = [\n      strict$1('selector'),\n      defaulted$1('getInitial', Option.none),\n      defaulted$1('execute', defaultExecute),\n      onKeyboardHandler('onEscape'),\n      defaulted$1('executeOnMove', false),\n      defaulted$1('allowVertical', true)\n    ];\n    var findCurrent$1 = function (component, flowConfig) {\n      return flowConfig.focusManager.get(component).bind(function (elem) {\n        return closest$3(elem, flowConfig.selector);\n      });\n    };\n    var execute$3 = function (component, simulatedEvent, flowConfig) {\n      return findCurrent$1(component, flowConfig).bind(function (focused) {\n        return flowConfig.execute(component, simulatedEvent, focused);\n      });\n    };\n    var focusIn$1 = function (component, flowConfig) {\n      flowConfig.getInitial(component).orThunk(function () {\n        return descendant$1(component.element(), flowConfig.selector);\n      }).each(function (first) {\n        flowConfig.focusManager.set(component, first);\n      });\n    };\n    var moveLeft$1 = function (element, focused, info) {\n      return horizontal(element, info.selector, focused, -1);\n    };\n    var moveRight$1 = function (element, focused, info) {\n      return horizontal(element, info.selector, focused, +1);\n    };\n    var doMove$1 = function (movement) {\n      return function (component, simulatedEvent, flowConfig) {\n        return movement(component, simulatedEvent, flowConfig).bind(function () {\n          return flowConfig.executeOnMove ? execute$3(component, simulatedEvent, flowConfig) : Option.some(true);\n        });\n      };\n    };\n    var doEscape$1 = function (component, simulatedEvent, flowConfig, _flowState) {\n      return flowConfig.onEscape(component, simulatedEvent);\n    };\n    var getKeydownRules$2 = function (_component, _se, flowConfig, _flowState) {\n      var westMovers = LEFT().concat(flowConfig.allowVertical ? UP() : []);\n      var eastMovers = RIGHT().concat(flowConfig.allowVertical ? DOWN() : []);\n      return [\n        rule(inSet(westMovers), doMove$1(west$2(moveLeft$1, moveRight$1))),\n        rule(inSet(eastMovers), doMove$1(east$2(moveLeft$1, moveRight$1))),\n        rule(inSet(ENTER()), execute$3),\n        rule(inSet(SPACE()), execute$3),\n        rule(inSet(ESCAPE()), doEscape$1)\n      ];\n    };\n    var getKeyupRules$2 = constant([rule(inSet(SPACE()), stopEventForFirefox)]);\n    var FlowType = typical(schema$6, NoState.init, getKeydownRules$2, getKeyupRules$2, function () {\n      return Option.some(focusIn$1);\n    });\n\n    var outcome = MixedBag([\n      'rowIndex',\n      'columnIndex',\n      'cell'\n    ], []);\n    var toCell = function (matrix, rowIndex, columnIndex) {\n      return Option.from(matrix[rowIndex]).bind(function (row) {\n        return Option.from(row[columnIndex]).map(function (cell) {\n          return outcome({\n            rowIndex: rowIndex,\n            columnIndex: columnIndex,\n            cell: cell\n          });\n        });\n      });\n    };\n    var cycleHorizontal$1 = function (matrix, rowIndex, startCol, deltaCol) {\n      var row = matrix[rowIndex];\n      var colsInRow = row.length;\n      var newColIndex = cycleBy(startCol, deltaCol, 0, colsInRow - 1);\n      return toCell(matrix, rowIndex, newColIndex);\n    };\n    var cycleVertical$1 = function (matrix, colIndex, startRow, deltaRow) {\n      var nextRowIndex = cycleBy(startRow, deltaRow, 0, matrix.length - 1);\n      var colsInNextRow = matrix[nextRowIndex].length;\n      var nextColIndex = cap(colIndex, 0, colsInNextRow - 1);\n      return toCell(matrix, nextRowIndex, nextColIndex);\n    };\n    var moveHorizontal = function (matrix, rowIndex, startCol, deltaCol) {\n      var row = matrix[rowIndex];\n      var colsInRow = row.length;\n      var newColIndex = cap(startCol + deltaCol, 0, colsInRow - 1);\n      return toCell(matrix, rowIndex, newColIndex);\n    };\n    var moveVertical = function (matrix, colIndex, startRow, deltaRow) {\n      var nextRowIndex = cap(startRow + deltaRow, 0, matrix.length - 1);\n      var colsInNextRow = matrix[nextRowIndex].length;\n      var nextColIndex = cap(colIndex, 0, colsInNextRow - 1);\n      return toCell(matrix, nextRowIndex, nextColIndex);\n    };\n    var cycleRight$1 = function (matrix, startRow, startCol) {\n      return cycleHorizontal$1(matrix, startRow, startCol, +1);\n    };\n    var cycleLeft$1 = function (matrix, startRow, startCol) {\n      return cycleHorizontal$1(matrix, startRow, startCol, -1);\n    };\n    var cycleUp$1 = function (matrix, startRow, startCol) {\n      return cycleVertical$1(matrix, startCol, startRow, -1);\n    };\n    var cycleDown$1 = function (matrix, startRow, startCol) {\n      return cycleVertical$1(matrix, startCol, startRow, +1);\n    };\n    var moveLeft$2 = function (matrix, startRow, startCol) {\n      return moveHorizontal(matrix, startRow, startCol, -1);\n    };\n    var moveRight$2 = function (matrix, startRow, startCol) {\n      return moveHorizontal(matrix, startRow, startCol, +1);\n    };\n    var moveUp = function (matrix, startRow, startCol) {\n      return moveVertical(matrix, startCol, startRow, -1);\n    };\n    var moveDown = function (matrix, startRow, startCol) {\n      return moveVertical(matrix, startCol, startRow, +1);\n    };\n\n    var schema$7 = [\n      strictObjOf('selectors', [\n        strict$1('row'),\n        strict$1('cell')\n      ]),\n      defaulted$1('cycles', true),\n      defaulted$1('previousSelector', Option.none),\n      defaulted$1('execute', defaultExecute)\n    ];\n    var focusIn$2 = function (component, matrixConfig) {\n      var focused = matrixConfig.previousSelector(component).orThunk(function () {\n        var selectors = matrixConfig.selectors;\n        return descendant$1(component.element(), selectors.cell);\n      });\n      focused.each(function (cell) {\n        matrixConfig.focusManager.set(component, cell);\n      });\n    };\n    var execute$4 = function (component, simulatedEvent, matrixConfig) {\n      return search(component.element()).bind(function (focused) {\n        return matrixConfig.execute(component, simulatedEvent, focused);\n      });\n    };\n    var toMatrix = function (rows, matrixConfig) {\n      return map(rows, function (row) {\n        return descendants(row, matrixConfig.selectors.cell);\n      });\n    };\n    var doMove$2 = function (ifCycle, ifMove) {\n      return function (element, focused, matrixConfig) {\n        var move = matrixConfig.cycles ? ifCycle : ifMove;\n        return closest$3(focused, matrixConfig.selectors.row).bind(function (inRow) {\n          var cellsInRow = descendants(inRow, matrixConfig.selectors.cell);\n          return findIndex$1(cellsInRow, focused).bind(function (colIndex) {\n            var allRows = descendants(element, matrixConfig.selectors.row);\n            return findIndex$1(allRows, inRow).bind(function (rowIndex) {\n              var matrix = toMatrix(allRows, matrixConfig);\n              return move(matrix, rowIndex, colIndex).map(function (next) {\n                return next.cell();\n              });\n            });\n          });\n        });\n      };\n    };\n    var moveLeft$3 = doMove$2(cycleLeft$1, moveLeft$2);\n    var moveRight$3 = doMove$2(cycleRight$1, moveRight$2);\n    var moveNorth$1 = doMove$2(cycleUp$1, moveUp);\n    var moveSouth$1 = doMove$2(cycleDown$1, moveDown);\n    var getKeydownRules$3 = constant([\n      rule(inSet(LEFT()), west$2(moveLeft$3, moveRight$3)),\n      rule(inSet(RIGHT()), east$2(moveLeft$3, moveRight$3)),\n      rule(inSet(UP()), north$2(moveNorth$1)),\n      rule(inSet(DOWN()), south$2(moveSouth$1)),\n      rule(inSet(SPACE().concat(ENTER())), execute$4)\n    ]);\n    var getKeyupRules$3 = constant([rule(inSet(SPACE()), stopEventForFirefox)]);\n    var MatrixType = typical(schema$7, NoState.init, getKeydownRules$3, getKeyupRules$3, function () {\n      return Option.some(focusIn$2);\n    });\n\n    var schema$8 = [\n      strict$1('selector'),\n      defaulted$1('execute', defaultExecute),\n      defaulted$1('moveOnTab', false)\n    ];\n    var execute$5 = function (component, simulatedEvent, menuConfig) {\n      return menuConfig.focusManager.get(component).bind(function (focused) {\n        return menuConfig.execute(component, simulatedEvent, focused);\n      });\n    };\n    var focusIn$3 = function (component, menuConfig) {\n      descendant$1(component.element(), menuConfig.selector).each(function (first) {\n        menuConfig.focusManager.set(component, first);\n      });\n    };\n    var moveUp$1 = function (element, focused, info) {\n      return horizontal(element, info.selector, focused, -1);\n    };\n    var moveDown$1 = function (element, focused, info) {\n      return horizontal(element, info.selector, focused, +1);\n    };\n    var fireShiftTab = function (component, simulatedEvent, menuConfig) {\n      return menuConfig.moveOnTab ? move(moveUp$1)(component, simulatedEvent, menuConfig) : Option.none();\n    };\n    var fireTab = function (component, simulatedEvent, menuConfig) {\n      return menuConfig.moveOnTab ? move(moveDown$1)(component, simulatedEvent, menuConfig) : Option.none();\n    };\n    var getKeydownRules$4 = constant([\n      rule(inSet(UP()), move(moveUp$1)),\n      rule(inSet(DOWN()), move(moveDown$1)),\n      rule(and([\n        isShift,\n        inSet(TAB())\n      ]), fireShiftTab),\n      rule(and([\n        isNotShift,\n        inSet(TAB())\n      ]), fireTab),\n      rule(inSet(ENTER()), execute$5),\n      rule(inSet(SPACE()), execute$5)\n    ]);\n    var getKeyupRules$4 = constant([rule(inSet(SPACE()), stopEventForFirefox)]);\n    var MenuType = typical(schema$8, NoState.init, getKeydownRules$4, getKeyupRules$4, function () {\n      return Option.some(focusIn$3);\n    });\n\n    var schema$9 = [\n      onKeyboardHandler('onSpace'),\n      onKeyboardHandler('onEnter'),\n      onKeyboardHandler('onShiftEnter'),\n      onKeyboardHandler('onLeft'),\n      onKeyboardHandler('onRight'),\n      onKeyboardHandler('onTab'),\n      onKeyboardHandler('onShiftTab'),\n      onKeyboardHandler('onUp'),\n      onKeyboardHandler('onDown'),\n      onKeyboardHandler('onEscape'),\n      defaulted$1('stopSpaceKeyup', false),\n      option('focusIn')\n    ];\n    var getKeydownRules$5 = function (component, simulatedEvent, specialInfo) {\n      return [\n        rule(inSet(SPACE()), specialInfo.onSpace),\n        rule(and([\n          isNotShift,\n          inSet(ENTER())\n        ]), specialInfo.onEnter),\n        rule(and([\n          isShift,\n          inSet(ENTER())\n        ]), specialInfo.onShiftEnter),\n        rule(and([\n          isShift,\n          inSet(TAB())\n        ]), specialInfo.onShiftTab),\n        rule(and([\n          isNotShift,\n          inSet(TAB())\n        ]), specialInfo.onTab),\n        rule(inSet(UP()), specialInfo.onUp),\n        rule(inSet(DOWN()), specialInfo.onDown),\n        rule(inSet(LEFT()), specialInfo.onLeft),\n        rule(inSet(RIGHT()), specialInfo.onRight),\n        rule(inSet(SPACE()), specialInfo.onSpace),\n        rule(inSet(ESCAPE()), specialInfo.onEscape)\n      ];\n    };\n    var getKeyupRules$5 = function (component, simulatedEvent, specialInfo) {\n      return specialInfo.stopSpaceKeyup ? [rule(inSet(SPACE()), stopEventForFirefox)] : [];\n    };\n    var SpecialType = typical(schema$9, NoState.init, getKeydownRules$5, getKeyupRules$5, function (specialInfo) {\n      return specialInfo.focusIn;\n    });\n\n    var acyclic = AcyclicType.schema();\n    var cyclic = CyclicType.schema();\n    var flow = FlowType.schema();\n    var flatgrid$1 = FlatgridType.schema();\n    var matrix = MatrixType.schema();\n    var execution = ExecutionType.schema();\n    var menu = MenuType.schema();\n    var special = SpecialType.schema();\n\n    var KeyboardBranches = /*#__PURE__*/Object.freeze({\n        acyclic: acyclic,\n        cyclic: cyclic,\n        flow: flow,\n        flatgrid: flatgrid$1,\n        matrix: matrix,\n        execution: execution,\n        menu: menu,\n        special: special\n    });\n\n    var Keying = createModes$1({\n      branchKey: 'mode',\n      branches: KeyboardBranches,\n      name: 'keying',\n      active: {\n        events: function (keyingConfig, keyingState) {\n          var handler = keyingConfig.handler;\n          return handler.toEvents(keyingConfig, keyingState);\n        }\n      },\n      apis: {\n        focusIn: function (component, keyConfig, keyState) {\n          keyConfig.sendFocusIn(keyConfig).fold(function () {\n            component.getSystem().triggerFocus(component.element(), component.element());\n          }, function (sendFocusIn) {\n            sendFocusIn(component, keyConfig, keyState);\n          });\n        },\n        setGridSize: function (component, keyConfig, keyState, numRows, numColumns) {\n          if (!hasKey$1(keyState, 'setGridSize')) {\n            domGlobals.console.error('Layout does not support setGridSize');\n          } else {\n            keyState.setGridSize(numRows, numColumns);\n          }\n        }\n      },\n      state: KeyingState\n    });\n\n    var set$5 = function (component, replaceConfig, replaceState, data) {\n      preserve(function () {\n        var newChildren = map(data, component.getSystem().build);\n        replaceChildren(component, newChildren);\n      }, component.element());\n    };\n    var insert = function (component, replaceConfig, insertion, childSpec) {\n      var child = component.getSystem().build(childSpec);\n      attachWith(component, child, insertion);\n    };\n    var append$2 = function (component, replaceConfig, replaceState, appendee) {\n      insert(component, replaceConfig, append, appendee);\n    };\n    var prepend$1 = function (component, replaceConfig, replaceState, prependee) {\n      insert(component, replaceConfig, prepend, prependee);\n    };\n    var remove$7 = function (component, replaceConfig, replaceState, removee) {\n      var children = contents(component);\n      var foundChild = find(children, function (child) {\n        return eq(removee.element(), child.element());\n      });\n      foundChild.each(detach);\n    };\n    var contents = function (component, replaceConfig) {\n      return component.components();\n    };\n    var replaceAt = function (component, replaceConfig, replaceState, replaceeIndex, replacer) {\n      var children = contents(component);\n      return Option.from(children[replaceeIndex]).map(function (replacee) {\n        remove$7(component, replaceConfig, replaceState, replacee);\n        replacer.each(function (r) {\n          insert(component, replaceConfig, function (p, c) {\n            appendAt(p, c, replaceeIndex);\n          }, r);\n        });\n        return replacee;\n      });\n    };\n    var replaceBy = function (component, replaceConfig, replaceState, replaceePred, replacer) {\n      var children = contents(component);\n      return findIndex(children, replaceePred).bind(function (replaceeIndex) {\n        return replaceAt(component, replaceConfig, replaceState, replaceeIndex, replacer);\n      });\n    };\n\n    var ReplaceApis = /*#__PURE__*/Object.freeze({\n        append: append$2,\n        prepend: prepend$1,\n        remove: remove$7,\n        replaceAt: replaceAt,\n        replaceBy: replaceBy,\n        set: set$5,\n        contents: contents\n    });\n\n    var Replacing = create$1({\n      fields: [],\n      name: 'replacing',\n      apis: ReplaceApis\n    });\n\n    var events$4 = function (name, eventHandlers) {\n      var events = derive(eventHandlers);\n      return create$1({\n        fields: [strict$1('enabled')],\n        name: name,\n        active: { events: constant(events) }\n      });\n    };\n    var config = function (name, eventHandlers) {\n      var me = events$4(name, eventHandlers);\n      return {\n        key: name,\n        value: {\n          config: {},\n          me: me,\n          configAsRaw: constant({}),\n          initialConfig: {},\n          state: NoState\n        }\n      };\n    };\n\n    var focus$2 = function (component, focusConfig) {\n      if (!focusConfig.ignore) {\n        focus$1(component.element());\n        focusConfig.onFocus(component);\n      }\n    };\n    var blur$1 = function (component, focusConfig) {\n      if (!focusConfig.ignore) {\n        blur(component.element());\n      }\n    };\n    var isFocused = function (component) {\n      return hasFocus(component.element());\n    };\n\n    var FocusApis = /*#__PURE__*/Object.freeze({\n        focus: focus$2,\n        blur: blur$1,\n        isFocused: isFocused\n    });\n\n    var exhibit$1 = function (base, focusConfig) {\n      var mod = focusConfig.ignore ? {} : { attributes: { tabindex: '-1' } };\n      return nu$6(mod);\n    };\n    var events$5 = function (focusConfig) {\n      return derive([run(focus(), function (component, simulatedEvent) {\n          focus$2(component, focusConfig);\n          simulatedEvent.stop();\n        })].concat(focusConfig.stopMousedown ? [run(mousedown(), function (_, simulatedEvent) {\n          simulatedEvent.event().prevent();\n        })] : []));\n    };\n\n    var ActiveFocus = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$1,\n        events: events$5\n    });\n\n    var FocusSchema = [\n      onHandler('onFocus'),\n      defaulted$1('stopMousedown', false),\n      defaulted$1('ignore', false)\n    ];\n\n    var Focusing = create$1({\n      fields: FocusSchema,\n      name: 'focusing',\n      active: ActiveFocus,\n      apis: FocusApis\n    });\n\n    var updateAriaState = function (component, toggleConfig, toggleState) {\n      var ariaInfo = toggleConfig.aria;\n      ariaInfo.update(component, ariaInfo, toggleState.get());\n    };\n    var updateClass = function (component, toggleConfig, toggleState) {\n      toggleConfig.toggleClass.each(function (toggleClass) {\n        if (toggleState.get()) {\n          add$2(component.element(), toggleClass);\n        } else {\n          remove$4(component.element(), toggleClass);\n        }\n      });\n    };\n    var toggle = function (component, toggleConfig, toggleState) {\n      set$6(component, toggleConfig, toggleState, !toggleState.get());\n    };\n    var on$1 = function (component, toggleConfig, toggleState) {\n      toggleState.set(true);\n      updateClass(component, toggleConfig, toggleState);\n      updateAriaState(component, toggleConfig, toggleState);\n    };\n    var off = function (component, toggleConfig, toggleState) {\n      toggleState.set(false);\n      updateClass(component, toggleConfig, toggleState);\n      updateAriaState(component, toggleConfig, toggleState);\n    };\n    var set$6 = function (component, toggleConfig, toggleState, state) {\n      var action = state ? on$1 : off;\n      action(component, toggleConfig, toggleState);\n    };\n    var isOn = function (component, toggleConfig, toggleState) {\n      return toggleState.get();\n    };\n    var onLoad$4 = function (component, toggleConfig, toggleState) {\n      set$6(component, toggleConfig, toggleState, toggleConfig.selected);\n    };\n\n    var ToggleApis = /*#__PURE__*/Object.freeze({\n        onLoad: onLoad$4,\n        toggle: toggle,\n        isOn: isOn,\n        on: on$1,\n        off: off,\n        set: set$6\n    });\n\n    var exhibit$2 = function (base, toggleConfig, toggleState) {\n      return nu$6({});\n    };\n    var events$6 = function (toggleConfig, toggleState) {\n      var execute = executeEvent(toggleConfig, toggleState, toggle);\n      var load = loadEvent(toggleConfig, toggleState, onLoad$4);\n      return derive(flatten([\n        toggleConfig.toggleOnExecute ? [execute] : [],\n        [load]\n      ]));\n    };\n\n    var ActiveToggle = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$2,\n        events: events$6\n    });\n\n    var SetupBehaviourCellState = function (initialState) {\n      var init = function () {\n        var cell = Cell(initialState);\n        var get = function () {\n          return cell.get();\n        };\n        var set = function (newState) {\n          return cell.set(newState);\n        };\n        var clear = function () {\n          return cell.set(initialState);\n        };\n        var readState = function () {\n          return cell.get();\n        };\n        return {\n          get: get,\n          set: set,\n          clear: clear,\n          readState: readState\n        };\n      };\n      return { init: init };\n    };\n\n    var updatePressed = function (component, ariaInfo, status) {\n      set$1(component.element(), 'aria-pressed', status);\n      if (ariaInfo.syncWithExpanded) {\n        updateExpanded(component, ariaInfo, status);\n      }\n    };\n    var updateSelected = function (component, ariaInfo, status) {\n      set$1(component.element(), 'aria-selected', status);\n    };\n    var updateChecked = function (component, ariaInfo, status) {\n      set$1(component.element(), 'aria-checked', status);\n    };\n    var updateExpanded = function (component, ariaInfo, status) {\n      set$1(component.element(), 'aria-expanded', status);\n    };\n\n    var ToggleSchema = [\n      defaulted$1('selected', false),\n      option('toggleClass'),\n      defaulted$1('toggleOnExecute', true),\n      defaultedOf('aria', { mode: 'none' }, choose$1('mode', {\n        pressed: [\n          defaulted$1('syncWithExpanded', false),\n          output('update', updatePressed)\n        ],\n        checked: [output('update', updateChecked)],\n        expanded: [output('update', updateExpanded)],\n        selected: [output('update', updateSelected)],\n        none: [output('update', noop)]\n      }))\n    ];\n\n    var Toggling = create$1({\n      fields: ToggleSchema,\n      name: 'toggling',\n      active: ActiveToggle,\n      apis: ToggleApis,\n      state: SetupBehaviourCellState(false)\n    });\n\n    var pointerEvents = function () {\n      var onClick = function (component, simulatedEvent) {\n        simulatedEvent.stop();\n        emitExecute(component);\n      };\n      return [\n        run(click(), onClick),\n        run(tap(), onClick),\n        cutter(touchstart()),\n        cutter(mousedown())\n      ];\n    };\n    var events$7 = function (optAction) {\n      var executeHandler = function (action) {\n        return runOnExecute(function (component, simulatedEvent) {\n          action(component);\n          simulatedEvent.stop();\n        });\n      };\n      return derive(flatten([\n        optAction.map(executeHandler).toArray(),\n        pointerEvents()\n      ]));\n    };\n\n    var hoverEvent = 'alloy.item-hover';\n    var focusEvent = 'alloy.item-focus';\n    var onHover = function (item) {\n      if (search(item.element()).isNone() || Focusing.isFocused(item)) {\n        if (!Focusing.isFocused(item)) {\n          Focusing.focus(item);\n        }\n        emitWith(item, hoverEvent, { item: item });\n      }\n    };\n    var onFocus = function (item) {\n      emitWith(item, focusEvent, { item: item });\n    };\n    var hover = constant(hoverEvent);\n    var focus$3 = constant(focusEvent);\n\n    var builder = function (detail) {\n      return {\n        dom: detail.dom,\n        domModification: __assign(__assign({}, detail.domModification), { attributes: __assign(__assign(__assign({ 'role': detail.toggling.isSome() ? 'menuitemcheckbox' : 'menuitem' }, detail.domModification.attributes), { 'aria-haspopup': detail.hasSubmenu }), detail.hasSubmenu ? { 'aria-expanded': false } : {}) }),\n        behaviours: SketchBehaviours.augment(detail.itemBehaviours, [\n          detail.toggling.fold(Toggling.revoke, function (tConfig) {\n            return Toggling.config(__assign({ aria: { mode: 'checked' } }, tConfig));\n          }),\n          Focusing.config({\n            ignore: detail.ignoreFocus,\n            stopMousedown: detail.ignoreFocus,\n            onFocus: function (component) {\n              onFocus(component);\n            }\n          }),\n          Keying.config({ mode: 'execution' }),\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: detail.data\n            }\n          }),\n          config('item-type-events', __spreadArrays(pointerEvents(), [\n            run(mouseover(), onHover),\n            run(focusItem(), Focusing.focus)\n          ]))\n        ]),\n        components: detail.components,\n        eventOrder: detail.eventOrder\n      };\n    };\n    var schema$a = [\n      strict$1('data'),\n      strict$1('components'),\n      strict$1('dom'),\n      defaulted$1('hasSubmenu', false),\n      option('toggling'),\n      SketchBehaviours.field('itemBehaviours', [\n        Toggling,\n        Focusing,\n        Keying,\n        Representing\n      ]),\n      defaulted$1('ignoreFocus', false),\n      defaulted$1('domModification', {}),\n      output('builder', builder),\n      defaulted$1('eventOrder', {})\n    ];\n\n    var builder$1 = function (detail) {\n      return {\n        dom: detail.dom,\n        components: detail.components,\n        events: derive([stopper(focusItem())])\n      };\n    };\n    var schema$b = [\n      strict$1('dom'),\n      strict$1('components'),\n      output('builder', builder$1)\n    ];\n\n    var owner$2 = function () {\n      return 'item-widget';\n    };\n    var parts = constant([required({\n        name: 'widget',\n        overrides: function (detail) {\n          return {\n            behaviours: derive$1([Representing.config({\n                store: {\n                  mode: 'manual',\n                  getValue: function (component) {\n                    return detail.data;\n                  },\n                  setValue: function () {\n                  }\n                }\n              })])\n          };\n        }\n      })]);\n\n    var builder$2 = function (detail) {\n      var subs = substitutes(owner$2(), detail, parts());\n      var components$1 = components(owner$2(), detail, subs.internals());\n      var focusWidget = function (component) {\n        return getPart(component, detail, 'widget').map(function (widget) {\n          Keying.focusIn(widget);\n          return widget;\n        });\n      };\n      var onHorizontalArrow = function (component, simulatedEvent) {\n        return inside(simulatedEvent.event().target()) ? Option.none() : function () {\n          if (detail.autofocus) {\n            simulatedEvent.setSource(component.element());\n            return Option.none();\n          } else {\n            return Option.none();\n          }\n        }();\n      };\n      return {\n        dom: detail.dom,\n        components: components$1,\n        domModification: detail.domModification,\n        events: derive([\n          runOnExecute(function (component, simulatedEvent) {\n            focusWidget(component).each(function (widget) {\n              simulatedEvent.stop();\n            });\n          }),\n          run(mouseover(), onHover),\n          run(focusItem(), function (component, simulatedEvent) {\n            if (detail.autofocus) {\n              focusWidget(component);\n            } else {\n              Focusing.focus(component);\n            }\n          })\n        ]),\n        behaviours: SketchBehaviours.augment(detail.widgetBehaviours, [\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: detail.data\n            }\n          }),\n          Focusing.config({\n            ignore: detail.ignoreFocus,\n            onFocus: function (component) {\n              onFocus(component);\n            }\n          }),\n          Keying.config({\n            mode: 'special',\n            focusIn: detail.autofocus ? function (component) {\n              focusWidget(component);\n            } : revoke(),\n            onLeft: onHorizontalArrow,\n            onRight: onHorizontalArrow,\n            onEscape: function (component, simulatedEvent) {\n              if (!Focusing.isFocused(component) && !detail.autofocus) {\n                Focusing.focus(component);\n                return Option.some(true);\n              } else if (detail.autofocus) {\n                simulatedEvent.setSource(component.element());\n                return Option.none();\n              } else {\n                return Option.none();\n              }\n            }\n          })\n        ])\n      };\n    };\n    var schema$c = [\n      strict$1('uid'),\n      strict$1('data'),\n      strict$1('components'),\n      strict$1('dom'),\n      defaulted$1('autofocus', false),\n      defaulted$1('ignoreFocus', false),\n      SketchBehaviours.field('widgetBehaviours', [\n        Representing,\n        Focusing,\n        Keying\n      ]),\n      defaulted$1('domModification', {}),\n      defaultUidsSchema(parts()),\n      output('builder', builder$2)\n    ];\n\n    var itemSchema$1 = choose$1('type', {\n      widget: schema$c,\n      item: schema$a,\n      separator: schema$b\n    });\n    var configureGrid = function (detail, movementInfo) {\n      return {\n        mode: 'flatgrid',\n        selector: '.' + detail.markers.item,\n        initSize: {\n          numColumns: movementInfo.initSize.numColumns,\n          numRows: movementInfo.initSize.numRows\n        },\n        focusManager: detail.focusManager\n      };\n    };\n    var configureMatrix = function (detail, movementInfo) {\n      return {\n        mode: 'matrix',\n        selectors: {\n          row: movementInfo.rowSelector,\n          cell: '.' + detail.markers.item\n        },\n        focusManager: detail.focusManager\n      };\n    };\n    var configureMenu = function (detail, movementInfo) {\n      return {\n        mode: 'menu',\n        selector: '.' + detail.markers.item,\n        moveOnTab: movementInfo.moveOnTab,\n        focusManager: detail.focusManager\n      };\n    };\n    var parts$1 = constant([group({\n        factory: {\n          sketch: function (spec) {\n            var itemInfo = asRawOrDie('menu.spec item', itemSchema$1, spec);\n            return itemInfo.builder(itemInfo);\n          }\n        },\n        name: 'items',\n        unit: 'item',\n        defaults: function (detail, u) {\n          return u.hasOwnProperty('uid') ? u : __assign(__assign({}, u), { uid: generate$2('item') });\n        },\n        overrides: function (detail, u) {\n          return {\n            type: u.type,\n            ignoreFocus: detail.fakeFocus,\n            domModification: { classes: [detail.markers.item] }\n          };\n        }\n      })]);\n    var schema$d = constant([\n      strict$1('value'),\n      strict$1('items'),\n      strict$1('dom'),\n      strict$1('components'),\n      defaulted$1('eventOrder', {}),\n      field$1('menuBehaviours', [\n        Highlighting,\n        Representing,\n        Composing,\n        Keying\n      ]),\n      defaultedOf('movement', {\n        mode: 'menu',\n        moveOnTab: true\n      }, choose$1('mode', {\n        grid: [\n          initSize(),\n          output('config', configureGrid)\n        ],\n        matrix: [\n          output('config', configureMatrix),\n          strict$1('rowSelector')\n        ],\n        menu: [\n          defaulted$1('moveOnTab', true),\n          output('config', configureMenu)\n        ]\n      })),\n      itemMarkers(),\n      defaulted$1('fakeFocus', false),\n      defaulted$1('focusManager', dom()),\n      onHandler('onHighlight')\n    ]);\n\n    var focus$4 = constant('alloy.menu-focus');\n\n    var make$1 = function (detail, components, spec, externals) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        markers: detail.markers,\n        behaviours: augment(detail.menuBehaviours, [\n          Highlighting.config({\n            highlightClass: detail.markers.selectedItem,\n            itemClass: detail.markers.item,\n            onHighlight: detail.onHighlight\n          }),\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: detail.value\n            }\n          }),\n          Composing.config({ find: Option.some }),\n          Keying.config(detail.movement.config(detail, detail.movement))\n        ]),\n        events: derive([\n          run(focus$3(), function (menu, simulatedEvent) {\n            var event = simulatedEvent.event();\n            menu.getSystem().getByDom(event.target()).each(function (item) {\n              Highlighting.highlight(menu, item);\n              simulatedEvent.stop();\n              emitWith(menu, focus$4(), {\n                menu: menu,\n                item: item\n              });\n            });\n          }),\n          run(hover(), function (menu, simulatedEvent) {\n            var item = simulatedEvent.event().item();\n            Highlighting.highlight(menu, item);\n          })\n        ]),\n        components: components,\n        eventOrder: detail.eventOrder,\n        domModification: { attributes: { role: 'menu' } }\n      };\n    };\n\n    var Menu = composite$1({\n      name: 'Menu',\n      configFields: schema$d(),\n      partFields: parts$1(),\n      factory: make$1\n    });\n\n    var transpose = function (obj) {\n      return tupleMap(obj, function (v, k) {\n        return {\n          k: v,\n          v: k\n        };\n      });\n    };\n    var trace = function (items, byItem, byMenu, finish) {\n      return readOptFrom$1(byMenu, finish).bind(function (triggerItem) {\n        return readOptFrom$1(items, triggerItem).bind(function (triggerMenu) {\n          var rest = trace(items, byItem, byMenu, triggerMenu);\n          return Option.some([triggerMenu].concat(rest));\n        });\n      }).getOr([]);\n    };\n    var generate$5 = function (menus, expansions) {\n      var items = {};\n      each$1(menus, function (menuItems, menu) {\n        each(menuItems, function (item) {\n          items[item] = menu;\n        });\n      });\n      var byItem = expansions;\n      var byMenu = transpose(expansions);\n      var menuPaths = map$1(byMenu, function (_triggerItem, submenu) {\n        return [submenu].concat(trace(items, byItem, byMenu, submenu));\n      });\n      return map$1(items, function (menu) {\n        return readOptFrom$1(menuPaths, menu).getOr([menu]);\n      });\n    };\n\n    var init$3 = function () {\n      var expansions = Cell({});\n      var menus = Cell({});\n      var paths = Cell({});\n      var primary = Cell(Option.none());\n      var directory = Cell({});\n      var clear = function () {\n        expansions.set({});\n        menus.set({});\n        paths.set({});\n        primary.set(Option.none());\n      };\n      var isClear = function () {\n        return primary.get().isNone();\n      };\n      var setMenuBuilt = function (menuName, built) {\n        var _a;\n        menus.set(__assign(__assign({}, menus.get()), (_a = {}, _a[menuName] = {\n          type: 'prepared',\n          menu: built\n        }, _a)));\n      };\n      var setContents = function (sPrimary, sMenus, sExpansions, dir) {\n        primary.set(Option.some(sPrimary));\n        expansions.set(sExpansions);\n        menus.set(sMenus);\n        directory.set(dir);\n        var sPaths = generate$5(dir, sExpansions);\n        paths.set(sPaths);\n      };\n      var getTriggeringItem = function (menuValue) {\n        return find$1(expansions.get(), function (v, k) {\n          return v === menuValue;\n        });\n      };\n      var getTriggerData = function (menuValue, getItemByValue, path) {\n        return getPreparedMenu(menuValue).bind(function (menu) {\n          return getTriggeringItem(menuValue).bind(function (triggeringItemValue) {\n            return getItemByValue(triggeringItemValue).map(function (triggeredItem) {\n              return {\n                triggeredMenu: menu,\n                triggeringItem: triggeredItem,\n                triggeringPath: path\n              };\n            });\n          });\n        });\n      };\n      var getTriggeringPath = function (itemValue, getItemByValue) {\n        var extraPath = filter(lookupItem(itemValue).toArray(), function (menuValue) {\n          return getPreparedMenu(menuValue).isSome();\n        });\n        return readOptFrom$1(paths.get(), itemValue).bind(function (path) {\n          var revPath = reverse(extraPath.concat(path));\n          var triggers = bind(revPath, function (menuValue, menuIndex) {\n            return getTriggerData(menuValue, getItemByValue, revPath.slice(0, menuIndex + 1)).fold(function () {\n              return primary.get().is(menuValue) ? [] : [Option.none()];\n            }, function (data) {\n              return [Option.some(data)];\n            });\n          });\n          return sequence(triggers);\n        });\n      };\n      var expand = function (itemValue) {\n        return readOptFrom$1(expansions.get(), itemValue).map(function (menu) {\n          var current = readOptFrom$1(paths.get(), itemValue).getOr([]);\n          return [menu].concat(current);\n        });\n      };\n      var collapse = function (itemValue) {\n        return readOptFrom$1(paths.get(), itemValue).bind(function (path) {\n          return path.length > 1 ? Option.some(path.slice(1)) : Option.none();\n        });\n      };\n      var refresh = function (itemValue) {\n        return readOptFrom$1(paths.get(), itemValue);\n      };\n      var getPreparedMenu = function (menuValue) {\n        return lookupMenu(menuValue).bind(extractPreparedMenu);\n      };\n      var lookupMenu = function (menuValue) {\n        return readOptFrom$1(menus.get(), menuValue);\n      };\n      var lookupItem = function (itemValue) {\n        return readOptFrom$1(expansions.get(), itemValue);\n      };\n      var otherMenus = function (path) {\n        var menuValues = directory.get();\n        return difference(keys(menuValues), path);\n      };\n      var getPrimary = function () {\n        return primary.get().bind(getPreparedMenu);\n      };\n      var getMenus = function () {\n        return menus.get();\n      };\n      return {\n        setMenuBuilt: setMenuBuilt,\n        setContents: setContents,\n        expand: expand,\n        refresh: refresh,\n        collapse: collapse,\n        lookupMenu: lookupMenu,\n        lookupItem: lookupItem,\n        otherMenus: otherMenus,\n        getPrimary: getPrimary,\n        getMenus: getMenus,\n        clear: clear,\n        isClear: isClear,\n        getTriggeringPath: getTriggeringPath\n      };\n    };\n    var extractPreparedMenu = function (prep) {\n      return prep.type === 'prepared' ? Option.some(prep.menu) : Option.none();\n    };\n    var LayeredState = {\n      init: init$3,\n      extractPreparedMenu: extractPreparedMenu\n    };\n\n    var make$2 = function (detail, rawUiSpec) {\n      var submenuParentItems = Cell(Option.none());\n      var buildMenus = function (container, primaryName, menus) {\n        return map$1(menus, function (spec, name) {\n          var makeSketch = function () {\n            return Menu.sketch(__assign(__assign({ dom: spec.dom }, spec), {\n              value: name,\n              items: spec.items,\n              markers: detail.markers,\n              fakeFocus: detail.fakeFocus,\n              onHighlight: detail.onHighlight,\n              focusManager: detail.fakeFocus ? highlights() : dom()\n            }));\n          };\n          return name === primaryName ? {\n            type: 'prepared',\n            menu: container.getSystem().build(makeSketch())\n          } : {\n            type: 'notbuilt',\n            nbMenu: makeSketch\n          };\n        });\n      };\n      var layeredState = LayeredState.init();\n      var setup = function (container) {\n        var componentMap = buildMenus(container, detail.data.primary, detail.data.menus);\n        var directory = toDirectory();\n        layeredState.setContents(detail.data.primary, componentMap, detail.data.expansions, directory);\n        return layeredState.getPrimary();\n      };\n      var getItemValue = function (item) {\n        return Representing.getValue(item).value;\n      };\n      var getItemByValue = function (container, menus, itemValue) {\n        return findMap(menus, function (menu) {\n          if (!menu.getSystem().isConnected()) {\n            return Option.none();\n          }\n          var candidates = Highlighting.getCandidates(menu);\n          return find(candidates, function (c) {\n            return getItemValue(c) === itemValue;\n          });\n        });\n      };\n      var toDirectory = function (container) {\n        return map$1(detail.data.menus, function (data, menuName) {\n          return bind(data.items, function (item) {\n            return item.type === 'separator' ? [] : [item.data.value];\n          });\n        });\n      };\n      var setActiveMenu = function (container, menu) {\n        Highlighting.highlight(container, menu);\n        Highlighting.getHighlighted(menu).orThunk(function () {\n          return Highlighting.getFirst(menu);\n        }).each(function (item) {\n          dispatch(container, item.element(), focusItem());\n        });\n      };\n      var getMenus = function (state, menuValues) {\n        return cat(map(menuValues, function (mv) {\n          return state.lookupMenu(mv).bind(function (prep) {\n            return prep.type === 'prepared' ? Option.some(prep.menu) : Option.none();\n          });\n        }));\n      };\n      var closeOthers = function (container, state, path) {\n        var others = getMenus(state, state.otherMenus(path));\n        each(others, function (o) {\n          remove$5(o.element(), [detail.markers.backgroundMenu]);\n          if (!detail.stayInDom) {\n            Replacing.remove(container, o);\n          }\n        });\n      };\n      var getSubmenuParents = function (container) {\n        return submenuParentItems.get().getOrThunk(function () {\n          var r = {};\n          var items = descendants(container.element(), '.' + detail.markers.item);\n          var parentItems = filter(items, function (i) {\n            return get$2(i, 'aria-haspopup') === 'true';\n          });\n          each(parentItems, function (i) {\n            container.getSystem().getByDom(i).each(function (itemComp) {\n              var key = getItemValue(itemComp);\n              r[key] = itemComp;\n            });\n          });\n          submenuParentItems.set(Option.some(r));\n          return r;\n        });\n      };\n      var updateAriaExpansions = function (container, path) {\n        var parentItems = getSubmenuParents(container);\n        each$1(parentItems, function (v, k) {\n          var expanded = contains(path, k);\n          set$1(v.element(), 'aria-expanded', expanded);\n        });\n      };\n      var updateMenuPath = function (container, state, path) {\n        return Option.from(path[0]).bind(function (latestMenuName) {\n          return state.lookupMenu(latestMenuName).bind(function (menuPrep) {\n            if (menuPrep.type === 'notbuilt') {\n              return Option.none();\n            } else {\n              var activeMenu = menuPrep.menu;\n              var rest = getMenus(state, path.slice(1));\n              each(rest, function (r) {\n                add$2(r.element(), detail.markers.backgroundMenu);\n              });\n              if (!inBody(activeMenu.element())) {\n                Replacing.append(container, premade$1(activeMenu));\n              }\n              remove$5(activeMenu.element(), [detail.markers.backgroundMenu]);\n              setActiveMenu(container, activeMenu);\n              closeOthers(container, state, path);\n              return Option.some(activeMenu);\n            }\n          });\n        });\n      };\n      var ExpandHighlightDecision;\n      (function (ExpandHighlightDecision) {\n        ExpandHighlightDecision[ExpandHighlightDecision['HighlightSubmenu'] = 0] = 'HighlightSubmenu';\n        ExpandHighlightDecision[ExpandHighlightDecision['HighlightParent'] = 1] = 'HighlightParent';\n      }(ExpandHighlightDecision || (ExpandHighlightDecision = {})));\n      var buildIfRequired = function (container, menuName, menuPrep) {\n        if (menuPrep.type === 'notbuilt') {\n          var menu = container.getSystem().build(menuPrep.nbMenu());\n          layeredState.setMenuBuilt(menuName, menu);\n          return menu;\n        } else {\n          return menuPrep.menu;\n        }\n      };\n      var expandRight = function (container, item, decision) {\n        if (decision === void 0) {\n          decision = ExpandHighlightDecision.HighlightSubmenu;\n        }\n        var value = getItemValue(item);\n        return layeredState.expand(value).bind(function (path) {\n          updateAriaExpansions(container, path);\n          return Option.from(path[0]).bind(function (menuName) {\n            return layeredState.lookupMenu(menuName).bind(function (activeMenuPrep) {\n              var activeMenu = buildIfRequired(container, menuName, activeMenuPrep);\n              if (!inBody(activeMenu.element())) {\n                Replacing.append(container, premade$1(activeMenu));\n              }\n              detail.onOpenSubmenu(container, item, activeMenu, reverse(path));\n              if (decision === ExpandHighlightDecision.HighlightSubmenu) {\n                Highlighting.highlightFirst(activeMenu);\n                return updateMenuPath(container, layeredState, path);\n              } else {\n                Highlighting.dehighlightAll(activeMenu);\n                return Option.some(item);\n              }\n            });\n          });\n        });\n      };\n      var collapseLeft = function (container, item) {\n        var value = getItemValue(item);\n        return layeredState.collapse(value).bind(function (path) {\n          updateAriaExpansions(container, path);\n          return updateMenuPath(container, layeredState, path).map(function (activeMenu) {\n            detail.onCollapseMenu(container, item, activeMenu);\n            return activeMenu;\n          });\n        });\n      };\n      var updateView = function (container, item) {\n        var value = getItemValue(item);\n        return layeredState.refresh(value).bind(function (path) {\n          updateAriaExpansions(container, path);\n          return updateMenuPath(container, layeredState, path);\n        });\n      };\n      var onRight = function (container, item) {\n        return inside(item.element()) ? Option.none() : expandRight(container, item, ExpandHighlightDecision.HighlightSubmenu);\n      };\n      var onLeft = function (container, item) {\n        return inside(item.element()) ? Option.none() : collapseLeft(container, item);\n      };\n      var onEscape = function (container, item) {\n        return collapseLeft(container, item).orThunk(function () {\n          return detail.onEscape(container, item).map(function () {\n            return container;\n          });\n        });\n      };\n      var keyOnItem = function (f) {\n        return function (container, simulatedEvent) {\n          return closest$3(simulatedEvent.getSource(), '.' + detail.markers.item).bind(function (target) {\n            return container.getSystem().getByDom(target).toOption().bind(function (item) {\n              return f(container, item).map(function () {\n                return true;\n              });\n            });\n          });\n        };\n      };\n      var events = derive([\n        run(focus$4(), function (sandbox, simulatedEvent) {\n          var item = simulatedEvent.event().item();\n          layeredState.lookupItem(getItemValue(item)).each(function () {\n            var menu = simulatedEvent.event().menu();\n            Highlighting.highlight(sandbox, menu);\n            var value = getItemValue(simulatedEvent.event().item());\n            layeredState.refresh(value).each(function (path) {\n              return closeOthers(sandbox, layeredState, path);\n            });\n          });\n        }),\n        runOnExecute(function (component, simulatedEvent) {\n          var target = simulatedEvent.event().target();\n          component.getSystem().getByDom(target).each(function (item) {\n            var itemValue = getItemValue(item);\n            if (itemValue.indexOf('collapse-item') === 0) {\n              collapseLeft(component, item);\n            }\n            expandRight(component, item, ExpandHighlightDecision.HighlightSubmenu).fold(function () {\n              detail.onExecute(component, item);\n            }, function () {\n            });\n          });\n        }),\n        runOnAttached(function (container, simulatedEvent) {\n          setup(container).each(function (primary) {\n            Replacing.append(container, premade$1(primary));\n            detail.onOpenMenu(container, primary);\n            if (detail.highlightImmediately) {\n              setActiveMenu(container, primary);\n            }\n          });\n        })\n      ].concat(detail.navigateOnHover ? [run(hover(), function (sandbox, simulatedEvent) {\n          var item = simulatedEvent.event().item();\n          updateView(sandbox, item);\n          expandRight(sandbox, item, ExpandHighlightDecision.HighlightParent);\n          detail.onHover(sandbox, item);\n        })] : []));\n      var getActiveItem = function (container) {\n        return Highlighting.getHighlighted(container).bind(Highlighting.getHighlighted);\n      };\n      var collapseMenuApi = function (container) {\n        getActiveItem(container).each(function (currentItem) {\n          collapseLeft(container, currentItem);\n        });\n      };\n      var highlightPrimary = function (container) {\n        layeredState.getPrimary().each(function (primary) {\n          setActiveMenu(container, primary);\n        });\n      };\n      var extractMenuFromContainer = function (container) {\n        return Option.from(container.components()[0]).filter(function (comp) {\n          return get$2(comp.element(), 'role') === 'menu';\n        });\n      };\n      var repositionMenus = function (container) {\n        var maybeActivePrimary = layeredState.getPrimary().bind(function (primary) {\n          return getActiveItem(container).bind(function (currentItem) {\n            var itemValue = getItemValue(currentItem);\n            var allMenus = values(layeredState.getMenus());\n            var preparedMenus = cat(map(allMenus, LayeredState.extractPreparedMenu));\n            return layeredState.getTriggeringPath(itemValue, function (v) {\n              return getItemByValue(container, preparedMenus, v);\n            });\n          }).map(function (triggeringPath) {\n            return {\n              primary: primary,\n              triggeringPath: triggeringPath\n            };\n          });\n        });\n        maybeActivePrimary.fold(function () {\n          extractMenuFromContainer(container).each(function (primaryMenu) {\n            detail.onRepositionMenu(container, primaryMenu, []);\n          });\n        }, function (_a) {\n          var primary = _a.primary, triggeringPath = _a.triggeringPath;\n          detail.onRepositionMenu(container, primary, triggeringPath);\n        });\n      };\n      var apis = {\n        collapseMenu: collapseMenuApi,\n        highlightPrimary: highlightPrimary,\n        repositionMenus: repositionMenus\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        markers: detail.markers,\n        behaviours: augment(detail.tmenuBehaviours, [\n          Keying.config({\n            mode: 'special',\n            onRight: keyOnItem(onRight),\n            onLeft: keyOnItem(onLeft),\n            onEscape: keyOnItem(onEscape),\n            focusIn: function (container, keyInfo) {\n              layeredState.getPrimary().each(function (primary) {\n                dispatch(container, primary.element(), focusItem());\n              });\n            }\n          }),\n          Highlighting.config({\n            highlightClass: detail.markers.selectedMenu,\n            itemClass: detail.markers.menu\n          }),\n          Composing.config({\n            find: function (container) {\n              return Highlighting.getHighlighted(container);\n            }\n          }),\n          Replacing.config({})\n        ]),\n        eventOrder: detail.eventOrder,\n        apis: apis,\n        events: events\n      };\n    };\n    var collapseItem = constant('collapse-item');\n\n    var tieredData = function (primary, menus, expansions) {\n      return {\n        primary: primary,\n        menus: menus,\n        expansions: expansions\n      };\n    };\n    var singleData = function (name, menu) {\n      return {\n        primary: name,\n        menus: wrap$1(name, menu),\n        expansions: {}\n      };\n    };\n    var collapseItem$1 = function (text) {\n      return {\n        value: generate$1(collapseItem()),\n        meta: { text: text }\n      };\n    };\n    var tieredMenu = single$2({\n      name: 'TieredMenu',\n      configFields: [\n        onStrictKeyboardHandler('onExecute'),\n        onStrictKeyboardHandler('onEscape'),\n        onStrictHandler('onOpenMenu'),\n        onStrictHandler('onOpenSubmenu'),\n        onStrictHandler('onRepositionMenu'),\n        onHandler('onCollapseMenu'),\n        defaulted$1('highlightImmediately', true),\n        strictObjOf('data', [\n          strict$1('primary'),\n          strict$1('menus'),\n          strict$1('expansions')\n        ]),\n        defaulted$1('fakeFocus', false),\n        onHandler('onHighlight'),\n        onHandler('onHover'),\n        tieredMenuMarkers(),\n        strict$1('dom'),\n        defaulted$1('navigateOnHover', true),\n        defaulted$1('stayInDom', false),\n        field$1('tmenuBehaviours', [\n          Keying,\n          Highlighting,\n          Composing,\n          Replacing\n        ]),\n        defaulted$1('eventOrder', {})\n      ],\n      apis: {\n        collapseMenu: function (apis, tmenu) {\n          apis.collapseMenu(tmenu);\n        },\n        highlightPrimary: function (apis, tmenu) {\n          apis.highlightPrimary(tmenu);\n        },\n        repositionMenus: function (apis, tmenu) {\n          apis.repositionMenus(tmenu);\n        }\n      },\n      factory: make$2,\n      extraApis: {\n        tieredData: tieredData,\n        singleData: singleData,\n        collapseItem: collapseItem$1\n      }\n    });\n\n    var makeMenu = function (detail, menuSandbox, anchor, menuSpec, getBounds) {\n      var lazySink = function () {\n        return detail.lazySink(menuSandbox);\n      };\n      var layouts = menuSpec.type === 'horizontal' ? {\n        layouts: {\n          onLtr: function () {\n            return belowOrAbove();\n          },\n          onRtl: function () {\n            return belowOrAboveRtl();\n          }\n        }\n      } : {};\n      var isFirstTierSubmenu = function (triggeringPaths) {\n        return triggeringPaths.length === 2;\n      };\n      var getSubmenuLayouts = function (triggeringPaths) {\n        return isFirstTierSubmenu(triggeringPaths) ? layouts : {};\n      };\n      return tieredMenu.sketch({\n        dom: { tag: 'div' },\n        data: menuSpec.data,\n        markers: menuSpec.menu.markers,\n        onEscape: function () {\n          Sandboxing.close(menuSandbox);\n          detail.onEscape.map(function (handler) {\n            return handler(menuSandbox);\n          });\n          return Option.some(true);\n        },\n        onExecute: function () {\n          return Option.some(true);\n        },\n        onOpenMenu: function (tmenu, menu) {\n          Positioning.positionWithinBounds(lazySink().getOrDie(), anchor, menu, getBounds());\n        },\n        onOpenSubmenu: function (tmenu, item, submenu, triggeringPaths) {\n          var sink = lazySink().getOrDie();\n          Positioning.position(sink, __assign({\n            anchor: 'submenu',\n            item: item\n          }, getSubmenuLayouts(triggeringPaths)), submenu);\n        },\n        onRepositionMenu: function (tmenu, primaryMenu, submenuTriggers) {\n          var sink = lazySink().getOrDie();\n          Positioning.positionWithinBounds(sink, anchor, primaryMenu, getBounds());\n          each(submenuTriggers, function (st) {\n            var submenuLayouts = getSubmenuLayouts(st.triggeringPath);\n            Positioning.position(sink, __assign({\n              anchor: 'submenu',\n              item: st.triggeringItem\n            }, submenuLayouts), st.triggeredMenu);\n          });\n        }\n      });\n    };\n    var factory = function (detail, spec) {\n      var isPartOfRelated = function (sandbox, queryElem) {\n        var related = detail.getRelated(sandbox);\n        return related.exists(function (rel) {\n          return isPartOf(rel, queryElem);\n        });\n      };\n      var setContent = function (sandbox, thing) {\n        Sandboxing.setContent(sandbox, thing);\n      };\n      var showAt = function (sandbox, anchor, thing) {\n        showWithin(sandbox, anchor, thing, Option.none());\n      };\n      var showWithin = function (sandbox, anchor, thing, boxElement) {\n        showWithinBounds(sandbox, anchor, thing, function () {\n          return boxElement.map(function (elem) {\n            return box(elem);\n          });\n        });\n      };\n      var showWithinBounds = function (sandbox, anchor, thing, getBounds) {\n        var sink = detail.lazySink(sandbox).getOrDie();\n        Sandboxing.openWhileCloaked(sandbox, thing, function () {\n          return Positioning.positionWithinBounds(sink, anchor, sandbox, getBounds());\n        });\n        Representing.setValue(sandbox, Option.some({\n          mode: 'position',\n          anchor: anchor,\n          getBounds: getBounds\n        }));\n      };\n      var showMenuAt = function (sandbox, anchor, menuSpec) {\n        showMenuWithinBounds(sandbox, anchor, menuSpec, function () {\n          return Option.none();\n        });\n      };\n      var showMenuWithinBounds = function (sandbox, anchor, menuSpec, getBounds) {\n        var menu = makeMenu(detail, sandbox, anchor, menuSpec, getBounds);\n        Sandboxing.open(sandbox, menu);\n        Representing.setValue(sandbox, Option.some({\n          mode: 'menu',\n          menu: menu\n        }));\n      };\n      var hide = function (sandbox) {\n        Representing.setValue(sandbox, Option.none());\n        Sandboxing.close(sandbox);\n      };\n      var getContent = function (sandbox) {\n        return Sandboxing.getState(sandbox);\n      };\n      var reposition = function (sandbox) {\n        if (Sandboxing.isOpen(sandbox)) {\n          Representing.getValue(sandbox).each(function (state) {\n            switch (state.mode) {\n            case 'menu':\n              Sandboxing.getState(sandbox).each(function (tmenu) {\n                tieredMenu.repositionMenus(tmenu);\n              });\n              break;\n            case 'position':\n              var sink = detail.lazySink(sandbox).getOrDie();\n              Positioning.positionWithinBounds(sink, state.anchor, sandbox, state.getBounds());\n              break;\n            }\n          });\n        }\n      };\n      var apis = {\n        setContent: setContent,\n        showAt: showAt,\n        showWithin: showWithin,\n        showWithinBounds: showWithinBounds,\n        showMenuAt: showMenuAt,\n        showMenuWithinBounds: showMenuWithinBounds,\n        hide: hide,\n        getContent: getContent,\n        reposition: reposition,\n        isOpen: Sandboxing.isOpen\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        behaviours: augment(detail.inlineBehaviours, [\n          Sandboxing.config({\n            isPartOf: function (sandbox, data, queryElem) {\n              return isPartOf(data, queryElem) || isPartOfRelated(sandbox, queryElem);\n            },\n            getAttachPoint: function (sandbox) {\n              return detail.lazySink(sandbox).getOrDie();\n            },\n            onOpen: function (sandbox) {\n              detail.onShow(sandbox);\n            },\n            onClose: function (sandbox) {\n              detail.onHide(sandbox);\n            }\n          }),\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: Option.none()\n            }\n          }),\n          Receiving.config({\n            channels: __assign(__assign({}, receivingChannel(__assign({ isExtraPart: constant(false) }, detail.fireDismissalEventInstead.map(function (fe) {\n              return { fireEventInstead: { event: fe.event } };\n            }).getOr({})))), receivingChannel$1(__assign(__assign({ isExtraPart: constant(false) }, detail.fireRepositionEventInstead.map(function (fe) {\n              return { fireEventInstead: { event: fe.event } };\n            }).getOr({})), { doReposition: reposition })))\n          })\n        ]),\n        eventOrder: detail.eventOrder,\n        apis: apis\n      };\n    };\n    var InlineView = single$2({\n      name: 'InlineView',\n      configFields: [\n        strict$1('lazySink'),\n        onHandler('onShow'),\n        onHandler('onHide'),\n        optionFunction('onEscape'),\n        field$1('inlineBehaviours', [\n          Sandboxing,\n          Representing,\n          Receiving\n        ]),\n        optionObjOf('fireDismissalEventInstead', [defaulted$1('event', dismissRequested())]),\n        optionObjOf('fireRepositionEventInstead', [defaulted$1('event', repositionRequested())]),\n        defaulted$1('getRelated', Option.none),\n        defaulted$1('eventOrder', Option.none)\n      ],\n      factory: factory,\n      apis: {\n        showAt: function (apis, component, anchor, thing) {\n          apis.showAt(component, anchor, thing);\n        },\n        showWithin: function (apis, component, anchor, thing, boxElement) {\n          apis.showWithin(component, anchor, thing, boxElement);\n        },\n        showWithinBounds: function (apis, component, anchor, thing, bounds) {\n          apis.showWithinBounds(component, anchor, thing, bounds);\n        },\n        showMenuAt: function (apis, component, anchor, menuSpec) {\n          apis.showMenuAt(component, anchor, menuSpec);\n        },\n        showMenuWithinBounds: function (apis, component, anchor, menuSpec, bounds) {\n          apis.showMenuWithinBounds(component, anchor, menuSpec, bounds);\n        },\n        hide: function (apis, component) {\n          apis.hide(component);\n        },\n        isOpen: function (apis, component) {\n          return apis.isOpen(component);\n        },\n        getContent: function (apis, component) {\n          return apis.getContent(component);\n        },\n        setContent: function (apis, component, thing) {\n          apis.setContent(component, thing);\n        },\n        reposition: function (apis, component) {\n          apis.reposition(component);\n        }\n      }\n    });\n\n    var westEdgeX$1 = function (anchor) {\n      return anchor.x();\n    };\n    var middleX$1 = function (anchor, element) {\n      return anchor.x() + anchor.width() / 2 - element.width() / 2;\n    };\n    var eastEdgeX$1 = function (anchor, element) {\n      return anchor.x() + anchor.width() - element.width();\n    };\n    var northY$2 = function (anchor) {\n      return anchor.y();\n    };\n    var southY$2 = function (anchor, element) {\n      return anchor.y() + anchor.height() - element.height();\n    };\n    var southeast$3 = function (anchor, element, bubbles) {\n      return nu$7(westEdgeX$1(anchor), southY$2(anchor, element), bubbles.innerSoutheast(), southeast(), 'layout-se');\n    };\n    var southwest$3 = function (anchor, element, bubbles) {\n      return nu$7(eastEdgeX$1(anchor, element), southY$2(anchor, element), bubbles.innerSouthwest(), southwest(), 'layout-sw');\n    };\n    var northeast$3 = function (anchor, element, bubbles) {\n      return nu$7(westEdgeX$1(anchor), northY$2(anchor), bubbles.innerNortheast(), northeast(), 'layout-ne');\n    };\n    var northwest$3 = function (anchor, element, bubbles) {\n      return nu$7(eastEdgeX$1(anchor, element), northY$2(anchor), bubbles.innerNorthwest(), northwest(), 'layout-nw');\n    };\n    var north$3 = function (anchor, element, bubbles) {\n      return nu$7(middleX$1(anchor, element), northY$2(anchor), bubbles.innerNorth(), north(), 'layout-n');\n    };\n    var south$3 = function (anchor, element, bubbles) {\n      return nu$7(middleX$1(anchor, element), southY$2(anchor, element), bubbles.innerSouth(), south(), 'layout-s');\n    };\n\n    var factory$1 = function (detail) {\n      var events = events$7(detail.action);\n      var tag = detail.dom.tag;\n      var lookupAttr = function (attr) {\n        return readOptFrom$1(detail.dom, 'attributes').bind(function (attrs) {\n          return readOptFrom$1(attrs, attr);\n        });\n      };\n      var getModAttributes = function () {\n        if (tag === 'button') {\n          var type = lookupAttr('type').getOr('button');\n          var roleAttrs = lookupAttr('role').map(function (role) {\n            return { role: role };\n          }).getOr({});\n          return __assign({ type: type }, roleAttrs);\n        } else {\n          var role = lookupAttr('role').getOr('button');\n          return { role: role };\n        }\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: detail.components,\n        events: events,\n        behaviours: SketchBehaviours.augment(detail.buttonBehaviours, [\n          Focusing.config({}),\n          Keying.config({\n            mode: 'execution',\n            useSpace: true,\n            useEnter: true\n          })\n        ]),\n        domModification: { attributes: getModAttributes() },\n        eventOrder: detail.eventOrder\n      };\n    };\n    var Button = single$2({\n      name: 'Button',\n      factory: factory$1,\n      configFields: [\n        defaulted$1('uid', undefined),\n        strict$1('dom'),\n        defaulted$1('components', []),\n        SketchBehaviours.field('buttonBehaviours', [\n          Focusing,\n          Keying\n        ]),\n        option('action'),\n        option('role'),\n        defaulted$1('eventOrder', {})\n      ]\n    });\n\n    var record = function (spec) {\n      var uid = isSketchSpec(spec) && hasKey$1(spec, 'uid') ? spec.uid : generate$2('memento');\n      var get = function (anyInSystem) {\n        return anyInSystem.getSystem().getByUid(uid).getOrDie();\n      };\n      var getOpt = function (anyInSystem) {\n        return anyInSystem.getSystem().getByUid(uid).toOption();\n      };\n      var asSpec = function () {\n        return __assign(__assign({}, spec), { uid: uid });\n      };\n      return {\n        get: get,\n        getOpt: getOpt,\n        asSpec: asSpec\n      };\n    };\n\n    var defaultIcon = function (icons) {\n      return Option.from(icons()['temporary-placeholder']).getOr('!not found!');\n    };\n    var get$c = function (name, icons) {\n      return Option.from(icons()[name]).getOrThunk(function () {\n        return defaultIcon(icons);\n      });\n    };\n    var getOr = function (name, icons, fallback) {\n      return Option.from(icons()[name]).or(fallback).getOrThunk(function () {\n        return defaultIcon(icons);\n      });\n    };\n    var getFirst$1 = function (names, icons) {\n      return findMap(names, function (name) {\n        return Option.from(icons()[name]);\n      }).getOrThunk(function () {\n        return defaultIcon(icons);\n      });\n    };\n\n    var notificationIconMap = {\n      success: 'checkmark',\n      error: 'warning',\n      err: 'error',\n      warning: 'warning',\n      warn: 'warning',\n      info: 'info'\n    };\n    var factory$2 = function (detail) {\n      var memBannerText = record({\n        dom: {\n          tag: 'p',\n          innerHtml: detail.translationProvider(detail.text)\n        },\n        behaviours: derive$1([Replacing.config({})])\n      });\n      var renderPercentBar = function (percent) {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-bar'],\n            attributes: { style: 'width: ' + percent + '%' }\n          }\n        };\n      };\n      var renderPercentText = function (percent) {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-text'],\n            innerHtml: percent + '%'\n          }\n        };\n      };\n      var memBannerProgress = record({\n        dom: {\n          tag: 'div',\n          classes: detail.progress ? [\n            'tox-progress-bar',\n            'tox-progress-indicator'\n          ] : ['tox-progress-bar']\n        },\n        components: [\n          {\n            dom: {\n              tag: 'div',\n              classes: ['tox-bar-container']\n            },\n            components: [renderPercentBar(0)]\n          },\n          renderPercentText(0)\n        ],\n        behaviours: derive$1([Replacing.config({})])\n      });\n      var updateProgress = function (comp, percent) {\n        if (comp.getSystem().isConnected()) {\n          memBannerProgress.getOpt(comp).each(function (progress) {\n            Replacing.set(progress, [\n              {\n                dom: {\n                  tag: 'div',\n                  classes: ['tox-bar-container']\n                },\n                components: [renderPercentBar(percent)]\n              },\n              renderPercentText(percent)\n            ]);\n          });\n        }\n      };\n      var updateText = function (comp, text$1) {\n        if (comp.getSystem().isConnected()) {\n          var banner = memBannerText.get(comp);\n          Replacing.set(banner, [text(text$1)]);\n        }\n      };\n      var apis = {\n        updateProgress: updateProgress,\n        updateText: updateText\n      };\n      var iconChoices = flatten([\n        detail.icon.toArray(),\n        detail.level.toArray(),\n        detail.level.bind(function (level) {\n          return Option.from(notificationIconMap[level]);\n        }).toArray()\n      ]);\n      return {\n        uid: detail.uid,\n        dom: {\n          tag: 'div',\n          attributes: { role: 'alert' },\n          classes: detail.level.map(function (level) {\n            return [\n              'tox-notification',\n              'tox-notification--in',\n              'tox-notification--' + level\n            ];\n          }).getOr([\n            'tox-notification',\n            'tox-notification--in'\n          ])\n        },\n        components: [\n          {\n            dom: {\n              tag: 'div',\n              classes: ['tox-notification__icon'],\n              innerHtml: getFirst$1(iconChoices, detail.iconProvider)\n            }\n          },\n          {\n            dom: {\n              tag: 'div',\n              classes: ['tox-notification__body']\n            },\n            components: [memBannerText.asSpec()],\n            behaviours: derive$1([Replacing.config({})])\n          }\n        ].concat(detail.progress ? [memBannerProgress.asSpec()] : []).concat(Button.sketch({\n          dom: {\n            tag: 'button',\n            classes: [\n              'tox-notification__dismiss',\n              'tox-button',\n              'tox-button--naked',\n              'tox-button--icon'\n            ]\n          },\n          components: [{\n              dom: {\n                tag: 'div',\n                classes: ['tox-icon'],\n                innerHtml: get$c('close', detail.iconProvider),\n                attributes: { 'aria-label': detail.translationProvider('Close') }\n              }\n            }],\n          action: function (comp) {\n            detail.onAction(comp);\n          }\n        })),\n        apis: apis\n      };\n    };\n    var Notification = single$2({\n      name: 'Notification',\n      factory: factory$2,\n      configFields: [\n        option('level'),\n        strict$1('progress'),\n        strict$1('icon'),\n        strict$1('onAction'),\n        strict$1('text'),\n        strict$1('iconProvider'),\n        strict$1('translationProvider')\n      ],\n      apis: {\n        updateProgress: function (apis, comp, percent) {\n          apis.updateProgress(comp, percent);\n        },\n        updateText: function (apis, comp, text) {\n          apis.updateText(comp, text);\n        }\n      }\n    });\n\n    var global$2 = tinymce.util.Tools.resolve('tinymce.util.Delay');\n\n    function NotificationManagerImpl (editor, extras, uiMothership) {\n      var backstage = extras.backstage;\n      var getLayoutDirection = function (rel) {\n        switch (rel) {\n        case 'bc-bc':\n          return south$3;\n        case 'tc-tc':\n          return north$3;\n        case 'tc-bc':\n          return north$1;\n        case 'bc-tc':\n        default:\n          return south$1;\n        }\n      };\n      var prePositionNotifications = function (notifications) {\n        each(notifications, function (notification) {\n          return notification.moveTo(0, 0);\n        });\n      };\n      var positionNotifications = function (notifications) {\n        if (notifications.length > 0) {\n          head(notifications).each(function (firstItem) {\n            return firstItem.moveRel(null, 'banner');\n          });\n          each(notifications, function (notification, index) {\n            if (index > 0) {\n              notification.moveRel(notifications[index - 1].getEl(), 'bc-tc');\n            }\n          });\n        }\n      };\n      var reposition = function (notifications) {\n        prePositionNotifications(notifications);\n        positionNotifications(notifications);\n      };\n      var open = function (settings, closeCallback) {\n        var close = function () {\n          closeCallback();\n          InlineView.hide(notificationWrapper);\n        };\n        var notification = build$1(Notification.sketch({\n          text: settings.text,\n          level: contains([\n            'success',\n            'error',\n            'warning',\n            'warn',\n            'info'\n          ], settings.type) ? settings.type : undefined,\n          progress: settings.progressBar === true,\n          icon: Option.from(settings.icon),\n          onAction: close,\n          iconProvider: backstage.shared.providers.icons,\n          translationProvider: backstage.shared.providers.translate\n        }));\n        var notificationWrapper = build$1(InlineView.sketch({\n          dom: {\n            tag: 'div',\n            classes: ['tox-notifications-container']\n          },\n          lazySink: extras.backstage.shared.getSink,\n          fireDismissalEventInstead: {}\n        }));\n        uiMothership.add(notificationWrapper);\n        if (settings.timeout > 0) {\n          global$2.setTimeout(function () {\n            close();\n          }, settings.timeout);\n        }\n        return {\n          close: close,\n          moveTo: function (x, y) {\n            InlineView.showAt(notificationWrapper, {\n              anchor: 'makeshift',\n              x: x,\n              y: y\n            }, premade$1(notification));\n          },\n          moveRel: function (element, rel) {\n            if (rel !== 'banner') {\n              var layoutDirection_1 = getLayoutDirection(rel);\n              var nodeAnchor = {\n                anchor: 'node',\n                root: body(),\n                node: Option.some(Element.fromDom(element)),\n                layouts: {\n                  onRtl: function () {\n                    return [layoutDirection_1];\n                  },\n                  onLtr: function () {\n                    return [layoutDirection_1];\n                  }\n                }\n              };\n              InlineView.showAt(notificationWrapper, nodeAnchor, premade$1(notification));\n            } else {\n              InlineView.showAt(notificationWrapper, extras.backstage.shared.anchors.banner(), premade$1(notification));\n            }\n          },\n          text: function (nuText) {\n            Notification.updateText(notification, nuText);\n          },\n          settings: settings,\n          getEl: function () {\n            return notification.element().dom();\n          },\n          progressBar: {\n            value: function (percent) {\n              Notification.updateProgress(notification, percent);\n            }\n          }\n        };\n      };\n      var close = function (notification) {\n        notification.close();\n      };\n      var getArgs = function (notification) {\n        return notification.settings;\n      };\n      return {\n        open: open,\n        close: close,\n        reposition: reposition,\n        getArgs: getArgs\n      };\n    }\n\n    var first$1 = function (fn, rate) {\n      var timer = null;\n      var cancel = function () {\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n          timer = null;\n        }\n      };\n      var throttle = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (timer === null) {\n          timer = domGlobals.setTimeout(function () {\n            fn.apply(null, args);\n            timer = null;\n          }, rate);\n        }\n      };\n      return {\n        cancel: cancel,\n        throttle: throttle\n      };\n    };\n    var last$2 = function (fn, rate) {\n      var timer = null;\n      var cancel = function () {\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n          timer = null;\n        }\n      };\n      var throttle = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n        }\n        timer = domGlobals.setTimeout(function () {\n          fn.apply(null, args);\n          timer = null;\n        }, rate);\n      };\n      return {\n        cancel: cancel,\n        throttle: throttle\n      };\n    };\n\n    var global$3 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');\n\n    var isText$1 = function (node) {\n      return node.nodeType === domGlobals.Node.TEXT_NODE;\n    };\n    var isBoundary = function (dom, node) {\n      return dom.isBlock(node) || contains([\n        'BR',\n        'IMG',\n        'HR',\n        'INPUT'\n      ], node.nodeName) || dom.getContentEditable(node) === 'false';\n    };\n    var outcome$1 = Adt.generate([\n      { aborted: [] },\n      { edge: ['element'] },\n      { success: ['info'] }\n    ]);\n    var phase = Adt.generate([\n      { abort: [] },\n      { kontinue: [] },\n      { finish: ['info'] }\n    ]);\n    var repeat = function (dom, node, offset, process, walker, recent) {\n      var terminate = function () {\n        return recent.fold(outcome$1.aborted, outcome$1.edge);\n      };\n      var recurse = function () {\n        var next = walker();\n        if (next) {\n          return repeat(dom, next, Option.none(), process, walker, Option.some(node));\n        } else {\n          return terminate();\n        }\n      };\n      if (isBoundary(dom, node)) {\n        return terminate();\n      } else if (!isText$1(node)) {\n        return recurse();\n      } else {\n        var text = node.textContent;\n        return process(phase, node, text, offset).fold(outcome$1.aborted, function () {\n          return recurse();\n        }, outcome$1.success);\n      }\n    };\n    var repeatLeft = function (dom, node, offset, process, rootNode) {\n      var walker = new global$3(node, rootNode || dom.getRoot());\n      return repeat(dom, node, Option.some(offset), process, walker.prev, Option.none());\n    };\n\n    var autocompleteSelector = '[data-mce-autocompleter]';\n    var create$4 = function (editor, range) {\n      return detect$4(Element.fromDom(editor.selection.getNode())).getOrThunk(function () {\n        var wrapper = Element.fromHtml('<span data-mce-autocompleter=\"1\" data-mce-bogus=\"1\"></span>', editor.getDoc());\n        append(wrapper, Element.fromDom(range.extractContents()));\n        range.insertNode(wrapper.dom());\n        parent(wrapper).each(function (elm) {\n          return elm.dom().normalize();\n        });\n        last$1(wrapper).map(function (last) {\n          editor.selection.setCursorLocation(last.dom(), getEnd(last));\n        });\n        return wrapper;\n      });\n    };\n    var detect$4 = function (elm) {\n      return closest$3(elm, autocompleteSelector);\n    };\n\n    var isValidTextRange = function (rng) {\n      return rng.collapsed && rng.startContainer.nodeType === 3;\n    };\n    var whiteSpace = /[\\u00a0 \\t\\r\\n]/;\n    var parse = function (text, index, ch, minChars) {\n      var i;\n      for (i = index - 1; i >= 0; i--) {\n        var char = text.charAt(i);\n        if (whiteSpace.test(char)) {\n          return Option.none();\n        }\n        if (char === ch) {\n          break;\n        }\n      }\n      if (i === -1 || index - i < minChars) {\n        return Option.none();\n      }\n      return Option.some(text.substring(i + 1, index));\n    };\n    var getText = function (rng, ch) {\n      var text = rng.toString().substring(ch.length);\n      return text.replace(/\\u00A0/g, ' ').replace(/\\uFEFF/g, '');\n    };\n    var findStart = function (dom, initRange, ch, minChars) {\n      if (minChars === void 0) {\n        minChars = 0;\n      }\n      if (!isValidTextRange(initRange)) {\n        return Option.none();\n      }\n      var findTriggerCh = function (phase, element, text, optOffset) {\n        var index = optOffset.getOr(text.length);\n        return parse(text, index, ch, 1).fold(function () {\n          return text.match(whiteSpace) ? phase.abort() : phase.kontinue();\n        }, function (newText) {\n          var range = initRange.cloneRange();\n          range.setStart(element, index - newText.length - 1);\n          range.setEnd(initRange.endContainer, initRange.endOffset);\n          return text.length < minChars ? phase.abort() : phase.finish({\n            text: getText(range, ch),\n            range: range,\n            triggerChar: ch\n          });\n        });\n      };\n      return repeatLeft(dom, initRange.startContainer, initRange.startOffset, findTriggerCh).fold(Option.none, Option.none, Option.some);\n    };\n    var getContext = function (dom, initRange, ch, minChars) {\n      if (minChars === void 0) {\n        minChars = 0;\n      }\n      return detect$4(Element.fromDom(initRange.startContainer)).fold(function () {\n        return findStart(dom, initRange, ch, minChars);\n      }, function (elm) {\n        var range = dom.createRng();\n        range.selectNode(elm.dom());\n        return Option.some({\n          range: range,\n          text: getText(range, ch),\n          triggerChar: ch\n        });\n      });\n    };\n\n    var setup = function (api, editor) {\n      editor.on('keypress compositionend', api.onKeypress.throttle);\n      editor.on('remove', api.onKeypress.cancel);\n      var redirectKeyToItem = function (item, e) {\n        emitWith(item, keydown(), { raw: e });\n      };\n      editor.on('keydown', function (e) {\n        var getItem = function () {\n          return api.getView().bind(Highlighting.getHighlighted);\n        };\n        if (e.which === 8) {\n          api.onKeypress.throttle(e);\n        }\n        if (api.isActive()) {\n          if (e.which === 27) {\n            api.cancelIfNecessary();\n          }\n          if (api.isMenuOpen()) {\n            if (e.which === 13) {\n              getItem().each(emitExecute);\n              e.preventDefault();\n            } else if (e.which === 40) {\n              getItem().fold(function () {\n                api.getView().each(Highlighting.highlightFirst);\n              }, function (item) {\n                redirectKeyToItem(item, e);\n              });\n              e.preventDefault();\n              e.stopImmediatePropagation();\n            } else if (e.which === 37 || e.which === 38 || e.which === 39) {\n              getItem().each(function (item) {\n                redirectKeyToItem(item, e);\n                e.preventDefault();\n                e.stopImmediatePropagation();\n              });\n            }\n          } else {\n            if (e.which === 13 || e.which === 38 || e.which === 40) {\n              api.cancelIfNecessary();\n            }\n          }\n        }\n      });\n      editor.on('NodeChange', function (e) {\n        if (api.isActive() && !api.isProcessingAction() && detect$4(Element.fromDom(e.element)).isNone()) {\n          api.cancelIfNecessary();\n        }\n      });\n    };\n    var AutocompleterEditorEvents = { setup: setup };\n\n    var global$4 = tinymce.util.Tools.resolve('tinymce.util.Promise');\n\n    var point$2 = function (element, offset) {\n      return {\n        element: element,\n        offset: offset\n      };\n    };\n\n    var isText$2 = function (node) {\n      return node.nodeType === domGlobals.Node.TEXT_NODE;\n    };\n    var isElement$1 = function (node) {\n      return node.nodeType === domGlobals.Node.ELEMENT_NODE;\n    };\n    var toLast = function (node) {\n      if (isText$2(node)) {\n        return point$2(node, node.data.length);\n      } else {\n        var children = node.childNodes;\n        return children.length > 0 ? toLast(children[children.length - 1]) : point$2(node, children.length);\n      }\n    };\n    var toLeaf = function (node, offset) {\n      var children = node.childNodes;\n      if (children.length > 0 && offset < children.length) {\n        return toLeaf(children[offset], 0);\n      } else if (children.length > 0 && isElement$1(node) && children.length === offset) {\n        return toLast(children[children.length - 1]);\n      } else {\n        return point$2(node, offset);\n      }\n    };\n\n    var isStartOfWord = function (dom) {\n      var process = function (phase, element, text, optOffset) {\n        var index = optOffset.getOr(text.length);\n        return index === 0 ? phase.kontinue() : phase.finish(/\\s/.test(text.charAt(index - 1)));\n      };\n      return function (rng) {\n        var leaf = toLeaf(rng.startContainer, rng.startOffset);\n        return repeatLeft(dom, leaf.element, leaf.offset, process).fold(constant(true), constant(true), identity);\n      };\n    };\n    var getTriggerContext = function (dom, initRange, database) {\n      return findMap(database.triggerChars, function (ch) {\n        return getContext(dom, initRange, ch);\n      });\n    };\n    var lookup = function (editor, getDatabase) {\n      var database = getDatabase();\n      var rng = editor.selection.getRng();\n      return getTriggerContext(editor.dom, rng, database).bind(function (context) {\n        return lookupWithContext(editor, getDatabase, context);\n      });\n    };\n    var lookupWithContext = function (editor, getDatabase, context, fetchOptions) {\n      if (fetchOptions === void 0) {\n        fetchOptions = {};\n      }\n      var database = getDatabase();\n      var rng = editor.selection.getRng();\n      var startText = rng.startContainer.nodeValue;\n      var autocompleters = filter(database.lookupByChar(context.triggerChar), function (autocompleter) {\n        return context.text.length >= autocompleter.minChars && autocompleter.matches.getOrThunk(function () {\n          return isStartOfWord(editor.dom);\n        })(context.range, startText, context.text);\n      });\n      if (autocompleters.length === 0) {\n        return Option.none();\n      }\n      var lookupData = global$4.all(map(autocompleters, function (ac) {\n        var fetchResult = ac.fetch(context.text, ac.maxResults, fetchOptions);\n        return fetchResult.then(function (results) {\n          return {\n            matchText: context.text,\n            items: results,\n            columns: ac.columns,\n            onAction: ac.onAction\n          };\n        });\n      }));\n      return Option.some({\n        lookupData: lookupData,\n        context: context\n      });\n    };\n\n    var separatorMenuItemSchema = objOf([\n      strictString('type'),\n      optionString('text')\n    ]);\n    var createSeparatorMenuItem = function (spec) {\n      return asRaw('separatormenuitem', separatorMenuItemSchema, spec);\n    };\n\n    var autocompleterItemSchema = objOf([\n      state$1('type', function () {\n        return 'autocompleteitem';\n      }),\n      state$1('active', function () {\n        return false;\n      }),\n      state$1('disabled', function () {\n        return false;\n      }),\n      defaulted$1('meta', {}),\n      strictString('value'),\n      optionString('text'),\n      optionString('icon')\n    ]);\n    var autocompleterSchema = objOf([\n      strictString('type'),\n      strictString('ch'),\n      defaultedNumber('minChars', 1),\n      defaulted$1('columns', 1),\n      defaultedNumber('maxResults', 10),\n      optionFunction('matches'),\n      strictFunction('fetch'),\n      strictFunction('onAction')\n    ]);\n    var createSeparatorItem = function (spec) {\n      return asRaw('Autocompleter.Separator', separatorMenuItemSchema, spec);\n    };\n    var createAutocompleterItem = function (spec) {\n      return asRaw('Autocompleter.Item', autocompleterItemSchema, spec);\n    };\n    var createAutocompleter = function (spec) {\n      return asRaw('Autocompleter', autocompleterSchema, spec);\n    };\n\n    var stringArray = function (a) {\n      var all = {};\n      each(a, function (key) {\n        all[key] = {};\n      });\n      return keys(all);\n    };\n\n    var register = function (editor) {\n      var popups = editor.ui.registry.getAll().popups;\n      var dataset = map$1(popups, function (popup) {\n        return createAutocompleter(popup).fold(function (err) {\n          throw new Error(formatError(err));\n        }, function (x) {\n          return x;\n        });\n      });\n      var triggerChars = stringArray(mapToArray(dataset, function (v) {\n        return v.ch;\n      }));\n      var datasetValues = values(dataset);\n      var lookupByChar = function (ch) {\n        return filter(datasetValues, function (dv) {\n          return dv.ch === ch;\n        });\n      };\n      return {\n        dataset: dataset,\n        triggerChars: triggerChars,\n        lookupByChar: lookupByChar\n      };\n    };\n\n    var commonMenuItemFields = [\n      defaultedBoolean('disabled', false),\n      optionString('text'),\n      optionString('shortcut'),\n      field('value', 'value', defaultedThunk(function () {\n        return generate$1('menuitem-value');\n      }), anyValue$1()),\n      defaulted$1('meta', {})\n    ];\n\n    var menuItemSchema = objOf([\n      strictString('type'),\n      defaultedFunction('onSetup', function () {\n        return noop;\n      }),\n      defaultedFunction('onAction', noop),\n      optionString('icon')\n    ].concat(commonMenuItemFields));\n    var createMenuItem = function (spec) {\n      return asRaw('menuitem', menuItemSchema, spec);\n    };\n\n    var nestedMenuItemSchema = objOf([\n      strictString('type'),\n      strictFunction('getSubmenuItems'),\n      defaultedFunction('onSetup', function () {\n        return noop;\n      }),\n      optionString('icon')\n    ].concat(commonMenuItemFields));\n    var createNestedMenuItem = function (spec) {\n      return asRaw('nestedmenuitem', nestedMenuItemSchema, spec);\n    };\n\n    var toggleMenuItemSchema = objOf([\n      strictString('type'),\n      defaultedBoolean('active', false),\n      defaultedFunction('onSetup', function () {\n        return noop;\n      }),\n      strictFunction('onAction')\n    ].concat(commonMenuItemFields));\n    var createToggleMenuItem = function (spec) {\n      return asRaw('togglemenuitem', toggleMenuItemSchema, spec);\n    };\n\n    var choiceMenuItemSchema = objOf([\n      strictString('type'),\n      defaultedBoolean('active', false),\n      optionString('icon')\n    ].concat(commonMenuItemFields));\n    var createChoiceMenuItem = function (spec) {\n      return asRaw('choicemenuitem', choiceMenuItemSchema, spec);\n    };\n\n    var fancyTypes = [\n      'inserttable',\n      'colorswatch'\n    ];\n    var fancyMenuItemSchema = objOf([\n      strictString('type'),\n      strictStringEnum('fancytype', fancyTypes),\n      defaultedFunction('onAction', noop)\n    ]);\n    var createFancyMenuItem = function (spec) {\n      return asRaw('fancymenuitem', fancyMenuItemSchema, spec);\n    };\n\n    var detectSize = function (comp, margin, selectorClass) {\n      var descendants$1 = descendants(comp.element(), '.' + selectorClass);\n      if (descendants$1.length > 0) {\n        var columnLength = findIndex(descendants$1, function (c) {\n          var thisTop = c.dom().getBoundingClientRect().top;\n          var cTop = descendants$1[0].dom().getBoundingClientRect().top;\n          return Math.abs(thisTop - cTop) > margin;\n        }).getOr(descendants$1.length);\n        return Option.some({\n          numColumns: columnLength,\n          numRows: Math.ceil(descendants$1.length / columnLength)\n        });\n      } else {\n        return Option.none();\n      }\n    };\n\n    var namedEvents = function (name, handlers) {\n      return derive$1([config(name, handlers)]);\n    };\n    var unnamedEvents = function (handlers) {\n      return namedEvents(generate$1('unnamed-events'), handlers);\n    };\n    var SimpleBehaviours = {\n      namedEvents: namedEvents,\n      unnamedEvents: unnamedEvents\n    };\n\n    var TooltippingSchema = [\n      strict$1('lazySink'),\n      strict$1('tooltipDom'),\n      defaulted$1('exclusive', true),\n      defaulted$1('tooltipComponents', []),\n      defaulted$1('delay', 300),\n      defaultedStringEnum('mode', 'normal', [\n        'normal',\n        'follow-highlight'\n      ]),\n      defaulted$1('anchor', function (comp) {\n        return {\n          anchor: 'hotspot',\n          hotspot: comp,\n          layouts: {\n            onLtr: constant([\n              south$1,\n              north$1,\n              southeast$1,\n              northeast$1,\n              southwest$1,\n              northwest$1\n            ]),\n            onRtl: constant([\n              south$1,\n              north$1,\n              southeast$1,\n              northeast$1,\n              southwest$1,\n              northwest$1\n            ])\n          }\n        };\n      }),\n      onHandler('onHide'),\n      onHandler('onShow')\n    ];\n\n    var init$4 = function () {\n      var timer = Cell(Option.none());\n      var popup = Cell(Option.none());\n      var getTooltip = function () {\n        return popup.get();\n      };\n      var setTooltip = function (s) {\n        popup.set(Option.some(s));\n      };\n      var clearTooltip = function () {\n        popup.set(Option.none());\n      };\n      var clearTimer = function () {\n        timer.get().each(function (t) {\n          domGlobals.clearTimeout(t);\n        });\n      };\n      var resetTimer = function (f, delay) {\n        clearTimer();\n        timer.set(Option.some(domGlobals.setTimeout(function () {\n          f();\n        }, delay)));\n      };\n      var isShowing = function () {\n        return popup.get().isSome();\n      };\n      var readState = constant('not-implemented');\n      return nu$5({\n        getTooltip: getTooltip,\n        isShowing: isShowing,\n        setTooltip: setTooltip,\n        clearTooltip: clearTooltip,\n        clearTimer: clearTimer,\n        resetTimer: resetTimer,\n        readState: readState\n      });\n    };\n\n    var TooltippingState = /*#__PURE__*/Object.freeze({\n        init: init$4\n    });\n\n    var ExclusivityChannel = generate$1('tooltip.exclusive');\n    var ShowTooltipEvent = generate$1('tooltip.show');\n    var HideTooltipEvent = generate$1('tooltip.hide');\n\n    var hideAllExclusive = function (component, tConfig, tState) {\n      component.getSystem().broadcastOn([ExclusivityChannel], {});\n    };\n    var setComponents = function (component, tConfig, tState, specs) {\n      tState.getTooltip().each(function (tooltip) {\n        if (tooltip.getSystem().isConnected()) {\n          Replacing.set(tooltip, specs);\n        }\n      });\n    };\n\n    var TooltippingApis = /*#__PURE__*/Object.freeze({\n        hideAllExclusive: hideAllExclusive,\n        setComponents: setComponents\n    });\n\n    var events$8 = function (tooltipConfig, state) {\n      var hide = function (comp) {\n        state.getTooltip().each(function (p) {\n          detach(p);\n          tooltipConfig.onHide(comp, p);\n          state.clearTooltip();\n        });\n        state.clearTimer();\n      };\n      var show = function (comp) {\n        if (!state.isShowing()) {\n          hideAllExclusive(comp);\n          var sink = tooltipConfig.lazySink(comp).getOrDie();\n          var popup = comp.getSystem().build({\n            dom: tooltipConfig.tooltipDom,\n            components: tooltipConfig.tooltipComponents,\n            events: derive(tooltipConfig.mode === 'normal' ? [\n              run(mouseover(), function (_) {\n                emit(comp, ShowTooltipEvent);\n              }),\n              run(mouseout(), function (_) {\n                emit(comp, HideTooltipEvent);\n              })\n            ] : []),\n            behaviours: derive$1([Replacing.config({})])\n          });\n          state.setTooltip(popup);\n          attach$1(sink, popup);\n          tooltipConfig.onShow(comp, popup);\n          Positioning.position(sink, tooltipConfig.anchor(comp), popup);\n        }\n      };\n      return derive(flatten([\n        [\n          run(ShowTooltipEvent, function (comp) {\n            state.resetTimer(function () {\n              show(comp);\n            }, tooltipConfig.delay);\n          }),\n          run(HideTooltipEvent, function (comp) {\n            state.resetTimer(function () {\n              hide(comp);\n            }, tooltipConfig.delay);\n          }),\n          run(receive(), function (comp, message) {\n            var receivingData = message;\n            if (contains(receivingData.channels(), ExclusivityChannel)) {\n              hide(comp);\n            }\n          }),\n          runOnDetached(function (comp) {\n            hide(comp);\n          })\n        ],\n        tooltipConfig.mode === 'normal' ? [\n          run(focusin(), function (comp) {\n            emit(comp, ShowTooltipEvent);\n          }),\n          run(postBlur(), function (comp) {\n            emit(comp, HideTooltipEvent);\n          }),\n          run(mouseover(), function (comp) {\n            emit(comp, ShowTooltipEvent);\n          }),\n          run(mouseout(), function (comp) {\n            emit(comp, HideTooltipEvent);\n          })\n        ] : [\n          run(highlight(), function (comp, se) {\n            emit(comp, ShowTooltipEvent);\n          }),\n          run(dehighlight(), function (comp) {\n            emit(comp, HideTooltipEvent);\n          })\n        ]\n      ]));\n    };\n\n    var ActiveTooltipping = /*#__PURE__*/Object.freeze({\n        events: events$8\n    });\n\n    var Tooltipping = create$1({\n      fields: TooltippingSchema,\n      name: 'tooltipping',\n      active: ActiveTooltipping,\n      state: TooltippingState,\n      apis: TooltippingApis\n    });\n\n    var getAttrs = function (elem) {\n      var attributes = elem.dom().attributes !== undefined ? elem.dom().attributes : [];\n      return foldl(attributes, function (b, attr) {\n        var _a;\n        if (attr.name === 'class') {\n          return b;\n        } else {\n          return __assign(__assign({}, b), (_a = {}, _a[attr.name] = attr.value, _a));\n        }\n      }, {});\n    };\n    var getClasses = function (elem) {\n      return Array.prototype.slice.call(elem.dom().classList, 0);\n    };\n    var fromHtml$2 = function (html) {\n      var elem = Element.fromHtml(html);\n      var children$1 = children(elem);\n      var attrs = getAttrs(elem);\n      var classes = getClasses(elem);\n      var contents = children$1.length === 0 ? {} : { innerHtml: get$1(elem) };\n      return __assign({\n        tag: name(elem),\n        classes: classes,\n        attributes: attrs\n      }, contents);\n    };\n\n    var global$5 = tinymce.util.Tools.resolve('tinymce.util.I18n');\n\n    var navClass = 'tox-menu-nav__js';\n    var selectableClass = 'tox-collection__item';\n    var colorClass = 'tox-swatch';\n    var presetClasses = {\n      normal: navClass,\n      color: colorClass\n    };\n    var tickedClass = 'tox-collection__item--enabled';\n    var groupHeadingClass = 'tox-collection__group-heading';\n    var iconClass = 'tox-collection__item-icon';\n    var textClass = 'tox-collection__item-label';\n    var accessoryClass = 'tox-collection__item-accessory';\n    var caretClass = 'tox-collection__item-caret';\n    var checkmarkClass = 'tox-collection__item-checkmark';\n    var activeClass = 'tox-collection__item--active';\n    var iconClassRtl = 'tox-collection__item-icon-rtl';\n    var classForPreset = function (presets) {\n      return readOptFrom$1(presetClasses, presets).getOr(navClass);\n    };\n\n    var global$6 = tinymce.util.Tools.resolve('tinymce.Env');\n\n    var convertText = function (source) {\n      var mac = {\n        alt: '&#x2325;',\n        ctrl: '&#x2303;',\n        shift: '&#x21E7;',\n        meta: '&#x2318;',\n        access: '&#x2303;&#x2325;'\n      };\n      var other = {\n        meta: 'Ctrl',\n        access: 'Shift+Alt'\n      };\n      var replace = global$6.mac ? mac : other;\n      var shortcut = source.split('+');\n      var updated = map(shortcut, function (segment) {\n        var search = segment.toLowerCase().trim();\n        return has(replace, search) ? replace[search] : segment;\n      });\n      return global$6.mac ? updated.join('') : updated.join('+');\n    };\n    var ConvertShortcut = { convertText: convertText };\n\n    var renderIcon = function (iconHtml) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [iconClass],\n          innerHtml: iconHtml\n        }\n      };\n    };\n    var renderText = function (text$1) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [textClass]\n        },\n        components: [text(global$5.translate(text$1))]\n      };\n    };\n    var renderHtml = function (html) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [textClass],\n          innerHtml: html\n        }\n      };\n    };\n    var renderStyledText = function (style, text$1) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [textClass]\n        },\n        components: [{\n            dom: {\n              tag: style.tag,\n              attributes: { style: style.styleAttr }\n            },\n            components: [text(global$5.translate(text$1))]\n          }]\n      };\n    };\n    var renderShortcut = function (shortcut) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [accessoryClass],\n          innerHtml: ConvertShortcut.convertText(shortcut)\n        }\n      };\n    };\n    var renderCheckmark = function (icons) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [\n            iconClass,\n            checkmarkClass\n          ],\n          innerHtml: get$c('checkmark', icons)\n        }\n      };\n    };\n    var renderSubmenuCaret = function (icons) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [caretClass],\n          innerHtml: get$c('chevron-right', icons)\n        }\n      };\n    };\n    var renderDownwardsCaret = function (icons) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [caretClass],\n          innerHtml: get$c('chevron-down', icons)\n        }\n      };\n    };\n\n    var renderColorStructure = function (itemText, itemValue, iconSvg, providerBackstage) {\n      var colorPickerCommand = 'custom';\n      var removeColorCommand = 'remove';\n      var getDom = function () {\n        var common = colorClass;\n        var icon = iconSvg.getOr('');\n        var title = itemText.map(function (text) {\n          return ' title=\"' + providerBackstage.translate(text) + '\"';\n        }).getOr('');\n        if (itemValue === colorPickerCommand) {\n          return fromHtml$2('<button class=\"' + common + ' tox-swatches__picker-btn\"' + title + '>' + icon + '</button>');\n        } else if (itemValue === removeColorCommand) {\n          return fromHtml$2('<div class=\"' + common + ' tox-swatch--remove\"' + title + '>' + icon + '</div>');\n        } else {\n          return fromHtml$2('<div class=\"' + common + '\" style=\"background-color: ' + itemValue + '\" data-mce-color=\"' + itemValue + '\"' + title + '></div>');\n        }\n      };\n      return {\n        dom: getDom(),\n        optComponents: []\n      };\n    };\n    var renderNormalItemStructure = function (info, icon, renderIcons, textRender, rtlClass) {\n      var leftIcon = renderIcons ? info.checkMark.orThunk(function () {\n        return icon.or(Option.some('')).map(renderIcon);\n      }) : Option.none();\n      var domTitle = info.ariaLabel.map(function (label) {\n        return { attributes: { title: global$5.translate(label) } };\n      }).getOr({});\n      var dom = merge({\n        tag: 'div',\n        classes: [\n          navClass,\n          selectableClass\n        ].concat(rtlClass ? [iconClassRtl] : [])\n      }, domTitle);\n      var content = info.htmlContent.fold(function () {\n        return info.textContent.map(textRender);\n      }, function (html) {\n        return Option.some(renderHtml(html));\n      });\n      var menuItem = {\n        dom: dom,\n        optComponents: [\n          leftIcon,\n          content,\n          info.shortcutContent.map(renderShortcut),\n          info.caret\n        ]\n      };\n      return menuItem;\n    };\n    var rtlIcon = [\n      'list-num-default',\n      'list-num-lower-alpha',\n      'list-num-lower-greek',\n      'list-num-lower-roman',\n      'list-num-upper-alpha',\n      'list-num-upper-roman'\n    ];\n    var rtlTransform = [\n      'list-bull-circle',\n      'list-bull-default',\n      'list-bull-square'\n    ];\n    var renderItemStructure = function (info, providersBackstage, renderIcons, fallbackIcon) {\n      if (fallbackIcon === void 0) {\n        fallbackIcon = Option.none();\n      }\n      var getIconName = function (iconName) {\n        return iconName.map(function (name) {\n          return global$5.isRtl() && contains(rtlIcon, name) ? name + '-rtl' : name;\n        });\n      };\n      var needRtlClass = global$5.isRtl() && info.iconContent.exists(function (name) {\n        return contains(rtlTransform, name);\n      });\n      var icon = getIconName(info.iconContent).map(function (iconName) {\n        return getOr(iconName, providersBackstage.icons, fallbackIcon);\n      });\n      var textRender = Option.from(info.meta).fold(function () {\n        return renderText;\n      }, function (meta) {\n        return has(meta, 'style') ? curry(renderStyledText, meta.style) : renderText;\n      });\n      if (info.presets === 'color') {\n        return renderColorStructure(info.ariaLabel, info.value, icon, providersBackstage);\n      } else {\n        return renderNormalItemStructure(info, icon, renderIcons, textRender, needRtlClass);\n      }\n    };\n\n    var nativeDisabled = [\n      'input',\n      'button',\n      'textarea',\n      'select'\n    ];\n    var onLoad$5 = function (component, disableConfig, disableState) {\n      if (disableConfig.disabled) {\n        disable(component, disableConfig);\n      }\n    };\n    var hasNative = function (component, config) {\n      return config.useNative === true && contains(nativeDisabled, name(component.element()));\n    };\n    var nativeIsDisabled = function (component) {\n      return has$1(component.element(), 'disabled');\n    };\n    var nativeDisable = function (component) {\n      set$1(component.element(), 'disabled', 'disabled');\n    };\n    var nativeEnable = function (component) {\n      remove$1(component.element(), 'disabled');\n    };\n    var ariaIsDisabled = function (component) {\n      return get$2(component.element(), 'aria-disabled') === 'true';\n    };\n    var ariaDisable = function (component) {\n      set$1(component.element(), 'aria-disabled', 'true');\n    };\n    var ariaEnable = function (component) {\n      set$1(component.element(), 'aria-disabled', 'false');\n    };\n    var disable = function (component, disableConfig, disableState) {\n      disableConfig.disableClass.each(function (disableClass) {\n        add$2(component.element(), disableClass);\n      });\n      var f = hasNative(component, disableConfig) ? nativeDisable : ariaDisable;\n      f(component);\n      disableConfig.onDisabled(component);\n    };\n    var enable = function (component, disableConfig, disableState) {\n      disableConfig.disableClass.each(function (disableClass) {\n        remove$4(component.element(), disableClass);\n      });\n      var f = hasNative(component, disableConfig) ? nativeEnable : ariaEnable;\n      f(component);\n      disableConfig.onEnabled(component);\n    };\n    var isDisabled = function (component, disableConfig) {\n      return hasNative(component, disableConfig) ? nativeIsDisabled(component) : ariaIsDisabled(component);\n    };\n    var set$7 = function (component, disableConfig, disableState, disabled) {\n      var f = disabled ? disable : enable;\n      f(component, disableConfig, disableState);\n    };\n\n    var DisableApis = /*#__PURE__*/Object.freeze({\n        enable: enable,\n        disable: disable,\n        isDisabled: isDisabled,\n        onLoad: onLoad$5,\n        set: set$7\n    });\n\n    var exhibit$3 = function (base, disableConfig, disableState) {\n      return nu$6({ classes: disableConfig.disabled ? disableConfig.disableClass.map(pure).getOr([]) : [] });\n    };\n    var events$9 = function (disableConfig, disableState) {\n      return derive([\n        abort(execute(), function (component, simulatedEvent) {\n          return isDisabled(component, disableConfig);\n        }),\n        loadEvent(disableConfig, disableState, onLoad$5)\n      ]);\n    };\n\n    var ActiveDisable = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$3,\n        events: events$9\n    });\n\n    var DisableSchema = [\n      defaulted$1('disabled', false),\n      defaulted$1('useNative', true),\n      option('disableClass'),\n      onHandler('onDisabled'),\n      onHandler('onEnabled')\n    ];\n\n    var Disabling = create$1({\n      fields: DisableSchema,\n      name: 'disabling',\n      active: ActiveDisable,\n      apis: DisableApis\n    });\n\n    var item = function (disabled) {\n      return Disabling.config({\n        disabled: disabled,\n        disableClass: 'tox-collection__item--state-disabled'\n      });\n    };\n    var button = function (disabled) {\n      return Disabling.config({ disabled: disabled });\n    };\n    var splitButton = function (disabled) {\n      return Disabling.config({\n        disabled: disabled,\n        disableClass: 'tox-tbtn--disabled'\n      });\n    };\n    var toolbarButton = function (disabled) {\n      return Disabling.config({\n        disabled: disabled,\n        disableClass: 'tox-tbtn--disabled',\n        useNative: false\n      });\n    };\n    var DisablingConfigs = {\n      item: item,\n      button: button,\n      splitButton: splitButton,\n      toolbarButton: toolbarButton\n    };\n\n    var runWithApi = function (info, comp) {\n      var api = info.getApi(comp);\n      return function (f) {\n        f(api);\n      };\n    };\n    var onControlAttached = function (info, editorOffCell) {\n      return runOnAttached(function (comp) {\n        var run = runWithApi(info, comp);\n        run(function (api) {\n          var onDestroy = info.onSetup(api);\n          if (onDestroy !== null && onDestroy !== undefined) {\n            editorOffCell.set(onDestroy);\n          }\n        });\n      });\n    };\n    var onControlDetached = function (getApi, editorOffCell) {\n      return runOnDetached(function (comp) {\n        return runWithApi(getApi, comp)(editorOffCell.get());\n      });\n    };\n\n    var ItemResponse;\n    (function (ItemResponse) {\n      ItemResponse[ItemResponse['CLOSE_ON_EXECUTE'] = 0] = 'CLOSE_ON_EXECUTE';\n      ItemResponse[ItemResponse['BUBBLE_TO_SANDBOX'] = 1] = 'BUBBLE_TO_SANDBOX';\n    }(ItemResponse || (ItemResponse = {})));\n    var ItemResponse$1 = ItemResponse;\n\n    var onMenuItemExecute = function (info, itemResponse) {\n      return runOnExecute(function (comp, simulatedEvent) {\n        runWithApi(info, comp)(info.onAction);\n        if (!info.triggersSubmenu && itemResponse === ItemResponse$1.CLOSE_ON_EXECUTE) {\n          emit(comp, sandboxClose());\n          simulatedEvent.stop();\n        }\n      });\n    };\n    var menuItemEventOrder = {\n      'alloy.execute': [\n        'disabling',\n        'alloy.base.behaviour',\n        'toggling',\n        'item-events'\n      ]\n    };\n\n    var componentRenderPipeline = function (xs) {\n      return bind(xs, function (o) {\n        return o.toArray();\n      });\n    };\n    var renderCommonItem = function (spec, structure, itemResponse) {\n      var editorOffCell = Cell(noop);\n      return {\n        type: 'item',\n        dom: structure.dom,\n        components: componentRenderPipeline(structure.optComponents),\n        data: spec.data,\n        eventOrder: menuItemEventOrder,\n        hasSubmenu: spec.triggersSubmenu,\n        itemBehaviours: derive$1([\n          config('item-events', [\n            onMenuItemExecute(spec, itemResponse),\n            onControlAttached(spec, editorOffCell),\n            onControlDetached(spec, editorOffCell)\n          ]),\n          DisablingConfigs.item(spec.disabled),\n          Replacing.config({})\n        ].concat(spec.itemBehaviours))\n      };\n    };\n    var buildData = function (source) {\n      return {\n        value: source.value,\n        meta: merge({ text: source.text.getOr('') }, source.meta)\n      };\n    };\n\n    var global$7 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');\n\n    var tooltipBehaviour = function (meta, sharedBackstage) {\n      return get(meta, 'tooltipWorker').map(function (tooltipWorker) {\n        return [Tooltipping.config({\n            lazySink: sharedBackstage.getSink,\n            tooltipDom: {\n              tag: 'div',\n              classes: ['tox-tooltip-worker-container']\n            },\n            tooltipComponents: [],\n            anchor: function (comp) {\n              return {\n                anchor: 'submenu',\n                item: comp,\n                overrides: { maxHeightFunction: expandable }\n              };\n            },\n            mode: 'follow-highlight',\n            onShow: function (component, _tooltip) {\n              tooltipWorker(function (elm) {\n                Tooltipping.setComponents(component, [external({ element: Element.fromDom(elm) })]);\n              });\n            }\n          })];\n      }).getOr([]);\n    };\n    var escapeRegExp = function (text) {\n      return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n    };\n    var encodeText = function (text) {\n      return global$7.DOM.encode(text);\n    };\n    var replaceText = function (text, matchText) {\n      var translated = global$5.translate(text);\n      var encoded = encodeText(translated);\n      if (matchText.length > 0) {\n        var escapedMatchRegex = new RegExp(escapeRegExp(matchText), 'gi');\n        return encoded.replace(escapedMatchRegex, function (match) {\n          return '<span class=\"tox-autocompleter-highlight\">' + match + '</span>';\n        });\n      } else {\n        return encoded;\n      }\n    };\n    var renderAutocompleteItem = function (spec, matchText, useText, presets, onItemValueHandler, itemResponse, sharedBackstage, renderIcons) {\n      if (renderIcons === void 0) {\n        renderIcons = true;\n      }\n      var structure = renderItemStructure({\n        presets: presets,\n        textContent: Option.none(),\n        htmlContent: useText ? spec.text.map(function (text) {\n          return replaceText(text, matchText);\n        }) : Option.none(),\n        ariaLabel: spec.text,\n        iconContent: spec.icon,\n        shortcutContent: Option.none(),\n        checkMark: Option.none(),\n        caret: Option.none(),\n        value: spec.value\n      }, sharedBackstage.providers, renderIcons, spec.icon);\n      return renderCommonItem({\n        data: buildData(spec),\n        disabled: spec.disabled,\n        getApi: function () {\n          return {};\n        },\n        onAction: function (_api) {\n          return onItemValueHandler(spec.value, spec.meta);\n        },\n        onSetup: function () {\n          return function () {\n          };\n        },\n        triggersSubmenu: false,\n        itemBehaviours: tooltipBehaviour(spec.meta, sharedBackstage)\n      }, structure, itemResponse);\n    };\n\n    var renderChoiceItem = function (spec, useText, presets, onItemValueHandler, isSelected, itemResponse, providersBackstage) {\n      var getApi = function (component) {\n        return {\n          setActive: function (state) {\n            Toggling.set(component, state);\n          },\n          isActive: function () {\n            return Toggling.isOn(component);\n          },\n          isDisabled: function () {\n            return Disabling.isDisabled(component);\n          },\n          setDisabled: function (state) {\n            return Disabling.set(component, state);\n          }\n        };\n      };\n      var structure = renderItemStructure({\n        presets: presets,\n        textContent: useText ? spec.text : Option.none(),\n        htmlContent: Option.none(),\n        ariaLabel: spec.text,\n        iconContent: spec.icon,\n        shortcutContent: useText ? spec.shortcut : Option.none(),\n        checkMark: useText ? Option.some(renderCheckmark(providersBackstage.icons)) : Option.none(),\n        caret: Option.none(),\n        value: spec.value\n      }, providersBackstage, true);\n      return deepMerge(renderCommonItem({\n        data: buildData(spec),\n        disabled: spec.disabled,\n        getApi: getApi,\n        onAction: function (_api) {\n          return onItemValueHandler(spec.value);\n        },\n        onSetup: function (api) {\n          api.setActive(isSelected);\n          return function () {\n          };\n        },\n        triggersSubmenu: false,\n        itemBehaviours: []\n      }, structure, itemResponse), {\n        toggling: {\n          toggleClass: tickedClass,\n          toggleOnExecute: false,\n          selected: spec.active\n        }\n      });\n    };\n\n    var parts$2 = constant(generate$4(owner$2(), parts()));\n\n    var cellOverEvent = generate$1('cell-over');\n    var cellExecuteEvent = generate$1('cell-execute');\n    var makeCell = function (row, col, labelId) {\n      var _a;\n      var emitCellOver = function (c) {\n        return emitWith(c, cellOverEvent, {\n          row: row,\n          col: col\n        });\n      };\n      var emitExecute = function (c) {\n        return emitWith(c, cellExecuteEvent, {\n          row: row,\n          col: col\n        });\n      };\n      var onClick = function (c, se) {\n        se.stop();\n        emitExecute(c);\n      };\n      return build$1({\n        dom: {\n          tag: 'div',\n          attributes: (_a = { role: 'button' }, _a['aria-labelledby'] = labelId, _a)\n        },\n        behaviours: derive$1([\n          config('insert-table-picker-cell', [\n            run(mouseover(), Focusing.focus),\n            run(execute(), emitExecute),\n            run(click(), onClick),\n            run(tap(), onClick)\n          ]),\n          Toggling.config({\n            toggleClass: 'tox-insert-table-picker__selected',\n            toggleOnExecute: false\n          }),\n          Focusing.config({ onFocus: emitCellOver })\n        ])\n      });\n    };\n    var makeCells = function (labelId, numRows, numCols) {\n      var cells = [];\n      for (var i = 0; i < numRows; i++) {\n        var row = [];\n        for (var j = 0; j < numCols; j++) {\n          row.push(makeCell(i, j, labelId));\n        }\n        cells.push(row);\n      }\n      return cells;\n    };\n    var selectCells = function (cells, selectedRow, selectedColumn, numRows, numColumns) {\n      for (var i = 0; i < numRows; i++) {\n        for (var j = 0; j < numColumns; j++) {\n          Toggling.set(cells[i][j], i <= selectedRow && j <= selectedColumn);\n        }\n      }\n    };\n    var makeComponents = function (cells) {\n      return bind(cells, function (cellRow) {\n        return map(cellRow, premade$1);\n      });\n    };\n    var makeLabelText = function (row, col) {\n      return text(col + 1 + 'x' + (row + 1));\n    };\n    function renderInsertTableMenuItem(spec) {\n      var numRows = 10;\n      var numColumns = 10;\n      var sizeLabelId = generate$1('size-label');\n      var cells = makeCells(sizeLabelId, numRows, numColumns);\n      var memLabel = record({\n        dom: {\n          tag: 'span',\n          classes: ['tox-insert-table-picker__label'],\n          attributes: { id: sizeLabelId }\n        },\n        components: [text('0x0')],\n        behaviours: derive$1([Replacing.config({})])\n      });\n      return {\n        type: 'widget',\n        data: { value: generate$1('widget-id') },\n        dom: {\n          tag: 'div',\n          classes: ['tox-fancymenuitem']\n        },\n        autofocus: true,\n        components: [parts$2().widget({\n            dom: {\n              tag: 'div',\n              classes: ['tox-insert-table-picker']\n            },\n            components: makeComponents(cells).concat(memLabel.asSpec()),\n            behaviours: derive$1([\n              config('insert-table-picker', [\n                runWithTarget(cellOverEvent, function (c, t, e) {\n                  var row = e.event().row();\n                  var col = e.event().col();\n                  selectCells(cells, row, col, numRows, numColumns);\n                  Replacing.set(memLabel.get(c), [makeLabelText(row, col)]);\n                }),\n                runWithTarget(cellExecuteEvent, function (c, _, e) {\n                  spec.onAction({\n                    numRows: e.event().row() + 1,\n                    numColumns: e.event().col() + 1\n                  });\n                  emit(c, sandboxClose());\n                })\n              ]),\n              Keying.config({\n                initSize: {\n                  numRows: numRows,\n                  numColumns: numColumns\n                },\n                mode: 'flatgrid',\n                selector: '[role=\"button\"]'\n              })\n            ])\n          })]\n      };\n    }\n\n    var hexColour = function (hexString) {\n      return { value: constant(hexString) };\n    };\n    var shorthandRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;\n    var longformRegex = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i;\n    var isHexString = function (hex) {\n      return shorthandRegex.test(hex) || longformRegex.test(hex);\n    };\n    var getLongForm = function (hex) {\n      var hexString = hex.value().replace(shorthandRegex, function (m, r, g, b) {\n        return r + r + g + g + b + b;\n      });\n      return { value: constant(hexString) };\n    };\n    var extractValues = function (hex) {\n      var longForm = getLongForm(hex);\n      var splitForm = longformRegex.exec(longForm.value());\n      return splitForm === null ? [\n        'FFFFFF',\n        'FF',\n        'FF',\n        'FF'\n      ] : splitForm;\n    };\n    var toHex = function (component) {\n      var hex = component.toString(16);\n      return hex.length === 1 ? '0' + hex : hex;\n    };\n    var fromRgba = function (rgbaColour) {\n      var value = toHex(rgbaColour.red()) + toHex(rgbaColour.green()) + toHex(rgbaColour.blue());\n      return hexColour(value);\n    };\n\n    var min = Math.min;\n    var max = Math.max;\n    var round = Math.round;\n    var rgbRegex = /^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)/;\n    var rgbaRegex = /^rgba\\((\\d+),\\s*(\\d+),\\s*(\\d+),\\s*(\\d?(?:\\.\\d+)?)\\)/;\n    var rgbaColour = function (red, green, blue, alpha) {\n      return {\n        red: constant(red),\n        green: constant(green),\n        blue: constant(blue),\n        alpha: constant(alpha)\n      };\n    };\n    var isRgbaComponent = function (value) {\n      var num = parseInt(value, 10);\n      return num.toString() === value && num >= 0 && num <= 255;\n    };\n    var fromHsv = function (hsv) {\n      var r;\n      var g;\n      var b;\n      var hue = (hsv.hue() || 0) % 360;\n      var saturation = hsv.saturation() / 100;\n      var brightness = hsv.value() / 100;\n      saturation = max(0, min(saturation, 1));\n      brightness = max(0, min(brightness, 1));\n      if (saturation === 0) {\n        r = g = b = round(255 * brightness);\n        return rgbaColour(r, g, b, 1);\n      }\n      var side = hue / 60;\n      var chroma = brightness * saturation;\n      var x = chroma * (1 - Math.abs(side % 2 - 1));\n      var match = brightness - chroma;\n      switch (Math.floor(side)) {\n      case 0:\n        r = chroma;\n        g = x;\n        b = 0;\n        break;\n      case 1:\n        r = x;\n        g = chroma;\n        b = 0;\n        break;\n      case 2:\n        r = 0;\n        g = chroma;\n        b = x;\n        break;\n      case 3:\n        r = 0;\n        g = x;\n        b = chroma;\n        break;\n      case 4:\n        r = x;\n        g = 0;\n        b = chroma;\n        break;\n      case 5:\n        r = chroma;\n        g = 0;\n        b = x;\n        break;\n      default:\n        r = g = b = 0;\n      }\n      r = round(255 * (r + match));\n      g = round(255 * (g + match));\n      b = round(255 * (b + match));\n      return rgbaColour(r, g, b, 1);\n    };\n    var fromHex = function (hexColour) {\n      var result = extractValues(hexColour);\n      var red = parseInt(result[1], 16);\n      var green = parseInt(result[2], 16);\n      var blue = parseInt(result[3], 16);\n      return rgbaColour(red, green, blue, 1);\n    };\n    var fromStringValues = function (red, green, blue, alpha) {\n      var r = parseInt(red, 10);\n      var g = parseInt(green, 10);\n      var b = parseInt(blue, 10);\n      var a = parseFloat(alpha);\n      return rgbaColour(r, g, b, a);\n    };\n    var fromString = function (rgbaString) {\n      if (rgbaString === 'transparent') {\n        return Option.some(rgbaColour(0, 0, 0, 0));\n      }\n      var rgbMatch = rgbRegex.exec(rgbaString);\n      if (rgbMatch !== null) {\n        return Option.some(fromStringValues(rgbMatch[1], rgbMatch[2], rgbMatch[3], '1'));\n      }\n      var rgbaMatch = rgbaRegex.exec(rgbaString);\n      if (rgbaMatch !== null) {\n        return Option.some(fromStringValues(rgbaMatch[1], rgbaMatch[2], rgbaMatch[3], rgbaMatch[4]));\n      }\n      return Option.none();\n    };\n    var toString = function (rgba) {\n      return 'rgba(' + rgba.red() + ',' + rgba.green() + ',' + rgba.blue() + ',' + rgba.alpha() + ')';\n    };\n    var redColour = constant(rgbaColour(255, 0, 0, 1));\n\n    var global$8 = tinymce.util.Tools.resolve('tinymce.util.LocalStorage');\n\n    var storageName = 'tinymce-custom-colors';\n    function ColorCache (max) {\n      if (max === void 0) {\n        max = 10;\n      }\n      var storageString = global$8.getItem(storageName);\n      var localstorage = isString(storageString) ? JSON.parse(storageString) : [];\n      var prune = function (list) {\n        var diff = max - list.length;\n        return diff < 0 ? list.slice(0, max) : list;\n      };\n      var cache = prune(localstorage);\n      var add = function (key) {\n        indexOf(cache, key).each(remove);\n        cache.unshift(key);\n        if (cache.length > max) {\n          cache.pop();\n        }\n        global$8.setItem(storageName, JSON.stringify(cache));\n      };\n      var remove = function (idx) {\n        cache.splice(idx, 1);\n      };\n      var state = function () {\n        return cache.slice(0);\n      };\n      return {\n        add: add,\n        state: state\n      };\n    }\n\n    var choiceItem = 'choiceitem';\n    var defaultColors = [\n      {\n        type: choiceItem,\n        text: 'Light Green',\n        value: '#BFEDD2'\n      },\n      {\n        type: choiceItem,\n        text: 'Light Yellow',\n        value: '#FBEEB8'\n      },\n      {\n        type: choiceItem,\n        text: 'Light Red',\n        value: '#F8CAC6'\n      },\n      {\n        type: choiceItem,\n        text: 'Light Purple',\n        value: '#ECCAFA'\n      },\n      {\n        type: choiceItem,\n        text: 'Light Blue',\n        value: '#C2E0F4'\n      },\n      {\n        type: choiceItem,\n        text: 'Green',\n        value: '#2DC26B'\n      },\n      {\n        type: choiceItem,\n        text: 'Yellow',\n        value: '#F1C40F'\n      },\n      {\n        type: choiceItem,\n        text: 'Red',\n        value: '#E03E2D'\n      },\n      {\n        type: choiceItem,\n        text: 'Purple',\n        value: '#B96AD9'\n      },\n      {\n        type: choiceItem,\n        text: 'Blue',\n        value: '#3598DB'\n      },\n      {\n        type: choiceItem,\n        text: 'Dark Turquoise',\n        value: '#169179'\n      },\n      {\n        type: choiceItem,\n        text: 'Orange',\n        value: '#E67E23'\n      },\n      {\n        type: choiceItem,\n        text: 'Dark Red',\n        value: '#BA372A'\n      },\n      {\n        type: choiceItem,\n        text: 'Dark Purple',\n        value: '#843FA1'\n      },\n      {\n        type: choiceItem,\n        text: 'Dark Blue',\n        value: '#236FA1'\n      },\n      {\n        type: choiceItem,\n        text: 'Light Gray',\n        value: '#ECF0F1'\n      },\n      {\n        type: choiceItem,\n        text: 'Medium Gray',\n        value: '#CED4D9'\n      },\n      {\n        type: choiceItem,\n        text: 'Gray',\n        value: '#95A5A6'\n      },\n      {\n        type: choiceItem,\n        text: 'Dark Gray',\n        value: '#7E8C8D'\n      },\n      {\n        type: choiceItem,\n        text: 'Navy Blue',\n        value: '#34495E'\n      },\n      {\n        type: choiceItem,\n        text: 'Black',\n        value: '#000000'\n      },\n      {\n        type: choiceItem,\n        text: 'White',\n        value: '#ffffff'\n      }\n    ];\n    var colorCache = ColorCache(10);\n    var mapColors = function (colorMap) {\n      var colors = [];\n      var canvas = domGlobals.document.createElement('canvas');\n      canvas.height = 1;\n      canvas.width = 1;\n      var ctx = canvas.getContext('2d');\n      var byteAsHex = function (colorByte, alphaByte) {\n        var bg = 255;\n        var alpha = alphaByte / 255;\n        var colorByteWithWhiteBg = Math.round(colorByte * alpha + bg * (1 - alpha));\n        return ('0' + colorByteWithWhiteBg.toString(16)).slice(-2).toUpperCase();\n      };\n      var asHexColor = function (color) {\n        if (/^[0-9A-Fa-f]{6}$/.test(color)) {\n          return '#' + color.toUpperCase();\n        }\n        ctx.clearRect(0, 0, canvas.width, canvas.height);\n        ctx.fillStyle = '#FFFFFF';\n        ctx.fillStyle = color;\n        ctx.fillRect(0, 0, 1, 1);\n        var rgba = ctx.getImageData(0, 0, 1, 1).data;\n        var r = rgba[0], g = rgba[1], b = rgba[2], a = rgba[3];\n        return '#' + byteAsHex(r, a) + byteAsHex(g, a) + byteAsHex(b, a);\n      };\n      for (var i = 0; i < colorMap.length; i += 2) {\n        colors.push({\n          text: colorMap[i + 1],\n          value: asHexColor(colorMap[i]),\n          type: 'choiceitem'\n        });\n      }\n      return colors;\n    };\n    var getColorCols = function (editor, defaultCols) {\n      return editor.getParam('color_cols', defaultCols, 'number');\n    };\n    var hasCustomColors = function (editor) {\n      return editor.getParam('custom_colors') !== false;\n    };\n    var getColorMap = function (editor) {\n      return editor.getParam('color_map');\n    };\n    var getColors = function (editor) {\n      var unmapped = getColorMap(editor);\n      return unmapped !== undefined ? mapColors(unmapped) : defaultColors;\n    };\n    var getCurrentColors = function () {\n      return map(colorCache.state(), function (color) {\n        return {\n          type: choiceItem,\n          text: color,\n          value: color\n        };\n      });\n    };\n    var addColor = function (color) {\n      colorCache.add(color);\n    };\n    var Settings = {\n      mapColors: mapColors,\n      getColorCols: getColorCols,\n      hasCustomColors: hasCustomColors,\n      getColorMap: getColorMap,\n      getColors: getColors,\n      getCurrentColors: getCurrentColors,\n      addColor: addColor\n    };\n\n    var fireSkinLoaded = function (editor) {\n      return editor.fire('SkinLoaded');\n    };\n    var fireResizeEditor = function (editor) {\n      return editor.fire('ResizeEditor');\n    };\n    var fireBeforeRenderUI = function (editor) {\n      return editor.fire('BeforeRenderUI');\n    };\n    var fireResizeContent = function (editor, e) {\n      return editor.fire('ResizeContent', e);\n    };\n    var fireScrollContent = function (editor, e) {\n      return editor.fire('ScrollContent', e);\n    };\n    var fireTextColorChange = function (editor, data) {\n      return editor.fire('TextColorChange', data);\n    };\n    var Events = {\n      fireSkinLoaded: fireSkinLoaded,\n      fireResizeEditor: fireResizeEditor,\n      fireScrollContent: fireScrollContent,\n      fireBeforeRenderUI: fireBeforeRenderUI,\n      fireResizeContent: fireResizeContent,\n      fireTextColorChange: fireTextColorChange\n    };\n\n    var getCurrentColor = function (editor, format) {\n      var color;\n      editor.dom.getParents(editor.selection.getStart(), function (elm) {\n        var value;\n        if (value = elm.style[format === 'forecolor' ? 'color' : 'background-color']) {\n          color = color ? color : value;\n        }\n      });\n      return color;\n    };\n    var applyFormat = function (editor, format, value) {\n      editor.undoManager.transact(function () {\n        editor.focus();\n        editor.formatter.apply(format, { value: value });\n        editor.nodeChanged();\n      });\n    };\n    var removeFormat = function (editor, format) {\n      editor.undoManager.transact(function () {\n        editor.focus();\n        editor.formatter.remove(format, { value: null }, null, true);\n        editor.nodeChanged();\n      });\n    };\n    var registerCommands = function (editor) {\n      editor.addCommand('mceApplyTextcolor', function (format, value) {\n        applyFormat(editor, format, value);\n      });\n      editor.addCommand('mceRemoveTextcolor', function (format) {\n        removeFormat(editor, format);\n      });\n    };\n    var calcCols = function (colors) {\n      return Math.max(5, Math.ceil(Math.sqrt(colors)));\n    };\n    var getColorCols$1 = function (editor) {\n      var colors = Settings.getColors(editor);\n      var defaultCols = calcCols(colors.length);\n      return Settings.getColorCols(editor, defaultCols);\n    };\n    var getAdditionalColors = function (hasCustom) {\n      var type = 'choiceitem';\n      var remove = {\n        type: type,\n        text: 'Remove color',\n        icon: 'color-swatch-remove-color',\n        value: 'remove'\n      };\n      var custom = {\n        type: type,\n        text: 'Custom color',\n        icon: 'color-picker',\n        value: 'custom'\n      };\n      return hasCustom ? [\n        remove,\n        custom\n      ] : [remove];\n    };\n    var applyColor = function (editor, format, value, onChoice) {\n      if (value === 'custom') {\n        var dialog = colorPickerDialog(editor);\n        dialog(function (colorOpt) {\n          colorOpt.each(function (color) {\n            Settings.addColor(color);\n            editor.execCommand('mceApplyTextcolor', format, color);\n            onChoice(color);\n          });\n        }, '#000000');\n      } else if (value === 'remove') {\n        onChoice('');\n        editor.execCommand('mceRemoveTextcolor', format);\n      } else {\n        onChoice(value);\n        editor.execCommand('mceApplyTextcolor', format, value);\n      }\n    };\n    var getMenuColors = function (colors, hasCustom) {\n      return colors.concat(Settings.getCurrentColors().concat(getAdditionalColors(hasCustom)));\n    };\n    var getFetch = function (colors, hasCustom) {\n      return function (callback) {\n        callback(getMenuColors(colors, hasCustom));\n      };\n    };\n    var setIconColor = function (splitButtonApi, name, newColor) {\n      var setIconFillAndStroke = function (pathId, color) {\n        splitButtonApi.setIconFill(pathId, color);\n        splitButtonApi.setIconStroke(pathId, color);\n      };\n      var id = name === 'forecolor' ? 'tox-icon-text-color__color' : 'tox-icon-highlight-bg-color__color';\n      setIconFillAndStroke(id, newColor);\n    };\n    var registerTextColorButton = function (editor, name, format, tooltip, lastColor) {\n      editor.ui.registry.addSplitButton(name, {\n        tooltip: tooltip,\n        presets: 'color',\n        icon: name === 'forecolor' ? 'text-color' : 'highlight-bg-color',\n        select: function (value) {\n          var optCurrentRgb = Option.from(getCurrentColor(editor, format));\n          return optCurrentRgb.bind(function (currentRgb) {\n            return fromString(currentRgb).map(function (rgba) {\n              var currentHex = fromRgba(rgba).value();\n              return contains$1(value.toLowerCase(), currentHex);\n            });\n          }).getOr(false);\n        },\n        columns: getColorCols$1(editor),\n        fetch: getFetch(Settings.getColors(editor), Settings.hasCustomColors(editor)),\n        onAction: function (splitButtonApi) {\n          if (lastColor.get() !== null) {\n            applyColor(editor, format, lastColor.get(), function () {\n            });\n          }\n        },\n        onItemAction: function (splitButtonApi, value) {\n          applyColor(editor, format, value, function (newColor) {\n            lastColor.set(newColor);\n            Events.fireTextColorChange(editor, {\n              name: name,\n              color: newColor\n            });\n          });\n        },\n        onSetup: function (splitButtonApi) {\n          if (lastColor.get() !== null) {\n            setIconColor(splitButtonApi, name, lastColor.get());\n          }\n          var handler = function (e) {\n            if (e.name === name) {\n              setIconColor(splitButtonApi, e.name, e.color);\n            }\n          };\n          editor.on('TextColorChange', handler);\n          return function () {\n            editor.off('TextColorChange', handler);\n          };\n        }\n      });\n    };\n    var registerTextColorMenuItem = function (editor, name, format, text) {\n      editor.ui.registry.addNestedMenuItem(name, {\n        text: text,\n        icon: name === 'forecolor' ? 'text-color' : 'highlight-bg-color',\n        getSubmenuItems: function () {\n          return [{\n              type: 'fancymenuitem',\n              fancytype: 'colorswatch',\n              onAction: function (data) {\n                applyColor(editor, format, data.value, noop);\n              }\n            }];\n        }\n      });\n    };\n    var colorPickerDialog = function (editor) {\n      return function (callback, value) {\n        var getOnSubmit = function (callback) {\n          return function (api) {\n            var data = api.getData();\n            callback(Option.from(data.colorpicker));\n            api.close();\n          };\n        };\n        var onAction = function (api, details) {\n          if (details.name === 'hex-valid') {\n            if (details.value) {\n              api.enable('ok');\n            } else {\n              api.disable('ok');\n            }\n          }\n        };\n        var initialData = { colorpicker: value };\n        var submit = getOnSubmit(callback);\n        editor.windowManager.open({\n          title: 'Color Picker',\n          size: 'normal',\n          body: {\n            type: 'panel',\n            items: [{\n                type: 'colorpicker',\n                name: 'colorpicker',\n                label: 'Color'\n              }]\n          },\n          buttons: [\n            {\n              type: 'cancel',\n              name: 'cancel',\n              text: 'Cancel'\n            },\n            {\n              type: 'submit',\n              name: 'save',\n              text: 'Save',\n              primary: true\n            }\n          ],\n          initialData: initialData,\n          onAction: onAction,\n          onSubmit: submit,\n          onClose: function () {\n          },\n          onCancel: function () {\n            callback(Option.none());\n          }\n        });\n      };\n    };\n    var register$1 = function (editor) {\n      registerCommands(editor);\n      var lastForeColor = Cell(null);\n      var lastBackColor = Cell(null);\n      registerTextColorButton(editor, 'forecolor', 'forecolor', 'Text color', lastForeColor);\n      registerTextColorButton(editor, 'backcolor', 'hilitecolor', 'Background color', lastBackColor);\n      registerTextColorMenuItem(editor, 'forecolor', 'forecolor', 'Text color');\n      registerTextColorMenuItem(editor, 'backcolor', 'hilitecolor', 'Background color');\n    };\n    var ColorSwatch = {\n      register: register$1,\n      getColors: getMenuColors,\n      getFetch: getFetch,\n      colorPickerDialog: colorPickerDialog,\n      getCurrentColor: getCurrentColor,\n      getColorCols: getColorCols$1,\n      calcCols: calcCols\n    };\n\n    var chunk$1 = function (rowDom, numColumns) {\n      return function (items) {\n        var chunks = chunk(items, numColumns);\n        return map(chunks, function (c) {\n          return {\n            dom: rowDom,\n            components: c\n          };\n        });\n      };\n    };\n    var forSwatch = function (columns) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox-menu',\n            'tox-swatches-menu'\n          ]\n        },\n        components: [{\n            dom: {\n              tag: 'div',\n              classes: ['tox-swatches']\n            },\n            components: [Menu.parts().items({\n                preprocess: columns !== 'auto' ? chunk$1({\n                  tag: 'div',\n                  classes: ['tox-swatches__row']\n                }, columns) : identity\n              })]\n          }]\n      };\n    };\n    var forToolbar = function (columns) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox-menu',\n            'tox-collection',\n            'tox-collection--toolbar',\n            'tox-collection--toolbar-lg'\n          ]\n        },\n        components: [Menu.parts().items({\n            preprocess: chunk$1({\n              tag: 'div',\n              classes: ['tox-collection__group']\n            }, columns)\n          })]\n      };\n    };\n    var preprocessCollection = function (items, isSeparator) {\n      var allSplits = [];\n      var currentSplit = [];\n      each(items, function (item, i) {\n        if (isSeparator(item, i)) {\n          if (currentSplit.length > 0) {\n            allSplits.push(currentSplit);\n          }\n          currentSplit = [];\n          if (has(item.dom, 'innerHtml')) {\n            currentSplit.push(item);\n          }\n        } else {\n          currentSplit.push(item);\n        }\n      });\n      if (currentSplit.length > 0) {\n        allSplits.push(currentSplit);\n      }\n      return map(allSplits, function (s) {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-collection__group']\n          },\n          components: s\n        };\n      });\n    };\n    var forCollection = function (columns, initItems, _hasIcons) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox-menu',\n            'tox-collection'\n          ].concat(columns === 1 ? ['tox-collection--list'] : ['tox-collection--grid'])\n        },\n        components: [Menu.parts().items({\n            preprocess: function (items) {\n              if (columns !== 'auto' && columns > 1) {\n                return chunk$1({\n                  tag: 'div',\n                  classes: ['tox-collection__group']\n                }, columns)(items);\n              } else {\n                return preprocessCollection(items, function (_item, i) {\n                  return initItems[i].type === 'separator';\n                });\n              }\n            }\n          })]\n      };\n    };\n    var forHorizontalCollection = function (initItems, _hasIcons) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox-collection',\n            'tox-collection--horizontal'\n          ]\n        },\n        components: [Menu.parts().items({\n            preprocess: function (items) {\n              return preprocessCollection(items, function (_item, i) {\n                return initItems[i].type === 'separator';\n              });\n            }\n          })]\n      };\n    };\n\n    var forMenu = function (presets) {\n      if (presets === 'color') {\n        return 'tox-swatches';\n      } else {\n        return 'tox-menu';\n      }\n    };\n    var classes = function (presets) {\n      return {\n        backgroundMenu: 'tox-background-menu',\n        selectedMenu: 'tox-selected-menu',\n        selectedItem: 'tox-collection__item--active',\n        hasIcons: 'tox-menu--has-icons',\n        menu: forMenu(presets),\n        tieredMenu: 'tox-tiered-menu'\n      };\n    };\n\n    var markers$1 = function (presets) {\n      var menuClasses = classes(presets);\n      return {\n        backgroundMenu: menuClasses.backgroundMenu,\n        selectedMenu: menuClasses.selectedMenu,\n        menu: menuClasses.menu,\n        selectedItem: menuClasses.selectedItem,\n        item: classForPreset(presets)\n      };\n    };\n    var dom$1 = function (hasIcons, columns, presets) {\n      var menuClasses = classes(presets);\n      return {\n        tag: 'div',\n        classes: flatten([\n          [\n            menuClasses.menu,\n            'tox-menu-' + columns + '-column'\n          ],\n          hasIcons ? [menuClasses.hasIcons] : []\n        ])\n      };\n    };\n    var components$1 = [Menu.parts().items({})];\n    var part = function (hasIcons, columns, presets) {\n      var menuClasses = classes(presets);\n      var d = {\n        tag: 'div',\n        classes: flatten([[menuClasses.tieredMenu]])\n      };\n      return {\n        dom: d,\n        markers: markers$1(presets)\n      };\n    };\n\n    var hasIcon = function (item) {\n      return item.icon !== undefined || item.type === 'togglemenuitem' || item.type === 'choicemenuitem';\n    };\n    var menuHasIcons = function (xs) {\n      return exists(xs, hasIcon);\n    };\n    var handleError = function (error) {\n      domGlobals.console.error(formatError(error));\n      domGlobals.console.log(error);\n      return Option.none();\n    };\n    var createHorizontalPartialMenuWithAlloyItems = function (value, _hasIcons, items, _columns, _presets) {\n      var structure = forHorizontalCollection(items);\n      return {\n        value: value,\n        dom: structure.dom,\n        components: structure.components,\n        items: items\n      };\n    };\n    var createPartialMenuWithAlloyItems = function (value, hasIcons, items, columns, presets) {\n      if (presets === 'color') {\n        var structure = forSwatch(columns);\n        return {\n          value: value,\n          dom: structure.dom,\n          components: structure.components,\n          items: items\n        };\n      }\n      if (presets === 'normal' && columns === 'auto') {\n        var structure = forCollection(columns, items);\n        return {\n          value: value,\n          dom: structure.dom,\n          components: structure.components,\n          items: items\n        };\n      }\n      if (presets === 'normal' && columns === 1) {\n        var structure = forCollection(1, items);\n        return {\n          value: value,\n          dom: structure.dom,\n          components: structure.components,\n          items: items\n        };\n      }\n      if (presets === 'normal') {\n        var structure = forCollection(columns, items);\n        return {\n          value: value,\n          dom: structure.dom,\n          components: structure.components,\n          items: items\n        };\n      }\n      if (presets === 'listpreview' && columns !== 'auto') {\n        var structure = forToolbar(columns);\n        return {\n          value: value,\n          dom: structure.dom,\n          components: structure.components,\n          items: items\n        };\n      }\n      return {\n        value: value,\n        dom: dom$1(hasIcons, columns, presets),\n        components: components$1,\n        items: items\n      };\n    };\n\n    var createPartialChoiceMenu = function (value, items, onItemValueHandler, columns, presets, itemResponse, select, providersBackstage) {\n      var hasIcons = menuHasIcons(items);\n      var presetItemTypes = presets !== 'color' ? 'normal' : 'color';\n      var alloyItems = createChoiceItems(items, onItemValueHandler, columns, presetItemTypes, itemResponse, select, providersBackstage);\n      return createPartialMenuWithAlloyItems(value, hasIcons, alloyItems, columns, presets);\n    };\n    var createChoiceItems = function (items, onItemValueHandler, columns, itemPresets, itemResponse, select, providersBackstage) {\n      return cat(map(items, function (item) {\n        if (item.type === 'choiceitem') {\n          return createChoiceMenuItem(item).fold(handleError, function (d) {\n            return Option.some(renderChoiceItem(d, columns === 1, itemPresets, onItemValueHandler, select(item.value), itemResponse, providersBackstage));\n          });\n        } else {\n          return Option.none();\n        }\n      }));\n    };\n\n    var deriveMenuMovement = function (columns, presets) {\n      var menuMarkers = markers$1(presets);\n      if (columns === 1) {\n        return {\n          mode: 'menu',\n          moveOnTab: true\n        };\n      } else if (columns === 'auto') {\n        return {\n          mode: 'grid',\n          selector: '.' + menuMarkers.item,\n          initSize: {\n            numColumns: 1,\n            numRows: 1\n          }\n        };\n      } else {\n        var rowClass = presets === 'color' ? 'tox-swatches__row' : 'tox-collection__group';\n        return {\n          mode: 'matrix',\n          rowSelector: '.' + rowClass\n        };\n      }\n    };\n    var deriveCollectionMovement = function (columns, presets) {\n      if (columns === 1) {\n        return {\n          mode: 'menu',\n          moveOnTab: false,\n          selector: '.tox-collection__item'\n        };\n      } else if (columns === 'auto') {\n        return {\n          mode: 'flatgrid',\n          selector: '.' + 'tox-collection__item',\n          initSize: {\n            numColumns: 1,\n            numRows: 1\n          }\n        };\n      } else {\n        return {\n          mode: 'matrix',\n          selectors: {\n            row: presets === 'color' ? '.tox-swatches__row' : '.tox-collection__group',\n            cell: presets === 'color' ? '.' + colorClass : '.' + selectableClass\n          }\n        };\n      }\n    };\n\n    function renderColorSwatchItem(spec, backstage) {\n      var items = ColorSwatch.getColors(backstage.colorinput.getColors(), backstage.colorinput.hasCustomColors());\n      var columns = backstage.colorinput.getColorCols();\n      var presets = 'color';\n      var menuSpec = createPartialChoiceMenu(generate$1('menu-value'), items, function (value) {\n        spec.onAction({ value: value });\n      }, columns, presets, ItemResponse$1.CLOSE_ON_EXECUTE, function () {\n        return false;\n      }, backstage.shared.providers);\n      var widgetSpec = deepMerge(__assign(__assign({}, menuSpec), {\n        markers: markers$1(presets),\n        movement: deriveMenuMovement(columns, presets)\n      }));\n      return {\n        type: 'widget',\n        data: { value: generate$1('widget-id') },\n        dom: {\n          tag: 'div',\n          classes: ['tox-fancymenuitem']\n        },\n        autofocus: true,\n        components: [parts$2().widget(Menu.sketch(widgetSpec))]\n      };\n    }\n\n    var fancyMenuItems = {\n      inserttable: renderInsertTableMenuItem,\n      colorswatch: renderColorSwatchItem\n    };\n    var valueOpt = function (obj, key) {\n      return Object.prototype.hasOwnProperty.call(obj, key) ? Option.some(obj[key]) : Option.none();\n    };\n    var renderFancyMenuItem = function (spec, backstage) {\n      return valueOpt(fancyMenuItems, spec.fancytype).map(function (render) {\n        return render(spec, backstage);\n      });\n    };\n\n    var renderNormalItem = function (spec, itemResponse, providersBackstage, renderIcons) {\n      if (renderIcons === void 0) {\n        renderIcons = true;\n      }\n      var getApi = function (component) {\n        return {\n          isDisabled: function () {\n            return Disabling.isDisabled(component);\n          },\n          setDisabled: function (state) {\n            return Disabling.set(component, state);\n          }\n        };\n      };\n      var structure = renderItemStructure({\n        presets: 'normal',\n        iconContent: spec.icon,\n        textContent: spec.text,\n        htmlContent: Option.none(),\n        ariaLabel: spec.text,\n        caret: Option.none(),\n        checkMark: Option.none(),\n        shortcutContent: spec.shortcut\n      }, providersBackstage, renderIcons);\n      return renderCommonItem({\n        data: buildData(spec),\n        getApi: getApi,\n        disabled: spec.disabled,\n        onAction: spec.onAction,\n        onSetup: spec.onSetup,\n        triggersSubmenu: false,\n        itemBehaviours: []\n      }, structure, itemResponse);\n    };\n\n    var renderNestedItem = function (spec, itemResponse, providersBackstage, renderIcons, downwardsCaret) {\n      if (renderIcons === void 0) {\n        renderIcons = true;\n      }\n      if (downwardsCaret === void 0) {\n        downwardsCaret = false;\n      }\n      var caret = downwardsCaret ? renderDownwardsCaret(providersBackstage.icons) : renderSubmenuCaret(providersBackstage.icons);\n      var getApi = function (component) {\n        return {\n          isDisabled: function () {\n            return Disabling.isDisabled(component);\n          },\n          setDisabled: function (state) {\n            return Disabling.set(component, state);\n          }\n        };\n      };\n      var structure = renderItemStructure({\n        presets: 'normal',\n        iconContent: spec.icon,\n        textContent: spec.text,\n        htmlContent: Option.none(),\n        ariaLabel: spec.text,\n        caret: Option.some(caret),\n        checkMark: Option.none(),\n        shortcutContent: spec.shortcut\n      }, providersBackstage, renderIcons);\n      return renderCommonItem({\n        data: buildData(spec),\n        getApi: getApi,\n        disabled: spec.disabled,\n        onAction: noop,\n        onSetup: spec.onSetup,\n        triggersSubmenu: true,\n        itemBehaviours: []\n      }, structure, itemResponse);\n    };\n\n    var renderSeparatorItem = function (spec) {\n      var innerHtml = spec.text.fold(function () {\n        return {};\n      }, function (text) {\n        return { innerHtml: text };\n      });\n      return {\n        type: 'separator',\n        dom: __assign({\n          tag: 'div',\n          classes: [\n            selectableClass,\n            groupHeadingClass\n          ]\n        }, innerHtml),\n        components: []\n      };\n    };\n\n    var renderToggleMenuItem = function (spec, itemResponse, providersBackstage) {\n      var getApi = function (component) {\n        return {\n          setActive: function (state) {\n            Toggling.set(component, state);\n          },\n          isActive: function () {\n            return Toggling.isOn(component);\n          },\n          isDisabled: function () {\n            return Disabling.isDisabled(component);\n          },\n          setDisabled: function (state) {\n            return Disabling.set(component, state);\n          }\n        };\n      };\n      var structure = renderItemStructure({\n        iconContent: Option.none(),\n        textContent: spec.text,\n        htmlContent: Option.none(),\n        ariaLabel: spec.text,\n        checkMark: Option.some(renderCheckmark(providersBackstage.icons)),\n        caret: Option.none(),\n        shortcutContent: spec.shortcut,\n        presets: 'normal',\n        meta: spec.meta\n      }, providersBackstage, true);\n      return deepMerge(renderCommonItem({\n        data: buildData(spec),\n        disabled: spec.disabled,\n        getApi: getApi,\n        onAction: spec.onAction,\n        onSetup: spec.onSetup,\n        triggersSubmenu: false,\n        itemBehaviours: []\n      }, structure, itemResponse), {\n        toggling: {\n          toggleClass: tickedClass,\n          toggleOnExecute: false,\n          selected: spec.active\n        }\n      });\n    };\n\n    var autocomplete = renderAutocompleteItem;\n    var separator = renderSeparatorItem;\n    var normal = renderNormalItem;\n    var nested = renderNestedItem;\n    var toggle$1 = renderToggleMenuItem;\n    var fancy = renderFancyMenuItem;\n\n    var FocusMode;\n    (function (FocusMode) {\n      FocusMode[FocusMode['ContentFocus'] = 0] = 'ContentFocus';\n      FocusMode[FocusMode['UiFocus'] = 1] = 'UiFocus';\n    }(FocusMode || (FocusMode = {})));\n    var hasIcon$1 = function (item) {\n      return item.icon !== undefined || item.type === 'togglemenuitem' || item.type === 'choicemenuitem';\n    };\n    var menuHasIcons$1 = function (xs) {\n      return exists(xs, hasIcon$1);\n    };\n    var createMenuItemFromBridge = function (item, itemResponse, backstage, menuHasIcons, isHorizontalMenu) {\n      var providersBackstage = backstage.shared.providers;\n      var parseForHorizontalMenu = function (menuitem) {\n        return !isHorizontalMenu ? menuitem : __assign(__assign({}, menuitem), {\n          shortcut: Option.none(),\n          icon: menuitem.text.isSome() ? Option.none() : menuitem.icon\n        });\n      };\n      switch (item.type) {\n      case 'menuitem':\n        return createMenuItem(item).fold(handleError, function (d) {\n          return Option.some(normal(parseForHorizontalMenu(d), itemResponse, providersBackstage, menuHasIcons));\n        });\n      case 'nestedmenuitem':\n        return createNestedMenuItem(item).fold(handleError, function (d) {\n          return Option.some(nested(parseForHorizontalMenu(d), itemResponse, providersBackstage, menuHasIcons, isHorizontalMenu));\n        });\n      case 'togglemenuitem':\n        return createToggleMenuItem(item).fold(handleError, function (d) {\n          return Option.some(toggle$1(parseForHorizontalMenu(d), itemResponse, providersBackstage));\n        });\n      case 'separator':\n        return createSeparatorMenuItem(item).fold(handleError, function (d) {\n          return Option.some(separator(d));\n        });\n      case 'fancymenuitem':\n        return createFancyMenuItem(item).fold(handleError, function (d) {\n          return fancy(parseForHorizontalMenu(d), backstage);\n        });\n      default: {\n          domGlobals.console.error('Unknown item in general menu', item);\n          return Option.none();\n        }\n      }\n    };\n    var createAutocompleteItems = function (items, matchText, onItemValueHandler, columns, itemResponse, sharedBackstage) {\n      var renderText = columns === 1;\n      var renderIcons = !renderText || menuHasIcons$1(items);\n      return cat(map(items, function (item) {\n        if (item.type === 'separator') {\n          return createSeparatorItem(item).fold(handleError, function (d) {\n            return Option.some(separator(d));\n          });\n        } else {\n          return createAutocompleterItem(item).fold(handleError, function (d) {\n            return Option.some(autocomplete(d, matchText, renderText, 'normal', onItemValueHandler, itemResponse, sharedBackstage, renderIcons));\n          });\n        }\n      }));\n    };\n    var createPartialMenu = function (value, items, itemResponse, backstage, isHorizontalMenu) {\n      var hasIcons = menuHasIcons$1(items);\n      var alloyItems = cat(map(items, function (item) {\n        var itemHasIcon = function (i) {\n          return isHorizontalMenu ? !i.hasOwnProperty('text') : hasIcons;\n        };\n        var createItem = function (i) {\n          return createMenuItemFromBridge(i, itemResponse, backstage, itemHasIcon(i), isHorizontalMenu);\n        };\n        if (item.type === 'nestedmenuitem' && item.getSubmenuItems().length <= 0) {\n          return createItem(merge(item, { disabled: true }));\n        } else {\n          return createItem(item);\n        }\n      }));\n      var createPartial = isHorizontalMenu ? createHorizontalPartialMenuWithAlloyItems : createPartialMenuWithAlloyItems;\n      return createPartial(value, hasIcons, alloyItems, 1, 'normal');\n    };\n    var createTieredDataFrom = function (partialMenu) {\n      return tieredMenu.singleData(partialMenu.value, partialMenu);\n    };\n    var createMenuFrom = function (partialMenu, columns, focusMode, presets) {\n      var focusManager = focusMode === FocusMode.ContentFocus ? highlights() : dom();\n      var movement = deriveMenuMovement(columns, presets);\n      var menuMarkers = markers$1(presets);\n      return {\n        dom: partialMenu.dom,\n        components: partialMenu.components,\n        items: partialMenu.items,\n        value: partialMenu.value,\n        markers: {\n          selectedItem: menuMarkers.selectedItem,\n          item: menuMarkers.item\n        },\n        movement: movement,\n        fakeFocus: focusMode === FocusMode.ContentFocus,\n        focusManager: focusManager,\n        menuBehaviours: SimpleBehaviours.unnamedEvents(columns !== 'auto' ? [] : [runOnAttached(function (comp, se) {\n            detectSize(comp, 4, menuMarkers.item).each(function (_a) {\n              var numColumns = _a.numColumns, numRows = _a.numRows;\n              Keying.setGridSize(comp, numRows, numColumns);\n            });\n          })])\n      };\n    };\n\n    var register$2 = function (editor, sharedBackstage) {\n      var activeAutocompleter = Cell(Option.none());\n      var processingAction = Cell(false);\n      var autocompleter = build$1(InlineView.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-autocompleter']\n        },\n        components: [],\n        fireDismissalEventInstead: {},\n        inlineBehaviours: derive$1([config('dismissAutocompleter', [run(dismissRequested(), function () {\n              return cancelIfNecessary();\n            })])]),\n        lazySink: sharedBackstage.getSink\n      }));\n      var isMenuOpen = function () {\n        return InlineView.isOpen(autocompleter);\n      };\n      var isActive = function () {\n        return activeAutocompleter.get().isSome();\n      };\n      var hideIfNecessary = function () {\n        if (isActive()) {\n          InlineView.hide(autocompleter);\n        }\n      };\n      var cancelIfNecessary = function () {\n        if (isActive()) {\n          var lastElement = activeAutocompleter.get().map(function (ac) {\n            return ac.element;\n          });\n          detect$4(lastElement.getOr(Element.fromDom(editor.selection.getNode()))).each(unwrap);\n          hideIfNecessary();\n          activeAutocompleter.set(Option.none());\n          processingAction.set(false);\n        }\n      };\n      var getAutocompleters = cached(function () {\n        return register(editor);\n      });\n      var getCombinedItems = function (triggerChar, matches) {\n        var columns = findMap(matches, function (m) {\n          return Option.from(m.columns);\n        }).getOr(1);\n        return bind(matches, function (match) {\n          var choices = match.items;\n          return createAutocompleteItems(choices, match.matchText, function (itemValue, itemMeta) {\n            var nr = editor.selection.getRng();\n            getContext(editor.dom, nr, triggerChar).fold(function () {\n              return domGlobals.console.error('Lost context. Cursor probably moved');\n            }, function (_a) {\n              var range = _a.range;\n              var autocompleterApi = {\n                hide: function () {\n                  cancelIfNecessary();\n                },\n                reload: function (fetchOptions) {\n                  hideIfNecessary();\n                  load(fetchOptions);\n                }\n              };\n              processingAction.set(true);\n              match.onAction(autocompleterApi, range, itemValue, itemMeta);\n              processingAction.set(false);\n            });\n          }, columns, ItemResponse$1.BUBBLE_TO_SANDBOX, sharedBackstage);\n        });\n      };\n      var commenceIfNecessary = function (context) {\n        if (!isActive()) {\n          var wrapper = create$4(editor, context.range);\n          activeAutocompleter.set(Option.some({\n            triggerChar: context.triggerChar,\n            element: wrapper,\n            matchLength: context.text.length\n          }));\n          processingAction.set(false);\n        }\n      };\n      var display = function (ac, context, lookupData, items) {\n        ac.matchLength = context.text.length;\n        var columns = findMap(lookupData, function (ld) {\n          return Option.from(ld.columns);\n        }).getOr(1);\n        InlineView.showAt(autocompleter, {\n          anchor: 'node',\n          root: Element.fromDom(editor.getBody()),\n          node: Option.from(ac.element)\n        }, Menu.sketch(createMenuFrom(createPartialMenuWithAlloyItems('autocompleter-value', true, items, columns, 'normal'), columns, FocusMode.ContentFocus, 'normal')));\n        InlineView.getContent(autocompleter).each(Highlighting.highlightFirst);\n      };\n      var doLookup = function (fetchOptions) {\n        return activeAutocompleter.get().map(function (ac) {\n          return getContext(editor.dom, editor.selection.getRng(), ac.triggerChar).bind(function (newContext) {\n            return lookupWithContext(editor, getAutocompleters, newContext, fetchOptions);\n          });\n        }).getOrThunk(function () {\n          return lookup(editor, getAutocompleters);\n        });\n      };\n      var load = function (fetchOptions) {\n        doLookup(fetchOptions).fold(cancelIfNecessary, function (lookupInfo) {\n          commenceIfNecessary(lookupInfo.context);\n          lookupInfo.lookupData.then(function (lookupData) {\n            activeAutocompleter.get().map(function (ac) {\n              var context = lookupInfo.context;\n              if (ac.triggerChar === context.triggerChar) {\n                var combinedItems = getCombinedItems(context.triggerChar, lookupData);\n                if (combinedItems.length > 0) {\n                  display(ac, context, lookupData, combinedItems);\n                } else if (context.text.length - ac.matchLength >= 10) {\n                  cancelIfNecessary();\n                } else {\n                  hideIfNecessary();\n                }\n              }\n            });\n          });\n        });\n      };\n      var onKeypress = last$2(function (e) {\n        if (e.which === 27) {\n          return;\n        }\n        load();\n      }, 50);\n      var autocompleterUiApi = {\n        onKeypress: onKeypress,\n        cancelIfNecessary: cancelIfNecessary,\n        isMenuOpen: isMenuOpen,\n        isActive: isActive,\n        isProcessingAction: processingAction.get,\n        getView: function () {\n          return InlineView.getContent(autocompleter);\n        }\n      };\n      AutocompleterEditorEvents.setup(autocompleterUiApi, editor);\n    };\n    var Autocompleter = { register: register$2 };\n\n    var mkEvent = function (target, x, y, stop, prevent, kill, raw) {\n      return {\n        target: constant(target),\n        x: constant(x),\n        y: constant(y),\n        stop: stop,\n        prevent: prevent,\n        kill: kill,\n        raw: constant(raw)\n      };\n    };\n    var fromRawEvent = function (rawEvent) {\n      var target = Element.fromDom(rawEvent.target);\n      var stop = function () {\n        rawEvent.stopPropagation();\n      };\n      var prevent = function () {\n        rawEvent.preventDefault();\n      };\n      var kill = compose(prevent, stop);\n      return mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent);\n    };\n    var handle = function (filter, handler) {\n      return function (rawEvent) {\n        if (!filter(rawEvent)) {\n          return;\n        }\n        handler(fromRawEvent(rawEvent));\n      };\n    };\n    var binder = function (element, event, filter, handler, useCapture) {\n      var wrapped = handle(filter, handler);\n      element.dom().addEventListener(event, wrapped, useCapture);\n      return { unbind: curry(unbind, element, event, wrapped, useCapture) };\n    };\n    var bind$2 = function (element, event, filter, handler) {\n      return binder(element, event, filter, handler, false);\n    };\n    var capture = function (element, event, filter, handler) {\n      return binder(element, event, filter, handler, true);\n    };\n    var unbind = function (element, event, handler, useCapture) {\n      element.dom().removeEventListener(event, handler, useCapture);\n    };\n\n    var filter$1 = constant(true);\n    var bind$3 = function (element, event, handler) {\n      return bind$2(element, event, filter$1, handler);\n    };\n    var capture$1 = function (element, event, handler) {\n      return capture(element, event, filter$1, handler);\n    };\n    var fromRawEvent$1 = fromRawEvent;\n\n    var closest$4 = function (scope, selector, isRoot) {\n      return closest$3(scope, selector, isRoot).isSome();\n    };\n\n    function DelayedFunction (fun, delay) {\n      var ref = null;\n      var schedule = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        ref = domGlobals.setTimeout(function () {\n          fun.apply(null, args);\n          ref = null;\n        }, delay);\n      };\n      var cancel = function () {\n        if (ref !== null) {\n          domGlobals.clearTimeout(ref);\n          ref = null;\n        }\n      };\n      return {\n        cancel: cancel,\n        schedule: schedule\n      };\n    }\n\n    var SIGNIFICANT_MOVE = 5;\n    var LONGPRESS_DELAY = 400;\n    var getTouch = function (event) {\n      var raw = event.raw();\n      if (raw.touches === undefined || raw.touches.length !== 1) {\n        return Option.none();\n      }\n      return Option.some(raw.touches[0]);\n    };\n    var isFarEnough = function (touch, data) {\n      var distX = Math.abs(touch.clientX - data.x());\n      var distY = Math.abs(touch.clientY - data.y());\n      return distX > SIGNIFICANT_MOVE || distY > SIGNIFICANT_MOVE;\n    };\n    var monitor = function (settings) {\n      var startData = Cell(Option.none());\n      var longpressFired = Cell(false);\n      var longpress$1 = DelayedFunction(function (event) {\n        settings.triggerEvent(longpress(), event);\n        longpressFired.set(true);\n      }, LONGPRESS_DELAY);\n      var handleTouchstart = function (event) {\n        getTouch(event).each(function (touch) {\n          longpress$1.cancel();\n          var data = {\n            x: constant(touch.clientX),\n            y: constant(touch.clientY),\n            target: event.target\n          };\n          longpress$1.schedule(event);\n          longpressFired.set(false);\n          startData.set(Option.some(data));\n        });\n        return Option.none();\n      };\n      var handleTouchmove = function (event) {\n        longpress$1.cancel();\n        getTouch(event).each(function (touch) {\n          startData.get().each(function (data) {\n            if (isFarEnough(touch, data)) {\n              startData.set(Option.none());\n            }\n          });\n        });\n        return Option.none();\n      };\n      var handleTouchend = function (event) {\n        longpress$1.cancel();\n        var isSame = function (data) {\n          return eq(data.target(), event.target());\n        };\n        return startData.get().filter(isSame).map(function (data) {\n          if (longpressFired.get()) {\n            event.prevent();\n            return false;\n          } else {\n            return settings.triggerEvent(tap(), event);\n          }\n        });\n      };\n      var handlers = wrapAll$1([\n        {\n          key: touchstart(),\n          value: handleTouchstart\n        },\n        {\n          key: touchmove(),\n          value: handleTouchmove\n        },\n        {\n          key: touchend(),\n          value: handleTouchend\n        }\n      ]);\n      var fireIfReady = function (event, type) {\n        return readOptFrom$1(handlers, type).bind(function (handler) {\n          return handler(event);\n        });\n      };\n      return { fireIfReady: fireIfReady };\n    };\n\n    var isDangerous = function (event) {\n      var keyEv = event.raw();\n      return keyEv.which === BACKSPACE()[0] && !contains([\n        'input',\n        'textarea'\n      ], name(event.target())) && !closest$4(event.target(), '[contenteditable=\"true\"]');\n    };\n    var isFirefox = detect$3().browser.isFirefox();\n    var settingsSchema = objOfOnly([\n      strictFunction('triggerEvent'),\n      defaulted$1('stopBackspace', true)\n    ]);\n    var bindFocus = function (container, handler) {\n      if (isFirefox) {\n        return capture$1(container, 'focus', handler);\n      } else {\n        return bind$3(container, 'focusin', handler);\n      }\n    };\n    var bindBlur = function (container, handler) {\n      if (isFirefox) {\n        return capture$1(container, 'blur', handler);\n      } else {\n        return bind$3(container, 'focusout', handler);\n      }\n    };\n    var setup$1 = function (container, rawSettings) {\n      var settings = asRawOrDie('Getting GUI events settings', settingsSchema, rawSettings);\n      var pointerEvents = [\n        'touchstart',\n        'touchmove',\n        'touchend',\n        'touchcancel',\n        'gesturestart',\n        'mousedown',\n        'mouseup',\n        'mouseover',\n        'mousemove',\n        'mouseout',\n        'click'\n      ];\n      var tapEvent = monitor(settings);\n      var simpleEvents = map(pointerEvents.concat([\n        'selectstart',\n        'input',\n        'contextmenu',\n        'change',\n        'transitionend',\n        'drag',\n        'dragstart',\n        'dragend',\n        'dragenter',\n        'dragleave',\n        'dragover',\n        'drop',\n        'keyup'\n      ]), function (type) {\n        return bind$3(container, type, function (event) {\n          tapEvent.fireIfReady(event, type).each(function (tapStopped) {\n            if (tapStopped) {\n              event.kill();\n            }\n          });\n          var stopped = settings.triggerEvent(type, event);\n          if (stopped) {\n            event.kill();\n          }\n        });\n      });\n      var pasteTimeout = Cell(Option.none());\n      var onPaste = bind$3(container, 'paste', function (event) {\n        tapEvent.fireIfReady(event, 'paste').each(function (tapStopped) {\n          if (tapStopped) {\n            event.kill();\n          }\n        });\n        var stopped = settings.triggerEvent('paste', event);\n        if (stopped) {\n          event.kill();\n        }\n        pasteTimeout.set(Option.some(domGlobals.setTimeout(function () {\n          settings.triggerEvent(postPaste(), event);\n        }, 0)));\n      });\n      var onKeydown = bind$3(container, 'keydown', function (event) {\n        var stopped = settings.triggerEvent('keydown', event);\n        if (stopped) {\n          event.kill();\n        } else if (settings.stopBackspace === true && isDangerous(event)) {\n          event.prevent();\n        }\n      });\n      var onFocusIn = bindFocus(container, function (event) {\n        var stopped = settings.triggerEvent('focusin', event);\n        if (stopped) {\n          event.kill();\n        }\n      });\n      var focusoutTimeout = Cell(Option.none());\n      var onFocusOut = bindBlur(container, function (event) {\n        var stopped = settings.triggerEvent('focusout', event);\n        if (stopped) {\n          event.kill();\n        }\n        focusoutTimeout.set(Option.some(domGlobals.setTimeout(function () {\n          settings.triggerEvent(postBlur(), event);\n        }, 0)));\n      });\n      var unbind = function () {\n        each(simpleEvents, function (e) {\n          e.unbind();\n        });\n        onKeydown.unbind();\n        onFocusIn.unbind();\n        onFocusOut.unbind();\n        onPaste.unbind();\n        pasteTimeout.get().each(domGlobals.clearTimeout);\n        focusoutTimeout.get().each(domGlobals.clearTimeout);\n      };\n      return { unbind: unbind };\n    };\n\n    var derive$2 = function (rawEvent, rawTarget) {\n      var source = readOptFrom$1(rawEvent, 'target').map(function (getTarget) {\n        return getTarget();\n      }).getOr(rawTarget);\n      return Cell(source);\n    };\n\n    var fromSource = function (event, source) {\n      var stopper = Cell(false);\n      var cutter = Cell(false);\n      var stop = function () {\n        stopper.set(true);\n      };\n      var cut = function () {\n        cutter.set(true);\n      };\n      return {\n        stop: stop,\n        cut: cut,\n        isStopped: stopper.get,\n        isCut: cutter.get,\n        event: constant(event),\n        setSource: source.set,\n        getSource: source.get\n      };\n    };\n    var fromExternal = function (event) {\n      var stopper = Cell(false);\n      var stop = function () {\n        stopper.set(true);\n      };\n      return {\n        stop: stop,\n        cut: noop,\n        isStopped: stopper.get,\n        isCut: constant(false),\n        event: constant(event),\n        setSource: die('Cannot set source of a broadcasted event'),\n        getSource: die('Cannot get source of a broadcasted event')\n      };\n    };\n\n    var adt$b = Adt.generate([\n      { stopped: [] },\n      { resume: ['element'] },\n      { complete: [] }\n    ]);\n    var doTriggerHandler = function (lookup, eventType, rawEvent, target, source, logger) {\n      var handler = lookup(eventType, target);\n      var simulatedEvent = fromSource(rawEvent, source);\n      return handler.fold(function () {\n        logger.logEventNoHandlers(eventType, target);\n        return adt$b.complete();\n      }, function (handlerInfo) {\n        var descHandler = handlerInfo.descHandler();\n        var eventHandler = getCurried(descHandler);\n        eventHandler(simulatedEvent);\n        if (simulatedEvent.isStopped()) {\n          logger.logEventStopped(eventType, handlerInfo.element(), descHandler.purpose());\n          return adt$b.stopped();\n        } else if (simulatedEvent.isCut()) {\n          logger.logEventCut(eventType, handlerInfo.element(), descHandler.purpose());\n          return adt$b.complete();\n        } else {\n          return parent(handlerInfo.element()).fold(function () {\n            logger.logNoParent(eventType, handlerInfo.element(), descHandler.purpose());\n            return adt$b.complete();\n          }, function (parent) {\n            logger.logEventResponse(eventType, handlerInfo.element(), descHandler.purpose());\n            return adt$b.resume(parent);\n          });\n        }\n      });\n    };\n    var doTriggerOnUntilStopped = function (lookup, eventType, rawEvent, rawTarget, source, logger) {\n      return doTriggerHandler(lookup, eventType, rawEvent, rawTarget, source, logger).fold(function () {\n        return true;\n      }, function (parent) {\n        return doTriggerOnUntilStopped(lookup, eventType, rawEvent, parent, source, logger);\n      }, function () {\n        return false;\n      });\n    };\n    var triggerHandler = function (lookup, eventType, rawEvent, target, logger) {\n      var source = derive$2(rawEvent, target);\n      return doTriggerHandler(lookup, eventType, rawEvent, target, source, logger);\n    };\n    var broadcast = function (listeners, rawEvent, logger) {\n      var simulatedEvent = fromExternal(rawEvent);\n      each(listeners, function (listener) {\n        var descHandler = listener.descHandler();\n        var handler = getCurried(descHandler);\n        handler(simulatedEvent);\n      });\n      return simulatedEvent.isStopped();\n    };\n    var triggerUntilStopped = function (lookup, eventType, rawEvent, logger) {\n      var rawTarget = rawEvent.target();\n      return triggerOnUntilStopped(lookup, eventType, rawEvent, rawTarget, logger);\n    };\n    var triggerOnUntilStopped = function (lookup, eventType, rawEvent, rawTarget, logger) {\n      var source = derive$2(rawEvent, rawTarget);\n      return doTriggerOnUntilStopped(lookup, eventType, rawEvent, rawTarget, source, logger);\n    };\n\n    var eventHandler = Immutable('element', 'descHandler');\n    var broadcastHandler = function (id, handler) {\n      return {\n        id: constant(id),\n        descHandler: constant(handler)\n      };\n    };\n    function EventRegistry () {\n      var registry = {};\n      var registerId = function (extraArgs, id, events) {\n        each$1(events, function (v, k) {\n          var handlers = registry[k] !== undefined ? registry[k] : {};\n          handlers[id] = curryArgs(v, extraArgs);\n          registry[k] = handlers;\n        });\n      };\n      var findHandler = function (handlers, elem) {\n        return read$1(elem).fold(function () {\n          return Option.none();\n        }, function (id) {\n          var reader = readOpt$1(id);\n          return handlers.bind(reader).map(function (descHandler) {\n            return eventHandler(elem, descHandler);\n          });\n        });\n      };\n      var filterByType = function (type) {\n        return readOptFrom$1(registry, type).map(function (handlers) {\n          return mapToArray(handlers, function (f, id) {\n            return broadcastHandler(id, f);\n          });\n        }).getOr([]);\n      };\n      var find = function (isAboveRoot, type, target) {\n        var readType = readOpt$1(type);\n        var handlers = readType(registry);\n        return closest$1(target, function (elem) {\n          return findHandler(handlers, elem);\n        }, isAboveRoot);\n      };\n      var unregisterId = function (id) {\n        each$1(registry, function (handlersById, eventName) {\n          if (handlersById.hasOwnProperty(id)) {\n            delete handlersById[id];\n          }\n        });\n      };\n      return {\n        registerId: registerId,\n        unregisterId: unregisterId,\n        filterByType: filterByType,\n        find: find\n      };\n    }\n\n    function Registry () {\n      var events = EventRegistry();\n      var components = {};\n      var readOrTag = function (component) {\n        var elem = component.element();\n        return read$1(elem).fold(function () {\n          return write('uid-', component.element());\n        }, function (uid) {\n          return uid;\n        });\n      };\n      var failOnDuplicate = function (component, tagId) {\n        var conflict = components[tagId];\n        if (conflict === component) {\n          unregister(component);\n        } else {\n          throw new Error('The tagId \"' + tagId + '\" is already used by: ' + element(conflict.element()) + '\\nCannot use it for: ' + element(component.element()) + '\\n' + 'The conflicting element is' + (inBody(conflict.element()) ? ' ' : ' not ') + 'already in the DOM');\n        }\n      };\n      var register = function (component) {\n        var tagId = readOrTag(component);\n        if (hasKey$1(components, tagId)) {\n          failOnDuplicate(component, tagId);\n        }\n        var extraArgs = [component];\n        events.registerId(extraArgs, tagId, component.events());\n        components[tagId] = component;\n      };\n      var unregister = function (component) {\n        read$1(component.element()).each(function (tagId) {\n          delete components[tagId];\n          events.unregisterId(tagId);\n        });\n      };\n      var filter = function (type) {\n        return events.filterByType(type);\n      };\n      var find = function (isAboveRoot, type, target) {\n        return events.find(isAboveRoot, type, target);\n      };\n      var getById = function (id) {\n        return readOpt$1(id)(components);\n      };\n      return {\n        find: find,\n        filter: filter,\n        register: register,\n        unregister: unregister,\n        getById: getById\n      };\n    }\n\n    var factory$3 = function (detail) {\n      var _a = detail.dom, attributes = _a.attributes, domWithoutAttributes = __rest(_a, ['attributes']);\n      return {\n        uid: detail.uid,\n        dom: __assign({\n          tag: 'div',\n          attributes: __assign({ role: 'presentation' }, attributes)\n        }, domWithoutAttributes),\n        components: detail.components,\n        behaviours: get$b(detail.containerBehaviours),\n        events: detail.events,\n        domModification: detail.domModification,\n        eventOrder: detail.eventOrder\n      };\n    };\n    var Container = single$2({\n      name: 'Container',\n      factory: factory$3,\n      configFields: [\n        defaulted$1('components', []),\n        field$1('containerBehaviours', []),\n        defaulted$1('events', {}),\n        defaulted$1('domModification', {}),\n        defaulted$1('eventOrder', {})\n      ]\n    });\n\n    var takeover = function (root) {\n      var isAboveRoot = function (el) {\n        return parent(root.element()).fold(function () {\n          return true;\n        }, function (parent) {\n          return eq(el, parent);\n        });\n      };\n      var registry = Registry();\n      var lookup = function (eventName, target) {\n        return registry.find(isAboveRoot, eventName, target);\n      };\n      var domEvents = setup$1(root.element(), {\n        triggerEvent: function (eventName, event) {\n          return monitorEvent(eventName, event.target(), function (logger) {\n            return triggerUntilStopped(lookup, eventName, event, logger);\n          });\n        }\n      });\n      var systemApi = {\n        debugInfo: constant('real'),\n        triggerEvent: function (eventName, target, data) {\n          monitorEvent(eventName, target, function (logger) {\n            triggerOnUntilStopped(lookup, eventName, data, target, logger);\n          });\n        },\n        triggerFocus: function (target, originator) {\n          read$1(target).fold(function () {\n            focus$1(target);\n          }, function (_alloyId) {\n            monitorEvent(focus(), target, function (logger) {\n              triggerHandler(lookup, focus(), {\n                originator: constant(originator),\n                kill: noop,\n                prevent: noop,\n                target: constant(target)\n              }, target, logger);\n            });\n          });\n        },\n        triggerEscape: function (comp, simulatedEvent) {\n          systemApi.triggerEvent('keydown', comp.element(), simulatedEvent.event());\n        },\n        getByUid: function (uid) {\n          return getByUid(uid);\n        },\n        getByDom: function (elem) {\n          return getByDom(elem);\n        },\n        build: build$1,\n        addToGui: function (c) {\n          add(c);\n        },\n        removeFromGui: function (c) {\n          remove$1(c);\n        },\n        addToWorld: function (c) {\n          addToWorld(c);\n        },\n        removeFromWorld: function (c) {\n          removeFromWorld(c);\n        },\n        broadcast: function (message) {\n          broadcast$1(message);\n        },\n        broadcastOn: function (channels, message) {\n          broadcastOn(channels, message);\n        },\n        broadcastEvent: function (eventName, event) {\n          broadcastEvent(eventName, event);\n        },\n        isConnected: constant(true)\n      };\n      var addToWorld = function (component) {\n        component.connect(systemApi);\n        if (!isText(component.element())) {\n          registry.register(component);\n          each(component.components(), addToWorld);\n          systemApi.triggerEvent(systemInit(), component.element(), { target: constant(component.element()) });\n        }\n      };\n      var removeFromWorld = function (component) {\n        if (!isText(component.element())) {\n          each(component.components(), removeFromWorld);\n          registry.unregister(component);\n        }\n        component.disconnect();\n      };\n      var add = function (component) {\n        attach$1(root, component);\n      };\n      var remove$1 = function (component) {\n        detach(component);\n      };\n      var destroy = function () {\n        domEvents.unbind();\n        remove(root.element());\n      };\n      var broadcastData = function (data) {\n        var receivers = registry.filter(receive());\n        each(receivers, function (receiver) {\n          var descHandler = receiver.descHandler();\n          var handler = getCurried(descHandler);\n          handler(data);\n        });\n      };\n      var broadcast$1 = function (message) {\n        broadcastData({\n          universal: constant(true),\n          data: constant(message)\n        });\n      };\n      var broadcastOn = function (channels, message) {\n        broadcastData({\n          universal: constant(false),\n          channels: constant(channels),\n          data: constant(message)\n        });\n      };\n      var broadcastEvent = function (eventName, event) {\n        var listeners = registry.filter(eventName);\n        return broadcast(listeners, event);\n      };\n      var getByUid = function (uid) {\n        return registry.getById(uid).fold(function () {\n          return Result.error(new Error('Could not find component with uid: \"' + uid + '\" in system.'));\n        }, Result.value);\n      };\n      var getByDom = function (elem) {\n        var uid = read$1(elem).getOr('not found');\n        return getByUid(uid);\n      };\n      addToWorld(root);\n      return {\n        root: constant(root),\n        element: root.element,\n        destroy: destroy,\n        add: add,\n        remove: remove$1,\n        getByUid: getByUid,\n        getByDom: getByDom,\n        addToWorld: addToWorld,\n        removeFromWorld: removeFromWorld,\n        broadcast: broadcast$1,\n        broadcastOn: broadcastOn,\n        broadcastEvent: broadcastEvent\n      };\n    };\n\n    var global$9 = tinymce.util.Tools.resolve('tinymce.EditorManager');\n\n    var getSkinUrl = function (editor) {\n      var settings = editor.settings;\n      var skin = settings.skin;\n      var skinUrl = settings.skin_url;\n      if (skin !== false) {\n        var skinName = skin ? skin : 'oxide';\n        if (skinUrl) {\n          skinUrl = editor.documentBaseURI.toAbsolute(skinUrl);\n        } else {\n          skinUrl = global$9.baseURL + '/skins/ui/' + skinName;\n        }\n      }\n      return skinUrl;\n    };\n    var isReadOnly = function (editor) {\n      return editor.getParam('readonly', false, 'boolean');\n    };\n    var isSkinDisabled = function (editor) {\n      return editor.getParam('skin') === false;\n    };\n    var getHeightSetting = function (editor) {\n      return editor.getParam('height', Math.max(editor.getElement().offsetHeight, 200));\n    };\n    var getWidthSetting = function (editor) {\n      return editor.getParam('width', global$7.DOM.getStyle(editor.getElement(), 'width'));\n    };\n    var getMinWidthSetting = function (editor) {\n      return Option.from(editor.settings.min_width).filter(isNumber);\n    };\n    var getMinHeightSetting = function (editor) {\n      return Option.from(editor.settings.min_height).filter(isNumber);\n    };\n    var getMaxWidthSetting = function (editor) {\n      return Option.from(editor.getParam('max_width')).filter(isNumber);\n    };\n    var getMaxHeightSetting = function (editor) {\n      return Option.from(editor.getParam('max_height')).filter(isNumber);\n    };\n    var getUserStyleFormats = function (editor) {\n      return Option.from(editor.getParam('style_formats')).filter(isArray);\n    };\n    var isMergeStyleFormats = function (editor) {\n      return editor.getParam('style_formats_merge', false, 'boolean');\n    };\n    var getRemovedMenuItems = function (editor) {\n      return editor.getParam('removed_menuitems', '');\n    };\n    var isMenubarEnabled = function (editor) {\n      return editor.getParam('menubar', true, 'boolean') !== false;\n    };\n    var isToolbarEnabled = function (editor) {\n      var toolbar = editor.getParam('toolbar', true);\n      var isToolbarTrue = toolbar === true;\n      var isToolbarString = isString(toolbar);\n      var isToolbarObjectArray = isArray(toolbar) && toolbar.length > 0;\n      return !isMultipleToolbars(editor) && (isToolbarObjectArray || isToolbarString || isToolbarTrue);\n    };\n    var getMultipleToolbarsSetting = function (editor) {\n      var keys$1 = keys(editor.settings);\n      var toolbarKeys = filter(keys$1, function (key) {\n        return /^toolbar([1-9])$/.test(key);\n      });\n      var toolbars = map(toolbarKeys, function (key) {\n        return editor.getParam(key, false, 'string');\n      });\n      var toolbarArray = filter(toolbars, function (toolbar) {\n        return typeof toolbar === 'string';\n      });\n      return toolbarArray.length > 0 ? Option.some(toolbarArray) : Option.none();\n    };\n    var isMultipleToolbars = function (editor) {\n      return getMultipleToolbarsSetting(editor).fold(function () {\n        var toolbar = editor.getParam('toolbar', [], 'string[]');\n        return toolbar.length > 0;\n      }, function () {\n        return true;\n      });\n    };\n    var ToolbarDrawer;\n    (function (ToolbarDrawer) {\n      ToolbarDrawer['default'] = '';\n      ToolbarDrawer['floating'] = 'floating';\n      ToolbarDrawer['sliding'] = 'sliding';\n      ToolbarDrawer['scrolling'] = 'scrolling';\n    }(ToolbarDrawer || (ToolbarDrawer = {})));\n    var getToolbarDrawer = function (editor) {\n      return editor.getParam('toolbar_drawer', '', 'string');\n    };\n    var fixedContainerSelector = function (editor) {\n      return editor.getParam('fixed_toolbar_container', '', 'string');\n    };\n    var fixedContainerElement = function (editor) {\n      var selector = fixedContainerSelector(editor);\n      return selector.length > 0 && editor.inline ? descendant$1(body(), selector) : Option.none();\n    };\n    var useFixedContainer = function (editor) {\n      return editor.inline && fixedContainerElement(editor).isSome();\n    };\n    var getUiContainer = function (editor) {\n      var fixedContainer = fixedContainerElement(editor);\n      return fixedContainer.getOr(body());\n    };\n    var isDistractionFree = function (editor) {\n      return editor.inline && !isMenubarEnabled(editor) && !isToolbarEnabled(editor) && !isMultipleToolbars(editor);\n    };\n    var isStickyToolbar = function (editor) {\n      var isStickyToolbar = editor.getParam('toolbar_sticky', false, 'boolean');\n      return (isStickyToolbar || editor.inline) && !useFixedContainer(editor) && !isDistractionFree(editor);\n    };\n    var isDraggableModal = function (editor) {\n      return editor.getParam('draggable_modal', false, 'boolean');\n    };\n\n    var SIGNIFICANT_MOVE$1 = 5;\n    var LONGPRESS_DELAY$1 = 400;\n    var getTouch$1 = function (event) {\n      if (event.touches === undefined || event.touches.length !== 1) {\n        return Option.none();\n      }\n      return Option.some(event.touches[0]);\n    };\n    var isFarEnough$1 = function (touch, data) {\n      var distX = Math.abs(touch.clientX - data.x());\n      var distY = Math.abs(touch.clientY - data.y());\n      return distX > SIGNIFICANT_MOVE$1 || distY > SIGNIFICANT_MOVE$1;\n    };\n    var setup$2 = function (editor) {\n      var startData = Cell(Option.none());\n      var longpressFired = Cell(false);\n      var debounceLongpress = last$2(function (e) {\n        editor.fire('longpress', __assign(__assign({}, e), { type: 'longpress' }));\n        longpressFired.set(true);\n      }, LONGPRESS_DELAY$1);\n      editor.on('touchstart', function (e) {\n        getTouch$1(e).each(function (touch) {\n          debounceLongpress.cancel();\n          var data = {\n            x: constant(touch.clientX),\n            y: constant(touch.clientY),\n            target: constant(e.target)\n          };\n          debounceLongpress.throttle(e);\n          longpressFired.set(false);\n          startData.set(Option.some(data));\n        });\n      }, true);\n      editor.on('touchmove', function (e) {\n        debounceLongpress.cancel();\n        getTouch$1(e).each(function (touch) {\n          startData.get().each(function (data) {\n            if (isFarEnough$1(touch, data)) {\n              startData.set(Option.none());\n              longpressFired.set(false);\n              editor.fire('longpresscancel');\n            }\n          });\n        });\n      }, true);\n      editor.on('touchend touchcancel', function (e) {\n        debounceLongpress.cancel();\n        if (e.type === 'touchcancel') {\n          return;\n        }\n        startData.get().filter(function (data) {\n          return data.target().isEqualNode(e.target);\n        }).each(function () {\n          if (longpressFired.get()) {\n            e.preventDefault();\n          } else {\n            var result = editor.fire('tap', { touches: e.touches });\n            if (result.isDefaultPrevented()) {\n              e.preventDefault();\n            }\n          }\n        });\n      }, true);\n    };\n    var TouchEvents = { setup: setup$2 };\n\n    var formChangeEvent = generate$1('form-component-change');\n    var formCloseEvent = generate$1('form-close');\n    var formCancelEvent = generate$1('form-cancel');\n    var formActionEvent = generate$1('form-action');\n    var formSubmitEvent = generate$1('form-submit');\n    var formBlockEvent = generate$1('form-block');\n    var formUnblockEvent = generate$1('form-unblock');\n    var formTabChangeEvent = generate$1('form-tabchange');\n    var formResizeEvent = generate$1('form-resize');\n\n    var renderAlertBanner = function (spec, providersBackstage) {\n      return Container.sketch({\n        dom: {\n          tag: 'div',\n          attributes: { role: 'alert' },\n          classes: [\n            'tox-notification',\n            'tox-notification--in',\n            'tox-notification--' + spec.level\n          ]\n        },\n        components: [\n          {\n            dom: {\n              tag: 'div',\n              classes: ['tox-notification__icon']\n            },\n            components: [Button.sketch({\n                dom: {\n                  tag: 'button',\n                  classes: [\n                    'tox-button',\n                    'tox-button--naked',\n                    'tox-button--icon'\n                  ],\n                  innerHtml: get$c(spec.icon, providersBackstage.icons),\n                  attributes: { title: providersBackstage.translate(spec.iconTooltip) }\n                },\n                action: function (comp) {\n                  emitWith(comp, formActionEvent, {\n                    name: 'alert-banner',\n                    value: spec.url\n                  });\n                }\n              })]\n          },\n          {\n            dom: {\n              tag: 'div',\n              classes: ['tox-notification__body'],\n              innerHtml: providersBackstage.translate(spec.text)\n            }\n          }\n        ]\n      });\n    };\n\n    var renderBar = function (spec, backstage) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox-bar',\n            'tox-form__controls-h-stack'\n          ]\n        },\n        components: map(spec.items, backstage.interpreter)\n      };\n    };\n\n    var schema$e = constant([\n      defaulted$1('prefix', 'form-field'),\n      field$1('fieldBehaviours', [\n        Composing,\n        Representing\n      ])\n    ]);\n    var parts$3 = constant([\n      optional({\n        schema: [strict$1('dom')],\n        name: 'label'\n      }),\n      optional({\n        factory: {\n          sketch: function (spec) {\n            return {\n              uid: spec.uid,\n              dom: {\n                tag: 'span',\n                styles: { display: 'none' },\n                attributes: { 'aria-hidden': 'true' },\n                innerHtml: spec.text\n              }\n            };\n          }\n        },\n        schema: [strict$1('text')],\n        name: 'aria-descriptor'\n      }),\n      required({\n        factory: {\n          sketch: function (spec) {\n            var excludeFactory = exclude$1(spec, ['factory']);\n            return spec.factory.sketch(excludeFactory);\n          }\n        },\n        schema: [strict$1('factory')],\n        name: 'field'\n      })\n    ]);\n\n    var factory$4 = function (detail, components, spec, externals) {\n      var behaviours = augment(detail.fieldBehaviours, [\n        Composing.config({\n          find: function (container) {\n            return getPart(container, detail, 'field');\n          }\n        }),\n        Representing.config({\n          store: {\n            mode: 'manual',\n            getValue: function (field) {\n              return Composing.getCurrent(field).bind(Representing.getValue);\n            },\n            setValue: function (field, value) {\n              Composing.getCurrent(field).each(function (current) {\n                Representing.setValue(current, value);\n              });\n            }\n          }\n        })\n      ]);\n      var events = derive([runOnAttached(function (component, simulatedEvent) {\n          var ps = getParts(component, detail, [\n            'label',\n            'field',\n            'aria-descriptor'\n          ]);\n          ps.field().each(function (field) {\n            var id = generate$1(detail.prefix);\n            ps.label().each(function (label) {\n              set$1(label.element(), 'for', id);\n              set$1(field.element(), 'id', id);\n            });\n            ps['aria-descriptor']().each(function (descriptor) {\n              var descriptorId = generate$1(detail.prefix);\n              set$1(descriptor.element(), 'id', descriptorId);\n              set$1(field.element(), 'aria-describedby', descriptorId);\n            });\n          });\n        })]);\n      var apis = {\n        getField: function (container) {\n          return getPart(container, detail, 'field');\n        },\n        getLabel: function (container) {\n          return getPart(container, detail, 'label');\n        }\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: behaviours,\n        events: events,\n        apis: apis\n      };\n    };\n    var FormField = composite$1({\n      name: 'FormField',\n      configFields: schema$e(),\n      partFields: parts$3(),\n      factory: factory$4,\n      apis: {\n        getField: function (apis, comp) {\n          return apis.getField(comp);\n        },\n        getLabel: function (apis, comp) {\n          return apis.getLabel(comp);\n        }\n      }\n    });\n\n    var schema$f = constant([\n      option('data'),\n      defaulted$1('inputAttributes', {}),\n      defaulted$1('inputStyles', {}),\n      defaulted$1('tag', 'input'),\n      defaulted$1('inputClasses', []),\n      onHandler('onSetValue'),\n      defaulted$1('styles', {}),\n      defaulted$1('eventOrder', {}),\n      field$1('inputBehaviours', [\n        Representing,\n        Focusing\n      ]),\n      defaulted$1('selectOnFocus', true)\n    ]);\n    var focusBehaviours = function (detail) {\n      return derive$1([Focusing.config({\n          onFocus: detail.selectOnFocus === false ? noop : function (component) {\n            var input = component.element();\n            var value = get$5(input);\n            input.dom().setSelectionRange(0, value.length);\n          }\n        })]);\n    };\n    var behaviours = function (detail) {\n      return __assign(__assign({}, focusBehaviours(detail)), augment(detail.inputBehaviours, [Representing.config({\n          store: {\n            mode: 'manual',\n            initialValue: detail.data.getOr(undefined),\n            getValue: function (input) {\n              return get$5(input.element());\n            },\n            setValue: function (input, data) {\n              var current = get$5(input.element());\n              if (current !== data) {\n                set$3(input.element(), data);\n              }\n            }\n          },\n          onSetValue: detail.onSetValue\n        })]));\n    };\n    var dom$2 = function (detail) {\n      return {\n        tag: detail.tag,\n        attributes: __assign({ type: 'text' }, detail.inputAttributes),\n        styles: detail.inputStyles,\n        classes: detail.inputClasses\n      };\n    };\n\n    var factory$5 = function (detail, spec) {\n      return {\n        uid: detail.uid,\n        dom: dom$2(detail),\n        components: [],\n        behaviours: behaviours(detail),\n        eventOrder: detail.eventOrder\n      };\n    };\n    var Input = single$2({\n      name: 'Input',\n      configFields: schema$f(),\n      factory: factory$5\n    });\n\n    var exports$1 = {}, module = { exports: exports$1 };\n    (function (define, exports, module, require) {\n      (function (f) {\n        if (typeof exports === 'object' && typeof module !== 'undefined') {\n          module.exports = f();\n        } else if (typeof define === 'function' && define.amd) {\n          define([], f);\n        } else {\n          var g;\n          if (typeof window !== 'undefined') {\n            g = window;\n          } else if (typeof global !== 'undefined') {\n            g = global;\n          } else if (typeof self !== 'undefined') {\n            g = self;\n          } else {\n            g = this;\n          }\n          g.EphoxContactWrapper = f();\n        }\n      }(function () {\n        return function () {\n          function r(e, n, t) {\n            function o(i, f) {\n              if (!n[i]) {\n                if (!e[i]) {\n                  var c = 'function' == typeof require && require;\n                  if (!f && c)\n                    return c(i, !0);\n                  if (u)\n                    return u(i, !0);\n                  var a = new Error('Cannot find module \\'' + i + '\\'');\n                  throw a.code = 'MODULE_NOT_FOUND', a;\n                }\n                var p = n[i] = { exports: {} };\n                e[i][0].call(p.exports, function (r) {\n                  var n = e[i][1][r];\n                  return o(n || r);\n                }, p, p.exports, r, e, n, t);\n              }\n              return n[i].exports;\n            }\n            for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++)\n              o(t[i]);\n            return o;\n          }\n          return r;\n        }()({\n          1: [\n            function (require, module, exports) {\n              var process = module.exports = {};\n              var cachedSetTimeout;\n              var cachedClearTimeout;\n              function defaultSetTimout() {\n                throw new Error('setTimeout has not been defined');\n              }\n              function defaultClearTimeout() {\n                throw new Error('clearTimeout has not been defined');\n              }\n              (function () {\n                try {\n                  if (typeof setTimeout === 'function') {\n                    cachedSetTimeout = setTimeout;\n                  } else {\n                    cachedSetTimeout = defaultSetTimout;\n                  }\n                } catch (e) {\n                  cachedSetTimeout = defaultSetTimout;\n                }\n                try {\n                  if (typeof clearTimeout === 'function') {\n                    cachedClearTimeout = clearTimeout;\n                  } else {\n                    cachedClearTimeout = defaultClearTimeout;\n                  }\n                } catch (e) {\n                  cachedClearTimeout = defaultClearTimeout;\n                }\n              }());\n              function runTimeout(fun) {\n                if (cachedSetTimeout === setTimeout) {\n                  return setTimeout(fun, 0);\n                }\n                if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n                  cachedSetTimeout = setTimeout;\n                  return setTimeout(fun, 0);\n                }\n                try {\n                  return cachedSetTimeout(fun, 0);\n                } catch (e) {\n                  try {\n                    return cachedSetTimeout.call(null, fun, 0);\n                  } catch (e) {\n                    return cachedSetTimeout.call(this, fun, 0);\n                  }\n                }\n              }\n              function runClearTimeout(marker) {\n                if (cachedClearTimeout === clearTimeout) {\n                  return clearTimeout(marker);\n                }\n                if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n                  cachedClearTimeout = clearTimeout;\n                  return clearTimeout(marker);\n                }\n                try {\n                  return cachedClearTimeout(marker);\n                } catch (e) {\n                  try {\n                    return cachedClearTimeout.call(null, marker);\n                  } catch (e) {\n                    return cachedClearTimeout.call(this, marker);\n                  }\n                }\n              }\n              var queue = [];\n              var draining = false;\n              var currentQueue;\n              var queueIndex = -1;\n              function cleanUpNextTick() {\n                if (!draining || !currentQueue) {\n                  return;\n                }\n                draining = false;\n                if (currentQueue.length) {\n                  queue = currentQueue.concat(queue);\n                } else {\n                  queueIndex = -1;\n                }\n                if (queue.length) {\n                  drainQueue();\n                }\n              }\n              function drainQueue() {\n                if (draining) {\n                  return;\n                }\n                var timeout = runTimeout(cleanUpNextTick);\n                draining = true;\n                var len = queue.length;\n                while (len) {\n                  currentQueue = queue;\n                  queue = [];\n                  while (++queueIndex < len) {\n                    if (currentQueue) {\n                      currentQueue[queueIndex].run();\n                    }\n                  }\n                  queueIndex = -1;\n                  len = queue.length;\n                }\n                currentQueue = null;\n                draining = false;\n                runClearTimeout(timeout);\n              }\n              process.nextTick = function (fun) {\n                var args = new Array(arguments.length - 1);\n                if (arguments.length > 1) {\n                  for (var i = 1; i < arguments.length; i++) {\n                    args[i - 1] = arguments[i];\n                  }\n                }\n                queue.push(new Item(fun, args));\n                if (queue.length === 1 && !draining) {\n                  runTimeout(drainQueue);\n                }\n              };\n              function Item(fun, array) {\n                this.fun = fun;\n                this.array = array;\n              }\n              Item.prototype.run = function () {\n                this.fun.apply(null, this.array);\n              };\n              process.title = 'browser';\n              process.browser = true;\n              process.env = {};\n              process.argv = [];\n              process.version = '';\n              process.versions = {};\n              function noop() {\n              }\n              process.on = noop;\n              process.addListener = noop;\n              process.once = noop;\n              process.off = noop;\n              process.removeListener = noop;\n              process.removeAllListeners = noop;\n              process.emit = noop;\n              process.prependListener = noop;\n              process.prependOnceListener = noop;\n              process.listeners = function (name) {\n                return [];\n              };\n              process.binding = function (name) {\n                throw new Error('process.binding is not supported');\n              };\n              process.cwd = function () {\n                return '/';\n              };\n              process.chdir = function (dir) {\n                throw new Error('process.chdir is not supported');\n              };\n              process.umask = function () {\n                return 0;\n              };\n            },\n            {}\n          ],\n          2: [\n            function (require, module, exports) {\n              (function (setImmediate) {\n                (function (root) {\n                  var setTimeoutFunc = setTimeout;\n                  function noop() {\n                  }\n                  function bind(fn, thisArg) {\n                    return function () {\n                      fn.apply(thisArg, arguments);\n                    };\n                  }\n                  function Promise(fn) {\n                    if (typeof this !== 'object')\n                      throw new TypeError('Promises must be constructed via new');\n                    if (typeof fn !== 'function')\n                      throw new TypeError('not a function');\n                    this._state = 0;\n                    this._handled = false;\n                    this._value = undefined;\n                    this._deferreds = [];\n                    doResolve(fn, this);\n                  }\n                  function handle(self, deferred) {\n                    while (self._state === 3) {\n                      self = self._value;\n                    }\n                    if (self._state === 0) {\n                      self._deferreds.push(deferred);\n                      return;\n                    }\n                    self._handled = true;\n                    Promise._immediateFn(function () {\n                      var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;\n                      if (cb === null) {\n                        (self._state === 1 ? resolve : reject)(deferred.promise, self._value);\n                        return;\n                      }\n                      var ret;\n                      try {\n                        ret = cb(self._value);\n                      } catch (e) {\n                        reject(deferred.promise, e);\n                        return;\n                      }\n                      resolve(deferred.promise, ret);\n                    });\n                  }\n                  function resolve(self, newValue) {\n                    try {\n                      if (newValue === self)\n                        throw new TypeError('A promise cannot be resolved with itself.');\n                      if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {\n                        var then = newValue.then;\n                        if (newValue instanceof Promise) {\n                          self._state = 3;\n                          self._value = newValue;\n                          finale(self);\n                          return;\n                        } else if (typeof then === 'function') {\n                          doResolve(bind(then, newValue), self);\n                          return;\n                        }\n                      }\n                      self._state = 1;\n                      self._value = newValue;\n                      finale(self);\n                    } catch (e) {\n                      reject(self, e);\n                    }\n                  }\n                  function reject(self, newValue) {\n                    self._state = 2;\n                    self._value = newValue;\n                    finale(self);\n                  }\n                  function finale(self) {\n                    if (self._state === 2 && self._deferreds.length === 0) {\n                      Promise._immediateFn(function () {\n                        if (!self._handled) {\n                          Promise._unhandledRejectionFn(self._value);\n                        }\n                      });\n                    }\n                    for (var i = 0, len = self._deferreds.length; i < len; i++) {\n                      handle(self, self._deferreds[i]);\n                    }\n                    self._deferreds = null;\n                  }\n                  function Handler(onFulfilled, onRejected, promise) {\n                    this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n                    this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n                    this.promise = promise;\n                  }\n                  function doResolve(fn, self) {\n                    var done = false;\n                    try {\n                      fn(function (value) {\n                        if (done)\n                          return;\n                        done = true;\n                        resolve(self, value);\n                      }, function (reason) {\n                        if (done)\n                          return;\n                        done = true;\n                        reject(self, reason);\n                      });\n                    } catch (ex) {\n                      if (done)\n                        return;\n                      done = true;\n                      reject(self, ex);\n                    }\n                  }\n                  Promise.prototype['catch'] = function (onRejected) {\n                    return this.then(null, onRejected);\n                  };\n                  Promise.prototype.then = function (onFulfilled, onRejected) {\n                    var prom = new this.constructor(noop);\n                    handle(this, new Handler(onFulfilled, onRejected, prom));\n                    return prom;\n                  };\n                  Promise.all = function (arr) {\n                    var args = Array.prototype.slice.call(arr);\n                    return new Promise(function (resolve, reject) {\n                      if (args.length === 0)\n                        return resolve([]);\n                      var remaining = args.length;\n                      function res(i, val) {\n                        try {\n                          if (val && (typeof val === 'object' || typeof val === 'function')) {\n                            var then = val.then;\n                            if (typeof then === 'function') {\n                              then.call(val, function (val) {\n                                res(i, val);\n                              }, reject);\n                              return;\n                            }\n                          }\n                          args[i] = val;\n                          if (--remaining === 0) {\n                            resolve(args);\n                          }\n                        } catch (ex) {\n                          reject(ex);\n                        }\n                      }\n                      for (var i = 0; i < args.length; i++) {\n                        res(i, args[i]);\n                      }\n                    });\n                  };\n                  Promise.resolve = function (value) {\n                    if (value && typeof value === 'object' && value.constructor === Promise) {\n                      return value;\n                    }\n                    return new Promise(function (resolve) {\n                      resolve(value);\n                    });\n                  };\n                  Promise.reject = function (value) {\n                    return new Promise(function (resolve, reject) {\n                      reject(value);\n                    });\n                  };\n                  Promise.race = function (values) {\n                    return new Promise(function (resolve, reject) {\n                      for (var i = 0, len = values.length; i < len; i++) {\n                        values[i].then(resolve, reject);\n                      }\n                    });\n                  };\n                  Promise._immediateFn = typeof setImmediate === 'function' ? function (fn) {\n                    setImmediate(fn);\n                  } : function (fn) {\n                    setTimeoutFunc(fn, 0);\n                  };\n                  Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {\n                    if (typeof console !== 'undefined' && console) {\n                      console.warn('Possible Unhandled Promise Rejection:', err);\n                    }\n                  };\n                  Promise._setImmediateFn = function _setImmediateFn(fn) {\n                    Promise._immediateFn = fn;\n                  };\n                  Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {\n                    Promise._unhandledRejectionFn = fn;\n                  };\n                  if (typeof module !== 'undefined' && module.exports) {\n                    module.exports = Promise;\n                  } else if (!root.Promise) {\n                    root.Promise = Promise;\n                  }\n                }(this));\n              }.call(this, require('timers').setImmediate));\n            },\n            { 'timers': 3 }\n          ],\n          3: [\n            function (require, module, exports) {\n              (function (setImmediate, clearImmediate) {\n                var nextTick = require('process/browser.js').nextTick;\n                var apply = Function.prototype.apply;\n                var slice = Array.prototype.slice;\n                var immediateIds = {};\n                var nextImmediateId = 0;\n                exports.setTimeout = function () {\n                  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n                };\n                exports.setInterval = function () {\n                  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n                };\n                exports.clearTimeout = exports.clearInterval = function (timeout) {\n                  timeout.close();\n                };\n                function Timeout(id, clearFn) {\n                  this._id = id;\n                  this._clearFn = clearFn;\n                }\n                Timeout.prototype.unref = Timeout.prototype.ref = function () {\n                };\n                Timeout.prototype.close = function () {\n                  this._clearFn.call(window, this._id);\n                };\n                exports.enroll = function (item, msecs) {\n                  clearTimeout(item._idleTimeoutId);\n                  item._idleTimeout = msecs;\n                };\n                exports.unenroll = function (item) {\n                  clearTimeout(item._idleTimeoutId);\n                  item._idleTimeout = -1;\n                };\n                exports._unrefActive = exports.active = function (item) {\n                  clearTimeout(item._idleTimeoutId);\n                  var msecs = item._idleTimeout;\n                  if (msecs >= 0) {\n                    item._idleTimeoutId = setTimeout(function onTimeout() {\n                      if (item._onTimeout)\n                        item._onTimeout();\n                    }, msecs);\n                  }\n                };\n                exports.setImmediate = typeof setImmediate === 'function' ? setImmediate : function (fn) {\n                  var id = nextImmediateId++;\n                  var args = arguments.length < 2 ? false : slice.call(arguments, 1);\n                  immediateIds[id] = true;\n                  nextTick(function onNextTick() {\n                    if (immediateIds[id]) {\n                      if (args) {\n                        fn.apply(null, args);\n                      } else {\n                        fn.call(null);\n                      }\n                      exports.clearImmediate(id);\n                    }\n                  });\n                  return id;\n                };\n                exports.clearImmediate = typeof clearImmediate === 'function' ? clearImmediate : function (id) {\n                  delete immediateIds[id];\n                };\n              }.call(this, require('timers').setImmediate, require('timers').clearImmediate));\n            },\n            {\n              'process/browser.js': 1,\n              'timers': 3\n            }\n          ],\n          4: [\n            function (require, module, exports) {\n              var promisePolyfill = require('promise-polyfill');\n              var Global = function () {\n                if (typeof window !== 'undefined') {\n                  return window;\n                } else {\n                  return Function('return this;')();\n                }\n              }();\n              module.exports = { boltExport: Global.Promise || promisePolyfill };\n            },\n            { 'promise-polyfill': 2 }\n          ]\n        }, {}, [4])(4);\n      }));\n    }(undefined, exports$1, module, undefined));\n    var Promise = module.exports.boltExport;\n\n    var nu$a = function (baseFn) {\n      var data = Option.none();\n      var callbacks = [];\n      var map = function (f) {\n        return nu$a(function (nCallback) {\n          get(function (data) {\n            nCallback(f(data));\n          });\n        });\n      };\n      var get = function (nCallback) {\n        if (isReady()) {\n          call(nCallback);\n        } else {\n          callbacks.push(nCallback);\n        }\n      };\n      var set = function (x) {\n        data = Option.some(x);\n        run(callbacks);\n        callbacks = [];\n      };\n      var isReady = function () {\n        return data.isSome();\n      };\n      var run = function (cbs) {\n        each(cbs, call);\n      };\n      var call = function (cb) {\n        data.each(function (x) {\n          domGlobals.setTimeout(function () {\n            cb(x);\n          }, 0);\n        });\n      };\n      baseFn(set);\n      return {\n        get: get,\n        map: map,\n        isReady: isReady\n      };\n    };\n    var pure$1 = function (a) {\n      return nu$a(function (callback) {\n        callback(a);\n      });\n    };\n    var LazyValue = {\n      nu: nu$a,\n      pure: pure$1\n    };\n\n    var errorReporter = function (err) {\n      domGlobals.setTimeout(function () {\n        throw err;\n      }, 0);\n    };\n    var make$3 = function (run) {\n      var get = function (callback) {\n        run().then(callback, errorReporter);\n      };\n      var map = function (fab) {\n        return make$3(function () {\n          return run().then(fab);\n        });\n      };\n      var bind = function (aFutureB) {\n        return make$3(function () {\n          return run().then(function (v) {\n            return aFutureB(v).toPromise();\n          });\n        });\n      };\n      var anonBind = function (futureB) {\n        return make$3(function () {\n          return run().then(function () {\n            return futureB.toPromise();\n          });\n        });\n      };\n      var toLazy = function () {\n        return LazyValue.nu(get);\n      };\n      var toCached = function () {\n        var cache = null;\n        return make$3(function () {\n          if (cache === null) {\n            cache = run();\n          }\n          return cache;\n        });\n      };\n      var toPromise = run;\n      return {\n        map: map,\n        bind: bind,\n        anonBind: anonBind,\n        toLazy: toLazy,\n        toCached: toCached,\n        toPromise: toPromise,\n        get: get\n      };\n    };\n    var nu$b = function (baseFn) {\n      return make$3(function () {\n        return new Promise(baseFn);\n      });\n    };\n    var pure$2 = function (a) {\n      return make$3(function () {\n        return Promise.resolve(a);\n      });\n    };\n    var Future = {\n      nu: nu$b,\n      pure: pure$2\n    };\n\n    var ariaElements = [\n      'input',\n      'textarea'\n    ];\n    var isAriaElement = function (elem) {\n      var name$1 = name(elem);\n      return contains(ariaElements, name$1);\n    };\n    var markValid = function (component, invalidConfig) {\n      var elem = invalidConfig.getRoot(component).getOr(component.element());\n      remove$4(elem, invalidConfig.invalidClass);\n      invalidConfig.notify.each(function (notifyInfo) {\n        if (isAriaElement(component.element())) {\n          set$1(component.element(), 'aria-invalid', false);\n        }\n        notifyInfo.getContainer(component).each(function (container) {\n          set(container, notifyInfo.validHtml);\n        });\n        notifyInfo.onValid(component);\n      });\n    };\n    var markInvalid = function (component, invalidConfig, invalidState, text) {\n      var elem = invalidConfig.getRoot(component).getOr(component.element());\n      add$2(elem, invalidConfig.invalidClass);\n      invalidConfig.notify.each(function (notifyInfo) {\n        if (isAriaElement(component.element())) {\n          set$1(component.element(), 'aria-invalid', true);\n        }\n        notifyInfo.getContainer(component).each(function (container) {\n          set(container, text);\n        });\n        notifyInfo.onInvalid(component, text);\n      });\n    };\n    var query = function (component, invalidConfig, invalidState) {\n      return invalidConfig.validator.fold(function () {\n        return Future.pure(Result.value(true));\n      }, function (validatorInfo) {\n        return validatorInfo.validate(component);\n      });\n    };\n    var run$1 = function (component, invalidConfig, invalidState) {\n      invalidConfig.notify.each(function (notifyInfo) {\n        notifyInfo.onValidate(component);\n      });\n      return query(component, invalidConfig).map(function (valid) {\n        if (component.getSystem().isConnected()) {\n          return valid.fold(function (err) {\n            markInvalid(component, invalidConfig, invalidState, err);\n            return Result.error(err);\n          }, function (v) {\n            markValid(component, invalidConfig);\n            return Result.value(v);\n          });\n        } else {\n          return Result.error('No longer in system');\n        }\n      });\n    };\n    var isInvalid = function (component, invalidConfig) {\n      var elem = invalidConfig.getRoot(component).getOr(component.element());\n      return has$2(elem, invalidConfig.invalidClass);\n    };\n\n    var InvalidateApis = /*#__PURE__*/Object.freeze({\n        markValid: markValid,\n        markInvalid: markInvalid,\n        query: query,\n        run: run$1,\n        isInvalid: isInvalid\n    });\n\n    var events$a = function (invalidConfig, invalidState) {\n      return invalidConfig.validator.map(function (validatorInfo) {\n        return derive([run(validatorInfo.onEvent, function (component) {\n            run$1(component, invalidConfig, invalidState).get(identity);\n          })].concat(validatorInfo.validateOnLoad ? [runOnAttached(function (component) {\n            run$1(component, invalidConfig, invalidState).get(noop);\n          })] : []));\n      }).getOr({});\n    };\n\n    var ActiveInvalidate = /*#__PURE__*/Object.freeze({\n        events: events$a\n    });\n\n    var InvalidateSchema = [\n      strict$1('invalidClass'),\n      defaulted$1('getRoot', Option.none),\n      optionObjOf('notify', [\n        defaulted$1('aria', 'alert'),\n        defaulted$1('getContainer', Option.none),\n        defaulted$1('validHtml', ''),\n        onHandler('onValid'),\n        onHandler('onInvalid'),\n        onHandler('onValidate')\n      ]),\n      optionObjOf('validator', [\n        strict$1('validate'),\n        defaulted$1('onEvent', 'input'),\n        defaulted$1('validateOnLoad', true)\n      ])\n    ];\n\n    var Invalidating = create$1({\n      fields: InvalidateSchema,\n      name: 'invalidating',\n      active: ActiveInvalidate,\n      apis: InvalidateApis,\n      extra: {\n        validation: function (validator) {\n          return function (component) {\n            var v = Representing.getValue(component);\n            return Future.pure(validator(v));\n          };\n        }\n      }\n    });\n\n    var exhibit$4 = function (base, tabConfig) {\n      return nu$6({\n        attributes: wrapAll$1([{\n            key: tabConfig.tabAttr,\n            value: 'true'\n          }])\n      });\n    };\n\n    var ActiveTabstopping = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$4\n    });\n\n    var TabstopSchema = [defaulted$1('tabAttr', 'data-alloy-tabstop')];\n\n    var Tabstopping = create$1({\n      fields: TabstopSchema,\n      name: 'tabstopping',\n      active: ActiveTabstopping\n    });\n\n    var renderFormFieldWith = function (pLabel, pField, extraClasses, extraBehaviours) {\n      var spec = renderFormFieldSpecWith(pLabel, pField, extraClasses, extraBehaviours);\n      return FormField.sketch(spec);\n    };\n    var renderFormField = function (pLabel, pField) {\n      return renderFormFieldWith(pLabel, pField, [], []);\n    };\n    var renderFormFieldSpecWith = function (pLabel, pField, extraClasses, extraBehaviours) {\n      return {\n        dom: renderFormFieldDomWith(extraClasses),\n        components: pLabel.toArray().concat([pField]),\n        fieldBehaviours: derive$1(extraBehaviours)\n      };\n    };\n    var renderFormFieldDom = function () {\n      return renderFormFieldDomWith([]);\n    };\n    var renderFormFieldDomWith = function (extraClasses) {\n      return {\n        tag: 'div',\n        classes: ['tox-form__group'].concat(extraClasses)\n      };\n    };\n    var renderLabel = function (label, providersBackstage) {\n      return FormField.parts().label({\n        dom: {\n          tag: 'label',\n          classes: ['tox-label'],\n          innerHtml: providersBackstage.translate(label)\n        }\n      });\n    };\n\n    var getCoupled = function (component, coupleConfig, coupleState, name) {\n      return coupleState.getOrCreate(component, coupleConfig, name);\n    };\n\n    var CouplingApis = /*#__PURE__*/Object.freeze({\n        getCoupled: getCoupled\n    });\n\n    var CouplingSchema = [strictOf('others', setOf$1(Result.value, anyValue$1()))];\n\n    var init$5 = function (spec) {\n      var coupled = {};\n      var getOrCreate = function (component, coupleConfig, name) {\n        var available = keys(coupleConfig.others);\n        if (!available) {\n          throw new Error('Cannot find coupled component: ' + name + '. Known coupled components: ' + JSON.stringify(available, null, 2));\n        } else {\n          return readOptFrom$1(coupled, name).getOrThunk(function () {\n            var builder = readOptFrom$1(coupleConfig.others, name).getOrDie('No information found for coupled component: ' + name);\n            var spec = builder(component);\n            var built = component.getSystem().build(spec);\n            coupled[name] = built;\n            return built;\n          });\n        }\n      };\n      var readState = constant({});\n      return nu$5({\n        readState: readState,\n        getOrCreate: getOrCreate\n      });\n    };\n\n    var CouplingState = /*#__PURE__*/Object.freeze({\n        init: init$5\n    });\n\n    var Coupling = create$1({\n      fields: CouplingSchema,\n      name: 'coupling',\n      apis: CouplingApis,\n      state: CouplingState\n    });\n\n    var suffix = constant('sink');\n    var partType = constant(optional({\n      name: suffix(),\n      overrides: constant({\n        dom: { tag: 'div' },\n        behaviours: derive$1([Positioning.config({ useFixed: always })]),\n        events: derive([\n          cutter(keydown()),\n          cutter(mousedown()),\n          cutter(click())\n        ])\n      })\n    }));\n\n    var HighlightOnOpen;\n    (function (HighlightOnOpen) {\n      HighlightOnOpen[HighlightOnOpen['HighlightFirst'] = 0] = 'HighlightFirst';\n      HighlightOnOpen[HighlightOnOpen['HighlightNone'] = 1] = 'HighlightNone';\n    }(HighlightOnOpen || (HighlightOnOpen = {})));\n    var getAnchor = function (detail, component) {\n      var hotspot = detail.getHotspot(component).getOr(component);\n      var anchor = 'hotspot';\n      var overrides = detail.getAnchorOverrides();\n      return detail.layouts.fold(function () {\n        return {\n          anchor: anchor,\n          hotspot: hotspot,\n          overrides: overrides\n        };\n      }, function (layouts) {\n        return {\n          anchor: anchor,\n          hotspot: hotspot,\n          overrides: overrides,\n          layouts: layouts\n        };\n      });\n    };\n    var fetch = function (detail, mapFetch, component) {\n      var fetcher = detail.fetch;\n      return fetcher(component).map(mapFetch);\n    };\n    var openF = function (detail, mapFetch, anchor, component, sandbox, externals, highlightOnOpen) {\n      var futureData = fetch(detail, mapFetch, component);\n      var getLazySink = getSink(component, detail);\n      return futureData.map(function (tdata) {\n        return tdata.bind(function (data) {\n          return Option.from(tieredMenu.sketch(__assign(__assign({}, externals.menu()), {\n            uid: generate$2(''),\n            data: data,\n            highlightImmediately: highlightOnOpen === HighlightOnOpen.HighlightFirst,\n            onOpenMenu: function (tmenu, menu) {\n              var sink = getLazySink().getOrDie();\n              Positioning.position(sink, anchor, menu);\n              Sandboxing.decloak(sandbox);\n            },\n            onOpenSubmenu: function (tmenu, item, submenu) {\n              var sink = getLazySink().getOrDie();\n              Positioning.position(sink, {\n                anchor: 'submenu',\n                item: item\n              }, submenu);\n              Sandboxing.decloak(sandbox);\n            },\n            onRepositionMenu: function (tmenu, primaryMenu, submenuTriggers) {\n              var sink = getLazySink().getOrDie();\n              Positioning.position(sink, anchor, primaryMenu);\n              each(submenuTriggers, function (st) {\n                Positioning.position(sink, {\n                  anchor: 'submenu',\n                  item: st.triggeringItem\n                }, st.triggeredMenu);\n              });\n            },\n            onEscape: function () {\n              Focusing.focus(component);\n              Sandboxing.close(sandbox);\n              return Option.some(true);\n            }\n          })));\n        });\n      });\n    };\n    var open$1 = function (detail, mapFetch, hotspot, sandbox, externals, onOpenSync, highlightOnOpen) {\n      var anchor = getAnchor(detail, hotspot);\n      var processed = openF(detail, mapFetch, anchor, hotspot, sandbox, externals, highlightOnOpen);\n      return processed.map(function (tdata) {\n        tdata.fold(function () {\n          if (Sandboxing.isOpen(sandbox)) {\n            Sandboxing.close(sandbox);\n          }\n        }, function (data) {\n          Sandboxing.cloak(sandbox);\n          Sandboxing.open(sandbox, data);\n          onOpenSync(sandbox);\n        });\n        return sandbox;\n      });\n    };\n    var close$1 = function (detail, mapFetch, component, sandbox, _externals, _onOpenSync, _highlightOnOpen) {\n      Sandboxing.close(sandbox);\n      return Future.pure(sandbox);\n    };\n    var togglePopup = function (detail, mapFetch, hotspot, externals, onOpenSync, highlightOnOpen) {\n      var sandbox = Coupling.getCoupled(hotspot, 'sandbox');\n      var showing = Sandboxing.isOpen(sandbox);\n      var action = showing ? close$1 : open$1;\n      return action(detail, mapFetch, hotspot, sandbox, externals, onOpenSync, highlightOnOpen);\n    };\n    var matchWidth = function (hotspot, container, useMinWidth) {\n      var menu = Composing.getCurrent(container).getOr(container);\n      var buttonWidth = get$7(hotspot.element());\n      if (useMinWidth) {\n        set$2(menu.element(), 'min-width', buttonWidth + 'px');\n      } else {\n        set$4(menu.element(), buttonWidth);\n      }\n    };\n    var getSink = function (anyInSystem, sinkDetail) {\n      return anyInSystem.getSystem().getByUid(sinkDetail.uid + '-' + suffix()).map(function (internalSink) {\n        return function () {\n          return Result.value(internalSink);\n        };\n      }).getOrThunk(function () {\n        return sinkDetail.lazySink.fold(function () {\n          return function () {\n            return Result.error(new Error('No internal sink is specified, nor could an external sink be found'));\n          };\n        }, function (lazySinkFn) {\n          return function () {\n            return lazySinkFn(anyInSystem);\n          };\n        });\n      });\n    };\n    var doRepositionMenus = function (sandbox) {\n      Sandboxing.getState(sandbox).each(function (tmenu) {\n        tieredMenu.repositionMenus(tmenu);\n      });\n    };\n    var makeSandbox = function (detail, hotspot, extras) {\n      var ariaOwner = manager();\n      var onOpen = function (component, menu) {\n        var anchor = getAnchor(detail, hotspot);\n        ariaOwner.link(hotspot.element());\n        if (detail.matchWidth) {\n          matchWidth(anchor.hotspot, menu, detail.useMinWidth);\n        }\n        detail.onOpen(anchor, component, menu);\n        if (extras !== undefined && extras.onOpen !== undefined) {\n          extras.onOpen(component, menu);\n        }\n      };\n      var onClose = function (component, menu) {\n        ariaOwner.unlink(hotspot.element());\n        if (extras !== undefined && extras.onClose !== undefined) {\n          extras.onClose(component, menu);\n        }\n      };\n      var lazySink = getSink(hotspot, detail);\n      return {\n        dom: {\n          tag: 'div',\n          classes: detail.sandboxClasses,\n          attributes: {\n            id: ariaOwner.id(),\n            role: 'listbox'\n          }\n        },\n        behaviours: SketchBehaviours.augment(detail.sandboxBehaviours, [\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: hotspot\n            }\n          }),\n          Sandboxing.config({\n            onOpen: onOpen,\n            onClose: onClose,\n            isPartOf: function (container, data, queryElem) {\n              return isPartOf(data, queryElem) || isPartOf(hotspot, queryElem);\n            },\n            getAttachPoint: function () {\n              return lazySink().getOrDie();\n            }\n          }),\n          Composing.config({\n            find: function (sandbox) {\n              return Sandboxing.getState(sandbox).bind(function (menu) {\n                return Composing.getCurrent(menu);\n              });\n            }\n          }),\n          Receiving.config({\n            channels: __assign(__assign({}, receivingChannel({ isExtraPart: constant(false) })), receivingChannel$1({\n              isExtraPart: constant(false),\n              doReposition: doRepositionMenus\n            }))\n          })\n        ])\n      };\n    };\n    var repositionMenus = function (comp) {\n      var sandbox = Coupling.getCoupled(comp, 'sandbox');\n      doRepositionMenus(sandbox);\n    };\n\n    var sandboxFields = function () {\n      return [\n        defaulted$1('sandboxClasses', []),\n        SketchBehaviours.field('sandboxBehaviours', [\n          Composing,\n          Receiving,\n          Sandboxing,\n          Representing\n        ])\n      ];\n    };\n\n    var schema$g = constant([\n      strict$1('dom'),\n      strict$1('fetch'),\n      onHandler('onOpen'),\n      onKeyboardHandler('onExecute'),\n      defaulted$1('getHotspot', Option.some),\n      defaulted$1('getAnchorOverrides', constant({})),\n      defaulted$1('layouts', Option.none()),\n      field$1('dropdownBehaviours', [\n        Toggling,\n        Coupling,\n        Keying,\n        Focusing\n      ]),\n      strict$1('toggleClass'),\n      defaulted$1('eventOrder', {}),\n      option('lazySink'),\n      defaulted$1('matchWidth', false),\n      defaulted$1('useMinWidth', false),\n      option('role')\n    ].concat(sandboxFields()));\n    var parts$4 = constant([\n      external$1({\n        schema: [tieredMenuMarkers()],\n        name: 'menu',\n        defaults: function (detail) {\n          return { onExecute: detail.onExecute };\n        }\n      }),\n      partType()\n    ]);\n\n    var factory$6 = function (detail, components, _spec, externals) {\n      var _a;\n      var lookupAttr = function (attr) {\n        return readOptFrom$1(detail.dom, 'attributes').bind(function (attrs) {\n          return readOptFrom$1(attrs, attr);\n        });\n      };\n      var switchToMenu = function (sandbox) {\n        Sandboxing.getState(sandbox).each(function (tmenu) {\n          tieredMenu.highlightPrimary(tmenu);\n        });\n      };\n      var action = function (component) {\n        var onOpenSync = switchToMenu;\n        togglePopup(detail, function (x) {\n          return x;\n        }, component, externals, onOpenSync, HighlightOnOpen.HighlightFirst).get(noop);\n      };\n      var apis = {\n        expand: function (comp) {\n          if (!Toggling.isOn(comp)) {\n            togglePopup(detail, function (x) {\n              return x;\n            }, comp, externals, noop, HighlightOnOpen.HighlightNone).get(noop);\n          }\n        },\n        open: function (comp) {\n          if (!Toggling.isOn(comp)) {\n            togglePopup(detail, function (x) {\n              return x;\n            }, comp, externals, noop, HighlightOnOpen.HighlightFirst).get(noop);\n          }\n        },\n        isOpen: Toggling.isOn,\n        close: function (comp) {\n          if (Toggling.isOn(comp)) {\n            togglePopup(detail, function (x) {\n              return x;\n            }, comp, externals, noop, HighlightOnOpen.HighlightFirst).get(noop);\n          }\n        },\n        repositionMenus: function (comp) {\n          if (Toggling.isOn(comp)) {\n            repositionMenus(comp);\n          }\n        }\n      };\n      var triggerExecute = function (comp, se) {\n        emitExecute(comp);\n        return Option.some(true);\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: augment(detail.dropdownBehaviours, [\n          Toggling.config({\n            toggleClass: detail.toggleClass,\n            aria: { mode: 'expanded' }\n          }),\n          Coupling.config({\n            others: {\n              sandbox: function (hotspot) {\n                return makeSandbox(detail, hotspot, {\n                  onOpen: function () {\n                    Toggling.on(hotspot);\n                  },\n                  onClose: function () {\n                    Toggling.off(hotspot);\n                  }\n                });\n              }\n            }\n          }),\n          Keying.config({\n            mode: 'special',\n            onSpace: triggerExecute,\n            onEnter: triggerExecute,\n            onDown: function (comp, se) {\n              if (Dropdown.isOpen(comp)) {\n                var sandbox = Coupling.getCoupled(comp, 'sandbox');\n                switchToMenu(sandbox);\n              } else {\n                Dropdown.open(comp);\n              }\n              return Option.some(true);\n            },\n            onEscape: function (comp, se) {\n              if (Dropdown.isOpen(comp)) {\n                Dropdown.close(comp);\n                return Option.some(true);\n              } else {\n                return Option.none();\n              }\n            }\n          }),\n          Focusing.config({})\n        ]),\n        events: events$7(Option.some(action)),\n        eventOrder: __assign(__assign({}, detail.eventOrder), (_a = {}, _a[execute()] = [\n          'disabling',\n          'toggling',\n          'alloy.base.behaviour'\n        ], _a)),\n        apis: apis,\n        domModification: {\n          attributes: __assign(__assign({ 'aria-haspopup': 'true' }, detail.role.fold(function () {\n            return {};\n          }, function (role) {\n            return { role: role };\n          })), detail.dom.tag === 'button' ? { type: lookupAttr('type').getOr('button') } : {})\n        }\n      };\n    };\n    var Dropdown = composite$1({\n      name: 'Dropdown',\n      configFields: schema$g(),\n      partFields: parts$4(),\n      factory: factory$6,\n      apis: {\n        open: function (apis, comp) {\n          return apis.open(comp);\n        },\n        expand: function (apis, comp) {\n          return apis.expand(comp);\n        },\n        close: function (apis, comp) {\n          return apis.close(comp);\n        },\n        isOpen: function (apis, comp) {\n          return apis.isOpen(comp);\n        },\n        repositionMenus: function (apis, comp) {\n          return apis.repositionMenus(comp);\n        }\n      }\n    });\n\n    var exhibit$5 = function (base, unselectConfig) {\n      return nu$6({\n        styles: {\n          '-webkit-user-select': 'none',\n          'user-select': 'none',\n          '-ms-user-select': 'none',\n          '-moz-user-select': '-moz-none'\n        },\n        attributes: { unselectable: 'on' }\n      });\n    };\n    var events$b = function (unselectConfig) {\n      return derive([abort(selectstart(), constant(true))]);\n    };\n\n    var ActiveUnselecting = /*#__PURE__*/Object.freeze({\n        events: events$b,\n        exhibit: exhibit$5\n    });\n\n    var Unselecting = create$1({\n      fields: [],\n      name: 'unselecting',\n      active: ActiveUnselecting\n    });\n\n    var renderPanelButton = function (spec, sharedBackstage) {\n      return Dropdown.sketch({\n        dom: spec.dom,\n        components: spec.components,\n        toggleClass: 'mce-active',\n        dropdownBehaviours: derive$1([\n          Unselecting.config({}),\n          Tabstopping.config({})\n        ]),\n        layouts: spec.layouts,\n        sandboxClasses: ['tox-dialog__popups'],\n        lazySink: sharedBackstage.getSink,\n        fetch: function (comp) {\n          return Future.nu(function (callback) {\n            return spec.fetch(callback);\n          }).map(function (items) {\n            return Option.from(createTieredDataFrom(deepMerge(createPartialChoiceMenu(generate$1('menu-value'), items, function (value) {\n              spec.onItemAction(comp, value);\n            }, spec.columns, spec.presets, ItemResponse$1.CLOSE_ON_EXECUTE, function () {\n              return false;\n            }, sharedBackstage.providers), { movement: deriveMenuMovement(spec.columns, spec.presets) })));\n          });\n        },\n        parts: { menu: part(false, 1, spec.presets) }\n      });\n    };\n\n    var colorInputChangeEvent = generate$1('color-input-change');\n    var colorSwatchChangeEvent = generate$1('color-swatch-change');\n    var colorPickerCancelEvent = generate$1('color-picker-cancel');\n    var renderColorInput = function (spec, sharedBackstage, colorInputBackstage) {\n      var pField = FormField.parts().field({\n        factory: Input,\n        inputClasses: ['tox-textfield'],\n        onSetValue: function (c) {\n          return Invalidating.run(c).get(function () {\n          });\n        },\n        inputBehaviours: derive$1([\n          Tabstopping.config({}),\n          Invalidating.config({\n            invalidClass: 'tox-textbox-field-invalid',\n            getRoot: function (comp) {\n              return parent(comp.element());\n            },\n            notify: {\n              onValid: function (comp) {\n                var val = Representing.getValue(comp);\n                emitWith(comp, colorInputChangeEvent, { color: val });\n              }\n            },\n            validator: {\n              validateOnLoad: false,\n              validate: function (input) {\n                var inputValue = Representing.getValue(input);\n                if (inputValue.length === 0) {\n                  return Future.pure(Result.value(true));\n                } else {\n                  var span = Element.fromTag('span');\n                  set$2(span, 'background-color', inputValue);\n                  var res = getRaw(span, 'background-color').fold(function () {\n                    return Result.error('blah');\n                  }, function (_) {\n                    return Result.value(inputValue);\n                  });\n                  return Future.pure(res);\n                }\n              }\n            }\n          })\n        ]),\n        selectOnFocus: false\n      });\n      var pLabel = spec.label.map(function (label) {\n        return renderLabel(label, sharedBackstage.providers);\n      });\n      var emitSwatchChange = function (colorBit, value) {\n        emitWith(colorBit, colorSwatchChangeEvent, { value: value });\n      };\n      var onItemAction = function (comp, value) {\n        memColorButton.getOpt(comp).each(function (colorBit) {\n          if (value === 'custom') {\n            colorInputBackstage.colorPicker(function (valueOpt) {\n              valueOpt.fold(function () {\n                return emit(colorBit, colorPickerCancelEvent);\n              }, function (value) {\n                emitSwatchChange(colorBit, value);\n                Settings.addColor(value);\n              });\n            }, '#ffffff');\n          } else if (value === 'remove') {\n            emitSwatchChange(colorBit, '');\n          } else {\n            emitSwatchChange(colorBit, value);\n          }\n        });\n      };\n      var memColorButton = record(renderPanelButton({\n        dom: {\n          tag: 'span',\n          attributes: { 'aria-label': sharedBackstage.providers.translate('Color swatch') }\n        },\n        layouts: Option.some({\n          onRtl: function () {\n            return [southeast$1];\n          },\n          onLtr: function () {\n            return [southwest$1];\n          }\n        }),\n        components: [],\n        fetch: ColorSwatch.getFetch(colorInputBackstage.getColors(), colorInputBackstage.hasCustomColors()),\n        columns: colorInputBackstage.getColorCols(),\n        presets: 'color',\n        onItemAction: onItemAction\n      }, sharedBackstage));\n      return FormField.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-form__group']\n        },\n        components: pLabel.toArray().concat([{\n            dom: {\n              tag: 'div',\n              classes: ['tox-color-input']\n            },\n            components: [\n              pField,\n              memColorButton.asSpec()\n            ]\n          }]),\n        fieldBehaviours: derive$1([config('form-field-events', [\n            run(colorInputChangeEvent, function (comp, se) {\n              memColorButton.getOpt(comp).each(function (colorButton) {\n                set$2(colorButton.element(), 'background-color', se.event().color());\n              });\n              emitWith(comp, formChangeEvent, { name: spec.name });\n            }),\n            run(colorSwatchChangeEvent, function (comp, se) {\n              FormField.getField(comp).each(function (field) {\n                Representing.setValue(field, se.event().value());\n                Composing.getCurrent(comp).each(Focusing.focus);\n              });\n            }),\n            run(colorPickerCancelEvent, function (comp, se) {\n              FormField.getField(comp).each(function (field) {\n                Composing.getCurrent(comp).each(Focusing.focus);\n              });\n            })\n          ])])\n      });\n    };\n\n    var hsvColour = function (hue, saturation, value) {\n      return {\n        hue: constant(hue),\n        saturation: constant(saturation),\n        value: constant(value)\n      };\n    };\n    var fromRgb = function (rgbaColour) {\n      var h = 0;\n      var s = 0;\n      var v = 0;\n      var r = rgbaColour.red() / 255;\n      var g = rgbaColour.green() / 255;\n      var b = rgbaColour.blue() / 255;\n      var minRGB = Math.min(r, Math.min(g, b));\n      var maxRGB = Math.max(r, Math.max(g, b));\n      if (minRGB === maxRGB) {\n        v = minRGB;\n        return hsvColour(0, 0, v * 100);\n      }\n      var d = r === minRGB ? g - b : b === minRGB ? r - g : b - r;\n      h = r === minRGB ? 3 : b === minRGB ? 1 : 5;\n      h = 60 * (h - d / (maxRGB - minRGB));\n      s = (maxRGB - minRGB) / maxRGB;\n      v = maxRGB;\n      return hsvColour(Math.round(h), Math.round(s * 100), Math.round(v * 100));\n    };\n\n    var calcHex = function (value) {\n      var hue = (100 - value) / 100 * 360;\n      var hsv = hsvColour(hue, 100, 100);\n      var rgb = fromHsv(hsv);\n      return fromRgba(rgb);\n    };\n\n    var fieldsUpdate = constant(generate$1('rgb-hex-update'));\n    var sliderUpdate = constant(generate$1('slider-update'));\n    var paletteUpdate = constant(generate$1('palette-update'));\n\n    var labelPart = optional({\n      schema: [strict$1('dom')],\n      name: 'label'\n    });\n    var edgePart = function (name) {\n      return optional({\n        name: '' + name + '-edge',\n        overrides: function (detail) {\n          var action = detail.model.manager.edgeActions[name];\n          return action.fold(function () {\n            return {};\n          }, function (a) {\n            return {\n              events: derive([\n                runActionExtra(touchstart(), a, [detail]),\n                runActionExtra(mousedown(), a, [detail]),\n                runActionExtra(mousemove(), function (l, se, det) {\n                  if (det.mouseIsDown.get()) {\n                    a(l, det);\n                  }\n                }, [detail])\n              ])\n            };\n          });\n        }\n      });\n    };\n    var tlEdgePart = edgePart('top-left');\n    var tedgePart = edgePart('top');\n    var trEdgePart = edgePart('top-right');\n    var redgePart = edgePart('right');\n    var brEdgePart = edgePart('bottom-right');\n    var bedgePart = edgePart('bottom');\n    var blEdgePart = edgePart('bottom-left');\n    var ledgePart = edgePart('left');\n    var thumbPart = required({\n      name: 'thumb',\n      defaults: constant({ dom: { styles: { position: 'absolute' } } }),\n      overrides: function (detail) {\n        return {\n          events: derive([\n            redirectToPart(touchstart(), detail, 'spectrum'),\n            redirectToPart(touchmove(), detail, 'spectrum'),\n            redirectToPart(touchend(), detail, 'spectrum'),\n            redirectToPart(mousedown(), detail, 'spectrum'),\n            redirectToPart(mousemove(), detail, 'spectrum'),\n            redirectToPart(mouseup(), detail, 'spectrum')\n          ])\n        };\n      }\n    });\n    var spectrumPart = required({\n      schema: [state$1('mouseIsDown', function () {\n          return Cell(false);\n        })],\n      name: 'spectrum',\n      overrides: function (detail) {\n        var modelDetail = detail.model;\n        var model = modelDetail.manager;\n        var setValueFrom = function (component, simulatedEvent) {\n          return model.getValueFromEvent(simulatedEvent).map(function (value) {\n            return model.setValueFrom(component, detail, value);\n          });\n        };\n        return {\n          behaviours: derive$1([\n            Keying.config({\n              mode: 'special',\n              onLeft: function (spectrum) {\n                return model.onLeft(spectrum, detail);\n              },\n              onRight: function (spectrum) {\n                return model.onRight(spectrum, detail);\n              },\n              onUp: function (spectrum) {\n                return model.onUp(spectrum, detail);\n              },\n              onDown: function (spectrum) {\n                return model.onDown(spectrum, detail);\n              }\n            }),\n            Focusing.config({})\n          ]),\n          events: derive([\n            run(touchstart(), setValueFrom),\n            run(touchmove(), setValueFrom),\n            run(mousedown(), setValueFrom),\n            run(mousemove(), function (spectrum, se) {\n              if (detail.mouseIsDown.get()) {\n                setValueFrom(spectrum, se);\n              }\n            })\n          ])\n        };\n      }\n    });\n    var SliderParts = [\n      labelPart,\n      ledgePart,\n      redgePart,\n      tedgePart,\n      bedgePart,\n      tlEdgePart,\n      trEdgePart,\n      blEdgePart,\n      brEdgePart,\n      thumbPart,\n      spectrumPart\n    ];\n\n    var _sliderChangeEvent = 'slider.change.value';\n    var sliderChangeEvent = constant(_sliderChangeEvent);\n    var isTouchEvent = function (evt) {\n      return evt.type.indexOf('touch') !== -1;\n    };\n    var getEventSource = function (simulatedEvent) {\n      var evt = simulatedEvent.event().raw();\n      if (isTouchEvent(evt)) {\n        var touchEvent = evt;\n        return touchEvent.touches !== undefined && touchEvent.touches.length === 1 ? Option.some(touchEvent.touches[0]).map(function (t) {\n          return Position(t.clientX, t.clientY);\n        }) : Option.none();\n      } else {\n        var mouseEvent = evt;\n        return mouseEvent.clientX !== undefined ? Option.some(mouseEvent).map(function (me) {\n          return Position(me.clientX, me.clientY);\n        }) : Option.none();\n      }\n    };\n\n    var t = 'top', r$1 = 'right', b = 'bottom', l = 'left';\n    var minX = function (detail) {\n      return detail.model.minX;\n    };\n    var minY = function (detail) {\n      return detail.model.minY;\n    };\n    var min1X = function (detail) {\n      return detail.model.minX - 1;\n    };\n    var min1Y = function (detail) {\n      return detail.model.minY - 1;\n    };\n    var maxX = function (detail) {\n      return detail.model.maxX;\n    };\n    var maxY = function (detail) {\n      return detail.model.maxY;\n    };\n    var max1X = function (detail) {\n      return detail.model.maxX + 1;\n    };\n    var max1Y = function (detail) {\n      return detail.model.maxY + 1;\n    };\n    var range$2 = function (detail, max, min) {\n      return max(detail) - min(detail);\n    };\n    var xRange = function (detail) {\n      return range$2(detail, maxX, minX);\n    };\n    var yRange = function (detail) {\n      return range$2(detail, maxY, minY);\n    };\n    var halfX = function (detail) {\n      return xRange(detail) / 2;\n    };\n    var halfY = function (detail) {\n      return yRange(detail) / 2;\n    };\n    var step = function (detail) {\n      return detail.stepSize;\n    };\n    var snap = function (detail) {\n      return detail.snapToGrid;\n    };\n    var snapStart = function (detail) {\n      return detail.snapStart;\n    };\n    var rounded = function (detail) {\n      return detail.rounded;\n    };\n    var hasEdge = function (detail, edgeName) {\n      return detail[edgeName + '-edge'] !== undefined;\n    };\n    var hasLEdge = function (detail) {\n      return hasEdge(detail, l);\n    };\n    var hasREdge = function (detail) {\n      return hasEdge(detail, r$1);\n    };\n    var hasTEdge = function (detail) {\n      return hasEdge(detail, t);\n    };\n    var hasBEdge = function (detail) {\n      return hasEdge(detail, b);\n    };\n    var currentValue = function (detail) {\n      return detail.model.value.get();\n    };\n\n    var xValue = function (x) {\n      return { x: constant(x) };\n    };\n    var yValue = function (y) {\n      return { y: constant(y) };\n    };\n    var xyValue = function (x, y) {\n      return {\n        x: constant(x),\n        y: constant(y)\n      };\n    };\n    var fireSliderChange = function (component, value) {\n      emitWith(component, sliderChangeEvent(), { value: value });\n    };\n    var setToTLEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(min1X(detail), min1Y(detail)));\n    };\n    var setToTEdge = function (edge, detail) {\n      fireSliderChange(edge, yValue(min1Y(detail)));\n    };\n    var setToTEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(halfX(detail), min1Y(detail)));\n    };\n    var setToTREdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(max1X(detail), min1Y(detail)));\n    };\n    var setToREdge = function (edge, detail) {\n      fireSliderChange(edge, xValue(max1X(detail)));\n    };\n    var setToREdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(max1X(detail), halfY(detail)));\n    };\n    var setToBREdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(max1X(detail), max1Y(detail)));\n    };\n    var setToBEdge = function (edge, detail) {\n      fireSliderChange(edge, yValue(max1Y(detail)));\n    };\n    var setToBEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(halfX(detail), max1Y(detail)));\n    };\n    var setToBLEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(min1X(detail), max1Y(detail)));\n    };\n    var setToLEdge = function (edge, detail) {\n      fireSliderChange(edge, xValue(min1X(detail)));\n    };\n    var setToLEdgeXY = function (edge, detail) {\n      fireSliderChange(edge, xyValue(min1X(detail), halfY(detail)));\n    };\n\n    var reduceBy = function (value, min, max, step) {\n      if (value < min) {\n        return value;\n      } else if (value > max) {\n        return max;\n      } else if (value === min) {\n        return min - 1;\n      } else {\n        return Math.max(min, value - step);\n      }\n    };\n    var increaseBy = function (value, min, max, step) {\n      if (value > max) {\n        return value;\n      } else if (value < min) {\n        return min;\n      } else if (value === max) {\n        return max + 1;\n      } else {\n        return Math.min(max, value + step);\n      }\n    };\n    var capValue = function (value, min, max) {\n      return Math.max(min, Math.min(max, value));\n    };\n    var snapValueOf = function (value, min, max, step, snapStart) {\n      return snapStart.fold(function () {\n        var initValue = value - min;\n        var extraValue = Math.round(initValue / step) * step;\n        return capValue(min + extraValue, min - 1, max + 1);\n      }, function (start) {\n        var remainder = (value - start) % step;\n        var adjustment = Math.round(remainder / step);\n        var rawSteps = Math.floor((value - start) / step);\n        var maxSteps = Math.floor((max - start) / step);\n        var numSteps = Math.min(maxSteps, rawSteps + adjustment);\n        var r = start + numSteps * step;\n        return Math.max(start, r);\n      });\n    };\n    var findOffsetOf = function (value, min, max) {\n      return Math.min(max, Math.max(value, min)) - min;\n    };\n    var findValueOf = function (args) {\n      var min = args.min, max = args.max, range = args.range, value = args.value, step = args.step, snap = args.snap, snapStart = args.snapStart, rounded = args.rounded, hasMinEdge = args.hasMinEdge, hasMaxEdge = args.hasMaxEdge, minBound = args.minBound, maxBound = args.maxBound, screenRange = args.screenRange;\n      var capMin = hasMinEdge ? min - 1 : min;\n      var capMax = hasMaxEdge ? max + 1 : max;\n      if (value < minBound) {\n        return capMin;\n      } else if (value > maxBound) {\n        return capMax;\n      } else {\n        var offset = findOffsetOf(value, minBound, maxBound);\n        var newValue = capValue(offset / screenRange * range + min, capMin, capMax);\n        if (snap && newValue >= min && newValue <= max) {\n          return snapValueOf(newValue, min, max, step, snapStart);\n        } else if (rounded) {\n          return Math.round(newValue);\n        } else {\n          return newValue;\n        }\n      }\n    };\n    var findOffsetOfValue = function (args) {\n      var min = args.min, max = args.max, range = args.range, value = args.value, hasMinEdge = args.hasMinEdge, hasMaxEdge = args.hasMaxEdge, maxBound = args.maxBound, maxOffset = args.maxOffset, centerMinEdge = args.centerMinEdge, centerMaxEdge = args.centerMaxEdge;\n      if (value < min) {\n        return hasMinEdge ? 0 : centerMinEdge;\n      } else if (value > max) {\n        return hasMaxEdge ? maxBound : centerMaxEdge;\n      } else {\n        return (value - min) / range * maxOffset;\n      }\n    };\n\n    var top = 'top', right = 'right', bottom = 'bottom', left = 'left', width = 'width', height = 'height';\n    var getBounds$1 = function (component) {\n      return component.element().dom().getBoundingClientRect();\n    };\n    var getBoundsProperty = function (bounds, property) {\n      return bounds[property];\n    };\n    var getMinXBounds = function (component) {\n      var bounds = getBounds$1(component);\n      return getBoundsProperty(bounds, left);\n    };\n    var getMaxXBounds = function (component) {\n      var bounds = getBounds$1(component);\n      return getBoundsProperty(bounds, right);\n    };\n    var getMinYBounds = function (component) {\n      var bounds = getBounds$1(component);\n      return getBoundsProperty(bounds, top);\n    };\n    var getMaxYBounds = function (component) {\n      var bounds = getBounds$1(component);\n      return getBoundsProperty(bounds, bottom);\n    };\n    var getXScreenRange = function (component) {\n      var bounds = getBounds$1(component);\n      return getBoundsProperty(bounds, width);\n    };\n    var getYScreenRange = function (component) {\n      var bounds = getBounds$1(component);\n      return getBoundsProperty(bounds, height);\n    };\n    var getCenterOffsetOf = function (componentMinEdge, componentMaxEdge, spectrumMinEdge) {\n      return (componentMinEdge + componentMaxEdge) / 2 - spectrumMinEdge;\n    };\n    var getXCenterOffSetOf = function (component, spectrum) {\n      var componentBounds = getBounds$1(component);\n      var spectrumBounds = getBounds$1(spectrum);\n      var componentMinEdge = getBoundsProperty(componentBounds, left);\n      var componentMaxEdge = getBoundsProperty(componentBounds, right);\n      var spectrumMinEdge = getBoundsProperty(spectrumBounds, left);\n      return getCenterOffsetOf(componentMinEdge, componentMaxEdge, spectrumMinEdge);\n    };\n    var getYCenterOffSetOf = function (component, spectrum) {\n      var componentBounds = getBounds$1(component);\n      var spectrumBounds = getBounds$1(spectrum);\n      var componentMinEdge = getBoundsProperty(componentBounds, top);\n      var componentMaxEdge = getBoundsProperty(componentBounds, bottom);\n      var spectrumMinEdge = getBoundsProperty(spectrumBounds, top);\n      return getCenterOffsetOf(componentMinEdge, componentMaxEdge, spectrumMinEdge);\n    };\n\n    var fireSliderChange$1 = function (spectrum, value) {\n      emitWith(spectrum, sliderChangeEvent(), { value: value });\n    };\n    var sliderValue = function (x) {\n      return { x: constant(x) };\n    };\n    var findValueOfOffset = function (spectrum, detail, left) {\n      var args = {\n        min: minX(detail),\n        max: maxX(detail),\n        range: xRange(detail),\n        value: left,\n        step: step(detail),\n        snap: snap(detail),\n        snapStart: snapStart(detail),\n        rounded: rounded(detail),\n        hasMinEdge: hasLEdge(detail),\n        hasMaxEdge: hasREdge(detail),\n        minBound: getMinXBounds(spectrum),\n        maxBound: getMaxXBounds(spectrum),\n        screenRange: getXScreenRange(spectrum)\n      };\n      return findValueOf(args);\n    };\n    var setValueFrom = function (spectrum, detail, value) {\n      var xValue = findValueOfOffset(spectrum, detail, value);\n      var sliderVal = sliderValue(xValue);\n      fireSliderChange$1(spectrum, sliderVal);\n      return xValue;\n    };\n    var setToMin = function (spectrum, detail) {\n      var min = minX(detail);\n      fireSliderChange$1(spectrum, sliderValue(min));\n    };\n    var setToMax = function (spectrum, detail) {\n      var max = maxX(detail);\n      fireSliderChange$1(spectrum, sliderValue(max));\n    };\n    var moveBy = function (direction, spectrum, detail) {\n      var f = direction > 0 ? increaseBy : reduceBy;\n      var xValue = f(currentValue(detail).x(), minX(detail), maxX(detail), step(detail));\n      fireSliderChange$1(spectrum, sliderValue(xValue));\n      return Option.some(xValue);\n    };\n    var handleMovement = function (direction) {\n      return function (spectrum, detail) {\n        return moveBy(direction, spectrum, detail).map(function () {\n          return true;\n        });\n      };\n    };\n    var getValueFromEvent = function (simulatedEvent) {\n      var pos = getEventSource(simulatedEvent);\n      return pos.map(function (p) {\n        return p.left();\n      });\n    };\n    var findOffsetOfValue$1 = function (spectrum, detail, value, minEdge, maxEdge) {\n      var minOffset = 0;\n      var maxOffset = getXScreenRange(spectrum);\n      var centerMinEdge = minEdge.bind(function (edge) {\n        return Option.some(getXCenterOffSetOf(edge, spectrum));\n      }).getOr(minOffset);\n      var centerMaxEdge = maxEdge.bind(function (edge) {\n        return Option.some(getXCenterOffSetOf(edge, spectrum));\n      }).getOr(maxOffset);\n      var args = {\n        min: minX(detail),\n        max: maxX(detail),\n        range: xRange(detail),\n        value: value,\n        hasMinEdge: hasLEdge(detail),\n        hasMaxEdge: hasREdge(detail),\n        minBound: getMinXBounds(spectrum),\n        minOffset: minOffset,\n        maxBound: getMaxXBounds(spectrum),\n        maxOffset: maxOffset,\n        centerMinEdge: centerMinEdge,\n        centerMaxEdge: centerMaxEdge\n      };\n      return findOffsetOfValue(args);\n    };\n    var findPositionOfValue = function (slider, spectrum, value, minEdge, maxEdge, detail) {\n      var offset = findOffsetOfValue$1(spectrum, detail, value, minEdge, maxEdge);\n      return getMinXBounds(spectrum) - getMinXBounds(slider) + offset;\n    };\n    var setPositionFromValue = function (slider, thumb, detail, edges) {\n      var value = currentValue(detail);\n      var pos = findPositionOfValue(slider, edges.getSpectrum(slider), value.x(), edges.getLeftEdge(slider), edges.getRightEdge(slider), detail);\n      var thumbRadius = get$7(thumb.element()) / 2;\n      set$2(thumb.element(), 'left', pos - thumbRadius + 'px');\n    };\n    var onLeft = handleMovement(-1);\n    var onRight = handleMovement(1);\n    var onUp = Option.none;\n    var onDown = Option.none;\n    var edgeActions = {\n      'top-left': Option.none(),\n      'top': Option.none(),\n      'top-right': Option.none(),\n      'right': Option.some(setToREdge),\n      'bottom-right': Option.none(),\n      'bottom': Option.none(),\n      'bottom-left': Option.none(),\n      'left': Option.some(setToLEdge)\n    };\n\n    var HorizontalModel = /*#__PURE__*/Object.freeze({\n        setValueFrom: setValueFrom,\n        setToMin: setToMin,\n        setToMax: setToMax,\n        findValueOfOffset: findValueOfOffset,\n        getValueFromEvent: getValueFromEvent,\n        findPositionOfValue: findPositionOfValue,\n        setPositionFromValue: setPositionFromValue,\n        onLeft: onLeft,\n        onRight: onRight,\n        onUp: onUp,\n        onDown: onDown,\n        edgeActions: edgeActions\n    });\n\n    var fireSliderChange$2 = function (spectrum, value) {\n      emitWith(spectrum, sliderChangeEvent(), { value: value });\n    };\n    var sliderValue$1 = function (y) {\n      return { y: constant(y) };\n    };\n    var findValueOfOffset$1 = function (spectrum, detail, top) {\n      var args = {\n        min: minY(detail),\n        max: maxY(detail),\n        range: yRange(detail),\n        value: top,\n        step: step(detail),\n        snap: snap(detail),\n        snapStart: snapStart(detail),\n        rounded: rounded(detail),\n        hasMinEdge: hasTEdge(detail),\n        hasMaxEdge: hasBEdge(detail),\n        minBound: getMinYBounds(spectrum),\n        maxBound: getMaxYBounds(spectrum),\n        screenRange: getYScreenRange(spectrum)\n      };\n      return findValueOf(args);\n    };\n    var setValueFrom$1 = function (spectrum, detail, value) {\n      var yValue = findValueOfOffset$1(spectrum, detail, value);\n      var sliderVal = sliderValue$1(yValue);\n      fireSliderChange$2(spectrum, sliderVal);\n      return yValue;\n    };\n    var setToMin$1 = function (spectrum, detail) {\n      var min = minY(detail);\n      fireSliderChange$2(spectrum, sliderValue$1(min));\n    };\n    var setToMax$1 = function (spectrum, detail) {\n      var max = maxY(detail);\n      fireSliderChange$2(spectrum, sliderValue$1(max));\n    };\n    var moveBy$1 = function (direction, spectrum, detail) {\n      var f = direction > 0 ? increaseBy : reduceBy;\n      var yValue = f(currentValue(detail).y(), minY(detail), maxY(detail), step(detail));\n      fireSliderChange$2(spectrum, sliderValue$1(yValue));\n      return Option.some(yValue);\n    };\n    var handleMovement$1 = function (direction) {\n      return function (spectrum, detail) {\n        return moveBy$1(direction, spectrum, detail).map(function () {\n          return true;\n        });\n      };\n    };\n    var getValueFromEvent$1 = function (simulatedEvent) {\n      var pos = getEventSource(simulatedEvent);\n      return pos.map(function (p) {\n        return p.top();\n      });\n    };\n    var findOffsetOfValue$2 = function (spectrum, detail, value, minEdge, maxEdge) {\n      var minOffset = 0;\n      var maxOffset = getYScreenRange(spectrum);\n      var centerMinEdge = minEdge.bind(function (edge) {\n        return Option.some(getYCenterOffSetOf(edge, spectrum));\n      }).getOr(minOffset);\n      var centerMaxEdge = maxEdge.bind(function (edge) {\n        return Option.some(getYCenterOffSetOf(edge, spectrum));\n      }).getOr(maxOffset);\n      var args = {\n        min: minY(detail),\n        max: maxY(detail),\n        range: yRange(detail),\n        value: value,\n        hasMinEdge: hasTEdge(detail),\n        hasMaxEdge: hasBEdge(detail),\n        minBound: getMinYBounds(spectrum),\n        minOffset: minOffset,\n        maxBound: getMaxYBounds(spectrum),\n        maxOffset: maxOffset,\n        centerMinEdge: centerMinEdge,\n        centerMaxEdge: centerMaxEdge\n      };\n      return findOffsetOfValue(args);\n    };\n    var findPositionOfValue$1 = function (slider, spectrum, value, minEdge, maxEdge, detail) {\n      var offset = findOffsetOfValue$2(spectrum, detail, value, minEdge, maxEdge);\n      return getMinYBounds(spectrum) - getMinYBounds(slider) + offset;\n    };\n    var setPositionFromValue$1 = function (slider, thumb, detail, edges) {\n      var value = currentValue(detail);\n      var pos = findPositionOfValue$1(slider, edges.getSpectrum(slider), value.y(), edges.getTopEdge(slider), edges.getBottomEdge(slider), detail);\n      var thumbRadius = get$6(thumb.element()) / 2;\n      set$2(thumb.element(), 'top', pos - thumbRadius + 'px');\n    };\n    var onLeft$1 = Option.none;\n    var onRight$1 = Option.none;\n    var onUp$1 = handleMovement$1(-1);\n    var onDown$1 = handleMovement$1(1);\n    var edgeActions$1 = {\n      'top-left': Option.none(),\n      'top': Option.some(setToTEdge),\n      'top-right': Option.none(),\n      'right': Option.none(),\n      'bottom-right': Option.none(),\n      'bottom': Option.some(setToBEdge),\n      'bottom-left': Option.none(),\n      'left': Option.none()\n    };\n\n    var VerticalModel = /*#__PURE__*/Object.freeze({\n        setValueFrom: setValueFrom$1,\n        setToMin: setToMin$1,\n        setToMax: setToMax$1,\n        findValueOfOffset: findValueOfOffset$1,\n        getValueFromEvent: getValueFromEvent$1,\n        findPositionOfValue: findPositionOfValue$1,\n        setPositionFromValue: setPositionFromValue$1,\n        onLeft: onLeft$1,\n        onRight: onRight$1,\n        onUp: onUp$1,\n        onDown: onDown$1,\n        edgeActions: edgeActions$1\n    });\n\n    var fireSliderChange$3 = function (spectrum, value) {\n      emitWith(spectrum, sliderChangeEvent(), { value: value });\n    };\n    var sliderValue$2 = function (x, y) {\n      return {\n        x: constant(x),\n        y: constant(y)\n      };\n    };\n    var setValueFrom$2 = function (spectrum, detail, value) {\n      var xValue = findValueOfOffset(spectrum, detail, value.left());\n      var yValue = findValueOfOffset$1(spectrum, detail, value.top());\n      var val = sliderValue$2(xValue, yValue);\n      fireSliderChange$3(spectrum, val);\n      return val;\n    };\n    var moveBy$2 = function (direction, isVerticalMovement, spectrum, detail) {\n      var f = direction > 0 ? increaseBy : reduceBy;\n      var xValue = isVerticalMovement ? currentValue(detail).x() : f(currentValue(detail).x(), minX(detail), maxX(detail), step(detail));\n      var yValue = !isVerticalMovement ? currentValue(detail).y() : f(currentValue(detail).y(), minY(detail), maxY(detail), step(detail));\n      fireSliderChange$3(spectrum, sliderValue$2(xValue, yValue));\n      return Option.some(xValue);\n    };\n    var handleMovement$2 = function (direction, isVerticalMovement) {\n      return function (spectrum, detail) {\n        return moveBy$2(direction, isVerticalMovement, spectrum, detail).map(function () {\n          return true;\n        });\n      };\n    };\n    var setToMin$2 = function (spectrum, detail) {\n      var mX = minX(detail);\n      var mY = minY(detail);\n      fireSliderChange$3(spectrum, sliderValue$2(mX, mY));\n    };\n    var setToMax$2 = function (spectrum, detail) {\n      var mX = maxX(detail);\n      var mY = maxY(detail);\n      fireSliderChange$3(spectrum, sliderValue$2(mX, mY));\n    };\n    var getValueFromEvent$2 = function (simulatedEvent) {\n      return getEventSource(simulatedEvent);\n    };\n    var setPositionFromValue$2 = function (slider, thumb, detail, edges) {\n      var value = currentValue(detail);\n      var xPos = findPositionOfValue(slider, edges.getSpectrum(slider), value.x(), edges.getLeftEdge(slider), edges.getRightEdge(slider), detail);\n      var yPos = findPositionOfValue$1(slider, edges.getSpectrum(slider), value.y(), edges.getTopEdge(slider), edges.getBottomEdge(slider), detail);\n      var thumbXRadius = get$7(thumb.element()) / 2;\n      var thumbYRadius = get$6(thumb.element()) / 2;\n      set$2(thumb.element(), 'left', xPos - thumbXRadius + 'px');\n      set$2(thumb.element(), 'top', yPos - thumbYRadius + 'px');\n    };\n    var onLeft$2 = handleMovement$2(-1, false);\n    var onRight$2 = handleMovement$2(1, false);\n    var onUp$2 = handleMovement$2(-1, true);\n    var onDown$2 = handleMovement$2(1, true);\n    var edgeActions$2 = {\n      'top-left': Option.some(setToTLEdgeXY),\n      'top': Option.some(setToTEdgeXY),\n      'top-right': Option.some(setToTREdgeXY),\n      'right': Option.some(setToREdgeXY),\n      'bottom-right': Option.some(setToBREdgeXY),\n      'bottom': Option.some(setToBEdgeXY),\n      'bottom-left': Option.some(setToBLEdgeXY),\n      'left': Option.some(setToLEdgeXY)\n    };\n\n    var TwoDModel = /*#__PURE__*/Object.freeze({\n        setValueFrom: setValueFrom$2,\n        setToMin: setToMin$2,\n        setToMax: setToMax$2,\n        getValueFromEvent: getValueFromEvent$2,\n        setPositionFromValue: setPositionFromValue$2,\n        onLeft: onLeft$2,\n        onRight: onRight$2,\n        onUp: onUp$2,\n        onDown: onDown$2,\n        edgeActions: edgeActions$2\n    });\n\n    var SliderSchema = [\n      defaulted$1('stepSize', 1),\n      defaulted$1('onChange', noop),\n      defaulted$1('onChoose', noop),\n      defaulted$1('onInit', noop),\n      defaulted$1('onDragStart', noop),\n      defaulted$1('onDragEnd', noop),\n      defaulted$1('snapToGrid', false),\n      defaulted$1('rounded', true),\n      option('snapStart'),\n      strictOf('model', choose$1('mode', {\n        x: [\n          defaulted$1('minX', 0),\n          defaulted$1('maxX', 100),\n          state$1('value', function (spec) {\n            return Cell(spec.mode.minX);\n          }),\n          strict$1('getInitialValue'),\n          output('manager', HorizontalModel)\n        ],\n        y: [\n          defaulted$1('minY', 0),\n          defaulted$1('maxY', 100),\n          state$1('value', function (spec) {\n            return Cell(spec.mode.minY);\n          }),\n          strict$1('getInitialValue'),\n          output('manager', VerticalModel)\n        ],\n        xy: [\n          defaulted$1('minX', 0),\n          defaulted$1('maxX', 100),\n          defaulted$1('minY', 0),\n          defaulted$1('maxY', 100),\n          state$1('value', function (spec) {\n            return Cell({\n              x: constant(spec.mode.minX),\n              y: constant(spec.mode.minY)\n            });\n          }),\n          strict$1('getInitialValue'),\n          output('manager', TwoDModel)\n        ]\n      })),\n      field$1('sliderBehaviours', [\n        Keying,\n        Representing\n      ]),\n      state$1('mouseIsDown', function () {\n        return Cell(false);\n      })\n    ];\n\n    var sketch = function (detail, components, _spec, _externals) {\n      var _a;\n      var getThumb = function (component) {\n        return getPartOrDie(component, detail, 'thumb');\n      };\n      var getSpectrum = function (component) {\n        return getPartOrDie(component, detail, 'spectrum');\n      };\n      var getLeftEdge = function (component) {\n        return getPart(component, detail, 'left-edge');\n      };\n      var getRightEdge = function (component) {\n        return getPart(component, detail, 'right-edge');\n      };\n      var getTopEdge = function (component) {\n        return getPart(component, detail, 'top-edge');\n      };\n      var getBottomEdge = function (component) {\n        return getPart(component, detail, 'bottom-edge');\n      };\n      var modelDetail = detail.model;\n      var model = modelDetail.manager;\n      var refresh = function (slider, thumb) {\n        model.setPositionFromValue(slider, thumb, detail, {\n          getLeftEdge: getLeftEdge,\n          getRightEdge: getRightEdge,\n          getTopEdge: getTopEdge,\n          getBottomEdge: getBottomEdge,\n          getSpectrum: getSpectrum\n        });\n      };\n      var changeValue = function (slider, newValue) {\n        modelDetail.value.set(newValue);\n        var thumb = getThumb(slider);\n        refresh(slider, thumb);\n        detail.onChange(slider, thumb, newValue);\n        return Option.some(true);\n      };\n      var resetToMin = function (slider) {\n        model.setToMin(slider, detail);\n      };\n      var resetToMax = function (slider) {\n        model.setToMax(slider, detail);\n      };\n      var choose = function (slider) {\n        var fireOnChoose = function () {\n          getPart(slider, detail, 'thumb').each(function (thumb) {\n            var value = modelDetail.value.get();\n            detail.onChoose(slider, thumb, value);\n          });\n        };\n        var wasDown = detail.mouseIsDown.get();\n        detail.mouseIsDown.set(false);\n        if (wasDown) {\n          fireOnChoose();\n        }\n      };\n      var onDragStart = function (slider, simulatedEvent) {\n        simulatedEvent.stop();\n        detail.mouseIsDown.set(true);\n        detail.onDragStart(slider, getThumb(slider));\n      };\n      var onDragEnd = function (slider, simulatedEvent) {\n        simulatedEvent.stop();\n        detail.onDragEnd(slider, getThumb(slider));\n        choose(slider);\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: augment(detail.sliderBehaviours, [\n          Keying.config({\n            mode: 'special',\n            focusIn: function (slider) {\n              return getPart(slider, detail, 'spectrum').map(Keying.focusIn).map(constant(true));\n            }\n          }),\n          Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function (_) {\n                return modelDetail.value.get();\n              }\n            }\n          }),\n          Receiving.config({ channels: (_a = {}, _a[mouseReleased()] = { onReceive: choose }, _a) })\n        ]),\n        events: derive([\n          run(sliderChangeEvent(), function (slider, simulatedEvent) {\n            changeValue(slider, simulatedEvent.event().value());\n          }),\n          runOnAttached(function (slider, simulatedEvent) {\n            var getInitial = modelDetail.getInitialValue();\n            modelDetail.value.set(getInitial);\n            var thumb = getThumb(slider);\n            refresh(slider, thumb);\n            var spectrum = getSpectrum(slider);\n            detail.onInit(slider, thumb, spectrum, modelDetail.value.get());\n          }),\n          run(touchstart(), onDragStart),\n          run(touchend(), onDragEnd),\n          run(mousedown(), onDragStart),\n          run(mouseup(), onDragEnd)\n        ]),\n        apis: {\n          resetToMin: resetToMin,\n          resetToMax: resetToMax,\n          changeValue: changeValue,\n          refresh: refresh\n        },\n        domModification: { styles: { position: 'relative' } }\n      };\n    };\n\n    var Slider = composite$1({\n      name: 'Slider',\n      configFields: SliderSchema,\n      partFields: SliderParts,\n      factory: sketch,\n      apis: {\n        resetToMin: function (apis, slider) {\n          apis.resetToMin(slider);\n        },\n        resetToMax: function (apis, slider) {\n          apis.resetToMax(slider);\n        },\n        refresh: function (apis, slider) {\n          apis.refresh(slider);\n        }\n      }\n    });\n\n    var sliderFactory = function (translate, getClass) {\n      var spectrum = Slider.parts().spectrum({\n        dom: {\n          tag: 'div',\n          classes: [getClass('hue-slider-spectrum')],\n          attributes: { role: 'presentation' }\n        }\n      });\n      var thumb = Slider.parts().thumb({\n        dom: {\n          tag: 'div',\n          classes: [getClass('hue-slider-thumb')],\n          attributes: { role: 'presentation' }\n        }\n      });\n      return Slider.sketch({\n        dom: {\n          tag: 'div',\n          classes: [getClass('hue-slider')],\n          attributes: { role: 'presentation' }\n        },\n        rounded: false,\n        model: {\n          mode: 'y',\n          getInitialValue: constant({ y: constant(0) })\n        },\n        components: [\n          spectrum,\n          thumb\n        ],\n        sliderBehaviours: derive$1([Focusing.config({})]),\n        onChange: function (slider, _thumb, value) {\n          emitWith(slider, sliderUpdate(), { value: value });\n        }\n      });\n    };\n    var HueSlider = { sliderFactory: sliderFactory };\n\n    var owner$3 = 'form';\n    var schema$h = [field$1('formBehaviours', [Representing])];\n    var getPartName = function (name) {\n      return '<alloy.field.' + name + '>';\n    };\n    var sketch$1 = function (fSpec) {\n      var parts = function () {\n        var record = [];\n        var field = function (name, config) {\n          record.push(name);\n          return generateOne(owner$3, getPartName(name), config);\n        };\n        return {\n          field: field,\n          record: function () {\n            return record;\n          }\n        };\n      }();\n      var spec = fSpec(parts);\n      var partNames = parts.record();\n      var fieldParts = map(partNames, function (n) {\n        return required({\n          name: n,\n          pname: getPartName(n)\n        });\n      });\n      return composite(owner$3, schema$h, fieldParts, make$4, spec);\n    };\n    var toResult$1 = function (o, e) {\n      return o.fold(function () {\n        return Result.error(e);\n      }, Result.value);\n    };\n    var make$4 = function (detail, components, spec) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: augment(detail.formBehaviours, [Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function (form) {\n                var resPs = getAllParts(form, detail);\n                return map$1(resPs, function (resPThunk, pName) {\n                  return resPThunk().bind(function (v) {\n                    var opt = Composing.getCurrent(v);\n                    return toResult$1(opt, 'missing current');\n                  }).map(Representing.getValue);\n                });\n              },\n              setValue: function (form, values) {\n                each$1(values, function (newValue, key) {\n                  getPart(form, detail, key).each(function (wrapper) {\n                    Composing.getCurrent(wrapper).each(function (field) {\n                      Representing.setValue(field, newValue);\n                    });\n                  });\n                });\n              }\n            }\n          })]),\n        apis: {\n          getField: function (form, key) {\n            return getPart(form, detail, key).bind(Composing.getCurrent);\n          }\n        }\n      };\n    };\n    var Form = {\n      getField: makeApi(function (apis, component, key) {\n        return apis.getField(component, key);\n      }),\n      sketch: sketch$1\n    };\n\n    var validInput = generate$1('valid-input');\n    var invalidInput = generate$1('invalid-input');\n    var validatingInput = generate$1('validating-input');\n    var translatePrefix = 'colorcustom.rgb.';\n    var rgbFormFactory = function (translate, getClass, onValidHexx, onInvalidHexx) {\n      var invalidation = function (label, isValid) {\n        return Invalidating.config({\n          invalidClass: getClass('invalid'),\n          notify: {\n            onValidate: function (comp) {\n              emitWith(comp, validatingInput, { type: label });\n            },\n            onValid: function (comp) {\n              emitWith(comp, validInput, {\n                type: label,\n                value: Representing.getValue(comp)\n              });\n            },\n            onInvalid: function (comp) {\n              emitWith(comp, invalidInput, {\n                type: label,\n                value: Representing.getValue(comp)\n              });\n            }\n          },\n          validator: {\n            validate: function (comp) {\n              var value = Representing.getValue(comp);\n              var res = isValid(value) ? Result.value(true) : Result.error(translate('aria.input.invalid'));\n              return Future.pure(res);\n            },\n            validateOnLoad: false\n          }\n        });\n      };\n      var renderTextField = function (isValid, name, label, description, data) {\n        var helptext = translate(translatePrefix + 'range');\n        var pLabel = FormField.parts().label({\n          dom: {\n            tag: 'label',\n            innerHtml: label,\n            attributes: { 'aria-label': description }\n          }\n        });\n        var pField = FormField.parts().field({\n          data: data,\n          factory: Input,\n          inputAttributes: __assign({ type: 'text' }, name === 'hex' ? { 'aria-live': 'polite' } : {}),\n          inputClasses: [getClass('textfield')],\n          inputBehaviours: derive$1([\n            invalidation(name, isValid),\n            Tabstopping.config({})\n          ]),\n          onSetValue: function (input) {\n            if (Invalidating.isInvalid(input)) {\n              var run = Invalidating.run(input);\n              run.get(noop);\n            }\n          }\n        });\n        var comps = [\n          pLabel,\n          pField\n        ];\n        var concats = name !== 'hex' ? [FormField.parts()['aria-descriptor']({ text: helptext })] : [];\n        var components = comps.concat(concats);\n        return {\n          dom: {\n            tag: 'div',\n            attributes: { role: 'presentation' }\n          },\n          components: components\n        };\n      };\n      var copyRgbToHex = function (form, rgba) {\n        var hex = fromRgba(rgba);\n        Form.getField(form, 'hex').each(function (hexField) {\n          if (!Focusing.isFocused(hexField)) {\n            Representing.setValue(form, { hex: hex.value() });\n          }\n        });\n        return hex;\n      };\n      var copyRgbToForm = function (form, rgb) {\n        var red = rgb.red();\n        var green = rgb.green();\n        var blue = rgb.blue();\n        Representing.setValue(form, {\n          red: red,\n          green: green,\n          blue: blue\n        });\n      };\n      var memPreview = record({\n        dom: {\n          tag: 'div',\n          classes: [getClass('rgba-preview')],\n          styles: { 'background-color': 'white' },\n          attributes: { role: 'presentation' }\n        }\n      });\n      var updatePreview = function (anyInSystem, hex) {\n        memPreview.getOpt(anyInSystem).each(function (preview) {\n          set$2(preview.element(), 'background-color', '#' + hex.value());\n        });\n      };\n      var factory = function () {\n        var state = {\n          red: constant(Cell(Option.some(255))),\n          green: constant(Cell(Option.some(255))),\n          blue: constant(Cell(Option.some(255))),\n          hex: constant(Cell(Option.some('ffffff')))\n        };\n        var copyHexToRgb = function (form, hex) {\n          var rgb = fromHex(hex);\n          copyRgbToForm(form, rgb);\n          setValueRgb(rgb);\n        };\n        var get = function (prop) {\n          return state[prop]().get();\n        };\n        var set = function (prop, value) {\n          state[prop]().set(value);\n        };\n        var getValueRgb = function () {\n          return get('red').bind(function (red) {\n            return get('green').bind(function (green) {\n              return get('blue').map(function (blue) {\n                return rgbaColour(red, green, blue, 1);\n              });\n            });\n          });\n        };\n        var setValueRgb = function (rgb) {\n          var red = rgb.red();\n          var green = rgb.green();\n          var blue = rgb.blue();\n          set('red', Option.some(red));\n          set('green', Option.some(green));\n          set('blue', Option.some(blue));\n        };\n        var onInvalidInput = function (form, simulatedEvent) {\n          var data = simulatedEvent.event();\n          if (data.type() !== 'hex') {\n            set(data.type(), Option.none());\n          } else {\n            onInvalidHexx(form);\n          }\n        };\n        var onValidHex = function (form, value) {\n          onValidHexx(form);\n          var hex = hexColour(value);\n          set('hex', Option.some(value));\n          var rgb = fromHex(hex);\n          copyRgbToForm(form, rgb);\n          setValueRgb(rgb);\n          emitWith(form, fieldsUpdate(), { hex: hex });\n          updatePreview(form, hex);\n        };\n        var onValidRgb = function (form, prop, value) {\n          var val = parseInt(value, 10);\n          set(prop, Option.some(val));\n          getValueRgb().each(function (rgb) {\n            var hex = copyRgbToHex(form, rgb);\n            updatePreview(form, hex);\n          });\n        };\n        var isHexInputEvent = function (data) {\n          return data.type() === 'hex';\n        };\n        var onValidInput = function (form, simulatedEvent) {\n          var data = simulatedEvent.event();\n          if (isHexInputEvent(data)) {\n            onValidHex(form, data.value());\n          } else {\n            onValidRgb(form, data.type(), data.value());\n          }\n        };\n        var formPartStrings = function (key) {\n          return {\n            label: translate(translatePrefix + key + '.label'),\n            description: translate(translatePrefix + key + '.description')\n          };\n        };\n        var redStrings = formPartStrings('red');\n        var greenStrings = formPartStrings('green');\n        var blueStrings = formPartStrings('blue');\n        var hexStrings = formPartStrings('hex');\n        return deepMerge(Form.sketch(function (parts) {\n          return {\n            dom: {\n              tag: 'form',\n              classes: [getClass('rgb-form')],\n              attributes: { 'aria-label': translate('aria.color.picker') }\n            },\n            components: [\n              parts.field('red', FormField.sketch(renderTextField(isRgbaComponent, 'red', redStrings.label, redStrings.description, 255))),\n              parts.field('green', FormField.sketch(renderTextField(isRgbaComponent, 'green', greenStrings.label, greenStrings.description, 255))),\n              parts.field('blue', FormField.sketch(renderTextField(isRgbaComponent, 'blue', blueStrings.label, blueStrings.description, 255))),\n              parts.field('hex', FormField.sketch(renderTextField(isHexString, 'hex', hexStrings.label, hexStrings.description, 'ffffff'))),\n              memPreview.asSpec()\n            ],\n            formBehaviours: derive$1([\n              Invalidating.config({ invalidClass: getClass('form-invalid') }),\n              config('rgb-form-events', [\n                run(validInput, onValidInput),\n                run(invalidInput, onInvalidInput),\n                run(validatingInput, onInvalidInput)\n              ])\n            ])\n          };\n        }), {\n          apis: {\n            updateHex: function (form, hex) {\n              Representing.setValue(form, { hex: hex.value() });\n              copyHexToRgb(form, hex);\n              updatePreview(form, hex);\n            }\n          }\n        });\n      };\n      var rgbFormSketcher = single$2({\n        factory: factory,\n        name: 'RgbForm',\n        configFields: [],\n        apis: {\n          updateHex: function (apis, form, hex) {\n            apis.updateHex(form, hex);\n          }\n        },\n        extraApis: {}\n      });\n      return rgbFormSketcher;\n    };\n    var RgbForm = { rgbFormFactory: rgbFormFactory };\n\n    var paletteFactory = function (_translate, getClass) {\n      var spectrumPart = Slider.parts().spectrum({\n        dom: {\n          tag: 'canvas',\n          attributes: { role: 'presentation' },\n          classes: [getClass('sv-palette-spectrum')]\n        }\n      });\n      var thumbPart = Slider.parts().thumb({\n        dom: {\n          tag: 'div',\n          attributes: { role: 'presentation' },\n          classes: [getClass('sv-palette-thumb')],\n          innerHtml: '<div class=' + getClass('sv-palette-inner-thumb') + ' role=\"presentation\"></div>'\n        }\n      });\n      var setColour = function (canvas, rgba) {\n        var width = canvas.width, height = canvas.height;\n        var ctx = canvas.getContext('2d');\n        if (ctx === null) {\n          return;\n        }\n        ctx.fillStyle = rgba;\n        ctx.fillRect(0, 0, width, height);\n        var grdWhite = ctx.createLinearGradient(0, 0, width, 0);\n        grdWhite.addColorStop(0, 'rgba(255,255,255,1)');\n        grdWhite.addColorStop(1, 'rgba(255,255,255,0)');\n        ctx.fillStyle = grdWhite;\n        ctx.fillRect(0, 0, width, height);\n        var grdBlack = ctx.createLinearGradient(0, 0, 0, height);\n        grdBlack.addColorStop(0, 'rgba(0,0,0,0)');\n        grdBlack.addColorStop(1, 'rgba(0,0,0,1)');\n        ctx.fillStyle = grdBlack;\n        ctx.fillRect(0, 0, width, height);\n      };\n      var setSliderColour = function (slider, rgba) {\n        var canvas = slider.components()[0].element().dom();\n        setColour(canvas, toString(rgba));\n      };\n      var factory = function (_detail) {\n        var getInitialValue = constant({\n          x: constant(0),\n          y: constant(0)\n        });\n        var onChange = function (slider, _thumb, value) {\n          emitWith(slider, paletteUpdate(), { value: value });\n        };\n        var onInit = function (_slider, _thumb, spectrum, _value) {\n          setColour(spectrum.element().dom(), toString(redColour()));\n        };\n        var sliderBehaviours = derive$1([\n          Composing.config({ find: Option.some }),\n          Focusing.config({})\n        ]);\n        return Slider.sketch({\n          dom: {\n            tag: 'div',\n            attributes: { role: 'presentation' },\n            classes: [getClass('sv-palette')]\n          },\n          model: {\n            mode: 'xy',\n            getInitialValue: getInitialValue\n          },\n          rounded: false,\n          components: [\n            spectrumPart,\n            thumbPart\n          ],\n          onChange: onChange,\n          onInit: onInit,\n          sliderBehaviours: sliderBehaviours\n        });\n      };\n      var saturationBrightnessPaletteSketcher = single$2({\n        factory: factory,\n        name: 'SaturationBrightnessPalette',\n        configFields: [],\n        apis: {\n          setRgba: function (_apis, slider, rgba) {\n            setSliderColour(slider, rgba);\n          }\n        },\n        extraApis: {}\n      });\n      return saturationBrightnessPaletteSketcher;\n    };\n    var SaturationBrightnessPalette = { paletteFactory: paletteFactory };\n\n    var makeFactory = function (translate, getClass) {\n      var factory = function (detail) {\n        var rgbForm = RgbForm.rgbFormFactory(translate, getClass, detail.onValidHex, detail.onInvalidHex);\n        var sbPalette = SaturationBrightnessPalette.paletteFactory(translate, getClass);\n        var state = { paletteRgba: constant(Cell(redColour())) };\n        var memPalette = record(sbPalette.sketch({}));\n        var memRgb = record(rgbForm.sketch({}));\n        var updatePalette = function (anyInSystem, hex) {\n          memPalette.getOpt(anyInSystem).each(function (palette) {\n            var rgba = fromHex(hex);\n            state.paletteRgba().set(rgba);\n            sbPalette.setRgba(palette, rgba);\n          });\n        };\n        var updateFields = function (anyInSystem, hex) {\n          memRgb.getOpt(anyInSystem).each(function (form) {\n            rgbForm.updateHex(form, hex);\n          });\n        };\n        var runUpdates = function (anyInSystem, hex, updates) {\n          each(updates, function (update) {\n            update(anyInSystem, hex);\n          });\n        };\n        var paletteUpdates = function () {\n          var updates = [updateFields];\n          return function (form, simulatedEvent) {\n            var value = simulatedEvent.event().value();\n            var oldRgb = state.paletteRgba().get();\n            var hsvColour$1 = fromRgb(oldRgb);\n            var newHsvColour = hsvColour(hsvColour$1.hue(), value.x(), 100 - value.y());\n            var rgb = fromHsv(newHsvColour);\n            var nuHex = fromRgba(rgb);\n            runUpdates(form, nuHex, updates);\n          };\n        };\n        var sliderUpdates = function () {\n          var updates = [\n            updatePalette,\n            updateFields\n          ];\n          return function (form, simulatedEvent) {\n            var value = simulatedEvent.event().value();\n            var hex = calcHex(value.y());\n            runUpdates(form, hex, updates);\n          };\n        };\n        return {\n          uid: detail.uid,\n          dom: detail.dom,\n          components: [\n            memPalette.asSpec(),\n            HueSlider.sliderFactory(translate, getClass),\n            memRgb.asSpec()\n          ],\n          behaviours: derive$1([\n            config('colour-picker-events', [\n              run(paletteUpdate(), paletteUpdates()),\n              run(sliderUpdate(), sliderUpdates())\n            ]),\n            Composing.config({\n              find: function (comp) {\n                return memRgb.getOpt(comp);\n              }\n            }),\n            Keying.config({ mode: 'acyclic' })\n          ])\n        };\n      };\n      var colourPickerSketcher = single$2({\n        name: 'ColourPicker',\n        configFields: [\n          strict$1('dom'),\n          defaulted$1('onValidHex', noop),\n          defaulted$1('onInvalidHex', noop)\n        ],\n        factory: factory\n      });\n      return colourPickerSketcher;\n    };\n    var ColourPicker = { makeFactory: makeFactory };\n\n    var self$1 = function () {\n      return Composing.config({ find: Option.some });\n    };\n    var memento = function (mem) {\n      return Composing.config({ find: mem.getOpt });\n    };\n    var childAt = function (index) {\n      return Composing.config({\n        find: function (comp) {\n          return child(comp.element(), index).bind(function (element) {\n            return comp.getSystem().getByDom(element).toOption();\n          });\n        }\n      });\n    };\n    var ComposingConfigs = {\n      self: self$1,\n      memento: memento,\n      childAt: childAt\n    };\n\n    var english = {\n      'colorcustom.rgb.red.label': 'R',\n      'colorcustom.rgb.red.description': 'Red component',\n      'colorcustom.rgb.green.label': 'G',\n      'colorcustom.rgb.green.description': 'Green component',\n      'colorcustom.rgb.blue.label': 'B',\n      'colorcustom.rgb.blue.description': 'Blue component',\n      'colorcustom.rgb.hex.label': '#',\n      'colorcustom.rgb.hex.description': 'Hex color code',\n      'colorcustom.rgb.range': 'Range 0 to 255',\n      'colorcustom.sb.saturation': 'Saturation',\n      'colorcustom.sb.brightness': 'Brightness',\n      'colorcustom.sb.picker': 'Saturation and Brightness Picker',\n      'colorcustom.sb.palette': 'Saturation and Brightness Palette',\n      'colorcustom.sb.instructions': 'Use arrow keys to select saturation and brightness, on x and y axes',\n      'colorcustom.hue.hue': 'Hue',\n      'colorcustom.hue.slider': 'Hue Slider',\n      'colorcustom.hue.palette': 'Hue Palette',\n      'colorcustom.hue.instructions': 'Use arrow keys to select a hue',\n      'aria.color.picker': 'Color Picker',\n      'aria.input.invalid': 'Invalid input'\n    };\n    var getEnglishText = function (key) {\n      return english[key];\n    };\n    var translate$1 = function (key) {\n      return getEnglishText(key);\n    };\n    var renderColorPicker = function (spec) {\n      var getClass = function (key) {\n        return 'tox-' + key;\n      };\n      var colourPickerFactory = ColourPicker.makeFactory(translate$1, getClass);\n      var onValidHex = function (form) {\n        emitWith(form, formActionEvent, {\n          name: 'hex-valid',\n          value: true\n        });\n      };\n      var onInvalidHex = function (form) {\n        emitWith(form, formActionEvent, {\n          name: 'hex-valid',\n          value: false\n        });\n      };\n      var memPicker = record(colourPickerFactory.sketch({\n        dom: {\n          tag: 'div',\n          classes: [getClass('color-picker-container')],\n          attributes: { role: 'presentation' }\n        },\n        onValidHex: onValidHex,\n        onInvalidHex: onInvalidHex\n      }));\n      return {\n        dom: { tag: 'div' },\n        components: [memPicker.asSpec()],\n        behaviours: derive$1([\n          Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function (comp) {\n                var picker = memPicker.get(comp);\n                var optRgbForm = Composing.getCurrent(picker);\n                var optHex = optRgbForm.bind(function (rgbForm) {\n                  var formValues = Representing.getValue(rgbForm);\n                  return formValues.hex;\n                });\n                return optHex.map(function (hex) {\n                  return '#' + hex;\n                }).getOr('');\n              },\n              setValue: function (comp, newValue) {\n                var pattern = /^#([a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?)/;\n                var m = pattern.exec(newValue);\n                var picker = memPicker.get(comp);\n                var optRgbForm = Composing.getCurrent(picker);\n                optRgbForm.fold(function () {\n                  domGlobals.console.log('Can not find form');\n                }, function (rgbForm) {\n                  Representing.setValue(rgbForm, { hex: Option.from(m[1]).getOr('') });\n                  Form.getField(rgbForm, 'hex').each(function (hexField) {\n                    emit(hexField, input());\n                  });\n                });\n              }\n            }\n          }),\n          ComposingConfigs.self()\n        ])\n      };\n    };\n\n    var global$a = tinymce.util.Tools.resolve('tinymce.Resource');\n\n    var isOldCustomEditor = function (spec) {\n      return Object.prototype.hasOwnProperty.call(spec, 'init');\n    };\n    var renderCustomEditor = function (spec) {\n      var editorApi = Cell(Option.none());\n      var memReplaced = record({ dom: { tag: spec.tag } });\n      var initialValue = Cell(Option.none());\n      return {\n        dom: {\n          tag: 'div',\n          classes: ['tox-custom-editor']\n        },\n        behaviours: derive$1([\n          config('editor-foo-events', [runOnAttached(function (component) {\n              memReplaced.getOpt(component).each(function (ta) {\n                (isOldCustomEditor(spec) ? spec.init(ta.element().dom()) : global$a.load(spec.scriptId, spec.scriptUrl).then(function (init) {\n                  return init(ta.element().dom(), spec.settings);\n                })).then(function (ea) {\n                  initialValue.get().each(function (cvalue) {\n                    ea.setValue(cvalue);\n                  });\n                  initialValue.set(Option.none());\n                  editorApi.set(Option.some(ea));\n                });\n              });\n            })]),\n          Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function () {\n                return editorApi.get().fold(function () {\n                  return initialValue.get().getOr('');\n                }, function (ed) {\n                  return ed.getValue();\n                });\n              },\n              setValue: function (component, value) {\n                editorApi.get().fold(function () {\n                  initialValue.set(Option.some(value));\n                }, function (ed) {\n                  return ed.setValue(value);\n                });\n              }\n            }\n          }),\n          ComposingConfigs.self()\n        ]),\n        components: [memReplaced.asSpec()]\n      };\n    };\n\n    var processors = objOf([\n      defaulted$1('preprocess', identity),\n      defaulted$1('postprocess', identity)\n    ]);\n    var memento$1 = function (mem, rawProcessors) {\n      var ps = asRawOrDie('RepresentingConfigs.memento processors', processors, rawProcessors);\n      return Representing.config({\n        store: {\n          mode: 'manual',\n          getValue: function (comp) {\n            var other = mem.get(comp);\n            var rawValue = Representing.getValue(other);\n            return ps.postprocess(rawValue);\n          },\n          setValue: function (comp, rawValue) {\n            var newValue = ps.preprocess(rawValue);\n            var other = mem.get(comp);\n            Representing.setValue(other, newValue);\n          }\n        }\n      });\n    };\n    var withComp = function (optInitialValue, getter, setter) {\n      return Representing.config(deepMerge({\n        store: {\n          mode: 'manual',\n          getValue: getter,\n          setValue: setter\n        }\n      }, optInitialValue.map(function (initialValue) {\n        return { store: { initialValue: initialValue } };\n      }).getOr({})));\n    };\n    var withElement = function (initialValue, getter, setter) {\n      return withComp(initialValue, function (c) {\n        return getter(c.element());\n      }, function (c, v) {\n        return setter(c.element(), v);\n      });\n    };\n    var domValue = function (optInitialValue) {\n      return withElement(optInitialValue, get$5, set$3);\n    };\n    var domHtml = function (optInitialValue) {\n      return withElement(optInitialValue, get$1, set);\n    };\n    var memory$1 = function (initialValue) {\n      return Representing.config({\n        store: {\n          mode: 'memory',\n          initialValue: initialValue\n        }\n      });\n    };\n    var RepresentingConfigs = {\n      memento: memento$1,\n      withElement: withElement,\n      withComp: withComp,\n      domValue: domValue,\n      domHtml: domHtml,\n      memory: memory$1\n    };\n\n    var extensionsAccepted = '.jpg,.jpeg,.png,.gif';\n    var filterByExtension = function (files) {\n      var re = new RegExp('(' + extensionsAccepted.split(/\\s*,\\s*/).join('|') + ')$', 'i');\n      return filter(from$1(files), function (file) {\n        return re.test(file.name);\n      });\n    };\n    var renderDropZone = function (spec, providersBackstage) {\n      var stopper = function (_, se) {\n        se.stop();\n      };\n      var sequence = function (actions) {\n        return function (comp, se) {\n          each(actions, function (a) {\n            a(comp, se);\n          });\n        };\n      };\n      var onDrop = function (comp, se) {\n        if (!Disabling.isDisabled(comp)) {\n          var transferEvent = se.event().raw();\n          handleFiles(comp, transferEvent.dataTransfer.files);\n        }\n      };\n      var onSelect = function (component, simulatedEvent) {\n        var files = simulatedEvent.event().raw().target.files;\n        handleFiles(component, files);\n      };\n      var handleFiles = function (component, files) {\n        Representing.setValue(component, filterByExtension(files));\n        emitWith(component, formChangeEvent, { name: spec.name });\n      };\n      var memInput = record({\n        dom: {\n          tag: 'input',\n          attributes: {\n            type: 'file',\n            accept: 'image/*'\n          },\n          styles: { display: 'none' }\n        },\n        behaviours: derive$1([config('input-file-events', [\n            cutter(click()),\n            cutter(tap())\n          ])])\n      });\n      var renderField = function (s) {\n        return {\n          uid: s.uid,\n          dom: {\n            tag: 'div',\n            classes: ['tox-dropzone-container']\n          },\n          behaviours: derive$1([\n            RepresentingConfigs.memory([]),\n            ComposingConfigs.self(),\n            Disabling.config({}),\n            Toggling.config({\n              toggleClass: 'dragenter',\n              toggleOnExecute: false\n            }),\n            config('dropzone-events', [\n              run('dragenter', sequence([\n                stopper,\n                Toggling.toggle\n              ])),\n              run('dragleave', sequence([\n                stopper,\n                Toggling.toggle\n              ])),\n              run('dragover', stopper),\n              run('drop', sequence([\n                stopper,\n                onDrop\n              ])),\n              run(change(), onSelect)\n            ])\n          ]),\n          components: [{\n              dom: {\n                tag: 'div',\n                classes: ['tox-dropzone'],\n                styles: {}\n              },\n              components: [\n                {\n                  dom: {\n                    tag: 'p',\n                    innerHtml: providersBackstage.translate('Drop an image here')\n                  }\n                },\n                Button.sketch({\n                  dom: {\n                    tag: 'button',\n                    innerHtml: providersBackstage.translate('Browse for an image'),\n                    styles: { position: 'relative' },\n                    classes: [\n                      'tox-button',\n                      'tox-button--secondary'\n                    ]\n                  },\n                  components: [memInput.asSpec()],\n                  action: function (comp) {\n                    var inputComp = memInput.get(comp);\n                    inputComp.element().dom().click();\n                  },\n                  buttonBehaviours: derive$1([Tabstopping.config({})])\n                })\n              ]\n            }]\n        };\n      };\n      var pLabel = spec.label.map(function (label) {\n        return renderLabel(label, providersBackstage);\n      });\n      var pField = FormField.parts().field({ factory: { sketch: renderField } });\n      return renderFormFieldWith(pLabel, pField, ['tox-form__group--stretched'], []);\n    };\n\n    var renderGrid = function (spec, backstage) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox-form__grid',\n            'tox-form__grid--' + spec.columns + 'col'\n          ]\n        },\n        components: map(spec.items, backstage.interpreter)\n      };\n    };\n\n    var beforeObject = generate$1('alloy-fake-before-tabstop');\n    var afterObject = generate$1('alloy-fake-after-tabstop');\n    var craftWithClasses = function (classes) {\n      return {\n        dom: {\n          tag: 'div',\n          styles: {\n            width: '1px',\n            height: '1px',\n            outline: 'none'\n          },\n          attributes: { tabindex: '0' },\n          classes: classes\n        },\n        behaviours: derive$1([\n          Focusing.config({ ignore: true }),\n          Tabstopping.config({})\n        ])\n      };\n    };\n    var craft = function (spec) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: ['tox-navobj']\n        },\n        components: [\n          craftWithClasses([beforeObject]),\n          spec,\n          craftWithClasses([afterObject])\n        ],\n        behaviours: derive$1([ComposingConfigs.childAt(1)])\n      };\n    };\n    var triggerTab = function (placeholder, shiftKey) {\n      emitWith(placeholder, keydown(), {\n        raw: {\n          which: 9,\n          shiftKey: shiftKey\n        }\n      });\n    };\n    var onFocus$1 = function (container, targetComp) {\n      var target = targetComp.element();\n      if (has$2(target, beforeObject)) {\n        triggerTab(container, true);\n      } else if (has$2(target, afterObject)) {\n        triggerTab(container, false);\n      }\n    };\n    var isPseudoStop = function (element) {\n      return closest$4(element, [\n        '.' + beforeObject,\n        '.' + afterObject\n      ].join(','), constant(false));\n    };\n    var NavigableObject = {\n      isPseudoStop: isPseudoStop,\n      onFocus: onFocus$1,\n      craft: craft\n    };\n\n    var platformNeedsSandboxing = !(detect$3().browser.isIE() || detect$3().browser.isEdge());\n    var getDynamicSource = function (isSandbox) {\n      var cachedValue = Cell('');\n      return {\n        getValue: function (frameComponent) {\n          return cachedValue.get();\n        },\n        setValue: function (frameComponent, html) {\n          if (!isSandbox) {\n            set$1(frameComponent.element(), 'src', 'javascript:\\'\\'');\n            var doc = frameComponent.element().dom().contentWindow.document;\n            doc.open();\n            doc.write(html);\n            doc.close();\n          } else {\n            set$1(frameComponent.element(), 'srcdoc', html);\n          }\n          cachedValue.set(html);\n        }\n      };\n    };\n    var renderIFrame = function (spec, providersBackstage) {\n      var isSandbox = platformNeedsSandboxing && spec.sandboxed;\n      var attributes = __assign(__assign({}, spec.label.map(function (title) {\n        return { title: title };\n      }).getOr({})), isSandbox ? { sandbox: 'allow-scripts allow-same-origin' } : {});\n      var sourcing = getDynamicSource(isSandbox);\n      var pLabel = spec.label.map(function (label) {\n        return renderLabel(label, providersBackstage);\n      });\n      var factory = function (newSpec) {\n        return NavigableObject.craft({\n          uid: newSpec.uid,\n          dom: {\n            tag: 'iframe',\n            attributes: attributes\n          },\n          behaviours: derive$1([\n            Tabstopping.config({}),\n            Focusing.config({}),\n            RepresentingConfigs.withComp(Option.none(), sourcing.getValue, sourcing.setValue)\n          ])\n        });\n      };\n      var pField = FormField.parts().field({ factory: { sketch: factory } });\n      return renderFormFieldWith(pLabel, pField, ['tox-form__group--stretched'], []);\n    };\n\n    function create$5(width, height) {\n      return resize(domGlobals.document.createElement('canvas'), width, height);\n    }\n    function clone$1(canvas) {\n      var tCanvas = create$5(canvas.width, canvas.height);\n      var ctx = get2dContext(tCanvas);\n      ctx.drawImage(canvas, 0, 0);\n      return tCanvas;\n    }\n    function get2dContext(canvas) {\n      return canvas.getContext('2d');\n    }\n    function resize(canvas, width, height) {\n      canvas.width = width;\n      canvas.height = height;\n      return canvas;\n    }\n\n    function getWidth(image) {\n      return image.naturalWidth || image.width;\n    }\n    function getHeight(image) {\n      return image.naturalHeight || image.height;\n    }\n\n    var promise = function () {\n      var Promise = function (fn) {\n        if (typeof this !== 'object') {\n          throw new TypeError('Promises must be constructed via new');\n        }\n        if (typeof fn !== 'function') {\n          throw new TypeError('not a function');\n        }\n        this._state = null;\n        this._value = null;\n        this._deferreds = [];\n        doResolve(fn, bind(resolve, this), bind(reject, this));\n      };\n      var asap = Promise.immediateFn || typeof window.setImmediate === 'function' && window.setImmediate || function (fn) {\n        domGlobals.setTimeout(fn, 1);\n      };\n      function bind(fn, thisArg) {\n        return function () {\n          return fn.apply(thisArg, arguments);\n        };\n      }\n      var isArray = Array.isArray || function (value) {\n        return Object.prototype.toString.call(value) === '[object Array]';\n      };\n      function handle(deferred) {\n        var me = this;\n        if (this._state === null) {\n          this._deferreds.push(deferred);\n          return;\n        }\n        asap(function () {\n          var cb = me._state ? deferred.onFulfilled : deferred.onRejected;\n          if (cb === null) {\n            (me._state ? deferred.resolve : deferred.reject)(me._value);\n            return;\n          }\n          var ret;\n          try {\n            ret = cb(me._value);\n          } catch (e) {\n            deferred.reject(e);\n            return;\n          }\n          deferred.resolve(ret);\n        });\n      }\n      function resolve(newValue) {\n        try {\n          if (newValue === this) {\n            throw new TypeError('A promise cannot be resolved with itself.');\n          }\n          if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {\n            var then = newValue.then;\n            if (typeof then === 'function') {\n              doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this));\n              return;\n            }\n          }\n          this._state = true;\n          this._value = newValue;\n          finale.call(this);\n        } catch (e) {\n          reject.call(this, e);\n        }\n      }\n      function reject(newValue) {\n        this._state = false;\n        this._value = newValue;\n        finale.call(this);\n      }\n      function finale() {\n        for (var _i = 0, _a = this._deferreds; _i < _a.length; _i++) {\n          var deferred = _a[_i];\n          handle.call(this, deferred);\n        }\n        this._deferreds = [];\n      }\n      function Handler(onFulfilled, onRejected, resolve, reject) {\n        this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n        this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n        this.resolve = resolve;\n        this.reject = reject;\n      }\n      function doResolve(fn, onFulfilled, onRejected) {\n        var done = false;\n        try {\n          fn(function (value) {\n            if (done) {\n              return;\n            }\n            done = true;\n            onFulfilled(value);\n          }, function (reason) {\n            if (done) {\n              return;\n            }\n            done = true;\n            onRejected(reason);\n          });\n        } catch (ex) {\n          if (done) {\n            return;\n          }\n          done = true;\n          onRejected(ex);\n        }\n      }\n      Promise.prototype.catch = function (onRejected) {\n        return this.then(null, onRejected);\n      };\n      Promise.prototype.then = function (onFulfilled, onRejected) {\n        var me = this;\n        return new Promise(function (resolve, reject) {\n          handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject));\n        });\n      };\n      Promise.all = function () {\n        var values = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          values[_i] = arguments[_i];\n        }\n        var args = Array.prototype.slice.call(values.length === 1 && isArray(values[0]) ? values[0] : values);\n        return new Promise(function (resolve, reject) {\n          if (args.length === 0) {\n            return resolve([]);\n          }\n          var remaining = args.length;\n          function res(i, val) {\n            try {\n              if (val && (typeof val === 'object' || typeof val === 'function')) {\n                var then = val.then;\n                if (typeof then === 'function') {\n                  then.call(val, function (val) {\n                    res(i, val);\n                  }, reject);\n                  return;\n                }\n              }\n              args[i] = val;\n              if (--remaining === 0) {\n                resolve(args);\n              }\n            } catch (ex) {\n              reject(ex);\n            }\n          }\n          for (var i = 0; i < args.length; i++) {\n            res(i, args[i]);\n          }\n        });\n      };\n      Promise.resolve = function (value) {\n        if (value && typeof value === 'object' && value.constructor === Promise) {\n          return value;\n        }\n        return new Promise(function (resolve) {\n          resolve(value);\n        });\n      };\n      Promise.reject = function (reason) {\n        return new Promise(function (resolve, reject) {\n          reject(reason);\n        });\n      };\n      Promise.race = function (values) {\n        return new Promise(function (resolve, reject) {\n          for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {\n            var value = values_1[_i];\n            value.then(resolve, reject);\n          }\n        });\n      };\n      return Promise;\n    };\n    var Promise$1 = window.Promise ? window.Promise : promise();\n\n    function blobToImage(blob) {\n      return new Promise$1(function (resolve, reject) {\n        var blobUrl = domGlobals.URL.createObjectURL(blob);\n        var image = new domGlobals.Image();\n        var removeListeners = function () {\n          image.removeEventListener('load', loaded);\n          image.removeEventListener('error', error);\n        };\n        function loaded() {\n          removeListeners();\n          resolve(image);\n        }\n        function error() {\n          removeListeners();\n          reject('Unable to load data of type ' + blob.type + ': ' + blobUrl);\n        }\n        image.addEventListener('load', loaded);\n        image.addEventListener('error', error);\n        image.src = blobUrl;\n        if (image.complete) {\n          loaded();\n        }\n      });\n    }\n    function dataUriToBlobSync(uri) {\n      var data = uri.split(',');\n      var matches = /data:([^;]+)/.exec(data[0]);\n      if (!matches) {\n        return Option.none();\n      }\n      var mimetype = matches[1];\n      var base64 = data[1];\n      var sliceSize = 1024;\n      var byteCharacters = domGlobals.atob(base64);\n      var bytesLength = byteCharacters.length;\n      var slicesCount = Math.ceil(bytesLength / sliceSize);\n      var byteArrays = new Array(slicesCount);\n      for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {\n        var begin = sliceIndex * sliceSize;\n        var end = Math.min(begin + sliceSize, bytesLength);\n        var bytes = new Array(end - begin);\n        for (var offset = begin, i = 0; offset < end; ++i, ++offset) {\n          bytes[i] = byteCharacters[offset].charCodeAt(0);\n        }\n        byteArrays[sliceIndex] = new Uint8Array(bytes);\n      }\n      return Option.some(new domGlobals.Blob(byteArrays, { type: mimetype }));\n    }\n    function dataUriToBlob(uri) {\n      return new Promise$1(function (resolve, reject) {\n        dataUriToBlobSync(uri).fold(function () {\n          reject('uri is not base64: ' + uri);\n        }, resolve);\n      });\n    }\n    function canvasToBlob(canvas, type, quality) {\n      type = type || 'image/png';\n      if (domGlobals.HTMLCanvasElement.prototype.toBlob) {\n        return new Promise$1(function (resolve, reject) {\n          canvas.toBlob(function (blob) {\n            if (blob) {\n              resolve(blob);\n            } else {\n              reject();\n            }\n          }, type, quality);\n        });\n      } else {\n        return dataUriToBlob(canvas.toDataURL(type, quality));\n      }\n    }\n    function canvasToDataURL(canvas, type, quality) {\n      type = type || 'image/png';\n      return canvas.toDataURL(type, quality);\n    }\n    function blobToCanvas(blob) {\n      return blobToImage(blob).then(function (image) {\n        revokeImageUrl(image);\n        var canvas = create$5(getWidth(image), getHeight(image));\n        var context = get2dContext(canvas);\n        context.drawImage(image, 0, 0);\n        return canvas;\n      });\n    }\n    function blobToDataUri(blob) {\n      return new Promise$1(function (resolve) {\n        var reader = new domGlobals.FileReader();\n        reader.onloadend = function () {\n          resolve(reader.result);\n        };\n        reader.readAsDataURL(blob);\n      });\n    }\n    function revokeImageUrl(image) {\n      domGlobals.URL.revokeObjectURL(image.src);\n    }\n\n    function create$6(getCanvas, blob, uri) {\n      var initialType = blob.type;\n      var getType = constant(initialType);\n      function toBlob() {\n        return Promise$1.resolve(blob);\n      }\n      function toDataURL() {\n        return uri;\n      }\n      function toBase64() {\n        return uri.split(',')[1];\n      }\n      function toAdjustedBlob(type, quality) {\n        return getCanvas.then(function (canvas) {\n          return canvasToBlob(canvas, type, quality);\n        });\n      }\n      function toAdjustedDataURL(type, quality) {\n        return getCanvas.then(function (canvas) {\n          return canvasToDataURL(canvas, type, quality);\n        });\n      }\n      function toAdjustedBase64(type, quality) {\n        return toAdjustedDataURL(type, quality).then(function (dataurl) {\n          return dataurl.split(',')[1];\n        });\n      }\n      function toCanvas() {\n        return getCanvas.then(clone$1);\n      }\n      return {\n        getType: getType,\n        toBlob: toBlob,\n        toDataURL: toDataURL,\n        toBase64: toBase64,\n        toAdjustedBlob: toAdjustedBlob,\n        toAdjustedDataURL: toAdjustedDataURL,\n        toAdjustedBase64: toAdjustedBase64,\n        toCanvas: toCanvas\n      };\n    }\n    function fromBlob(blob) {\n      return blobToDataUri(blob).then(function (uri) {\n        return create$6(blobToCanvas(blob), blob, uri);\n      });\n    }\n    function fromCanvas(canvas, type) {\n      return canvasToBlob(canvas, type).then(function (blob) {\n        return create$6(Promise$1.resolve(canvas), blob, canvas.toDataURL());\n      });\n    }\n\n    var blobToImageResult = function (blob) {\n      return fromBlob(blob);\n    };\n\n    function clamp(value, min, max) {\n      var parsedValue = typeof value === 'string' ? parseFloat(value) : value;\n      if (parsedValue > max) {\n        parsedValue = max;\n      } else if (parsedValue < min) {\n        parsedValue = min;\n      }\n      return parsedValue;\n    }\n    function identity$1() {\n      return [\n        1,\n        0,\n        0,\n        0,\n        0,\n        0,\n        1,\n        0,\n        0,\n        0,\n        0,\n        0,\n        1,\n        0,\n        0,\n        0,\n        0,\n        0,\n        1,\n        0,\n        0,\n        0,\n        0,\n        0,\n        1\n      ];\n    }\n    var DELTA_INDEX = [\n      0,\n      0.01,\n      0.02,\n      0.04,\n      0.05,\n      0.06,\n      0.07,\n      0.08,\n      0.1,\n      0.11,\n      0.12,\n      0.14,\n      0.15,\n      0.16,\n      0.17,\n      0.18,\n      0.2,\n      0.21,\n      0.22,\n      0.24,\n      0.25,\n      0.27,\n      0.28,\n      0.3,\n      0.32,\n      0.34,\n      0.36,\n      0.38,\n      0.4,\n      0.42,\n      0.44,\n      0.46,\n      0.48,\n      0.5,\n      0.53,\n      0.56,\n      0.59,\n      0.62,\n      0.65,\n      0.68,\n      0.71,\n      0.74,\n      0.77,\n      0.8,\n      0.83,\n      0.86,\n      0.89,\n      0.92,\n      0.95,\n      0.98,\n      1,\n      1.06,\n      1.12,\n      1.18,\n      1.24,\n      1.3,\n      1.36,\n      1.42,\n      1.48,\n      1.54,\n      1.6,\n      1.66,\n      1.72,\n      1.78,\n      1.84,\n      1.9,\n      1.96,\n      2,\n      2.12,\n      2.25,\n      2.37,\n      2.5,\n      2.62,\n      2.75,\n      2.87,\n      3,\n      3.2,\n      3.4,\n      3.6,\n      3.8,\n      4,\n      4.3,\n      4.7,\n      4.9,\n      5,\n      5.5,\n      6,\n      6.5,\n      6.8,\n      7,\n      7.3,\n      7.5,\n      7.8,\n      8,\n      8.4,\n      8.7,\n      9,\n      9.4,\n      9.6,\n      9.8,\n      10\n    ];\n    function multiply(matrix1, matrix2) {\n      var col = [];\n      var out = new Array(25);\n      var val;\n      for (var i = 0; i < 5; i++) {\n        for (var j = 0; j < 5; j++) {\n          col[j] = matrix2[j + i * 5];\n        }\n        for (var j = 0; j < 5; j++) {\n          val = 0;\n          for (var k = 0; k < 5; k++) {\n            val += matrix1[j + k * 5] * col[k];\n          }\n          out[j + i * 5] = val;\n        }\n      }\n      return out;\n    }\n    function adjustContrast(matrix, value) {\n      var x;\n      value = clamp(value, -1, 1);\n      value *= 100;\n      if (value < 0) {\n        x = 127 + value / 100 * 127;\n      } else {\n        x = value % 1;\n        if (x === 0) {\n          x = DELTA_INDEX[value];\n        } else {\n          x = DELTA_INDEX[Math.floor(value)] * (1 - x) + DELTA_INDEX[Math.floor(value) + 1] * x;\n        }\n        x = x * 127 + 127;\n      }\n      return multiply(matrix, [\n        x / 127,\n        0,\n        0,\n        0,\n        0.5 * (127 - x),\n        0,\n        x / 127,\n        0,\n        0,\n        0.5 * (127 - x),\n        0,\n        0,\n        x / 127,\n        0,\n        0.5 * (127 - x),\n        0,\n        0,\n        0,\n        1,\n        0,\n        0,\n        0,\n        0,\n        0,\n        1\n      ]);\n    }\n    function adjustBrightness(matrix, value) {\n      value = clamp(255 * value, -255, 255);\n      return multiply(matrix, [\n        1,\n        0,\n        0,\n        0,\n        value,\n        0,\n        1,\n        0,\n        0,\n        value,\n        0,\n        0,\n        1,\n        0,\n        value,\n        0,\n        0,\n        0,\n        1,\n        0,\n        0,\n        0,\n        0,\n        0,\n        1\n      ]);\n    }\n    function adjustColors(matrix, adjustR, adjustG, adjustB) {\n      adjustR = clamp(adjustR, 0, 2);\n      adjustG = clamp(adjustG, 0, 2);\n      adjustB = clamp(adjustB, 0, 2);\n      return multiply(matrix, [\n        adjustR,\n        0,\n        0,\n        0,\n        0,\n        0,\n        adjustG,\n        0,\n        0,\n        0,\n        0,\n        0,\n        adjustB,\n        0,\n        0,\n        0,\n        0,\n        0,\n        1,\n        0,\n        0,\n        0,\n        0,\n        0,\n        1\n      ]);\n    }\n\n    function colorFilter(ir, matrix) {\n      return ir.toCanvas().then(function (canvas) {\n        return applyColorFilter(canvas, ir.getType(), matrix);\n      });\n    }\n    function applyColorFilter(canvas, type, matrix) {\n      var context = get2dContext(canvas);\n      function applyMatrix(pixelsData, m) {\n        var r, g, b, a;\n        var data = pixelsData.data, m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3], m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7], m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11], m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15], m16 = m[16], m17 = m[17], m18 = m[18], m19 = m[19];\n        for (var i = 0; i < data.length; i += 4) {\n          r = data[i];\n          g = data[i + 1];\n          b = data[i + 2];\n          a = data[i + 3];\n          data[i] = r * m0 + g * m1 + b * m2 + a * m3 + m4;\n          data[i + 1] = r * m5 + g * m6 + b * m7 + a * m8 + m9;\n          data[i + 2] = r * m10 + g * m11 + b * m12 + a * m13 + m14;\n          data[i + 3] = r * m15 + g * m16 + b * m17 + a * m18 + m19;\n        }\n        return pixelsData;\n      }\n      var pixels = applyMatrix(context.getImageData(0, 0, canvas.width, canvas.height), matrix);\n      context.putImageData(pixels, 0, 0);\n      return fromCanvas(canvas, type);\n    }\n    function convoluteFilter(ir, matrix) {\n      return ir.toCanvas().then(function (canvas) {\n        return applyConvoluteFilter(canvas, ir.getType(), matrix);\n      });\n    }\n    function applyConvoluteFilter(canvas, type, matrix) {\n      var context = get2dContext(canvas);\n      function applyMatrix(pIn, pOut, aMatrix) {\n        function clamp(value, min, max) {\n          if (value > max) {\n            value = max;\n          } else if (value < min) {\n            value = min;\n          }\n          return value;\n        }\n        var side = Math.round(Math.sqrt(aMatrix.length));\n        var halfSide = Math.floor(side / 2);\n        var rgba = pIn.data;\n        var drgba = pOut.data;\n        var w = pIn.width;\n        var h = pIn.height;\n        for (var y = 0; y < h; y++) {\n          for (var x = 0; x < w; x++) {\n            var r = 0;\n            var g = 0;\n            var b = 0;\n            for (var cy = 0; cy < side; cy++) {\n              for (var cx = 0; cx < side; cx++) {\n                var scx = clamp(x + cx - halfSide, 0, w - 1);\n                var scy = clamp(y + cy - halfSide, 0, h - 1);\n                var innerOffset = (scy * w + scx) * 4;\n                var wt = aMatrix[cy * side + cx];\n                r += rgba[innerOffset] * wt;\n                g += rgba[innerOffset + 1] * wt;\n                b += rgba[innerOffset + 2] * wt;\n              }\n            }\n            var offset = (y * w + x) * 4;\n            drgba[offset] = clamp(r, 0, 255);\n            drgba[offset + 1] = clamp(g, 0, 255);\n            drgba[offset + 2] = clamp(b, 0, 255);\n          }\n        }\n        return pOut;\n      }\n      var pixelsIn = context.getImageData(0, 0, canvas.width, canvas.height);\n      var pixelsOut = context.getImageData(0, 0, canvas.width, canvas.height);\n      pixelsOut = applyMatrix(pixelsIn, pixelsOut, matrix);\n      context.putImageData(pixelsOut, 0, 0);\n      return fromCanvas(canvas, type);\n    }\n    function functionColorFilter(colorFn) {\n      var filterImpl = function (canvas, type, value) {\n        var context = get2dContext(canvas);\n        var lookup = new Array(256);\n        function applyLookup(pixelsData, lookupData) {\n          var data = pixelsData.data;\n          for (var i = 0; i < data.length; i += 4) {\n            data[i] = lookupData[data[i]];\n            data[i + 1] = lookupData[data[i + 1]];\n            data[i + 2] = lookupData[data[i + 2]];\n          }\n          return pixelsData;\n        }\n        for (var i = 0; i < lookup.length; i++) {\n          lookup[i] = colorFn(i, value);\n        }\n        var pixels = applyLookup(context.getImageData(0, 0, canvas.width, canvas.height), lookup);\n        context.putImageData(pixels, 0, 0);\n        return fromCanvas(canvas, type);\n      };\n      return function (ir, value) {\n        return ir.toCanvas().then(function (canvas) {\n          return filterImpl(canvas, ir.getType(), value);\n        });\n      };\n    }\n    function complexAdjustableColorFilter(matrixAdjustFn) {\n      return function (ir, adjust) {\n        return colorFilter(ir, matrixAdjustFn(identity$1(), adjust));\n      };\n    }\n    function basicColorFilter(matrix) {\n      return function (ir) {\n        return colorFilter(ir, matrix);\n      };\n    }\n    function basicConvolutionFilter(kernel) {\n      return function (ir) {\n        return convoluteFilter(ir, kernel);\n      };\n    }\n    var invert = basicColorFilter([\n      -1,\n      0,\n      0,\n      0,\n      255,\n      0,\n      -1,\n      0,\n      0,\n      255,\n      0,\n      0,\n      -1,\n      0,\n      255,\n      0,\n      0,\n      0,\n      1,\n      0,\n      0,\n      0,\n      0,\n      0,\n      1\n    ]);\n    var brightness = complexAdjustableColorFilter(adjustBrightness);\n    var contrast = complexAdjustableColorFilter(adjustContrast);\n    var colorize = function (ir, adjustR, adjustG, adjustB) {\n      return colorFilter(ir, adjustColors(identity$1(), adjustR, adjustG, adjustB));\n    };\n    var sharpen = basicConvolutionFilter([\n      0,\n      -1,\n      0,\n      -1,\n      5,\n      -1,\n      0,\n      -1,\n      0\n    ]);\n    var gamma = functionColorFilter(function (color, value) {\n      return Math.pow(color / 255, 1 - value) * 255;\n    });\n\n    function scale(image, dW, dH) {\n      var sW = getWidth(image);\n      var sH = getHeight(image);\n      var wRatio = dW / sW;\n      var hRatio = dH / sH;\n      var scaleCapped = false;\n      if (wRatio < 0.5 || wRatio > 2) {\n        wRatio = wRatio < 0.5 ? 0.5 : 2;\n        scaleCapped = true;\n      }\n      if (hRatio < 0.5 || hRatio > 2) {\n        hRatio = hRatio < 0.5 ? 0.5 : 2;\n        scaleCapped = true;\n      }\n      var scaled = _scale(image, wRatio, hRatio);\n      return !scaleCapped ? scaled : scaled.then(function (tCanvas) {\n        return scale(tCanvas, dW, dH);\n      });\n    }\n    function _scale(image, wRatio, hRatio) {\n      return new Promise$1(function (resolve) {\n        var sW = getWidth(image);\n        var sH = getHeight(image);\n        var dW = Math.floor(sW * wRatio);\n        var dH = Math.floor(sH * hRatio);\n        var canvas = create$5(dW, dH);\n        var context = get2dContext(canvas);\n        context.drawImage(image, 0, 0, sW, sH, 0, 0, dW, dH);\n        resolve(canvas);\n      });\n    }\n\n    function rotate(ir, angle) {\n      return ir.toCanvas().then(function (canvas) {\n        return applyRotate(canvas, ir.getType(), angle);\n      });\n    }\n    function applyRotate(image, type, angle) {\n      var canvas = create$5(image.width, image.height);\n      var context = get2dContext(canvas);\n      var translateX = 0;\n      var translateY = 0;\n      angle = angle < 0 ? 360 + angle : angle;\n      if (angle === 90 || angle === 270) {\n        resize(canvas, canvas.height, canvas.width);\n      }\n      if (angle === 90 || angle === 180) {\n        translateX = canvas.width;\n      }\n      if (angle === 270 || angle === 180) {\n        translateY = canvas.height;\n      }\n      context.translate(translateX, translateY);\n      context.rotate(angle * Math.PI / 180);\n      context.drawImage(image, 0, 0);\n      return fromCanvas(canvas, type);\n    }\n    function flip(ir, axis) {\n      return ir.toCanvas().then(function (canvas) {\n        return applyFlip(canvas, ir.getType(), axis);\n      });\n    }\n    function applyFlip(image, type, axis) {\n      var canvas = create$5(image.width, image.height);\n      var context = get2dContext(canvas);\n      if (axis === 'v') {\n        context.scale(1, -1);\n        context.drawImage(image, 0, -canvas.height);\n      } else {\n        context.scale(-1, 1);\n        context.drawImage(image, -canvas.width, 0);\n      }\n      return fromCanvas(canvas, type);\n    }\n    function crop(ir, x, y, w, h) {\n      return ir.toCanvas().then(function (canvas) {\n        return applyCrop(canvas, ir.getType(), x, y, w, h);\n      });\n    }\n    function applyCrop(image, type, x, y, w, h) {\n      var canvas = create$5(w, h);\n      var context = get2dContext(canvas);\n      context.drawImage(image, -x, -y);\n      return fromCanvas(canvas, type);\n    }\n    function resize$1(ir, w, h) {\n      return ir.toCanvas().then(function (canvas) {\n        return scale(canvas, w, h).then(function (newCanvas) {\n          return fromCanvas(newCanvas, ir.getType());\n        });\n      });\n    }\n\n    var invert$1 = function (ir) {\n      return invert(ir);\n    };\n    var sharpen$1 = function (ir) {\n      return sharpen(ir);\n    };\n    var gamma$1 = function (ir, value) {\n      return gamma(ir, value);\n    };\n    var colorize$1 = function (ir, adjustR, adjustG, adjustB) {\n      return colorize(ir, adjustR, adjustG, adjustB);\n    };\n    var brightness$1 = function (ir, adjust) {\n      return brightness(ir, adjust);\n    };\n    var contrast$1 = function (ir, adjust) {\n      return contrast(ir, adjust);\n    };\n    var flip$1 = function (ir, axis) {\n      return flip(ir, axis);\n    };\n    var crop$1 = function (ir, x, y, w, h) {\n      return crop(ir, x, y, w, h);\n    };\n    var resize$2 = function (ir, w, h) {\n      return resize$1(ir, w, h);\n    };\n    var rotate$1 = function (ir, angle) {\n      return rotate(ir, angle);\n    };\n\n    var renderIcon$1 = function (iconHtml, behaviours) {\n      return __assign({\n        dom: {\n          tag: 'span',\n          innerHtml: iconHtml,\n          classes: [\n            'tox-icon',\n            'tox-tbtn__icon-wrap'\n          ]\n        }\n      }, behaviours);\n    };\n    var renderIconFromPack = function (iconName, iconsProvider) {\n      return renderIcon$1(get$c(iconName, iconsProvider), {});\n    };\n    var renderReplacableIconFromPack = function (iconName, iconsProvider) {\n      return renderIcon$1(get$c(iconName, iconsProvider), { behaviours: derive$1([Replacing.config({})]) });\n    };\n    var renderLabel$1 = function (text, prefix, providersBackstage) {\n      return {\n        dom: {\n          tag: 'span',\n          innerHtml: providersBackstage.translate(text),\n          classes: [prefix + '__select-label']\n        },\n        behaviours: derive$1([Replacing.config({})])\n      };\n    };\n\n    var internalToolbarButtonExecute = generate$1('toolbar.button.execute');\n    var onToolbarButtonExecute = function (info) {\n      return runOnExecute(function (comp, simulatedEvent) {\n        runWithApi(info, comp)(function (itemApi) {\n          emitWith(comp, internalToolbarButtonExecute, { buttonApi: itemApi });\n          info.onAction(itemApi);\n        });\n      });\n    };\n    var toolbarButtonEventOrder = {\n      'alloy.execute': [\n        'disabling',\n        'alloy.base.behaviour',\n        'toggling',\n        'toolbar-button-events'\n      ]\n    };\n\n    var updateMenuText = generate$1('update-menu-text');\n    var updateMenuIcon = generate$1('update-menu-icon');\n    var renderCommonDropdown = function (spec, prefix, sharedBackstage) {\n      var editorOffCell = Cell(noop);\n      var optMemDisplayText = spec.text.map(function (text) {\n        return record(renderLabel$1(text, prefix, sharedBackstage.providers));\n      });\n      var optMemDisplayIcon = spec.icon.map(function (iconName) {\n        return record(renderReplacableIconFromPack(iconName, sharedBackstage.providers.icons));\n      });\n      var onLeftOrRightInMenu = function (comp, se) {\n        var dropdown = Representing.getValue(comp);\n        Focusing.focus(dropdown);\n        emitWith(dropdown, 'keydown', { raw: se.event().raw() });\n        Dropdown.close(dropdown);\n        return Option.some(true);\n      };\n      var role = spec.role.fold(function () {\n        return {};\n      }, function (role) {\n        return { role: role };\n      });\n      var tooltipAttributes = spec.tooltip.fold(function () {\n        return {};\n      }, function (tooltip) {\n        var translatedTooltip = sharedBackstage.providers.translate(tooltip);\n        return {\n          'title': translatedTooltip,\n          'aria-label': translatedTooltip\n        };\n      });\n      var memDropdown = record(Dropdown.sketch(__assign(__assign({}, role), {\n        dom: {\n          tag: 'button',\n          classes: [\n            prefix,\n            prefix + '--select'\n          ].concat(map(spec.classes, function (c) {\n            return prefix + '--' + c;\n          })),\n          attributes: __assign({}, tooltipAttributes)\n        },\n        components: componentRenderPipeline([\n          optMemDisplayIcon.map(function (mem) {\n            return mem.asSpec();\n          }),\n          optMemDisplayText.map(function (mem) {\n            return mem.asSpec();\n          }),\n          Option.some({\n            dom: {\n              tag: 'div',\n              classes: [prefix + '__select-chevron'],\n              innerHtml: get$c('chevron-down', sharedBackstage.providers.icons)\n            }\n          })\n        ]),\n        matchWidth: true,\n        useMinWidth: true,\n        dropdownBehaviours: derive$1(__spreadArrays(spec.dropdownBehaviours, [\n          DisablingConfigs.button(spec.disabled),\n          Unselecting.config({}),\n          Replacing.config({}),\n          config('dropdown-events', [\n            onControlAttached(spec, editorOffCell),\n            onControlDetached(spec, editorOffCell)\n          ]),\n          config('menubutton-update-display-text', [\n            run(updateMenuText, function (comp, se) {\n              optMemDisplayText.bind(function (mem) {\n                return mem.getOpt(comp);\n              }).each(function (displayText) {\n                Replacing.set(displayText, [text(sharedBackstage.providers.translate(se.event().text()))]);\n              });\n            }),\n            run(updateMenuIcon, function (comp, se) {\n              optMemDisplayIcon.bind(function (mem) {\n                return mem.getOpt(comp);\n              }).each(function (displayIcon) {\n                Replacing.set(displayIcon, [renderReplacableIconFromPack(se.event().icon(), sharedBackstage.providers.icons)]);\n              });\n            })\n          ])\n        ])),\n        eventOrder: deepMerge(toolbarButtonEventOrder, {\n          mousedown: [\n            'focusing',\n            'alloy.base.behaviour',\n            'item-type-events',\n            'normal-dropdown-events'\n          ]\n        }),\n        sandboxBehaviours: derive$1([Keying.config({\n            mode: 'special',\n            onLeft: onLeftOrRightInMenu,\n            onRight: onLeftOrRightInMenu\n          })]),\n        lazySink: sharedBackstage.getSink,\n        toggleClass: prefix + '--active',\n        parts: { menu: part(false, spec.columns, spec.presets) },\n        fetch: function () {\n          return Future.nu(spec.fetch);\n        }\n      })));\n      return memDropdown.asSpec();\n    };\n\n    var isMenuItemReference = function (item) {\n      return isString(item);\n    };\n    var isSeparator = function (item) {\n      return item.type === 'separator';\n    };\n    var isExpandingMenuItem = function (item) {\n      return has(item, 'getSubmenuItems');\n    };\n    var separator$1 = { type: 'separator' };\n    var unwrapReferences = function (items, menuItems) {\n      var realItems = foldl(items, function (acc, item) {\n        if (isMenuItemReference(item)) {\n          if (item === '') {\n            return acc;\n          } else if (item === '|') {\n            return acc.length > 0 && !isSeparator(acc[acc.length - 1]) ? acc.concat([separator$1]) : acc;\n          } else if (has(menuItems, item.toLowerCase())) {\n            return acc.concat([menuItems[item.toLowerCase()]]);\n          } else {\n            return acc;\n          }\n        } else {\n          return acc.concat([item]);\n        }\n      }, []);\n      if (realItems.length > 0 && isSeparator(realItems[realItems.length - 1])) {\n        realItems.pop();\n      }\n      return realItems;\n    };\n    var getFromExpandingItem = function (item, menuItems) {\n      var submenuItems = item.getSubmenuItems();\n      var rest = expand(submenuItems, menuItems);\n      var newMenus = deepMerge(rest.menus, wrap$1(item.value, rest.items));\n      var newExpansions = deepMerge(rest.expansions, wrap$1(item.value, item.value));\n      return {\n        item: item,\n        menus: newMenus,\n        expansions: newExpansions\n      };\n    };\n    var getFromItem = function (item, menuItems) {\n      return isExpandingMenuItem(item) ? getFromExpandingItem(item, menuItems) : {\n        item: item,\n        menus: {},\n        expansions: {}\n      };\n    };\n    var generateValueIfRequired = function (item) {\n      if (isSeparator(item)) {\n        return item;\n      } else {\n        var itemValue = readOptFrom$1(item, 'value').getOrThunk(function () {\n          return generate$1('generated-menu-item');\n        });\n        return deepMerge({ value: itemValue }, item);\n      }\n    };\n    var expand = function (items, menuItems) {\n      var realItems = unwrapReferences(isString(items) ? items.split(' ') : items, menuItems);\n      return foldr(realItems, function (acc, item) {\n        var itemWithValue = generateValueIfRequired(item);\n        var newData = getFromItem(itemWithValue, menuItems);\n        return {\n          menus: deepMerge(acc.menus, newData.menus),\n          items: [newData.item].concat(acc.items),\n          expansions: deepMerge(acc.expansions, newData.expansions)\n        };\n      }, {\n        menus: {},\n        expansions: {},\n        items: []\n      });\n    };\n\n    var build$2 = function (items, itemResponse, backstage, isHorizontalMenu) {\n      var primary = generate$1('primary-menu');\n      var data = expand(items, backstage.shared.providers.menuItems());\n      if (data.items.length === 0) {\n        return Option.none();\n      }\n      var mainMenu = createPartialMenu(primary, data.items, itemResponse, backstage, isHorizontalMenu);\n      var submenus = map$1(data.menus, function (menuItems, menuName) {\n        return createPartialMenu(menuName, menuItems, itemResponse, backstage, false);\n      });\n      var menus = deepMerge(submenus, wrap$1(primary, mainMenu));\n      return Option.from(tieredMenu.tieredData(primary, menus, data.expansions));\n    };\n\n    var getMenuButtonApi = function (component) {\n      return {\n        isDisabled: function () {\n          return Disabling.isDisabled(component);\n        },\n        setDisabled: function (state) {\n          return Disabling.set(component, state);\n        },\n        setActive: function (state) {\n          var elm = component.element();\n          if (state) {\n            add$2(elm, 'tox-tbtn--enabled');\n            set$1(elm, 'aria-pressed', true);\n          } else {\n            remove$4(elm, 'tox-tbtn--enabled');\n            remove$1(elm, 'aria-pressed');\n          }\n        },\n        isActive: function () {\n          return has$2(component.element(), 'tox-tbtn--enabled');\n        }\n      };\n    };\n    var renderMenuButton = function (spec, prefix, backstage, role) {\n      return renderCommonDropdown({\n        text: spec.text,\n        icon: spec.icon,\n        tooltip: spec.tooltip,\n        role: role,\n        fetch: function (callback) {\n          spec.fetch(function (items) {\n            callback(build$2(items, ItemResponse$1.CLOSE_ON_EXECUTE, backstage, false));\n          });\n        },\n        onSetup: spec.onSetup,\n        getApi: getMenuButtonApi,\n        columns: 1,\n        presets: 'normal',\n        classes: [],\n        dropdownBehaviours: [Tabstopping.config({})]\n      }, prefix, backstage.shared);\n    };\n    var getFetch$1 = function (items, getButton, backstage) {\n      var getMenuItemAction = function (item) {\n        return function (api) {\n          var newValue = !api.isActive();\n          api.setActive(newValue);\n          item.storage.set(newValue);\n          backstage.shared.getSink().each(function (sink) {\n            getButton().getOpt(sink).each(function (orig) {\n              focus$1(orig.element());\n              emitWith(orig, formActionEvent, {\n                name: item.name,\n                value: item.storage.get()\n              });\n            });\n          });\n        };\n      };\n      var getMenuItemSetup = function (item) {\n        return function (api) {\n          api.setActive(item.storage.get());\n        };\n      };\n      return function (success) {\n        success(map(items, function (item) {\n          var text = item.text.fold(function () {\n            return {};\n          }, function (text) {\n            return { text: text };\n          });\n          return __assign(__assign({ type: item.type }, text), {\n            onAction: getMenuItemAction(item),\n            onSetup: getMenuItemSetup(item)\n          });\n        }));\n      };\n    };\n\n    var renderCommonSpec = function (spec, actionOpt, extraBehaviours, dom, components) {\n      if (extraBehaviours === void 0) {\n        extraBehaviours = [];\n      }\n      var action = actionOpt.fold(function () {\n        return {};\n      }, function (action) {\n        return { action: action };\n      });\n      var common = __assign({\n        buttonBehaviours: derive$1([\n          DisablingConfigs.button(spec.disabled),\n          Tabstopping.config({}),\n          config('button press', [\n            preventDefault('click'),\n            preventDefault('mousedown')\n          ])\n        ].concat(extraBehaviours)),\n        eventOrder: {\n          click: [\n            'button press',\n            'alloy.base.behaviour'\n          ],\n          mousedown: [\n            'button press',\n            'alloy.base.behaviour'\n          ]\n        }\n      }, action);\n      var domFinal = deepMerge(common, { dom: dom });\n      return deepMerge(domFinal, { components: components });\n    };\n    var renderIconButtonSpec = function (spec, action, providersBackstage, extraBehaviours) {\n      if (extraBehaviours === void 0) {\n        extraBehaviours = [];\n      }\n      var tooltipAttributes = spec.tooltip.map(function (tooltip) {\n        return {\n          'aria-label': providersBackstage.translate(tooltip),\n          'title': providersBackstage.translate(tooltip)\n        };\n      }).getOr({});\n      var dom = {\n        tag: 'button',\n        classes: ['tox-tbtn'],\n        attributes: tooltipAttributes\n      };\n      var icon = spec.icon.map(function (iconName) {\n        return renderIconFromPack(iconName, providersBackstage.icons);\n      });\n      var components = componentRenderPipeline([icon]);\n      return renderCommonSpec(spec, action, extraBehaviours, dom, components);\n    };\n    var renderIconButton = function (spec, action, providersBackstage, extraBehaviours) {\n      if (extraBehaviours === void 0) {\n        extraBehaviours = [];\n      }\n      var iconButtonSpec = renderIconButtonSpec(spec, Option.some(action), providersBackstage, extraBehaviours);\n      return Button.sketch(iconButtonSpec);\n    };\n    var renderButtonSpec = function (spec, action, providersBackstage, extraBehaviours, extraClasses) {\n      if (extraBehaviours === void 0) {\n        extraBehaviours = [];\n      }\n      if (extraClasses === void 0) {\n        extraClasses = [];\n      }\n      var translatedText = providersBackstage.translate(spec.text);\n      var icon = spec.icon ? spec.icon.map(function (iconName) {\n        return renderIconFromPack(iconName, providersBackstage.icons);\n      }) : Option.none();\n      var components = icon.isSome() ? componentRenderPipeline([icon]) : [];\n      var innerHtml = icon.isSome() ? {} : { innerHtml: translatedText };\n      var classes = __spreadArrays(!spec.primary && !spec.borderless ? [\n        'tox-button',\n        'tox-button--secondary'\n      ] : ['tox-button'], icon.isSome() ? ['tox-button--icon'] : [], spec.borderless ? ['tox-button--naked'] : [], extraClasses);\n      var dom = __assign(__assign({\n        tag: 'button',\n        classes: classes\n      }, innerHtml), { attributes: { title: translatedText } });\n      return renderCommonSpec(spec, action, extraBehaviours, dom, components);\n    };\n    var renderButton = function (spec, action, providersBackstage, extraBehaviours, extraClasses) {\n      if (extraBehaviours === void 0) {\n        extraBehaviours = [];\n      }\n      if (extraClasses === void 0) {\n        extraClasses = [];\n      }\n      var buttonSpec = renderButtonSpec(spec, Option.some(action), providersBackstage, extraBehaviours, extraClasses);\n      return Button.sketch(buttonSpec);\n    };\n    var getAction = function (name, buttonType) {\n      return function (comp) {\n        if (buttonType === 'custom') {\n          emitWith(comp, formActionEvent, {\n            name: name,\n            value: {}\n          });\n        } else if (buttonType === 'submit') {\n          emit(comp, formSubmitEvent);\n        } else if (buttonType === 'cancel') {\n          emit(comp, formCancelEvent);\n        } else {\n          domGlobals.console.error('Unknown button type: ', buttonType);\n        }\n      };\n    };\n    var isMenuFooterButtonSpec = function (spec, buttonType) {\n      return buttonType === 'menu';\n    };\n    var isNormalFooterButtonSpec = function (spec, buttonType) {\n      return buttonType === 'custom' || buttonType === 'cancel' || buttonType === 'submit';\n    };\n    var renderFooterButton = function (spec, buttonType, backstage) {\n      if (isMenuFooterButtonSpec(spec, buttonType)) {\n        var getButton = function () {\n          return memButton_1;\n        };\n        var menuButtonSpec = spec;\n        var fixedSpec = __assign(__assign({}, spec), { fetch: getFetch$1(menuButtonSpec.items, getButton, backstage) });\n        var memButton_1 = record(renderMenuButton(fixedSpec, 'tox-tbtn', backstage, Option.none()));\n        return memButton_1.asSpec();\n      } else if (isNormalFooterButtonSpec(spec, buttonType)) {\n        var action = getAction(spec.name, buttonType);\n        var buttonSpec = __assign(__assign({}, spec), { borderless: false });\n        return renderButton(buttonSpec, action, backstage.shared.providers, []);\n      } else {\n        domGlobals.console.error('Unknown footer button type: ', buttonType);\n      }\n    };\n    var renderDialogButton = function (spec, providersBackstage) {\n      var action = getAction(spec.name, 'custom');\n      return renderFormField(Option.none(), FormField.parts().field(__assign({ factory: Button }, renderButtonSpec(spec, Option.some(action), providersBackstage, [\n        RepresentingConfigs.memory(''),\n        ComposingConfigs.self()\n      ]))));\n    };\n\n    var schema$i = constant([\n      defaulted$1('field1Name', 'field1'),\n      defaulted$1('field2Name', 'field2'),\n      onStrictHandler('onLockedChange'),\n      markers(['lockClass']),\n      defaulted$1('locked', false),\n      SketchBehaviours.field('coupledFieldBehaviours', [\n        Composing,\n        Representing\n      ])\n    ]);\n    var getField = function (comp, detail, partName) {\n      return getPart(comp, detail, partName).bind(Composing.getCurrent);\n    };\n    var coupledPart = function (selfName, otherName) {\n      return required({\n        factory: FormField,\n        name: selfName,\n        overrides: function (detail) {\n          return {\n            fieldBehaviours: derive$1([config('coupled-input-behaviour', [run(input(), function (me) {\n                  getField(me, detail, otherName).each(function (other) {\n                    getPart(me, detail, 'lock').each(function (lock) {\n                      if (Toggling.isOn(lock)) {\n                        detail.onLockedChange(me, other, lock);\n                      }\n                    });\n                  });\n                })])])\n          };\n        }\n      });\n    };\n    var parts$5 = constant([\n      coupledPart('field1', 'field2'),\n      coupledPart('field2', 'field1'),\n      required({\n        factory: Button,\n        schema: [strict$1('dom')],\n        name: 'lock',\n        overrides: function (detail) {\n          return {\n            buttonBehaviours: derive$1([Toggling.config({\n                selected: detail.locked,\n                toggleClass: detail.markers.lockClass,\n                aria: { mode: 'pressed' }\n              })])\n          };\n        }\n      })\n    ]);\n\n    var factory$7 = function (detail, components, spec, externals) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: SketchBehaviours.augment(detail.coupledFieldBehaviours, [\n          Composing.config({ find: Option.some }),\n          Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function (comp) {\n                var _a;\n                var parts = getPartsOrDie(comp, detail, [\n                  'field1',\n                  'field2'\n                ]);\n                return _a = {}, _a[detail.field1Name] = Representing.getValue(parts.field1()), _a[detail.field2Name] = Representing.getValue(parts.field2()), _a;\n              },\n              setValue: function (comp, value) {\n                var parts = getPartsOrDie(comp, detail, [\n                  'field1',\n                  'field2'\n                ]);\n                if (hasKey$1(value, detail.field1Name)) {\n                  Representing.setValue(parts.field1(), value[detail.field1Name]);\n                }\n                if (hasKey$1(value, detail.field2Name)) {\n                  Representing.setValue(parts.field2(), value[detail.field2Name]);\n                }\n              }\n            }\n          })\n        ]),\n        apis: {\n          getField1: function (component) {\n            return getPart(component, detail, 'field1');\n          },\n          getField2: function (component) {\n            return getPart(component, detail, 'field2');\n          },\n          getLock: function (component) {\n            return getPart(component, detail, 'lock');\n          }\n        }\n      };\n    };\n    var FormCoupledInputs = composite$1({\n      name: 'FormCoupledInputs',\n      configFields: schema$i(),\n      partFields: parts$5(),\n      factory: factory$7,\n      apis: {\n        getField1: function (apis, component) {\n          return apis.getField1(component);\n        },\n        getField2: function (apis, component) {\n          return apis.getField2(component);\n        },\n        getLock: function (apis, component) {\n          return apis.getLock(component);\n        }\n      }\n    });\n\n    var formatSize = function (size) {\n      var unitDec = {\n        '': 0,\n        'px': 0,\n        'pt': 1,\n        'mm': 1,\n        'pc': 2,\n        'ex': 2,\n        'em': 2,\n        'ch': 2,\n        'rem': 2,\n        'cm': 3,\n        'in': 4,\n        '%': 4\n      };\n      var maxDecimal = function (unit) {\n        return unit in unitDec ? unitDec[unit] : 1;\n      };\n      var numText = size.value.toFixed(maxDecimal(size.unit));\n      if (numText.indexOf('.') !== -1) {\n        numText = numText.replace(/\\.?0*$/, '');\n      }\n      return numText + size.unit;\n    };\n    var parseSize = function (sizeText) {\n      var numPattern = /^\\s*(\\d+(?:\\.\\d+)?)\\s*(|cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|%)\\s*$/;\n      var match = numPattern.exec(sizeText);\n      if (match !== null) {\n        var value = parseFloat(match[1]);\n        var unit = match[2];\n        return Result.value({\n          value: value,\n          unit: unit\n        });\n      } else {\n        return Result.error(sizeText);\n      }\n    };\n    var convertUnit = function (size, unit) {\n      var inInch = {\n        '': 96,\n        'px': 96,\n        'pt': 72,\n        'cm': 2.54,\n        'pc': 12,\n        'mm': 25.4,\n        'in': 1\n      };\n      var supported = function (u) {\n        return Object.prototype.hasOwnProperty.call(inInch, u);\n      };\n      if (size.unit === unit) {\n        return Option.some(size.value);\n      } else if (supported(size.unit) && supported(unit)) {\n        if (inInch[size.unit] === inInch[unit]) {\n          return Option.some(size.value);\n        } else {\n          return Option.some(size.value / inInch[size.unit] * inInch[unit]);\n        }\n      } else {\n        return Option.none();\n      }\n    };\n    var noSizeConversion = function (input) {\n      return Option.none();\n    };\n    var ratioSizeConversion = function (scale, unit) {\n      return function (size) {\n        return convertUnit(size, unit).map(function (value) {\n          return {\n            value: value * scale,\n            unit: unit\n          };\n        });\n      };\n    };\n    var makeRatioConverter = function (currentFieldText, otherFieldText) {\n      var cValue = parseSize(currentFieldText).toOption();\n      var oValue = parseSize(otherFieldText).toOption();\n      return lift2(cValue, oValue, function (cSize, oSize) {\n        return convertUnit(cSize, oSize.unit).map(function (val) {\n          return oSize.value / val;\n        }).map(function (r) {\n          return ratioSizeConversion(r, oSize.unit);\n        }).getOr(noSizeConversion);\n      }).getOr(noSizeConversion);\n    };\n\n    var renderSizeInput = function (spec, providersBackstage) {\n      var converter = noSizeConversion;\n      var ratioEvent = generate$1('ratio-event');\n      var pLock = FormCoupledInputs.parts().lock({\n        dom: {\n          tag: 'button',\n          classes: [\n            'tox-lock',\n            'tox-button',\n            'tox-button--naked',\n            'tox-button--icon'\n          ],\n          attributes: { title: providersBackstage.translate(spec.label.getOr('Constrain proportions')) }\n        },\n        components: [\n          {\n            dom: {\n              tag: 'span',\n              classes: [\n                'tox-icon',\n                'tox-lock-icon__lock'\n              ],\n              innerHtml: get$c('lock', providersBackstage.icons)\n            }\n          },\n          {\n            dom: {\n              tag: 'span',\n              classes: [\n                'tox-icon',\n                'tox-lock-icon__unlock'\n              ],\n              innerHtml: get$c('unlock', providersBackstage.icons)\n            }\n          }\n        ],\n        buttonBehaviours: derive$1([\n          DisablingConfigs.button(spec.disabled),\n          Tabstopping.config({})\n        ])\n      });\n      var formGroup = function (components) {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-form__group']\n          },\n          components: components\n        };\n      };\n      var getFieldPart = function (isField1) {\n        return FormField.parts().field({\n          factory: Input,\n          inputClasses: ['tox-textfield'],\n          inputBehaviours: derive$1([\n            Disabling.config({ disabled: spec.disabled }),\n            Tabstopping.config({}),\n            config('size-input-events', [\n              run(focusin(), function (component, simulatedEvent) {\n                emitWith(component, ratioEvent, { isField1: isField1 });\n              }),\n              run(change(), function (component, simulatedEvent) {\n                emitWith(component, formChangeEvent, { name: spec.name });\n              })\n            ])\n          ]),\n          selectOnFocus: false\n        });\n      };\n      var getLabel = function (label) {\n        return {\n          dom: {\n            tag: 'label',\n            classes: ['tox-label'],\n            innerHtml: providersBackstage.translate(label)\n          }\n        };\n      };\n      var widthField = FormCoupledInputs.parts().field1(formGroup([\n        FormField.parts().label(getLabel('Width')),\n        getFieldPart(true)\n      ]));\n      var heightField = FormCoupledInputs.parts().field2(formGroup([\n        FormField.parts().label(getLabel('Height')),\n        getFieldPart(false)\n      ]));\n      return FormCoupledInputs.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-form__group']\n        },\n        components: [{\n            dom: {\n              tag: 'div',\n              classes: ['tox-form__controls-h-stack']\n            },\n            components: [\n              widthField,\n              heightField,\n              formGroup([\n                getLabel('&nbsp;'),\n                pLock\n              ])\n            ]\n          }],\n        field1Name: 'width',\n        field2Name: 'height',\n        locked: true,\n        markers: { lockClass: 'tox-locked' },\n        onLockedChange: function (current, other, lock) {\n          parseSize(Representing.getValue(current)).each(function (size) {\n            converter(size).each(function (newSize) {\n              Representing.setValue(other, formatSize(newSize));\n            });\n          });\n        },\n        coupledFieldBehaviours: derive$1([\n          Disabling.config({\n            disabled: spec.disabled,\n            onDisabled: function (comp) {\n              FormCoupledInputs.getField1(comp).bind(FormField.getField).each(Disabling.disable);\n              FormCoupledInputs.getField2(comp).bind(FormField.getField).each(Disabling.disable);\n              FormCoupledInputs.getLock(comp).each(Disabling.disable);\n            },\n            onEnabled: function (comp) {\n              FormCoupledInputs.getField1(comp).bind(FormField.getField).each(Disabling.enable);\n              FormCoupledInputs.getField2(comp).bind(FormField.getField).each(Disabling.enable);\n              FormCoupledInputs.getLock(comp).each(Disabling.enable);\n            }\n          }),\n          config('size-input-events2', [run(ratioEvent, function (component, simulatedEvent) {\n              var isField1 = simulatedEvent.event().isField1();\n              var optCurrent = isField1 ? FormCoupledInputs.getField1(component) : FormCoupledInputs.getField2(component);\n              var optOther = isField1 ? FormCoupledInputs.getField2(component) : FormCoupledInputs.getField1(component);\n              var value1 = optCurrent.map(Representing.getValue).getOr('');\n              var value2 = optOther.map(Representing.getValue).getOr('');\n              converter = makeRatioConverter(value1, value2);\n            })])\n        ])\n      });\n    };\n\n    var undo = constant(generate$1('undo'));\n    var redo = constant(generate$1('redo'));\n    var zoom = constant(generate$1('zoom'));\n    var back = constant(generate$1('back'));\n    var apply = constant(generate$1('apply'));\n    var swap = constant(generate$1('swap'));\n    var transform = constant(generate$1('transform'));\n    var tempTransform = constant(generate$1('temp-transform'));\n    var transformApply = constant(generate$1('transform-apply'));\n    var internal = {\n      undo: undo,\n      redo: redo,\n      zoom: zoom,\n      back: back,\n      apply: apply,\n      swap: swap,\n      transform: transform,\n      tempTransform: tempTransform,\n      transformApply: transformApply\n    };\n    var saveState = constant('save-state');\n    var disable$1 = constant('disable');\n    var enable$1 = constant('enable');\n    var external$2 = {\n      formActionEvent: formActionEvent,\n      saveState: saveState,\n      disable: disable$1,\n      enable: enable$1\n    };\n\n    var renderEditPanel = function (imagePanel, providersBackstage) {\n      var createButton = function (text, action, disabled, primary) {\n        return record(renderButton({\n          name: text,\n          text: text,\n          disabled: disabled,\n          primary: primary,\n          icon: Option.none(),\n          borderless: false\n        }, action, providersBackstage));\n      };\n      var createIconButton = function (icon, tooltip, action, disabled) {\n        return record(renderIconButton({\n          name: icon,\n          icon: Option.some(icon),\n          tooltip: Option.some(tooltip),\n          disabled: disabled,\n          primary: false,\n          borderless: false\n        }, action, providersBackstage));\n      };\n      var disableAllComponents = function (comps, eventcomp) {\n        comps.map(function (mem) {\n          var component = mem.get(eventcomp);\n          if (component.hasConfigured(Disabling)) {\n            Disabling.disable(component);\n          }\n        });\n      };\n      var enableAllComponents = function (comps, eventcomp) {\n        comps.map(function (mem) {\n          var component = mem.get(eventcomp);\n          if (component.hasConfigured(Disabling)) {\n            Disabling.enable(component);\n          }\n        });\n      };\n      var panelDom = {\n        tag: 'div',\n        classes: [\n          'tox-image-tools__toolbar',\n          'tox-image-tools-edit-panel'\n        ]\n      };\n      var noop$1 = noop;\n      var emit$1 = function (comp, event, data) {\n        emitWith(comp, event, data);\n      };\n      var emitDisable = function (component) {\n        return emit(component, external$2.disable());\n      };\n      var emitEnable = function (component) {\n        return emit(component, external$2.enable());\n      };\n      var emitTransform = function (comp, transform) {\n        emitDisable(comp);\n        emit$1(comp, internal.transform(), { transform: transform });\n        emitEnable(comp);\n      };\n      var emitTempTransform = function (comp, transform) {\n        emitDisable(comp);\n        emit$1(comp, internal.tempTransform(), { transform: transform });\n        emitEnable(comp);\n      };\n      var getBackSwap = function (anyInSystem) {\n        return function () {\n          memContainer.getOpt(anyInSystem).each(function (container) {\n            Replacing.set(container, [ButtonPanel]);\n          });\n        };\n      };\n      var emitTransformApply = function (comp, transform) {\n        emitDisable(comp);\n        emit$1(comp, internal.transformApply(), {\n          transform: transform,\n          swap: getBackSwap(comp)\n        });\n        emitEnable(comp);\n      };\n      var createBackButton = function () {\n        return createButton('Back', function (button) {\n          return emit$1(button, internal.back(), { swap: getBackSwap(button) });\n        }, false, false);\n      };\n      var createSpacer = function () {\n        return record({\n          dom: {\n            tag: 'div',\n            classes: ['tox-spacer']\n          },\n          behaviours: derive$1([Disabling.config({})])\n        });\n      };\n      var createApplyButton = function () {\n        return createButton('Apply', function (button) {\n          return emit$1(button, internal.apply(), { swap: getBackSwap(button) });\n        }, true, true);\n      };\n      var makeCropTransform = function () {\n        return function (ir) {\n          var rect = imagePanel.getRect();\n          return crop$1(ir, rect.x, rect.y, rect.w, rect.h);\n        };\n      };\n      var cropPanelComponents = [\n        createBackButton(),\n        createSpacer(),\n        createButton('Apply', function (button) {\n          var transform = makeCropTransform();\n          emitTransformApply(button, transform);\n          imagePanel.hideCrop();\n        }, false, true)\n      ];\n      var CropPanel = Container.sketch({\n        dom: panelDom,\n        components: cropPanelComponents.map(function (mem) {\n          return mem.asSpec();\n        }),\n        containerBehaviours: derive$1([config('image-tools-crop-buttons-events', [\n            run(external$2.disable(), function (comp, se) {\n              disableAllComponents(cropPanelComponents, comp);\n            }),\n            run(external$2.enable(), function (comp, se) {\n              enableAllComponents(cropPanelComponents, comp);\n            })\n          ])])\n      });\n      var memSize = record(renderSizeInput({\n        name: 'size',\n        label: Option.none(),\n        constrain: true,\n        disabled: false\n      }, providersBackstage));\n      var makeResizeTransform = function (width, height) {\n        return function (ir) {\n          return resize$2(ir, width, height);\n        };\n      };\n      var resizePanelComponents = [\n        createBackButton(),\n        createSpacer(),\n        memSize,\n        createSpacer(),\n        createButton('Apply', function (button) {\n          memSize.getOpt(button).each(function (sizeInput) {\n            var value = Representing.getValue(sizeInput);\n            var width = parseInt(value.width, 10);\n            var height = parseInt(value.height, 10);\n            var transform = makeResizeTransform(width, height);\n            emitTransformApply(button, transform);\n          });\n        }, false, true)\n      ];\n      var ResizePanel = Container.sketch({\n        dom: panelDom,\n        components: resizePanelComponents.map(function (mem) {\n          return mem.asSpec();\n        }),\n        containerBehaviours: derive$1([config('image-tools-resize-buttons-events', [\n            run(external$2.disable(), function (comp, se) {\n              disableAllComponents(resizePanelComponents, comp);\n            }),\n            run(external$2.enable(), function (comp, se) {\n              enableAllComponents(resizePanelComponents, comp);\n            })\n          ])])\n      });\n      var makeValueTransform = function (transform, value) {\n        return function (ir) {\n          return transform(ir, value);\n        };\n      };\n      var horizontalFlip = makeValueTransform(flip$1, 'h');\n      var verticalFlip = makeValueTransform(flip$1, 'v');\n      var counterclockwiseRotate = makeValueTransform(rotate$1, -90);\n      var clockwiseRotate = makeValueTransform(rotate$1, 90);\n      var flipRotateOnAction = function (comp, operation) {\n        emitTempTransform(comp, operation);\n      };\n      var flipRotateComponents = [\n        createBackButton(),\n        createSpacer(),\n        createIconButton('flip-horizontally', 'Flip horizontally', function (button) {\n          flipRotateOnAction(button, horizontalFlip);\n        }, false),\n        createIconButton('flip-vertically', 'Flip vertically', function (button) {\n          flipRotateOnAction(button, verticalFlip);\n        }, false),\n        createIconButton('rotate-left', 'Rotate counterclockwise', function (button) {\n          flipRotateOnAction(button, counterclockwiseRotate);\n        }, false),\n        createIconButton('rotate-right', 'Rotate clockwise', function (button) {\n          flipRotateOnAction(button, clockwiseRotate);\n        }, false),\n        createSpacer(),\n        createApplyButton()\n      ];\n      var FlipRotatePanel = Container.sketch({\n        dom: panelDom,\n        components: flipRotateComponents.map(function (mem) {\n          return mem.asSpec();\n        }),\n        containerBehaviours: derive$1([config('image-tools-fliprotate-buttons-events', [\n            run(external$2.disable(), function (comp, se) {\n              disableAllComponents(flipRotateComponents, comp);\n            }),\n            run(external$2.enable(), function (comp, se) {\n              enableAllComponents(flipRotateComponents, comp);\n            })\n          ])])\n      });\n      var makeSlider = function (label, onChoose, min, value, max) {\n        var labelPart = Slider.parts().label({\n          dom: {\n            tag: 'label',\n            classes: ['tox-label'],\n            innerHtml: providersBackstage.translate(label)\n          }\n        });\n        var spectrum = Slider.parts().spectrum({\n          dom: {\n            tag: 'div',\n            classes: ['tox-slider__rail'],\n            attributes: { role: 'presentation' }\n          }\n        });\n        var thumb = Slider.parts().thumb({\n          dom: {\n            tag: 'div',\n            classes: ['tox-slider__handle'],\n            attributes: { role: 'presentation' }\n          }\n        });\n        return record(Slider.sketch({\n          dom: {\n            tag: 'div',\n            classes: ['tox-slider'],\n            attributes: { role: 'presentation' }\n          },\n          model: {\n            mode: 'x',\n            minX: min,\n            maxX: max,\n            getInitialValue: constant({ x: constant(value) })\n          },\n          components: [\n            labelPart,\n            spectrum,\n            thumb\n          ],\n          sliderBehaviours: derive$1([Focusing.config({})]),\n          onChoose: onChoose\n        }));\n      };\n      var makeVariableSlider = function (label, transform, min, value, max) {\n        var onChoose = function (slider, thumb, value) {\n          var valTransform = makeValueTransform(transform, value.x() / 100);\n          emitTransform(slider, valTransform);\n        };\n        return makeSlider(label, onChoose, min, value, max);\n      };\n      var variableFilterPanelComponents = function (label, transform, min, value, max) {\n        return [\n          createBackButton(),\n          makeVariableSlider(label, transform, min, value, max),\n          createApplyButton()\n        ];\n      };\n      var createVariableFilterPanel = function (label, transform, min, value, max) {\n        var filterPanelComponents = variableFilterPanelComponents(label, transform, min, value, max);\n        return Container.sketch({\n          dom: panelDom,\n          components: filterPanelComponents.map(function (mem) {\n            return mem.asSpec();\n          }),\n          containerBehaviours: derive$1([config('image-tools-filter-panel-buttons-events', [\n              run(external$2.disable(), function (comp, se) {\n                disableAllComponents(filterPanelComponents, comp);\n              }),\n              run(external$2.enable(), function (comp, se) {\n                enableAllComponents(filterPanelComponents, comp);\n              })\n            ])])\n        });\n      };\n      var filterPanelComponents = [\n        createBackButton(),\n        createSpacer(),\n        createApplyButton()\n      ];\n      var FilterPanel = Container.sketch({\n        dom: panelDom,\n        components: filterPanelComponents.map(function (mem) {\n          return mem.asSpec();\n        })\n      });\n      var BrightnessPanel = createVariableFilterPanel('Brightness', brightness$1, -100, 0, 100);\n      var ContrastPanel = createVariableFilterPanel('Contrast', contrast$1, -100, 0, 100);\n      var GammaPanel = createVariableFilterPanel('Gamma', gamma$1, -100, 0, 100);\n      var makeColorTransform = function (red, green, blue) {\n        return function (ir) {\n          return colorize$1(ir, red, green, blue);\n        };\n      };\n      var makeColorSlider = function (label) {\n        var onChoose = function (slider, thumb, value) {\n          var redOpt = memRed.getOpt(slider);\n          var blueOpt = memBlue.getOpt(slider);\n          var greenOpt = memGreen.getOpt(slider);\n          redOpt.each(function (red) {\n            blueOpt.each(function (blue) {\n              greenOpt.each(function (green) {\n                var r = Representing.getValue(red).x() / 100;\n                var g = Representing.getValue(green).x() / 100;\n                var b = Representing.getValue(blue).x() / 100;\n                var transform = makeColorTransform(r, g, b);\n                emitTransform(slider, transform);\n              });\n            });\n          });\n        };\n        return makeSlider(label, onChoose, 0, 100, 200);\n      };\n      var memRed = makeColorSlider('R');\n      var memGreen = makeColorSlider('G');\n      var memBlue = makeColorSlider('B');\n      var colorizePanelComponents = [\n        createBackButton(),\n        memRed,\n        memGreen,\n        memBlue,\n        createApplyButton()\n      ];\n      var ColorizePanel = Container.sketch({\n        dom: panelDom,\n        components: colorizePanelComponents.map(function (mem) {\n          return mem.asSpec();\n        })\n      });\n      var getTransformPanelEvent = function (panel, transform, update) {\n        return function (button) {\n          var swap = function () {\n            memContainer.getOpt(button).each(function (container) {\n              Replacing.set(container, [panel]);\n              update(container);\n            });\n          };\n          emit$1(button, internal.swap(), {\n            transform: transform,\n            swap: swap\n          });\n        };\n      };\n      var cropPanelUpdate = function (_anyInSystem) {\n        imagePanel.showCrop();\n      };\n      var resizePanelUpdate = function (anyInSystem) {\n        memSize.getOpt(anyInSystem).each(function (sizeInput) {\n          var measurements = imagePanel.getMeasurements();\n          var width = measurements.width;\n          var height = measurements.height;\n          Representing.setValue(sizeInput, {\n            width: width,\n            height: height\n          });\n        });\n      };\n      var sharpenTransform = Option.some(sharpen$1);\n      var invertTransform = Option.some(invert$1);\n      var buttonPanelComponents = [\n        createIconButton('crop', 'Crop', getTransformPanelEvent(CropPanel, Option.none(), cropPanelUpdate), false),\n        createIconButton('resize', 'Resize', getTransformPanelEvent(ResizePanel, Option.none(), resizePanelUpdate), false),\n        createIconButton('orientation', 'Orientation', getTransformPanelEvent(FlipRotatePanel, Option.none(), noop$1), false),\n        createIconButton('brightness', 'Brightness', getTransformPanelEvent(BrightnessPanel, Option.none(), noop$1), false),\n        createIconButton('sharpen', 'Sharpen', getTransformPanelEvent(FilterPanel, sharpenTransform, noop$1), false),\n        createIconButton('contrast', 'Contrast', getTransformPanelEvent(ContrastPanel, Option.none(), noop$1), false),\n        createIconButton('color-levels', 'Color levels', getTransformPanelEvent(ColorizePanel, Option.none(), noop$1), false),\n        createIconButton('gamma', 'Gamma', getTransformPanelEvent(GammaPanel, Option.none(), noop$1), false),\n        createIconButton('invert', 'Invert', getTransformPanelEvent(FilterPanel, invertTransform, noop$1), false)\n      ];\n      var ButtonPanel = Container.sketch({\n        dom: panelDom,\n        components: buttonPanelComponents.map(function (mem) {\n          return mem.asSpec();\n        })\n      });\n      var container = Container.sketch({\n        dom: { tag: 'div' },\n        components: [ButtonPanel],\n        containerBehaviours: derive$1([Replacing.config({})])\n      });\n      var memContainer = record(container);\n      var getApplyButton = function (anyInSystem) {\n        return memContainer.getOpt(anyInSystem).map(function (container) {\n          var panel = container.components()[0];\n          return panel.components()[panel.components().length - 1];\n        });\n      };\n      return {\n        memContainer: memContainer,\n        getApplyButton: getApplyButton\n      };\n    };\n\n    var global$b = tinymce.util.Tools.resolve('tinymce.dom.DomQuery');\n\n    var global$c = tinymce.util.Tools.resolve('tinymce.geom.Rect');\n\n    var global$d = tinymce.util.Tools.resolve('tinymce.util.Observable');\n\n    var global$e = tinymce.util.Tools.resolve('tinymce.util.Tools');\n\n    var global$f = tinymce.util.Tools.resolve('tinymce.util.VK');\n\n    function getDocumentSize(doc) {\n      var documentElement, body, scrollWidth, clientWidth;\n      var offsetWidth, scrollHeight, clientHeight, offsetHeight;\n      var max = Math.max;\n      documentElement = doc.documentElement;\n      body = doc.body;\n      scrollWidth = max(documentElement.scrollWidth, body.scrollWidth);\n      clientWidth = max(documentElement.clientWidth, body.clientWidth);\n      offsetWidth = max(documentElement.offsetWidth, body.offsetWidth);\n      scrollHeight = max(documentElement.scrollHeight, body.scrollHeight);\n      clientHeight = max(documentElement.clientHeight, body.clientHeight);\n      offsetHeight = max(documentElement.offsetHeight, body.offsetHeight);\n      return {\n        width: scrollWidth < offsetWidth ? clientWidth : scrollWidth,\n        height: scrollHeight < offsetHeight ? clientHeight : scrollHeight\n      };\n    }\n    function updateWithTouchData(e) {\n      var keys, i;\n      if (e.changedTouches) {\n        keys = 'screenX screenY pageX pageY clientX clientY'.split(' ');\n        for (i = 0; i < keys.length; i++) {\n          e[keys[i]] = e.changedTouches[0][keys[i]];\n        }\n      }\n    }\n    function DragHelper (id, settings) {\n      var $eventOverlay;\n      var doc = settings.document || domGlobals.document;\n      var downButton;\n      var start, stop, drag, startX, startY;\n      settings = settings || {};\n      var handleElement = doc.getElementById(settings.handle || id);\n      start = function (e) {\n        var docSize = getDocumentSize(doc);\n        var handleElm, cursor;\n        updateWithTouchData(e);\n        e.preventDefault();\n        downButton = e.button;\n        handleElm = handleElement;\n        startX = e.screenX;\n        startY = e.screenY;\n        if (domGlobals.window.getComputedStyle) {\n          cursor = domGlobals.window.getComputedStyle(handleElm, null).getPropertyValue('cursor');\n        } else {\n          cursor = handleElm.runtimeStyle.cursor;\n        }\n        $eventOverlay = global$b('<div></div>').css({\n          position: 'absolute',\n          top: 0,\n          left: 0,\n          width: docSize.width,\n          height: docSize.height,\n          zIndex: 2147483647,\n          opacity: 0.0001,\n          cursor: cursor\n        }).appendTo(doc.body);\n        global$b(doc).on('mousemove touchmove', drag).on('mouseup touchend', stop);\n        settings.start(e);\n      };\n      drag = function (e) {\n        updateWithTouchData(e);\n        if (e.button !== downButton) {\n          return stop(e);\n        }\n        e.deltaX = e.screenX - startX;\n        e.deltaY = e.screenY - startY;\n        e.preventDefault();\n        settings.drag(e);\n      };\n      stop = function (e) {\n        updateWithTouchData(e);\n        global$b(doc).off('mousemove touchmove', drag).off('mouseup touchend', stop);\n        $eventOverlay.remove();\n        if (settings.stop) {\n          settings.stop(e);\n        }\n      };\n      this.destroy = function () {\n        global$b(handleElement).off();\n      };\n      global$b(handleElement).on('mousedown touchstart', start);\n    }\n\n    var count = 0;\n    var create$7 = function (currentRect, viewPortRect, clampRect, containerElm, action) {\n      var instance;\n      var dragHelpers;\n      var blockers;\n      var prefix = 'tox-';\n      var id = prefix + 'crid-' + count++;\n      var handles = [\n        {\n          name: 'move',\n          xMul: 0,\n          yMul: 0,\n          deltaX: 1,\n          deltaY: 1,\n          deltaW: 0,\n          deltaH: 0,\n          label: 'Crop Mask'\n        },\n        {\n          name: 'nw',\n          xMul: 0,\n          yMul: 0,\n          deltaX: 1,\n          deltaY: 1,\n          deltaW: -1,\n          deltaH: -1,\n          label: 'Top Left Crop Handle'\n        },\n        {\n          name: 'ne',\n          xMul: 1,\n          yMul: 0,\n          deltaX: 0,\n          deltaY: 1,\n          deltaW: 1,\n          deltaH: -1,\n          label: 'Top Right Crop Handle'\n        },\n        {\n          name: 'sw',\n          xMul: 0,\n          yMul: 1,\n          deltaX: 1,\n          deltaY: 0,\n          deltaW: -1,\n          deltaH: 1,\n          label: 'Bottom Left Crop Handle'\n        },\n        {\n          name: 'se',\n          xMul: 1,\n          yMul: 1,\n          deltaX: 0,\n          deltaY: 0,\n          deltaW: 1,\n          deltaH: 1,\n          label: 'Bottom Right Crop Handle'\n        }\n      ];\n      blockers = [\n        'top',\n        'right',\n        'bottom',\n        'left'\n      ];\n      var getAbsoluteRect = function (outerRect, relativeRect) {\n        return {\n          x: relativeRect.x + outerRect.x,\n          y: relativeRect.y + outerRect.y,\n          w: relativeRect.w,\n          h: relativeRect.h\n        };\n      };\n      var getRelativeRect = function (outerRect, innerRect) {\n        return {\n          x: innerRect.x - outerRect.x,\n          y: innerRect.y - outerRect.y,\n          w: innerRect.w,\n          h: innerRect.h\n        };\n      };\n      var getInnerRect = function () {\n        return getRelativeRect(clampRect, currentRect);\n      };\n      function moveRect(handle, startRect, deltaX, deltaY) {\n        var x, y, w, h, rect;\n        x = startRect.x;\n        y = startRect.y;\n        w = startRect.w;\n        h = startRect.h;\n        x += deltaX * handle.deltaX;\n        y += deltaY * handle.deltaY;\n        w += deltaX * handle.deltaW;\n        h += deltaY * handle.deltaH;\n        if (w < 20) {\n          w = 20;\n        }\n        if (h < 20) {\n          h = 20;\n        }\n        rect = currentRect = global$c.clamp({\n          x: x,\n          y: y,\n          w: w,\n          h: h\n        }, clampRect, handle.name === 'move');\n        rect = getRelativeRect(clampRect, rect);\n        instance.fire('updateRect', { rect: rect });\n        setInnerRect(rect);\n      }\n      function render() {\n        function createDragHelper(handle) {\n          var startRect;\n          return new DragHelper(id, {\n            document: containerElm.ownerDocument,\n            handle: id + '-' + handle.name,\n            start: function () {\n              startRect = currentRect;\n            },\n            drag: function (e) {\n              moveRect(handle, startRect, e.deltaX, e.deltaY);\n            }\n          });\n        }\n        global$b('<div id=\"' + id + '\" class=\"' + prefix + 'croprect-container\"' + ' role=\"grid\" aria-dropeffect=\"execute\">').appendTo(containerElm);\n        global$e.each(blockers, function (blocker) {\n          global$b('#' + id, containerElm).append('<div id=\"' + id + '-' + blocker + '\"class=\"' + prefix + 'croprect-block\" style=\"display: none\" data-mce-bogus=\"all\">');\n        });\n        global$e.each(handles, function (handle) {\n          global$b('#' + id, containerElm).append('<div id=\"' + id + '-' + handle.name + '\" class=\"' + prefix + 'croprect-handle ' + prefix + 'croprect-handle-' + handle.name + '\"' + 'style=\"display: none\" data-mce-bogus=\"all\" role=\"gridcell\" tabindex=\"-1\"' + ' aria-label=\"' + handle.label + '\" aria-grabbed=\"false\" title=\"' + handle.label + '\">');\n        });\n        dragHelpers = global$e.map(handles, createDragHelper);\n        repaint(currentRect);\n        global$b(containerElm).on('focusin focusout', function (e) {\n          global$b(e.target).attr('aria-grabbed', e.type === 'focus' ? 'true' : 'false');\n        });\n        global$b(containerElm).on('keydown', function (e) {\n          var activeHandle;\n          global$e.each(handles, function (handle) {\n            if (e.target.id === id + '-' + handle.name) {\n              activeHandle = handle;\n              return false;\n            }\n          });\n          function moveAndBlock(evt, handle, startRect, deltaX, deltaY) {\n            evt.stopPropagation();\n            evt.preventDefault();\n            moveRect(activeHandle, startRect, deltaX, deltaY);\n          }\n          switch (e.keyCode) {\n          case global$f.LEFT:\n            moveAndBlock(e, activeHandle, currentRect, -10, 0);\n            break;\n          case global$f.RIGHT:\n            moveAndBlock(e, activeHandle, currentRect, 10, 0);\n            break;\n          case global$f.UP:\n            moveAndBlock(e, activeHandle, currentRect, 0, -10);\n            break;\n          case global$f.DOWN:\n            moveAndBlock(e, activeHandle, currentRect, 0, 10);\n            break;\n          case global$f.ENTER:\n          case global$f.SPACEBAR:\n            e.preventDefault();\n            action();\n            break;\n          }\n        });\n      }\n      function toggleVisibility(state) {\n        var selectors;\n        selectors = global$e.map(handles, function (handle) {\n          return '#' + id + '-' + handle.name;\n        }).concat(global$e.map(blockers, function (blocker) {\n          return '#' + id + '-' + blocker;\n        })).join(',');\n        if (state) {\n          global$b(selectors, containerElm).show();\n        } else {\n          global$b(selectors, containerElm).hide();\n        }\n      }\n      function repaint(rect) {\n        function updateElementRect(name, rect) {\n          if (rect.h < 0) {\n            rect.h = 0;\n          }\n          if (rect.w < 0) {\n            rect.w = 0;\n          }\n          global$b('#' + id + '-' + name, containerElm).css({\n            left: rect.x,\n            top: rect.y,\n            width: rect.w,\n            height: rect.h\n          });\n        }\n        global$e.each(handles, function (handle) {\n          global$b('#' + id + '-' + handle.name, containerElm).css({\n            left: rect.w * handle.xMul + rect.x,\n            top: rect.h * handle.yMul + rect.y\n          });\n        });\n        updateElementRect('top', {\n          x: viewPortRect.x,\n          y: viewPortRect.y,\n          w: viewPortRect.w,\n          h: rect.y - viewPortRect.y\n        });\n        updateElementRect('right', {\n          x: rect.x + rect.w,\n          y: rect.y,\n          w: viewPortRect.w - rect.x - rect.w + viewPortRect.x,\n          h: rect.h\n        });\n        updateElementRect('bottom', {\n          x: viewPortRect.x,\n          y: rect.y + rect.h,\n          w: viewPortRect.w,\n          h: viewPortRect.h - rect.y - rect.h + viewPortRect.y\n        });\n        updateElementRect('left', {\n          x: viewPortRect.x,\n          y: rect.y,\n          w: rect.x - viewPortRect.x,\n          h: rect.h\n        });\n        updateElementRect('move', rect);\n      }\n      function setRect(rect) {\n        currentRect = rect;\n        repaint(currentRect);\n      }\n      function setViewPortRect(rect) {\n        viewPortRect = rect;\n        repaint(currentRect);\n      }\n      function setInnerRect(rect) {\n        setRect(getAbsoluteRect(clampRect, rect));\n      }\n      function setClampRect(rect) {\n        clampRect = rect;\n        repaint(currentRect);\n      }\n      function destroy() {\n        global$e.each(dragHelpers, function (helper) {\n          helper.destroy();\n        });\n        dragHelpers = [];\n      }\n      render();\n      instance = global$e.extend({\n        toggleVisibility: toggleVisibility,\n        setClampRect: setClampRect,\n        setRect: setRect,\n        getInnerRect: getInnerRect,\n        setInnerRect: setInnerRect,\n        setViewPortRect: setViewPortRect,\n        destroy: destroy\n      }, global$d);\n      return instance;\n    };\n    var CropRect = { create: create$7 };\n\n    var loadImage = function (image) {\n      return new global$4(function (resolve) {\n        var loaded = function () {\n          image.removeEventListener('load', loaded);\n          resolve(image);\n        };\n        if (image.complete) {\n          resolve(image);\n        } else {\n          image.addEventListener('load', loaded);\n        }\n      });\n    };\n    var renderImagePanel = function (initialUrl) {\n      var memBg = record({\n        dom: {\n          tag: 'div',\n          classes: ['tox-image-tools__image-bg'],\n          attributes: { role: 'presentation' }\n        }\n      });\n      var zoomState = Cell(1);\n      var cropRect = Cell(Option.none());\n      var rectState = Cell({\n        x: 0,\n        y: 0,\n        w: 1,\n        h: 1\n      });\n      var viewRectState = Cell({\n        x: 0,\n        y: 0,\n        w: 1,\n        h: 1\n      });\n      var repaintImg = function (anyInSystem, img) {\n        memContainer.getOpt(anyInSystem).each(function (panel) {\n          var zoom = zoomState.get();\n          var panelW = get$7(panel.element());\n          var panelH = get$6(panel.element());\n          var width = img.dom().naturalWidth * zoom;\n          var height = img.dom().naturalHeight * zoom;\n          var left = Math.max(0, panelW / 2 - width / 2);\n          var top = Math.max(0, panelH / 2 - height / 2);\n          var css = {\n            left: left.toString() + 'px',\n            top: top.toString() + 'px',\n            width: width.toString() + 'px',\n            height: height.toString() + 'px',\n            position: 'absolute'\n          };\n          setAll$1(img, css);\n          memBg.getOpt(panel).each(function (bg) {\n            setAll$1(bg.element(), css);\n          });\n          cropRect.get().each(function (cRect) {\n            var rect = rectState.get();\n            cRect.setRect({\n              x: rect.x * zoom + left,\n              y: rect.y * zoom + top,\n              w: rect.w * zoom,\n              h: rect.h * zoom\n            });\n            cRect.setClampRect({\n              x: left,\n              y: top,\n              w: width,\n              h: height\n            });\n            cRect.setViewPortRect({\n              x: 0,\n              y: 0,\n              w: panelW,\n              h: panelH\n            });\n          });\n        });\n      };\n      var zoomFit = function (anyInSystem, img) {\n        memContainer.getOpt(anyInSystem).each(function (panel) {\n          var panelW = get$7(panel.element());\n          var panelH = get$6(panel.element());\n          var width = img.dom().naturalWidth;\n          var height = img.dom().naturalHeight;\n          var zoom = Math.min(panelW / width, panelH / height);\n          if (zoom >= 1) {\n            zoomState.set(1);\n          } else {\n            zoomState.set(zoom);\n          }\n        });\n      };\n      var updateSrc = function (anyInSystem, url) {\n        var img = Element.fromTag('img');\n        set$1(img, 'src', url);\n        return loadImage(img.dom()).then(function () {\n          return memContainer.getOpt(anyInSystem).map(function (panel) {\n            var aImg = external({ element: img });\n            Replacing.replaceAt(panel, 1, Option.some(aImg));\n            var lastViewRect = viewRectState.get();\n            var viewRect = {\n              x: 0,\n              y: 0,\n              w: img.dom().naturalWidth,\n              h: img.dom().naturalHeight\n            };\n            viewRectState.set(viewRect);\n            var rect = global$c.inflate(viewRect, -20, -20);\n            rectState.set(rect);\n            if (lastViewRect.w !== viewRect.w || lastViewRect.h !== viewRect.h) {\n              zoomFit(panel, img);\n            }\n            repaintImg(panel, img);\n            return img;\n          });\n        });\n      };\n      var zoom = function (anyInSystem, direction) {\n        var currentZoom = zoomState.get();\n        var newZoom = direction > 0 ? Math.min(2, currentZoom + 0.1) : Math.max(0.1, currentZoom - 0.1);\n        zoomState.set(newZoom);\n        memContainer.getOpt(anyInSystem).each(function (panel) {\n          var img = panel.components()[1].element();\n          repaintImg(panel, img);\n        });\n      };\n      var showCrop = function () {\n        cropRect.get().each(function (cRect) {\n          cRect.toggleVisibility(true);\n        });\n      };\n      var hideCrop = function () {\n        cropRect.get().each(function (cRect) {\n          cRect.toggleVisibility(false);\n        });\n      };\n      var getRect = function () {\n        return rectState.get();\n      };\n      var container = Container.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-image-tools__image']\n        },\n        components: [\n          memBg.asSpec(),\n          {\n            dom: {\n              tag: 'img',\n              attributes: { src: initialUrl }\n            }\n          },\n          {\n            dom: { tag: 'div' },\n            behaviours: derive$1([config('image-panel-crop-events', [runOnAttached(function (comp) {\n                  memContainer.getOpt(comp).each(function (container) {\n                    var el = container.element().dom();\n                    var cRect = CropRect.create({\n                      x: 10,\n                      y: 10,\n                      w: 100,\n                      h: 100\n                    }, {\n                      x: 0,\n                      y: 0,\n                      w: 200,\n                      h: 200\n                    }, {\n                      x: 0,\n                      y: 0,\n                      w: 200,\n                      h: 200\n                    }, el, function () {\n                    });\n                    cRect.toggleVisibility(false);\n                    cRect.on('updateRect', function (e) {\n                      var rect = e.rect;\n                      var zoom = zoomState.get();\n                      var newRect = {\n                        x: Math.round(rect.x / zoom),\n                        y: Math.round(rect.y / zoom),\n                        w: Math.round(rect.w / zoom),\n                        h: Math.round(rect.h / zoom)\n                      };\n                      rectState.set(newRect);\n                    });\n                    cropRect.set(Option.some(cRect));\n                  });\n                })])])\n          }\n        ],\n        containerBehaviours: derive$1([\n          Replacing.config({}),\n          config('image-panel-events', [runOnAttached(function (comp) {\n              updateSrc(comp, initialUrl);\n            })])\n        ])\n      });\n      var memContainer = record(container);\n      var getMeasurements = function () {\n        var viewRect = viewRectState.get();\n        return {\n          width: viewRect.w,\n          height: viewRect.h\n        };\n      };\n      return {\n        memContainer: memContainer,\n        updateSrc: updateSrc,\n        zoom: zoom,\n        showCrop: showCrop,\n        hideCrop: hideCrop,\n        getRect: getRect,\n        getMeasurements: getMeasurements\n      };\n    };\n\n    var createButton = function (innerHtml, icon, disabled, action, providersBackstage) {\n      return renderIconButton({\n        name: innerHtml,\n        icon: Option.some(icon),\n        disabled: disabled,\n        tooltip: Option.some(innerHtml),\n        primary: false,\n        borderless: false\n      }, action, providersBackstage);\n    };\n    var setButtonEnabled = function (button, enabled) {\n      if (enabled) {\n        Disabling.enable(button);\n      } else {\n        Disabling.disable(button);\n      }\n    };\n    var renderSideBar = function (providersBackstage) {\n      var updateButtonUndoStates = function (anyInSystem, undoEnabled, redoEnabled) {\n        memUndo.getOpt(anyInSystem).each(function (undo) {\n          setButtonEnabled(undo, undoEnabled);\n        });\n        memRedo.getOpt(anyInSystem).each(function (redo) {\n          setButtonEnabled(redo, redoEnabled);\n        });\n      };\n      var memUndo = record(createButton('Undo', 'undo', true, function (button) {\n        emitWith(button, internal.undo(), { direction: 1 });\n      }, providersBackstage));\n      var memRedo = record(createButton('Redo', 'redo', true, function (button) {\n        emitWith(button, internal.redo(), { direction: 1 });\n      }, providersBackstage));\n      var container = Container.sketch({\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox-image-tools__toolbar',\n            'tox-image-tools__sidebar'\n          ]\n        },\n        components: [\n          memUndo.asSpec(),\n          memRedo.asSpec(),\n          createButton('Zoom in', 'zoom-in', false, function (button) {\n            emitWith(button, internal.zoom(), { direction: 1 });\n          }, providersBackstage),\n          createButton('Zoom out', 'zoom-out', false, function (button) {\n            emitWith(button, internal.zoom(), { direction: -1 });\n          }, providersBackstage)\n        ]\n      });\n      return {\n        container: container,\n        updateButtonUndoStates: updateButtonUndoStates\n      };\n    };\n\n    function UndoStack () {\n      var data = [];\n      var index = -1;\n      function add(state) {\n        var removed;\n        removed = data.splice(++index);\n        data.push(state);\n        return {\n          state: state,\n          removed: removed\n        };\n      }\n      function undo() {\n        if (canUndo()) {\n          return data[--index];\n        }\n      }\n      function redo() {\n        if (canRedo()) {\n          return data[++index];\n        }\n      }\n      function canUndo() {\n        return index > 0;\n      }\n      function canRedo() {\n        return index !== -1 && index < data.length - 1;\n      }\n      return {\n        data: data,\n        add: add,\n        undo: undo,\n        redo: redo,\n        canUndo: canUndo,\n        canRedo: canRedo\n      };\n    }\n\n    var makeState = function (initialState) {\n      var blobState = Cell(initialState);\n      var tempState = Cell(Option.none());\n      var undoStack = UndoStack();\n      undoStack.add(initialState);\n      var getBlobState = function () {\n        return blobState.get();\n      };\n      var setBlobState = function (state) {\n        blobState.set(state);\n      };\n      var getTempState = function () {\n        return tempState.get().fold(function () {\n          return blobState.get();\n        }, function (temp) {\n          return temp;\n        });\n      };\n      var updateTempState = function (blob) {\n        var newTempState = createState(blob);\n        destroyTempState();\n        tempState.set(Option.some(newTempState));\n        return newTempState.url;\n      };\n      var createState = function (blob) {\n        return {\n          blob: blob,\n          url: domGlobals.URL.createObjectURL(blob)\n        };\n      };\n      var destroyState = function (state) {\n        domGlobals.URL.revokeObjectURL(state.url);\n      };\n      var destroyStates = function (states) {\n        global$e.each(states, destroyState);\n      };\n      var destroyTempState = function () {\n        tempState.get().each(destroyState);\n        tempState.set(Option.none());\n      };\n      var addBlobState = function (blob) {\n        var newState = createState(blob);\n        setBlobState(newState);\n        var removed = undoStack.add(newState).removed;\n        destroyStates(removed);\n        return newState.url;\n      };\n      var addTempState = function (blob) {\n        var newState = createState(blob);\n        tempState.set(Option.some(newState));\n        return newState.url;\n      };\n      var applyTempState = function (postApply) {\n        return tempState.get().fold(function () {\n        }, function (temp) {\n          addBlobState(temp.blob);\n          postApply();\n        });\n      };\n      var undo = function () {\n        var currentState = undoStack.undo();\n        setBlobState(currentState);\n        return currentState.url;\n      };\n      var redo = function () {\n        var currentState = undoStack.redo();\n        setBlobState(currentState);\n        return currentState.url;\n      };\n      var getHistoryStates = function () {\n        var undoEnabled = undoStack.canUndo();\n        var redoEnabled = undoStack.canRedo();\n        return {\n          undoEnabled: undoEnabled,\n          redoEnabled: redoEnabled\n        };\n      };\n      return {\n        getBlobState: getBlobState,\n        setBlobState: setBlobState,\n        addBlobState: addBlobState,\n        getTempState: getTempState,\n        updateTempState: updateTempState,\n        addTempState: addTempState,\n        applyTempState: applyTempState,\n        destroyTempState: destroyTempState,\n        undo: undo,\n        redo: redo,\n        getHistoryStates: getHistoryStates\n      };\n    };\n\n    var renderImageTools = function (detail, providersBackstage) {\n      var state = makeState(detail.currentState);\n      var zoom = function (anyInSystem, simulatedEvent) {\n        var direction = simulatedEvent.event().direction();\n        imagePanel.zoom(anyInSystem, direction);\n      };\n      var updateButtonUndoStates = function (anyInSystem) {\n        var historyStates = state.getHistoryStates();\n        sideBar.updateButtonUndoStates(anyInSystem, historyStates.undoEnabled, historyStates.redoEnabled);\n        emitWith(anyInSystem, external$2.formActionEvent, {\n          name: external$2.saveState(),\n          value: historyStates.undoEnabled\n        });\n      };\n      var disableUndoRedo = function (anyInSystem) {\n        sideBar.updateButtonUndoStates(anyInSystem, false, false);\n      };\n      var undo = function (anyInSystem, _simulatedEvent) {\n        var url = state.undo();\n        updateSrc(anyInSystem, url).then(function (oImg) {\n          unblock(anyInSystem);\n          updateButtonUndoStates(anyInSystem);\n        });\n      };\n      var redo = function (anyInSystem, _simulatedEvent) {\n        var url = state.redo();\n        updateSrc(anyInSystem, url).then(function (oImg) {\n          unblock(anyInSystem);\n          updateButtonUndoStates(anyInSystem);\n        });\n      };\n      var imageResultToBlob = function (ir) {\n        return ir.toBlob();\n      };\n      var block = function (anyInSystem) {\n        emitWith(anyInSystem, external$2.formActionEvent, {\n          name: external$2.disable(),\n          value: {}\n        });\n      };\n      var unblock = function (anyInSystem) {\n        editPanel.getApplyButton(anyInSystem).each(function (applyButton) {\n          Disabling.enable(applyButton);\n        });\n        emitWith(anyInSystem, external$2.formActionEvent, {\n          name: external$2.enable(),\n          value: {}\n        });\n      };\n      var updateSrc = function (anyInSystem, src) {\n        block(anyInSystem);\n        return imagePanel.updateSrc(anyInSystem, src);\n      };\n      var blobManipulate = function (anyInSystem, blob, filter, action, swap) {\n        block(anyInSystem);\n        return blobToImageResult(blob).then(filter).then(imageResultToBlob).then(action).then(function (url) {\n          return updateSrc(anyInSystem, url).then(function (oImg) {\n            updateButtonUndoStates(anyInSystem);\n            swap();\n            unblock(anyInSystem);\n            return oImg;\n          });\n        }).catch(function (err) {\n          domGlobals.console.log(err);\n          unblock(anyInSystem);\n          return err;\n        });\n      };\n      var manipulate = function (anyInSystem, filter, swap) {\n        var blob = state.getBlobState().blob;\n        var action = function (blob) {\n          return state.updateTempState(blob);\n        };\n        blobManipulate(anyInSystem, blob, filter, action, swap);\n      };\n      var tempManipulate = function (anyInSystem, filter) {\n        var blob = state.getTempState().blob;\n        var action = function (blob) {\n          return state.addTempState(blob);\n        };\n        blobManipulate(anyInSystem, blob, filter, action, noop);\n      };\n      var manipulateApply = function (anyInSystem, filter, swap) {\n        var blob = state.getBlobState().blob;\n        var action = function (blob) {\n          var url = state.addBlobState(blob);\n          destroyTempState(anyInSystem);\n          return url;\n        };\n        blobManipulate(anyInSystem, blob, filter, action, swap);\n      };\n      var apply = function (anyInSystem, simulatedEvent) {\n        var postApply = function () {\n          destroyTempState(anyInSystem);\n          var swap = simulatedEvent.event().swap();\n          swap();\n        };\n        state.applyTempState(postApply);\n      };\n      var destroyTempState = function (anyInSystem) {\n        var currentUrl = state.getBlobState().url;\n        state.destroyTempState();\n        updateButtonUndoStates(anyInSystem);\n        return currentUrl;\n      };\n      var cancel = function (anyInSystem) {\n        var currentUrl = destroyTempState(anyInSystem);\n        updateSrc(anyInSystem, currentUrl).then(function (oImg) {\n          unblock(anyInSystem);\n        });\n      };\n      var back = function (anyInSystem, simulatedEvent) {\n        cancel(anyInSystem);\n        var swap = simulatedEvent.event().swap();\n        swap();\n        imagePanel.hideCrop();\n      };\n      var transform = function (anyInSystem, simulatedEvent) {\n        return manipulate(anyInSystem, simulatedEvent.event().transform(), noop);\n      };\n      var tempTransform = function (anyInSystem, simulatedEvent) {\n        return tempManipulate(anyInSystem, simulatedEvent.event().transform());\n      };\n      var transformApply = function (anyInSystem, simulatedEvent) {\n        return manipulateApply(anyInSystem, simulatedEvent.event().transform(), simulatedEvent.event().swap());\n      };\n      var imagePanel = renderImagePanel(detail.currentState.url);\n      var sideBar = renderSideBar(providersBackstage);\n      var editPanel = renderEditPanel(imagePanel, providersBackstage);\n      var swap = function (anyInSystem, simulatedEvent) {\n        disableUndoRedo(anyInSystem);\n        var transform = simulatedEvent.event().transform();\n        var swap = simulatedEvent.event().swap();\n        transform.fold(function () {\n          swap();\n        }, function (transform) {\n          manipulate(anyInSystem, transform, swap);\n        });\n      };\n      return {\n        dom: {\n          tag: 'div',\n          attributes: { role: 'presentation' }\n        },\n        components: [\n          editPanel.memContainer.asSpec(),\n          imagePanel.memContainer.asSpec(),\n          sideBar.container\n        ],\n        behaviours: derive$1([\n          Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function () {\n                return state.getBlobState();\n              }\n            }\n          }),\n          config('image-tools-events', [\n            run(internal.undo(), undo),\n            run(internal.redo(), redo),\n            run(internal.zoom(), zoom),\n            run(internal.back(), back),\n            run(internal.apply(), apply),\n            run(internal.transform(), transform),\n            run(internal.tempTransform(), tempTransform),\n            run(internal.transformApply(), transformApply),\n            run(internal.swap(), swap)\n          ]),\n          ComposingConfigs.self()\n        ])\n      };\n    };\n\n    var factory$8 = function (detail, spec) {\n      var options = map(detail.options, function (option) {\n        return {\n          dom: {\n            tag: 'option',\n            value: option.value,\n            innerHtml: option.text\n          }\n        };\n      });\n      var initialValues = detail.data.map(function (v) {\n        return wrap$1('initialValue', v);\n      }).getOr({});\n      return {\n        uid: detail.uid,\n        dom: {\n          tag: 'select',\n          classes: detail.selectClasses,\n          attributes: detail.selectAttributes\n        },\n        components: options,\n        behaviours: augment(detail.selectBehaviours, [\n          Focusing.config({}),\n          Representing.config({\n            store: __assign({\n              mode: 'manual',\n              getValue: function (select) {\n                return get$5(select.element());\n              },\n              setValue: function (select, newValue) {\n                var found = find(detail.options, function (opt) {\n                  return opt.value === newValue;\n                });\n                if (found.isSome()) {\n                  set$3(select.element(), newValue);\n                }\n              }\n            }, initialValues)\n          })\n        ])\n      };\n    };\n    var HtmlSelect = single$2({\n      name: 'HtmlSelect',\n      configFields: [\n        strict$1('options'),\n        field$1('selectBehaviours', [\n          Focusing,\n          Representing\n        ]),\n        defaulted$1('selectClasses', []),\n        defaulted$1('selectAttributes', {}),\n        option('data')\n      ],\n      factory: factory$8\n    });\n\n    var renderSelectBox = function (spec, providersBackstage) {\n      var translatedOptions = map(spec.items, function (item) {\n        return {\n          text: providersBackstage.translate(item.text),\n          value: item.value\n        };\n      });\n      var pLabel = spec.label.map(function (label) {\n        return renderLabel(label, providersBackstage);\n      });\n      var pField = FormField.parts().field({\n        dom: {},\n        selectAttributes: { size: spec.size },\n        options: translatedOptions,\n        factory: HtmlSelect,\n        selectBehaviours: derive$1([\n          Disabling.config({ disabled: spec.disabled }),\n          Tabstopping.config({}),\n          config('selectbox-change', [run(change(), function (component, _) {\n              emitWith(component, formChangeEvent, { name: spec.name });\n            })])\n        ])\n      });\n      var chevron = spec.size > 1 ? Option.none() : Option.some({\n        dom: {\n          tag: 'div',\n          classes: ['tox-selectfield__icon-js'],\n          innerHtml: get$c('chevron-down', providersBackstage.icons)\n        }\n      });\n      var selectWrap = {\n        dom: {\n          tag: 'div',\n          classes: ['tox-selectfield']\n        },\n        components: flatten([\n          [pField],\n          chevron.toArray()\n        ])\n      };\n      return FormField.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-form__group']\n        },\n        components: flatten([\n          pLabel.toArray(),\n          [selectWrap]\n        ]),\n        fieldBehaviours: derive$1([Disabling.config({\n            disabled: spec.disabled,\n            onDisabled: function (comp) {\n              FormField.getField(comp).each(Disabling.disable);\n            },\n            onEnabled: function (comp) {\n              FormField.getField(comp).each(Disabling.enable);\n            }\n          })])\n      });\n    };\n\n    var renderTextField = function (spec, providersBackstage) {\n      var pLabel = spec.label.map(function (label) {\n        return renderLabel(label, providersBackstage);\n      });\n      var baseInputBehaviours = [\n        Disabling.config({ disabled: spec.disabled }),\n        Keying.config({\n          mode: 'execution',\n          useEnter: spec.multiline !== true,\n          useControlEnter: spec.multiline === true,\n          execute: function (comp) {\n            emit(comp, formSubmitEvent);\n            return Option.some(true);\n          }\n        }),\n        config('textfield-change', [\n          run(input(), function (component, _) {\n            emitWith(component, formChangeEvent, { name: spec.name });\n          }),\n          run(postPaste(), function (component, _) {\n            emitWith(component, formChangeEvent, { name: spec.name });\n          })\n        ]),\n        Tabstopping.config({})\n      ];\n      var validatingBehaviours = spec.validation.map(function (vl) {\n        return Invalidating.config({\n          getRoot: function (input) {\n            return parent(input.element());\n          },\n          invalidClass: 'tox-invalid',\n          validator: {\n            validate: function (input) {\n              var v = Representing.getValue(input);\n              var result = vl.validator(v);\n              return Future.pure(result === true ? Result.value(v) : Result.error(result));\n            },\n            validateOnLoad: vl.validateOnLoad\n          }\n        });\n      }).toArray();\n      var placeholder = spec.placeholder.fold(constant({}), function (p) {\n        return { placeholder: providersBackstage.translate(p) };\n      });\n      var inputMode = spec.inputMode.fold(constant({}), function (mode) {\n        return { inputmode: mode };\n      });\n      var inputAttributes = __assign(__assign({}, placeholder), inputMode);\n      var pField = FormField.parts().field({\n        tag: spec.multiline === true ? 'textarea' : 'input',\n        inputAttributes: inputAttributes,\n        inputClasses: [spec.classname],\n        inputBehaviours: derive$1(flatten([\n          baseInputBehaviours,\n          validatingBehaviours\n        ])),\n        selectOnFocus: false,\n        factory: Input\n      });\n      var extraClasses = spec.flex ? ['tox-form__group--stretched'] : [];\n      var extraClasses2 = extraClasses.concat(spec.maximized ? ['tox-form-group--maximize'] : []);\n      var extraBehaviours = [Disabling.config({\n          disabled: spec.disabled,\n          onDisabled: function (comp) {\n            FormField.getField(comp).each(Disabling.disable);\n          },\n          onEnabled: function (comp) {\n            FormField.getField(comp).each(Disabling.enable);\n          }\n        })];\n      return renderFormFieldWith(pLabel, pField, extraClasses2, extraBehaviours);\n    };\n    var renderInput = function (spec, providersBackstage) {\n      return renderTextField({\n        name: spec.name,\n        multiline: false,\n        label: spec.label,\n        inputMode: spec.inputMode,\n        placeholder: spec.placeholder,\n        flex: false,\n        disabled: spec.disabled,\n        classname: 'tox-textfield',\n        validation: Option.none(),\n        maximized: spec.maximized\n      }, providersBackstage);\n    };\n    var renderTextarea = function (spec, providersBackstage) {\n      return renderTextField({\n        name: spec.name,\n        multiline: true,\n        label: spec.label,\n        inputMode: Option.none(),\n        placeholder: spec.placeholder,\n        flex: true,\n        disabled: spec.disabled,\n        classname: 'tox-textarea',\n        validation: Option.none(),\n        maximized: spec.maximized\n      }, providersBackstage);\n    };\n\n    var events$c = function (streamConfig, streamState) {\n      var streams = streamConfig.stream.streams;\n      var processor = streams.setup(streamConfig, streamState);\n      return derive([\n        run(streamConfig.event, processor),\n        runOnDetached(function () {\n          return streamState.cancel();\n        })\n      ].concat(streamConfig.cancelEvent.map(function (e) {\n        return [run(e, function () {\n            return streamState.cancel();\n          })];\n      }).getOr([])));\n    };\n\n    var ActiveStreaming = /*#__PURE__*/Object.freeze({\n        events: events$c\n    });\n\n    var throttle = function (_config) {\n      var state = Cell(null);\n      var readState = function () {\n        return { timer: state.get() !== null ? 'set' : 'unset' };\n      };\n      var setTimer = function (t) {\n        state.set(t);\n      };\n      var cancel = function () {\n        var t = state.get();\n        if (t !== null) {\n          t.cancel();\n        }\n      };\n      return nu$5({\n        readState: readState,\n        setTimer: setTimer,\n        cancel: cancel\n      });\n    };\n    var init$6 = function (spec) {\n      return spec.stream.streams.state(spec);\n    };\n\n    var StreamingState = /*#__PURE__*/Object.freeze({\n        throttle: throttle,\n        init: init$6\n    });\n\n    var setup$3 = function (streamInfo, streamState) {\n      var sInfo = streamInfo.stream;\n      var throttler = last$2(streamInfo.onStream, sInfo.delay);\n      streamState.setTimer(throttler);\n      return function (component, simulatedEvent) {\n        throttler.throttle(component, simulatedEvent);\n        if (sInfo.stopEvent) {\n          simulatedEvent.stop();\n        }\n      };\n    };\n    var StreamingSchema = [\n      strictOf('stream', choose$1('mode', {\n        throttle: [\n          strict$1('delay'),\n          defaulted$1('stopEvent', true),\n          output('streams', {\n            setup: setup$3,\n            state: throttle\n          })\n        ]\n      })),\n      defaulted$1('event', 'input'),\n      option('cancelEvent'),\n      onStrictHandler('onStream')\n    ];\n\n    var Streaming = create$1({\n      fields: StreamingSchema,\n      name: 'streaming',\n      active: ActiveStreaming,\n      state: StreamingState\n    });\n\n    var setValueFromItem = function (model, input, item) {\n      var itemData = Representing.getValue(item);\n      Representing.setValue(input, itemData);\n      setCursorAtEnd(input);\n    };\n    var setSelectionOn = function (input, f) {\n      var el = input.element();\n      var value = get$5(el);\n      var node = el.dom();\n      if (get$2(el, 'type') !== 'number') {\n        f(node, value);\n      }\n    };\n    var setCursorAtEnd = function (input) {\n      setSelectionOn(input, function (node, value) {\n        return node.setSelectionRange(value.length, value.length);\n      });\n    };\n    var setSelectionToEnd = function (input, startOffset) {\n      setSelectionOn(input, function (node, value) {\n        return node.setSelectionRange(startOffset, value.length);\n      });\n    };\n    var attemptSelectOver = function (model, input, item) {\n      if (!model.selectsOver) {\n        return Option.none();\n      } else {\n        var currentValue = Representing.getValue(input);\n        var inputDisplay_1 = model.getDisplayText(currentValue);\n        var itemValue = Representing.getValue(item);\n        var itemDisplay = model.getDisplayText(itemValue);\n        return itemDisplay.indexOf(inputDisplay_1) === 0 ? Option.some(function () {\n          setValueFromItem(model, input, item);\n          setSelectionToEnd(input, inputDisplay_1.length);\n        }) : Option.none();\n      }\n    };\n\n    var itemExecute = constant('alloy.typeahead.itemexecute');\n\n    var make$5 = function (detail, components, spec, externals) {\n      var navigateList = function (comp, simulatedEvent, highlighter) {\n        detail.previewing.set(false);\n        var sandbox = Coupling.getCoupled(comp, 'sandbox');\n        if (Sandboxing.isOpen(sandbox)) {\n          Composing.getCurrent(sandbox).each(function (menu) {\n            Highlighting.getHighlighted(menu).fold(function () {\n              highlighter(menu);\n            }, function () {\n              dispatchEvent(sandbox, menu.element(), 'keydown', simulatedEvent);\n            });\n          });\n        } else {\n          var onOpenSync = function (sandbox) {\n            Composing.getCurrent(sandbox).each(highlighter);\n          };\n          open$1(detail, mapFetch(comp), comp, sandbox, externals, onOpenSync, HighlightOnOpen.HighlightFirst).get(noop);\n        }\n      };\n      var focusBehaviours$1 = focusBehaviours(detail);\n      var mapFetch = function (comp) {\n        return function (tdata) {\n          return tdata.map(function (data) {\n            var menus = values(data.menus);\n            var items = bind(menus, function (menu) {\n              return filter(menu.items, function (item) {\n                return item.type === 'item';\n              });\n            });\n            var repState = Representing.getState(comp);\n            repState.update(map(items, function (item) {\n              return item.data;\n            }));\n            return data;\n          });\n        };\n      };\n      var behaviours = [\n        Focusing.config({}),\n        Representing.config({\n          onSetValue: detail.onSetValue,\n          store: __assign({\n            mode: 'dataset',\n            getDataKey: function (comp) {\n              return get$5(comp.element());\n            },\n            getFallbackEntry: function (itemString) {\n              return {\n                value: itemString,\n                meta: {}\n              };\n            },\n            setValue: function (comp, data) {\n              set$3(comp.element(), detail.model.getDisplayText(data));\n            }\n          }, detail.initialData.map(function (d) {\n            return wrap$1('initialValue', d);\n          }).getOr({}))\n        }),\n        Streaming.config({\n          stream: {\n            mode: 'throttle',\n            delay: detail.responseTime,\n            stopEvent: false\n          },\n          onStream: function (component, simulatedEvent) {\n            var sandbox = Coupling.getCoupled(component, 'sandbox');\n            var focusInInput = Focusing.isFocused(component);\n            if (focusInInput) {\n              if (get$5(component.element()).length >= detail.minChars) {\n                var previousValue_1 = Composing.getCurrent(sandbox).bind(function (menu) {\n                  return Highlighting.getHighlighted(menu).map(Representing.getValue);\n                });\n                detail.previewing.set(true);\n                var onOpenSync = function (_sandbox) {\n                  Composing.getCurrent(sandbox).each(function (menu) {\n                    previousValue_1.fold(function () {\n                      if (detail.model.selectsOver) {\n                        Highlighting.highlightFirst(menu);\n                      }\n                    }, function (pv) {\n                      Highlighting.highlightBy(menu, function (item) {\n                        var itemData = Representing.getValue(item);\n                        return itemData.value === pv.value;\n                      });\n                      Highlighting.getHighlighted(menu).orThunk(function () {\n                        Highlighting.highlightFirst(menu);\n                        return Option.none();\n                      });\n                    });\n                  });\n                };\n                open$1(detail, mapFetch(component), component, sandbox, externals, onOpenSync, HighlightOnOpen.HighlightFirst).get(noop);\n              }\n            }\n          },\n          cancelEvent: typeaheadCancel()\n        }),\n        Keying.config({\n          mode: 'special',\n          onDown: function (comp, simulatedEvent) {\n            navigateList(comp, simulatedEvent, Highlighting.highlightFirst);\n            return Option.some(true);\n          },\n          onEscape: function (comp) {\n            var sandbox = Coupling.getCoupled(comp, 'sandbox');\n            if (Sandboxing.isOpen(sandbox)) {\n              Sandboxing.close(sandbox);\n              return Option.some(true);\n            }\n            return Option.none();\n          },\n          onUp: function (comp, simulatedEvent) {\n            navigateList(comp, simulatedEvent, Highlighting.highlightLast);\n            return Option.some(true);\n          },\n          onEnter: function (comp) {\n            var sandbox = Coupling.getCoupled(comp, 'sandbox');\n            var sandboxIsOpen = Sandboxing.isOpen(sandbox);\n            if (sandboxIsOpen && !detail.previewing.get()) {\n              return Composing.getCurrent(sandbox).bind(function (menu) {\n                return Highlighting.getHighlighted(menu);\n              }).map(function (item) {\n                emitWith(comp, itemExecute(), { item: item });\n                return true;\n              });\n            } else {\n              var currentValue = Representing.getValue(comp);\n              emit(comp, typeaheadCancel());\n              detail.onExecute(sandbox, comp, currentValue);\n              if (sandboxIsOpen) {\n                Sandboxing.close(sandbox);\n              }\n              return Option.some(true);\n            }\n          }\n        }),\n        Toggling.config({\n          toggleClass: detail.markers.openClass,\n          aria: { mode: 'expanded' }\n        }),\n        Coupling.config({\n          others: {\n            sandbox: function (hotspot) {\n              return makeSandbox(detail, hotspot, {\n                onOpen: function () {\n                  return Toggling.on(hotspot);\n                },\n                onClose: function () {\n                  return Toggling.off(hotspot);\n                }\n              });\n            }\n          }\n        }),\n        config('typeaheadevents', [\n          runOnExecute(function (comp) {\n            var onOpenSync = noop;\n            togglePopup(detail, mapFetch(comp), comp, externals, onOpenSync, HighlightOnOpen.HighlightFirst).get(noop);\n          }),\n          run(itemExecute(), function (comp, se) {\n            var sandbox = Coupling.getCoupled(comp, 'sandbox');\n            setValueFromItem(detail.model, comp, se.event().item());\n            emit(comp, typeaheadCancel());\n            detail.onItemExecute(comp, sandbox, se.event().item(), Representing.getValue(comp));\n            Sandboxing.close(sandbox);\n            setCursorAtEnd(comp);\n          })\n        ].concat(detail.dismissOnBlur ? [run(postBlur(), function (typeahead) {\n            var sandbox = Coupling.getCoupled(typeahead, 'sandbox');\n            if (search(sandbox.element()).isNone()) {\n              Sandboxing.close(sandbox);\n            }\n          })] : []))\n      ];\n      return {\n        uid: detail.uid,\n        dom: dom$2(deepMerge(detail, {\n          inputAttributes: {\n            'role': 'combobox',\n            'aria-autocomplete': 'list',\n            'aria-haspopup': 'true'\n          }\n        })),\n        behaviours: __assign(__assign({}, focusBehaviours$1), augment(detail.typeaheadBehaviours, behaviours)),\n        eventOrder: detail.eventOrder\n      };\n    };\n\n    var schema$j = constant([\n      option('lazySink'),\n      strict$1('fetch'),\n      defaulted$1('minChars', 5),\n      defaulted$1('responseTime', 1000),\n      onHandler('onOpen'),\n      defaulted$1('getHotspot', Option.some),\n      defaulted$1('getAnchorOverrides', constant({})),\n      defaulted$1('layouts', Option.none()),\n      defaulted$1('eventOrder', {}),\n      defaultedObjOf('model', {}, [\n        defaulted$1('getDisplayText', function (itemData) {\n          return itemData.meta !== undefined && itemData.meta.text !== undefined ? itemData.meta.text : itemData.value;\n        }),\n        defaulted$1('selectsOver', true),\n        defaulted$1('populateFromBrowse', true)\n      ]),\n      onHandler('onSetValue'),\n      onKeyboardHandler('onExecute'),\n      onHandler('onItemExecute'),\n      defaulted$1('inputClasses', []),\n      defaulted$1('inputAttributes', {}),\n      defaulted$1('inputStyles', {}),\n      defaulted$1('matchWidth', true),\n      defaulted$1('useMinWidth', false),\n      defaulted$1('dismissOnBlur', true),\n      markers(['openClass']),\n      option('initialData'),\n      field$1('typeaheadBehaviours', [\n        Focusing,\n        Representing,\n        Streaming,\n        Keying,\n        Toggling,\n        Coupling\n      ]),\n      state$1('previewing', function () {\n        return Cell(true);\n      })\n    ].concat(schema$f()).concat(sandboxFields()));\n    var parts$6 = constant([external$1({\n        schema: [tieredMenuMarkers()],\n        name: 'menu',\n        overrides: function (detail) {\n          return {\n            fakeFocus: true,\n            onHighlight: function (menu, item) {\n              if (!detail.previewing.get()) {\n                menu.getSystem().getByUid(detail.uid).each(function (input) {\n                  if (detail.model.populateFromBrowse) {\n                    setValueFromItem(detail.model, input, item);\n                  }\n                });\n              } else {\n                menu.getSystem().getByUid(detail.uid).each(function (input) {\n                  attemptSelectOver(detail.model, input, item).fold(function () {\n                    return Highlighting.dehighlight(menu, item);\n                  }, function (fn) {\n                    return fn();\n                  });\n                });\n              }\n              detail.previewing.set(false);\n            },\n            onExecute: function (menu, item) {\n              return menu.getSystem().getByUid(detail.uid).toOption().map(function (typeahead) {\n                emitWith(typeahead, itemExecute(), { item: item });\n                return true;\n              });\n            },\n            onHover: function (menu, item) {\n              detail.previewing.set(false);\n              menu.getSystem().getByUid(detail.uid).each(function (input) {\n                if (detail.model.populateFromBrowse) {\n                  setValueFromItem(detail.model, input, item);\n                }\n              });\n            }\n          };\n        }\n      })]);\n\n    var Typeahead = composite$1({\n      name: 'Typeahead',\n      configFields: schema$j(),\n      partFields: parts$6(),\n      factory: make$5\n    });\n\n    var wrap$2 = function (delegate) {\n      var toCached = function () {\n        return wrap$2(delegate.toCached());\n      };\n      var bindFuture = function (f) {\n        return wrap$2(delegate.bind(function (resA) {\n          return resA.fold(function (err) {\n            return Future.pure(Result.error(err));\n          }, function (a) {\n            return f(a);\n          });\n        }));\n      };\n      var bindResult = function (f) {\n        return wrap$2(delegate.map(function (resA) {\n          return resA.bind(f);\n        }));\n      };\n      var mapResult = function (f) {\n        return wrap$2(delegate.map(function (resA) {\n          return resA.map(f);\n        }));\n      };\n      var mapError = function (f) {\n        return wrap$2(delegate.map(function (resA) {\n          return resA.mapError(f);\n        }));\n      };\n      var foldResult = function (whenError, whenValue) {\n        return delegate.map(function (res) {\n          return res.fold(whenError, whenValue);\n        });\n      };\n      var withTimeout = function (timeout, errorThunk) {\n        return wrap$2(Future.nu(function (callback) {\n          var timedOut = false;\n          var timer = domGlobals.setTimeout(function () {\n            timedOut = true;\n            callback(Result.error(errorThunk()));\n          }, timeout);\n          delegate.get(function (result) {\n            if (!timedOut) {\n              domGlobals.clearTimeout(timer);\n              callback(result);\n            }\n          });\n        }));\n      };\n      return __assign(__assign({}, delegate), {\n        toCached: toCached,\n        bindFuture: bindFuture,\n        bindResult: bindResult,\n        mapResult: mapResult,\n        mapError: mapError,\n        foldResult: foldResult,\n        withTimeout: withTimeout\n      });\n    };\n    var nu$c = function (worker) {\n      return wrap$2(Future.nu(worker));\n    };\n    var value$2 = function (value) {\n      return wrap$2(Future.pure(Result.value(value)));\n    };\n    var error$1 = function (error) {\n      return wrap$2(Future.pure(Result.error(error)));\n    };\n    var fromResult$1 = function (result) {\n      return wrap$2(Future.pure(result));\n    };\n    var fromFuture = function (future) {\n      return wrap$2(future.map(Result.value));\n    };\n    var fromPromise = function (promise) {\n      return nu$c(function (completer) {\n        promise.then(function (value) {\n          completer(Result.value(value));\n        }, function (error) {\n          completer(Result.error(error));\n        });\n      });\n    };\n    var FutureResult = {\n      nu: nu$c,\n      wrap: wrap$2,\n      pure: value$2,\n      value: value$2,\n      error: error$1,\n      fromResult: fromResult$1,\n      fromFuture: fromFuture,\n      fromPromise: fromPromise\n    };\n\n    var separator$2 = { type: 'separator' };\n    var toMenuItem = function (target) {\n      return {\n        type: 'menuitem',\n        value: target.url,\n        text: target.title,\n        meta: { attach: target.attach },\n        onAction: function () {\n        }\n      };\n    };\n    var staticMenuItem = function (title, url) {\n      return {\n        type: 'menuitem',\n        value: url,\n        text: title,\n        meta: { attach: undefined },\n        onAction: function () {\n        }\n      };\n    };\n    var toMenuItems = function (targets) {\n      return map(targets, toMenuItem);\n    };\n    var filterLinkTargets = function (type, targets) {\n      return filter(targets, function (target) {\n        return target.type === type;\n      });\n    };\n    var filteredTargets = function (type, targets) {\n      return toMenuItems(filterLinkTargets(type, targets));\n    };\n    var headerTargets = function (linkInfo) {\n      return filteredTargets('header', linkInfo.targets);\n    };\n    var anchorTargets = function (linkInfo) {\n      return filteredTargets('anchor', linkInfo.targets);\n    };\n    var anchorTargetTop = function (linkInfo) {\n      return Option.from(linkInfo.anchorTop).map(function (url) {\n        return staticMenuItem('<top>', url);\n      }).toArray();\n    };\n    var anchorTargetBottom = function (linkInfo) {\n      return Option.from(linkInfo.anchorBottom).map(function (url) {\n        return staticMenuItem('<bottom>', url);\n      }).toArray();\n    };\n    var historyTargets = function (history) {\n      return map(history, function (url) {\n        return staticMenuItem(url, url);\n      });\n    };\n    var joinMenuLists = function (items) {\n      return foldl(items, function (a, b) {\n        var bothEmpty = a.length === 0 || b.length === 0;\n        return bothEmpty ? a.concat(b) : a.concat(separator$2, b);\n      }, []);\n    };\n    var filterByQuery = function (term, menuItems) {\n      var lowerCaseTerm = term.toLowerCase();\n      return filter(menuItems, function (item) {\n        var text = item.meta !== undefined && item.meta.text !== undefined ? item.meta.text : item.text;\n        return contains$1(text.toLowerCase(), lowerCaseTerm) || contains$1(item.value.toLowerCase(), lowerCaseTerm);\n      });\n    };\n\n    var getItems = function (fileType, input, urlBackstage) {\n      var urlInputValue = Representing.getValue(input);\n      var term = urlInputValue.meta.text !== undefined ? urlInputValue.meta.text : urlInputValue.value;\n      var info = urlBackstage.getLinkInformation();\n      return info.fold(function () {\n        return [];\n      }, function (linkInfo) {\n        var history = filterByQuery(term, historyTargets(urlBackstage.getHistory(fileType)));\n        return fileType === 'file' ? joinMenuLists([\n          history,\n          filterByQuery(term, headerTargets(linkInfo)),\n          filterByQuery(term, flatten([\n            anchorTargetTop(linkInfo),\n            anchorTargets(linkInfo),\n            anchorTargetBottom(linkInfo)\n          ]))\n        ]) : history;\n      });\n    };\n    var errorId = generate$1('aria-invalid');\n    var renderUrlInput = function (spec, backstage, urlBackstage) {\n      var _a;\n      var providersBackstage = backstage.shared.providers;\n      var updateHistory = function (component) {\n        var urlEntry = Representing.getValue(component);\n        urlBackstage.addToHistory(urlEntry.value, spec.filetype);\n      };\n      var pField = FormField.parts().field({\n        factory: Typeahead,\n        dismissOnBlur: true,\n        inputClasses: ['tox-textfield'],\n        sandboxClasses: ['tox-dialog__popups'],\n        inputAttributes: {\n          'aria-errormessage': errorId,\n          'type': 'url'\n        },\n        minChars: 0,\n        responseTime: 0,\n        fetch: function (input) {\n          var items = getItems(spec.filetype, input, urlBackstage);\n          var tdata = build$2(items, ItemResponse$1.BUBBLE_TO_SANDBOX, backstage, false);\n          return Future.pure(tdata);\n        },\n        getHotspot: function (comp) {\n          return memUrlBox.getOpt(comp);\n        },\n        onSetValue: function (comp, newValue) {\n          if (comp.hasConfigured(Invalidating)) {\n            Invalidating.run(comp).get(noop);\n          }\n        },\n        typeaheadBehaviours: derive$1(flatten([\n          urlBackstage.getValidationHandler().map(function (handler) {\n            return Invalidating.config({\n              getRoot: function (comp) {\n                return parent(comp.element());\n              },\n              invalidClass: 'tox-control-wrap--status-invalid',\n              notify: {\n                onInvalid: function (comp, err) {\n                  memInvalidIcon.getOpt(comp).each(function (invalidComp) {\n                    set$1(invalidComp.element(), 'title', providersBackstage.translate(err));\n                  });\n                }\n              },\n              validator: {\n                validate: function (input) {\n                  var urlEntry = Representing.getValue(input);\n                  return FutureResult.nu(function (completer) {\n                    handler({\n                      type: spec.filetype,\n                      url: urlEntry.value\n                    }, function (validation) {\n                      if (validation.status === 'invalid') {\n                        var err = Result.error(validation.message);\n                        completer(err);\n                      } else {\n                        var val = Result.value(validation.message);\n                        completer(val);\n                      }\n                    });\n                  });\n                },\n                validateOnLoad: false\n              }\n            });\n          }).toArray(),\n          [\n            Disabling.config({ disabled: spec.disabled }),\n            Tabstopping.config({}),\n            config('urlinput-events', flatten([\n              spec.filetype === 'file' ? [run(input(), function (comp) {\n                  emitWith(comp, formChangeEvent, { name: spec.name });\n                })] : [],\n              [\n                run(change(), function (comp) {\n                  emitWith(comp, formChangeEvent, { name: spec.name });\n                  updateHistory(comp);\n                }),\n                run(postPaste(), function (comp) {\n                  emitWith(comp, formChangeEvent, { name: spec.name });\n                  updateHistory(comp);\n                })\n              ]\n            ]))\n          ]\n        ])),\n        eventOrder: (_a = {}, _a[input()] = [\n          'streaming',\n          'urlinput-events',\n          'invalidating'\n        ], _a),\n        model: {\n          getDisplayText: function (itemData) {\n            return itemData.value;\n          },\n          selectsOver: false,\n          populateFromBrowse: false\n        },\n        markers: { openClass: 'tox-textfield--popup-open' },\n        lazySink: backstage.shared.getSink,\n        parts: { menu: part(false, 1, 'normal') },\n        onExecute: function (_menu, component, _entry) {\n          emitWith(component, formSubmitEvent, {});\n        },\n        onItemExecute: function (typeahead, _sandbox, _item, _value) {\n          updateHistory(typeahead);\n          emitWith(typeahead, formChangeEvent, { name: spec.name });\n        }\n      });\n      var pLabel = spec.label.map(function (label) {\n        return renderLabel(label, providersBackstage);\n      });\n      var makeIcon = function (name, errId, icon, label) {\n        if (icon === void 0) {\n          icon = name;\n        }\n        if (label === void 0) {\n          label = name;\n        }\n        return {\n          dom: {\n            tag: 'div',\n            classes: [\n              'tox-icon',\n              'tox-control-wrap__status-icon-' + name\n            ],\n            innerHtml: get$c(icon, providersBackstage.icons),\n            attributes: __assign({\n              'title': providersBackstage.translate(label),\n              'aria-live': 'polite'\n            }, errId.fold(function () {\n              return {};\n            }, function (id) {\n              return { id: id };\n            }))\n          }\n        };\n      };\n      var memInvalidIcon = record(makeIcon('invalid', Option.some(errorId), 'warning'));\n      var memStatus = record({\n        dom: {\n          tag: 'div',\n          classes: ['tox-control-wrap__status-icon-wrap']\n        },\n        components: [memInvalidIcon.asSpec()]\n      });\n      var optUrlPicker = urlBackstage.getUrlPicker(spec.filetype);\n      var browseUrlEvent = generate$1('browser.url.event');\n      var memUrlBox = record({\n        dom: {\n          tag: 'div',\n          classes: ['tox-control-wrap']\n        },\n        components: [\n          pField,\n          memStatus.asSpec()\n        ],\n        behaviours: derive$1([Disabling.config({ disabled: spec.disabled })])\n      });\n      var memUrlPickerButton = record(renderButton({\n        name: spec.name,\n        icon: Option.some('browse'),\n        text: spec.label.getOr(''),\n        disabled: spec.disabled,\n        primary: false,\n        borderless: true\n      }, function (component) {\n        return emit(component, browseUrlEvent);\n      }, providersBackstage, [], ['tox-browse-url']));\n      var controlHWrapper = function () {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-form__controls-h-stack']\n          },\n          components: flatten([\n            [memUrlBox.asSpec()],\n            optUrlPicker.map(function () {\n              return memUrlPickerButton.asSpec();\n            }).toArray()\n          ])\n        };\n      };\n      var openUrlPicker = function (comp) {\n        Composing.getCurrent(comp).each(function (field) {\n          var urlData = Representing.getValue(field);\n          optUrlPicker.each(function (picker) {\n            picker(urlData).get(function (chosenData) {\n              Representing.setValue(field, chosenData);\n              emitWith(comp, formChangeEvent, { name: spec.name });\n            });\n          });\n        });\n      };\n      return FormField.sketch({\n        dom: renderFormFieldDom(),\n        components: pLabel.toArray().concat([controlHWrapper()]),\n        fieldBehaviours: derive$1([\n          Disabling.config({\n            disabled: spec.disabled,\n            onDisabled: function (comp) {\n              FormField.getField(comp).each(Disabling.disable);\n              memUrlPickerButton.getOpt(comp).each(Disabling.disable);\n            },\n            onEnabled: function (comp) {\n              FormField.getField(comp).each(Disabling.enable);\n              memUrlPickerButton.getOpt(comp).each(Disabling.enable);\n            }\n          }),\n          config('url-input-events', [run(browseUrlEvent, openUrlPicker)])\n        ])\n      });\n    };\n\n    var renderCheckbox = function (spec, providerBackstage) {\n      var repBehaviour = Representing.config({\n        store: {\n          mode: 'manual',\n          getValue: function (comp) {\n            var el = comp.element().dom();\n            return el.checked;\n          },\n          setValue: function (comp, value) {\n            var el = comp.element().dom();\n            el.checked = value;\n          }\n        }\n      });\n      var toggleCheckboxHandler = function (comp) {\n        comp.element().dom().click();\n        return Option.some(true);\n      };\n      var pField = FormField.parts().field({\n        factory: { sketch: identity },\n        dom: {\n          tag: 'input',\n          classes: ['tox-checkbox__input'],\n          attributes: { type: 'checkbox' }\n        },\n        behaviours: derive$1([\n          ComposingConfigs.self(),\n          Disabling.config({ disabled: spec.disabled }),\n          Tabstopping.config({}),\n          Focusing.config({}),\n          repBehaviour,\n          Keying.config({\n            mode: 'special',\n            onEnter: toggleCheckboxHandler,\n            onSpace: toggleCheckboxHandler,\n            stopSpaceKeyup: true\n          }),\n          config('checkbox-events', [run(change(), function (component, _) {\n              emitWith(component, formChangeEvent, { name: spec.name });\n            })])\n        ])\n      });\n      var pLabel = FormField.parts().label({\n        dom: {\n          tag: 'span',\n          classes: ['tox-checkbox__label'],\n          innerHtml: providerBackstage.translate(spec.label)\n        },\n        behaviours: derive$1([Unselecting.config({})])\n      });\n      var makeIcon = function (className) {\n        var iconName = className === 'checked' ? 'selected' : 'unselected';\n        return {\n          dom: {\n            tag: 'span',\n            classes: [\n              'tox-icon',\n              'tox-checkbox-icon__' + className\n            ],\n            innerHtml: get$c(iconName, providerBackstage.icons)\n          }\n        };\n      };\n      var memIcons = record({\n        dom: {\n          tag: 'div',\n          classes: ['tox-checkbox__icons']\n        },\n        components: [\n          makeIcon('checked'),\n          makeIcon('unchecked')\n        ]\n      });\n      return FormField.sketch({\n        dom: {\n          tag: 'label',\n          classes: ['tox-checkbox']\n        },\n        components: [\n          pField,\n          memIcons.asSpec(),\n          pLabel\n        ],\n        fieldBehaviours: derive$1([Disabling.config({\n            disabled: spec.disabled,\n            disableClass: 'tox-checkbox--disabled',\n            onDisabled: function (comp) {\n              FormField.getField(comp).each(Disabling.disable);\n            },\n            onEnabled: function (comp) {\n              FormField.getField(comp).each(Disabling.enable);\n            }\n          })])\n      });\n    };\n\n    var renderHtmlPanel = function (spec) {\n      if (spec.presets === 'presentation') {\n        return Container.sketch({\n          dom: {\n            tag: 'div',\n            classes: ['tox-form__group'],\n            innerHtml: spec.html\n          }\n        });\n      } else {\n        return Container.sketch({\n          dom: {\n            tag: 'div',\n            classes: ['tox-form__group'],\n            innerHtml: spec.html,\n            attributes: { role: 'document' }\n          },\n          containerBehaviours: derive$1([\n            Tabstopping.config({}),\n            Focusing.config({})\n          ])\n        });\n      }\n    };\n\n    var renderLabel$2 = function (spec, backstageShared) {\n      var label = {\n        dom: {\n          tag: 'label',\n          innerHtml: backstageShared.providers.translate(spec.label),\n          classes: ['tox-label']\n        }\n      };\n      var comps = map(spec.items, backstageShared.interpreter);\n      return {\n        dom: {\n          tag: 'div',\n          classes: ['tox-form__group']\n        },\n        components: [label].concat(comps),\n        behaviours: derive$1([\n          ComposingConfigs.self(),\n          Replacing.config({}),\n          RepresentingConfigs.domHtml(Option.none()),\n          Keying.config({ mode: 'acyclic' })\n        ])\n      };\n    };\n\n    var renderCollection = function (spec, providersBackstage) {\n      var pLabel = spec.label.map(function (label) {\n        return renderLabel(label, providersBackstage);\n      });\n      var runOnItem = function (f) {\n        return function (comp, se) {\n          closest$3(se.event().target(), '[data-collection-item-value]').each(function (target) {\n            f(comp, se, target, get$2(target, 'data-collection-item-value'));\n          });\n        };\n      };\n      var escapeAttribute = function (ch) {\n        if (ch === '\"') {\n          return '&quot;';\n        }\n        return ch;\n      };\n      var setContents = function (comp, items) {\n        var htmlLines = map(items, function (item) {\n          var itemText = global$5.translate(item.text);\n          var textContent = spec.columns === 1 ? '<div class=\"tox-collection__item-label\">' + itemText + '</div>' : '';\n          var iconContent = '<div class=\"tox-collection__item-icon\">' + item.icon + '</div>';\n          var mapItemName = {\n            '_': ' ',\n            ' - ': ' ',\n            '-': ' '\n          };\n          var ariaLabel = itemText.replace(/\\_| \\- |\\-/g, function (match) {\n            return mapItemName[match];\n          });\n          return '<div class=\"tox-collection__item\" tabindex=\"-1\" data-collection-item-value=\"' + escapeAttribute(item.value) + '\" title=\"' + ariaLabel + '\" aria-label=\"' + ariaLabel + '\">' + iconContent + textContent + '</div>';\n        });\n        var chunks = spec.columns > 1 && spec.columns !== 'auto' ? chunk(htmlLines, spec.columns) : [htmlLines];\n        var html = map(chunks, function (ch) {\n          return '<div class=\"tox-collection__group\">' + ch.join('') + '</div>';\n        });\n        set(comp.element(), html.join(''));\n      };\n      var onClick = runOnItem(function (comp, se, tgt, itemValue) {\n        se.stop();\n        emitWith(comp, formActionEvent, {\n          name: spec.name,\n          value: itemValue\n        });\n      });\n      var collectionEvents = [\n        run(mouseover(), runOnItem(function (comp, se, tgt) {\n          focus$1(tgt);\n        })),\n        run(click(), onClick),\n        run(tap(), onClick),\n        run(focusin(), runOnItem(function (comp, se, tgt) {\n          descendant$1(comp.element(), '.' + activeClass).each(function (currentActive) {\n            remove$4(currentActive, activeClass);\n          });\n          add$2(tgt, activeClass);\n        })),\n        run(focusout(), runOnItem(function (comp) {\n          descendant$1(comp.element(), '.' + activeClass).each(function (currentActive) {\n            remove$4(currentActive, activeClass);\n          });\n        })),\n        runOnExecute(runOnItem(function (comp, se, tgt, itemValue) {\n          emitWith(comp, formActionEvent, {\n            name: spec.name,\n            value: itemValue\n          });\n        }))\n      ];\n      var pField = FormField.parts().field({\n        dom: {\n          tag: 'div',\n          classes: ['tox-collection'].concat(spec.columns !== 1 ? ['tox-collection--grid'] : ['tox-collection--list'])\n        },\n        components: [],\n        factory: { sketch: identity },\n        behaviours: derive$1([\n          Replacing.config({}),\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: []\n            },\n            onSetValue: function (comp, items) {\n              setContents(comp, items);\n              if (spec.columns === 'auto') {\n                detectSize(comp, 5, 'tox-collection__item').each(function (_a) {\n                  var numRows = _a.numRows, numColumns = _a.numColumns;\n                  Keying.setGridSize(comp, numRows, numColumns);\n                });\n              }\n              emit(comp, formResizeEvent);\n            }\n          }),\n          Tabstopping.config({}),\n          Keying.config(deriveCollectionMovement(spec.columns, 'normal')),\n          config('collection-events', collectionEvents)\n        ])\n      });\n      var extraClasses = ['tox-form__group--collection'];\n      return renderFormFieldWith(pLabel, pField, extraClasses, []);\n    };\n\n    var renderTable = function (spec, providersBackstage) {\n      var renderTh = function (text) {\n        return {\n          dom: {\n            tag: 'th',\n            innerHtml: providersBackstage.translate(text)\n          }\n        };\n      };\n      var renderHeader = function (header) {\n        return {\n          dom: { tag: 'thead' },\n          components: [{\n              dom: { tag: 'tr' },\n              components: map(header, renderTh)\n            }]\n        };\n      };\n      var renderTd = function (text) {\n        return {\n          dom: {\n            tag: 'td',\n            innerHtml: providersBackstage.translate(text)\n          }\n        };\n      };\n      var renderTr = function (row) {\n        return {\n          dom: { tag: 'tr' },\n          components: map(row, renderTd)\n        };\n      };\n      var renderRows = function (rows) {\n        return {\n          dom: { tag: 'tbody' },\n          components: map(rows, renderTr)\n        };\n      };\n      return {\n        dom: {\n          tag: 'table',\n          classes: ['tox-dialog__table']\n        },\n        components: [\n          renderHeader(spec.header),\n          renderRows(spec.cells)\n        ],\n        behaviours: derive$1([\n          Tabstopping.config({}),\n          Focusing.config({})\n        ])\n      };\n    };\n\n    var renderPanel = function (spec, backstage) {\n      return {\n        dom: {\n          tag: 'div',\n          classes: spec.classes\n        },\n        components: map(spec.items, backstage.shared.interpreter)\n      };\n    };\n\n    var make$6 = function (render) {\n      return function (parts, spec, backstage) {\n        return readOptFrom$1(spec, 'name').fold(function () {\n          return render(spec, backstage);\n        }, function (fieldName) {\n          return parts.field(fieldName, render(spec, backstage));\n        });\n      };\n    };\n    var makeIframe = function (render) {\n      return function (parts, spec, backstage) {\n        var iframeSpec = deepMerge(spec, { source: 'dynamic' });\n        return make$6(render)(parts, iframeSpec, backstage);\n      };\n    };\n    var factories = {\n      bar: make$6(function (spec, backstage) {\n        return renderBar(spec, backstage.shared);\n      }),\n      collection: make$6(function (spec, backstage) {\n        return renderCollection(spec, backstage.shared.providers);\n      }),\n      alertbanner: make$6(function (spec, backstage) {\n        return renderAlertBanner(spec, backstage.shared.providers);\n      }),\n      input: make$6(function (spec, backstage) {\n        return renderInput(spec, backstage.shared.providers);\n      }),\n      textarea: make$6(function (spec, backstage) {\n        return renderTextarea(spec, backstage.shared.providers);\n      }),\n      label: make$6(function (spec, backstage) {\n        return renderLabel$2(spec, backstage.shared);\n      }),\n      iframe: makeIframe(function (spec, backstage) {\n        return renderIFrame(spec, backstage.shared.providers);\n      }),\n      button: make$6(function (spec, backstage) {\n        return renderDialogButton(spec, backstage.shared.providers);\n      }),\n      checkbox: make$6(function (spec, backstage) {\n        return renderCheckbox(spec, backstage.shared.providers);\n      }),\n      colorinput: make$6(function (spec, backstage) {\n        return renderColorInput(spec, backstage.shared, backstage.colorinput);\n      }),\n      colorpicker: make$6(renderColorPicker),\n      dropzone: make$6(function (spec, backstage) {\n        return renderDropZone(spec, backstage.shared.providers);\n      }),\n      grid: make$6(function (spec, backstage) {\n        return renderGrid(spec, backstage.shared);\n      }),\n      selectbox: make$6(function (spec, backstage) {\n        return renderSelectBox(spec, backstage.shared.providers);\n      }),\n      sizeinput: make$6(function (spec, backstage) {\n        return renderSizeInput(spec, backstage.shared.providers);\n      }),\n      urlinput: make$6(function (spec, backstage) {\n        return renderUrlInput(spec, backstage, backstage.urlinput);\n      }),\n      customeditor: make$6(renderCustomEditor),\n      htmlpanel: make$6(renderHtmlPanel),\n      imagetools: make$6(function (spec, backstage) {\n        return renderImageTools(spec, backstage.shared.providers);\n      }),\n      table: make$6(function (spec, backstage) {\n        return renderTable(spec, backstage.shared.providers);\n      }),\n      panel: make$6(function (spec, backstage) {\n        return renderPanel(spec, backstage);\n      })\n    };\n    var noFormParts = {\n      field: function (_name, spec) {\n        return spec;\n      }\n    };\n    var interpretInForm = function (parts, spec, oldBackstage) {\n      var newBackstage = deepMerge(oldBackstage, {\n        shared: {\n          interpreter: function (childSpec) {\n            return interpretParts(parts, childSpec, newBackstage);\n          }\n        }\n      });\n      return interpretParts(parts, spec, newBackstage);\n    };\n    var interpretParts = function (parts, spec, backstage) {\n      return readOptFrom$1(factories, spec.type).fold(function () {\n        domGlobals.console.error('Unknown factory type \"' + spec.type + '\", defaulting to container: ', spec);\n        return spec;\n      }, function (factory) {\n        return factory(parts, spec, backstage);\n      });\n    };\n    var interpretWithoutForm = function (spec, backstage) {\n      var parts = noFormParts;\n      return interpretParts(parts, spec, backstage);\n    };\n\n    var expandable$1 = constant(function (element, available) {\n      setMax$1(element, Math.floor(available));\n    });\n\n    var bubbleAlignments = {\n      valignCentre: [],\n      alignCentre: [],\n      alignLeft: [],\n      alignRight: [],\n      right: [],\n      left: [],\n      bottom: [],\n      top: []\n    };\n    var getToolbarAnchor = function (bodyElement, lazyAnchorbar, useFixedToolbarContainer) {\n      var fixedToolbarAnchor = function () {\n        return {\n          anchor: 'node',\n          root: bodyElement(),\n          node: Option.from(bodyElement()),\n          bubble: nu$8(-12, -12, bubbleAlignments),\n          layouts: {\n            onRtl: function () {\n              return [northeast$3];\n            },\n            onLtr: function () {\n              return [northwest$3];\n            }\n          },\n          overrides: { maxHeightFunction: expandable() }\n        };\n      };\n      var standardAnchor = function () {\n        return {\n          anchor: 'hotspot',\n          hotspot: lazyAnchorbar(),\n          bubble: nu$8(-12, 12, bubbleAlignments),\n          layouts: {\n            onRtl: function () {\n              return [southeast$1];\n            },\n            onLtr: function () {\n              return [southwest$1];\n            }\n          },\n          overrides: { maxHeightFunction: expandable() }\n        };\n      };\n      return useFixedToolbarContainer ? fixedToolbarAnchor : standardAnchor;\n    };\n    var getBannerAnchor = function (bodyElement, lazyAnchorbar, useFixedToolbarContainer) {\n      var fixedToolbarAnchor = function () {\n        return {\n          anchor: 'node',\n          root: bodyElement(),\n          node: Option.from(bodyElement()),\n          layouts: {\n            onRtl: function () {\n              return [north$3];\n            },\n            onLtr: function () {\n              return [north$3];\n            }\n          }\n        };\n      };\n      var standardAnchor = function () {\n        return {\n          anchor: 'hotspot',\n          hotspot: lazyAnchorbar(),\n          layouts: {\n            onRtl: function () {\n              return [south$1];\n            },\n            onLtr: function () {\n              return [south$1];\n            }\n          }\n        };\n      };\n      return useFixedToolbarContainer ? fixedToolbarAnchor : standardAnchor;\n    };\n    var getToolbarOverflowAnchor = function (lazyMoreButton) {\n      return function () {\n        return {\n          anchor: 'hotspot',\n          hotspot: lazyMoreButton(),\n          overrides: { maxWidthFunction: expandable$1() },\n          layouts: {\n            onRtl: function () {\n              return [\n                southeast$1,\n                southwest$1\n              ];\n            },\n            onLtr: function () {\n              return [\n                southwest$1,\n                southeast$1\n              ];\n            }\n          }\n        };\n      };\n    };\n    var getCursorAnchor = function (editor, bodyElement) {\n      return function () {\n        return {\n          anchor: 'selection',\n          root: bodyElement(),\n          getSelection: function () {\n            var rng = editor.selection.getRng();\n            return Option.some(Selection.range(Element.fromDom(rng.startContainer), rng.startOffset, Element.fromDom(rng.endContainer), rng.endOffset));\n          }\n        };\n      };\n    };\n    var getNodeAnchor = function (bodyElement) {\n      return function (element) {\n        return {\n          anchor: 'node',\n          root: bodyElement(),\n          node: element\n        };\n      };\n    };\n    var getAnchors = function (editor, lazyAnchorbar, lazyMoreButton) {\n      var useFixedToolbarContainer = useFixedContainer(editor);\n      var bodyElement = function () {\n        return Element.fromDom(editor.getBody());\n      };\n      return {\n        toolbar: getToolbarAnchor(bodyElement, lazyAnchorbar, useFixedToolbarContainer),\n        toolbarOverflow: getToolbarOverflowAnchor(lazyMoreButton),\n        banner: getBannerAnchor(bodyElement, lazyAnchorbar, useFixedToolbarContainer),\n        cursor: getCursorAnchor(editor, bodyElement),\n        node: getNodeAnchor(bodyElement)\n      };\n    };\n    var Anchors = { getAnchors: getAnchors };\n\n    var colorPicker = function (editor) {\n      return function (callback, value) {\n        var dialog = ColorSwatch.colorPickerDialog(editor);\n        dialog(callback, value);\n      };\n    };\n    var hasCustomColors$1 = function (editor) {\n      return function () {\n        return Settings.hasCustomColors(editor);\n      };\n    };\n    var getColors$1 = function (editor) {\n      return function () {\n        return Settings.getColors(editor);\n      };\n    };\n    var getColorCols$2 = function (editor) {\n      return function () {\n        return ColorSwatch.getColorCols(editor);\n      };\n    };\n    var ColorInputBackstage = function (editor) {\n      return {\n        colorPicker: colorPicker(editor),\n        hasCustomColors: hasCustomColors$1(editor),\n        getColors: getColors$1(editor),\n        getColorCols: getColorCols$2(editor)\n      };\n    };\n\n    var isDraggableModal$1 = function (editor) {\n      return function () {\n        return isDraggableModal(editor);\n      };\n    };\n    var DialogBackstage = function (editor) {\n      return { isDraggableModal: isDraggableModal$1(editor) };\n    };\n\n    var defaultStyleFormats = [\n      {\n        title: 'Headings',\n        items: [\n          {\n            title: 'Heading 1',\n            format: 'h1'\n          },\n          {\n            title: 'Heading 2',\n            format: 'h2'\n          },\n          {\n            title: 'Heading 3',\n            format: 'h3'\n          },\n          {\n            title: 'Heading 4',\n            format: 'h4'\n          },\n          {\n            title: 'Heading 5',\n            format: 'h5'\n          },\n          {\n            title: 'Heading 6',\n            format: 'h6'\n          }\n        ]\n      },\n      {\n        title: 'Inline',\n        items: [\n          {\n            title: 'Bold',\n            icon: 'bold',\n            format: 'bold'\n          },\n          {\n            title: 'Italic',\n            icon: 'italic',\n            format: 'italic'\n          },\n          {\n            title: 'Underline',\n            icon: 'underline',\n            format: 'underline'\n          },\n          {\n            title: 'Strikethrough',\n            icon: 'strike-through',\n            format: 'strikethrough'\n          },\n          {\n            title: 'Superscript',\n            icon: 'superscript',\n            format: 'superscript'\n          },\n          {\n            title: 'Subscript',\n            icon: 'subscript',\n            format: 'subscript'\n          },\n          {\n            title: 'Code',\n            icon: 'code',\n            format: 'code'\n          }\n        ]\n      },\n      {\n        title: 'Blocks',\n        items: [\n          {\n            title: 'Paragraph',\n            format: 'p'\n          },\n          {\n            title: 'Blockquote',\n            format: 'blockquote'\n          },\n          {\n            title: 'Div',\n            format: 'div'\n          },\n          {\n            title: 'Pre',\n            format: 'pre'\n          }\n        ]\n      },\n      {\n        title: 'Align',\n        items: [\n          {\n            title: 'Left',\n            icon: 'align-left',\n            format: 'alignleft'\n          },\n          {\n            title: 'Center',\n            icon: 'align-center',\n            format: 'aligncenter'\n          },\n          {\n            title: 'Right',\n            icon: 'align-right',\n            format: 'alignright'\n          },\n          {\n            title: 'Justify',\n            icon: 'align-justify',\n            format: 'alignjustify'\n          }\n        ]\n      }\n    ];\n    var isNestedFormat = function (format) {\n      return has(format, 'items');\n    };\n    var isBlockFormat = function (format) {\n      return has(format, 'block');\n    };\n    var isInlineFormat = function (format) {\n      return has(format, 'inline');\n    };\n    var isSelectorFormat = function (format) {\n      return has(format, 'selector');\n    };\n    var mapFormats = function (userFormats) {\n      return foldl(userFormats, function (acc, fmt) {\n        if (isNestedFormat(fmt)) {\n          var result = mapFormats(fmt.items);\n          return {\n            customFormats: acc.customFormats.concat(result.customFormats),\n            formats: acc.formats.concat([{\n                title: fmt.title,\n                items: result.formats\n              }])\n          };\n        } else if (isInlineFormat(fmt) || isBlockFormat(fmt) || isSelectorFormat(fmt)) {\n          var formatName = 'custom-' + fmt.title.toLowerCase();\n          return {\n            customFormats: acc.customFormats.concat([{\n                name: formatName,\n                format: fmt\n              }]),\n            formats: acc.formats.concat([{\n                title: fmt.title,\n                format: formatName,\n                icon: fmt.icon\n              }])\n          };\n        } else {\n          return __assign(__assign({}, acc), { formats: acc.formats.concat(fmt) });\n        }\n      }, {\n        customFormats: [],\n        formats: []\n      });\n    };\n    var registerCustomFormats = function (editor, userFormats) {\n      var result = mapFormats(userFormats);\n      var registerFormats = function (customFormats) {\n        each(customFormats, function (fmt) {\n          if (!editor.formatter.has(fmt.name)) {\n            editor.formatter.register(fmt.name, fmt.format);\n          }\n        });\n      };\n      if (editor.formatter) {\n        registerFormats(result.customFormats);\n      } else {\n        editor.on('init', function () {\n          registerFormats(result.customFormats);\n        });\n      }\n      return result.formats;\n    };\n    var getStyleFormats = function (editor) {\n      return getUserStyleFormats(editor).map(function (userFormats) {\n        var registeredUserFormats = registerCustomFormats(editor, userFormats);\n        return isMergeStyleFormats(editor) ? defaultStyleFormats.concat(registeredUserFormats) : registeredUserFormats;\n      }).getOr(defaultStyleFormats);\n    };\n\n    var processBasic = function (item, isSelectedFor, getPreviewFor) {\n      var formatterSpec = {\n        type: 'formatter',\n        isSelected: isSelectedFor(item.format),\n        getStylePreview: getPreviewFor(item.format)\n      };\n      return deepMerge(item, formatterSpec);\n    };\n    var register$3 = function (editor, formats, isSelectedFor, getPreviewFor) {\n      var enrichSupported = function (item) {\n        return processBasic(item, isSelectedFor, getPreviewFor);\n      };\n      var enrichMenu = function (item) {\n        var submenuSpec = {\n          type: 'submenu',\n          isSelected: constant(false),\n          getStylePreview: function () {\n            return Option.none();\n          }\n        };\n        return deepMerge(item, submenuSpec);\n      };\n      var enrichCustom = function (item) {\n        var formatName = generate$1(item.title);\n        var customSpec = {\n          type: 'formatter',\n          format: formatName,\n          isSelected: isSelectedFor(formatName),\n          getStylePreview: getPreviewFor(formatName)\n        };\n        var newItem = deepMerge(item, customSpec);\n        editor.formatter.register(formatName, newItem);\n        return newItem;\n      };\n      var doEnrich = function (items) {\n        return map(items, function (item) {\n          var keys$1 = keys(item);\n          if (hasKey$1(item, 'items')) {\n            var newItems_1 = doEnrich(item.items);\n            return deepMerge(enrichMenu(item), {\n              getStyleItems: function () {\n                return newItems_1;\n              }\n            });\n          } else if (hasKey$1(item, 'format')) {\n            return enrichSupported(item);\n          } else if (keys$1.length === 1 && contains(keys$1, 'title')) {\n            return deepMerge(item, { type: 'separator' });\n          } else {\n            return enrichCustom(item);\n          }\n        });\n      };\n      return doEnrich(formats);\n    };\n\n    var init$7 = function (editor) {\n      var isSelectedFor = function (format) {\n        return function () {\n          return editor.formatter.match(format);\n        };\n      };\n      var getPreviewFor = function (format) {\n        return function () {\n          var fmt = editor.formatter.get(format);\n          return fmt !== undefined ? Option.some({\n            tag: fmt.length > 0 ? fmt[0].inline || fmt[0].block || 'div' : 'div',\n            styleAttr: editor.formatter.getCssText(format)\n          }) : Option.none();\n        };\n      };\n      var flatten = function (fmt) {\n        var subs = fmt.items;\n        return subs !== undefined && subs.length > 0 ? bind(subs, flatten) : [fmt.format];\n      };\n      var settingsFormats = Cell([]);\n      var settingsFlattenedFormats = Cell([]);\n      var eventsFormats = Cell([]);\n      var eventsFlattenedFormats = Cell([]);\n      var replaceSettings = Cell(false);\n      editor.on('init', function () {\n        var formats = getStyleFormats(editor);\n        var enriched = register$3(editor, formats, isSelectedFor, getPreviewFor);\n        settingsFormats.set(enriched);\n        settingsFlattenedFormats.set(bind(enriched, flatten));\n      });\n      editor.on('addStyleModifications', function (e) {\n        var modifications = register$3(editor, e.items, isSelectedFor, getPreviewFor);\n        eventsFormats.set(modifications);\n        replaceSettings.set(e.replace);\n        eventsFlattenedFormats.set(bind(modifications, flatten));\n      });\n      var getData = function () {\n        var fromSettings = replaceSettings.get() ? [] : settingsFormats.get();\n        var fromEvents = eventsFormats.get();\n        return fromSettings.concat(fromEvents);\n      };\n      var getFlattenedKeys = function () {\n        var fromSettings = replaceSettings.get() ? [] : settingsFlattenedFormats.get();\n        var fromEvents = eventsFlattenedFormats.get();\n        return fromSettings.concat(fromEvents);\n      };\n      return {\n        getData: getData,\n        getFlattenedKeys: getFlattenedKeys\n      };\n    };\n\n    var trim$1 = global$e.trim;\n    var hasContentEditableState = function (value) {\n      return function (node) {\n        if (node && node.nodeType === 1) {\n          if (node.contentEditable === value) {\n            return true;\n          }\n          if (node.getAttribute('data-mce-contenteditable') === value) {\n            return true;\n          }\n        }\n        return false;\n      };\n    };\n    var isContentEditableTrue = hasContentEditableState('true');\n    var isContentEditableFalse = hasContentEditableState('false');\n    var create$8 = function (type, title, url, level, attach) {\n      return {\n        type: type,\n        title: title,\n        url: url,\n        level: level,\n        attach: attach\n      };\n    };\n    var isChildOfContentEditableTrue = function (node) {\n      while (node = node.parentNode) {\n        var value = node.contentEditable;\n        if (value && value !== 'inherit') {\n          return isContentEditableTrue(node);\n        }\n      }\n      return false;\n    };\n    var select = function (selector, root) {\n      return map(descendants(Element.fromDom(root), selector), function (element) {\n        return element.dom();\n      });\n    };\n    var getElementText = function (elm) {\n      return elm.innerText || elm.textContent;\n    };\n    var getOrGenerateId = function (elm) {\n      return elm.id ? elm.id : generate$1('h');\n    };\n    var isAnchor = function (elm) {\n      return elm && elm.nodeName === 'A' && (elm.id || elm.name) !== undefined;\n    };\n    var isValidAnchor = function (elm) {\n      return isAnchor(elm) && isEditable(elm);\n    };\n    var isHeader = function (elm) {\n      return elm && /^(H[1-6])$/.test(elm.nodeName);\n    };\n    var isEditable = function (elm) {\n      return isChildOfContentEditableTrue(elm) && !isContentEditableFalse(elm);\n    };\n    var isValidHeader = function (elm) {\n      return isHeader(elm) && isEditable(elm);\n    };\n    var getLevel = function (elm) {\n      return isHeader(elm) ? parseInt(elm.nodeName.substr(1), 10) : 0;\n    };\n    var headerTarget = function (elm) {\n      var headerId = getOrGenerateId(elm);\n      var attach = function () {\n        elm.id = headerId;\n      };\n      return create$8('header', getElementText(elm), '#' + headerId, getLevel(elm), attach);\n    };\n    var anchorTarget = function (elm) {\n      var anchorId = elm.id || elm.name;\n      var anchorText = getElementText(elm);\n      return create$8('anchor', anchorText ? anchorText : '#' + anchorId, '#' + anchorId, 0, noop);\n    };\n    var getHeaderTargets = function (elms) {\n      return map(filter(elms, isValidHeader), headerTarget);\n    };\n    var getAnchorTargets = function (elms) {\n      return map(filter(elms, isValidAnchor), anchorTarget);\n    };\n    var getTargetElements = function (elm) {\n      var elms = select('h1,h2,h3,h4,h5,h6,a:not([href])', elm);\n      return elms;\n    };\n    var hasTitle = function (target) {\n      return trim$1(target.title).length > 0;\n    };\n    var find$5 = function (elm) {\n      var elms = getTargetElements(elm);\n      return filter(getHeaderTargets(elms).concat(getAnchorTargets(elms)), hasTitle);\n    };\n    var LinkTargets = { find: find$5 };\n\n    var STORAGE_KEY = 'tinymce-url-history';\n    var HISTORY_LENGTH = 5;\n    var isHttpUrl = function (url) {\n      return isString(url) && /^https?/.test(url);\n    };\n    var isArrayOfUrl = function (a) {\n      return isArray(a) && a.length <= HISTORY_LENGTH && forall(a, isHttpUrl);\n    };\n    var isRecordOfUrlArray = function (r) {\n      return isObject(r) && find$1(r, function (value) {\n        return !isArrayOfUrl(value);\n      }).isNone();\n    };\n    var getAllHistory = function () {\n      var unparsedHistory = domGlobals.localStorage.getItem(STORAGE_KEY);\n      if (unparsedHistory === null) {\n        return {};\n      }\n      var history;\n      try {\n        history = JSON.parse(unparsedHistory);\n      } catch (e) {\n        if (e instanceof SyntaxError) {\n          domGlobals.console.log('Local storage ' + STORAGE_KEY + ' was not valid JSON', e);\n          return {};\n        }\n        throw e;\n      }\n      if (!isRecordOfUrlArray(history)) {\n        domGlobals.console.log('Local storage ' + STORAGE_KEY + ' was not valid format', history);\n        return {};\n      }\n      return history;\n    };\n    var setAllHistory = function (history) {\n      if (!isRecordOfUrlArray(history)) {\n        throw new Error('Bad format for history:\\n' + JSON.stringify(history));\n      }\n      domGlobals.localStorage.setItem(STORAGE_KEY, JSON.stringify(history));\n    };\n    var getHistory = function (fileType) {\n      var history = getAllHistory();\n      return Object.prototype.hasOwnProperty.call(history, fileType) ? history[fileType] : [];\n    };\n    var addToHistory = function (url, fileType) {\n      if (!isHttpUrl(url)) {\n        return;\n      }\n      var history = getAllHistory();\n      var items = Object.prototype.hasOwnProperty.call(history, fileType) ? history[fileType] : [];\n      var itemsWithoutUrl = filter(items, function (item) {\n        return item !== url;\n      });\n      history[fileType] = [url].concat(itemsWithoutUrl).slice(0, HISTORY_LENGTH);\n      setAllHistory(history);\n    };\n\n    var hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n    var isTruthy = function (value) {\n      return !!value;\n    };\n    var makeMap = function (value) {\n      return map$1(global$e.makeMap(value, /[, ]/), isTruthy);\n    };\n    var getOpt = function (obj, key) {\n      return hasOwnProperty$2.call(obj, key) ? Option.some(obj[key]) : Option.none();\n    };\n    var getTextSetting = function (settings, name, defaultValue) {\n      var value = getOpt(settings, name).getOr(defaultValue);\n      return isString(value) ? Option.some(value) : Option.none();\n    };\n    var getPicker = function (settings) {\n      return Option.some(settings.file_picker_callback).filter(isFunction);\n    };\n    var getPickerTypes = function (settings) {\n      var optFileTypes = Option.some(settings.file_picker_types).filter(isTruthy);\n      var optLegacyTypes = Option.some(settings.file_browser_callback_types).filter(isTruthy);\n      var optTypes = optFileTypes.or(optLegacyTypes).map(makeMap);\n      return getPicker(settings).fold(function () {\n        return false;\n      }, function (_picker) {\n        return optTypes.fold(function () {\n          return true;\n        }, function (types) {\n          return keys(types).length > 0 ? types : false;\n        });\n      });\n    };\n    var getPickerSetting = function (settings, filetype) {\n      var pickerTypes = getPickerTypes(settings);\n      if (isBoolean(pickerTypes)) {\n        return pickerTypes ? getPicker(settings) : Option.none();\n      } else {\n        return pickerTypes[filetype] ? getPicker(settings) : Option.none();\n      }\n    };\n    var getUrlPicker = function (editor, filetype) {\n      return getPickerSetting(editor.settings, filetype).map(function (picker) {\n        return function (entry) {\n          return Future.nu(function (completer) {\n            var handler = function (value, meta) {\n              if (!isString(value)) {\n                throw new Error('Expected value to be string');\n              }\n              if (meta !== undefined && !isObject(meta)) {\n                throw new Error('Expected meta to be a object');\n              }\n              var r = {\n                value: value,\n                meta: meta\n              };\n              completer(r);\n            };\n            var meta = global$e.extend({ filetype: filetype }, Option.from(entry.meta).getOr({}));\n            picker.call(editor, handler, entry.value, meta);\n          });\n        };\n      });\n    };\n    var getLinkInformation = function (editor) {\n      if (editor.settings.typeahead_urls === false) {\n        return Option.none();\n      }\n      return Option.some({\n        targets: LinkTargets.find(editor.getBody()),\n        anchorTop: getTextSetting(editor.settings, 'anchor_top', '#top').getOrUndefined(),\n        anchorBottom: getTextSetting(editor.settings, 'anchor_bottom', '#bottom').getOrUndefined()\n      });\n    };\n    var getValidationHandler = function (editor) {\n      var optValidator = Option.from(editor.settings.file_picker_validator_handler).filter(isFunction);\n      return optValidator.orThunk(function () {\n        return Option.from(editor.settings.filepicker_validator_handler).filter(isFunction);\n      });\n    };\n    var UrlInputBackstage = function (editor) {\n      return {\n        getHistory: getHistory,\n        addToHistory: addToHistory,\n        getLinkInformation: function () {\n          return getLinkInformation(editor);\n        },\n        getValidationHandler: function () {\n          return getValidationHandler(editor);\n        },\n        getUrlPicker: function (filetype) {\n          return getUrlPicker(editor, filetype);\n        }\n      };\n    };\n\n    var init$8 = function (sink, editor, lazyAnchorbar, lazyMoreButton) {\n      var contextMenuState = Cell(false);\n      var backstage = {\n        shared: {\n          providers: {\n            icons: function () {\n              return editor.ui.registry.getAll().icons;\n            },\n            menuItems: function () {\n              return editor.ui.registry.getAll().menuItems;\n            },\n            translate: global$5.translate\n          },\n          interpreter: function (s) {\n            return interpretWithoutForm(s, backstage);\n          },\n          anchors: Anchors.getAnchors(editor, lazyAnchorbar, lazyMoreButton),\n          getSink: function () {\n            return Result.value(sink);\n          }\n        },\n        urlinput: UrlInputBackstage(editor),\n        styleselect: init$7(editor),\n        colorinput: ColorInputBackstage(editor),\n        dialog: DialogBackstage(editor),\n        isContextMenuOpen: function () {\n          return contextMenuState.get();\n        },\n        setContextMenuState: function (state) {\n          return contextMenuState.set(state);\n        }\n      };\n      return backstage;\n    };\n\n    var showContextToolbarEvent = 'contexttoolbar-show';\n    var hideContextToolbarEvent = 'contexttoolbar-hide';\n\n    var schema$k = constant([\n      strict$1('dom'),\n      defaulted$1('shell', true),\n      field$1('toolbarBehaviours', [Replacing])\n    ]);\n    var enhanceGroups = function (detail) {\n      return { behaviours: derive$1([Replacing.config({})]) };\n    };\n    var parts$7 = constant([optional({\n        name: 'groups',\n        overrides: enhanceGroups\n      })]);\n\n    var factory$9 = function (detail, components, spec, _externals) {\n      var setGroups = function (toolbar, groups) {\n        getGroupContainer(toolbar).fold(function () {\n          domGlobals.console.error('Toolbar was defined to not be a shell, but no groups container was specified in components');\n          throw new Error('Toolbar was defined to not be a shell, but no groups container was specified in components');\n        }, function (container) {\n          Replacing.set(container, groups);\n        });\n      };\n      var getGroupContainer = function (component) {\n        return detail.shell ? Option.some(component) : getPart(component, detail, 'groups');\n      };\n      var extra = detail.shell ? {\n        behaviours: [Replacing.config({})],\n        components: []\n      } : {\n        behaviours: [],\n        components: components\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: extra.components,\n        behaviours: augment(detail.toolbarBehaviours, extra.behaviours),\n        apis: { setGroups: setGroups },\n        domModification: { attributes: { role: 'group' } }\n      };\n    };\n    var Toolbar = composite$1({\n      name: 'Toolbar',\n      configFields: schema$k(),\n      partFields: parts$7(),\n      factory: factory$9,\n      apis: {\n        setGroups: function (apis, toolbar, groups) {\n          apis.setGroups(toolbar, groups);\n        }\n      }\n    });\n\n    var generate$6 = function (xs, f) {\n      var init = {\n        len: 0,\n        list: []\n      };\n      var r = foldl(xs, function (b, a) {\n        var value = f(a, b.len);\n        return value.fold(constant(b), function (v) {\n          return {\n            len: v.finish(),\n            list: b.list.concat([v])\n          };\n        });\n      }, init);\n      return r.list;\n    };\n\n    var output$1 = Immutable('within', 'extra', 'withinWidth');\n    var apportion = function (units, total, len) {\n      var parray = generate$6(units, function (unit, current) {\n        var width = len(unit);\n        return Option.some({\n          element: constant(unit),\n          start: constant(current),\n          finish: constant(current + width),\n          width: constant(width)\n        });\n      });\n      var within = filter(parray, function (unit) {\n        return unit.finish() <= total;\n      });\n      var withinWidth = foldr(within, function (acc, el) {\n        return acc + el.width();\n      }, 0);\n      var extra = parray.slice(within.length);\n      return {\n        within: constant(within),\n        extra: constant(extra),\n        withinWidth: constant(withinWidth)\n      };\n    };\n    var toUnit = function (parray) {\n      return map(parray, function (unit) {\n        return unit.element();\n      });\n    };\n    var fitLast = function (within, extra, withinWidth) {\n      var fits = toUnit(within.concat(extra));\n      return output$1(fits, [], withinWidth);\n    };\n    var overflow = function (within, extra, overflower, withinWidth) {\n      var fits = toUnit(within).concat([overflower]);\n      return output$1(fits, toUnit(extra), withinWidth);\n    };\n    var fitAll = function (within, extra, withinWidth) {\n      return output$1(toUnit(within), [], withinWidth);\n    };\n    var tryFit = function (total, units, len) {\n      var divide = apportion(units, total, len);\n      return divide.extra().length === 0 ? Option.some(divide) : Option.none();\n    };\n    var partition$3 = function (total, units, len, overflower) {\n      var divide = tryFit(total, units, len).getOrThunk(function () {\n        return apportion(units, total - len(overflower), len);\n      });\n      var within = divide.within();\n      var extra = divide.extra();\n      var withinWidth = divide.withinWidth();\n      if (extra.length === 1 && extra[0].width() <= len(overflower)) {\n        return fitLast(within, extra, withinWidth);\n      } else if (extra.length >= 1) {\n        return overflow(within, extra, overflower, withinWidth);\n      } else {\n        return fitAll(within, extra, withinWidth);\n      }\n    };\n\n    var setStoredGroups = function (toolbar, storedGroups) {\n      var bGroups = map(storedGroups, function (g) {\n        return premade$1(g);\n      });\n      Toolbar.setGroups(toolbar, bGroups);\n    };\n    var findFocusedComp = function (overflow, overflowButton) {\n      return overflow.bind(function (overf) {\n        return search(overf.element()).bind(function (focusedElm) {\n          return overf.getSystem().getByDom(focusedElm).toOption();\n        });\n      }).orThunk(function () {\n        return overflowButton.filter(Focusing.isFocused);\n      });\n    };\n    var refresh = function (toolbar, detail, overflow, isOpen) {\n      var primary = getPartOrDie(toolbar, detail, 'primary');\n      var overflowButton = getPart(toolbar, detail, 'overflow-button');\n      var overflowGroup = Coupling.getCoupled(toolbar, 'overflowGroup');\n      set$2(primary.element(), 'visibility', 'hidden');\n      var focusedComp = findFocusedComp(overflow, overflowButton);\n      overflow.each(function (overf) {\n        Toolbar.setGroups(overf, []);\n      });\n      var groups = detail.builtGroups.get();\n      setStoredGroups(primary, groups.concat([overflowGroup]));\n      var total = get$7(primary.element());\n      var overflows = partition$3(total, groups, function (comp) {\n        return get$7(comp.element());\n      }, overflowGroup);\n      if (overflows.extra().length === 0) {\n        Replacing.remove(primary, overflowGroup);\n        overflow.each(function (overf) {\n          Toolbar.setGroups(overf, []);\n        });\n      } else {\n        setStoredGroups(primary, overflows.within());\n        overflow.each(function (overf) {\n          setStoredGroups(overf, overflows.extra());\n        });\n      }\n      remove$6(primary.element(), 'visibility');\n      reflow(primary.element());\n      overflow.each(function (overf) {\n        overflowButton.each(function (button) {\n          return Toggling.set(button, isOpen(overf));\n        });\n        focusedComp.each(Focusing.focus);\n      });\n    };\n\n    var schema$l = constant([\n      strict$1('items'),\n      markers(['itemSelector']),\n      field$1('tgroupBehaviours', [Keying])\n    ]);\n    var parts$8 = constant([group({\n        name: 'items',\n        unit: 'item'\n      })]);\n\n    var factory$a = function (detail, components, spec, _externals) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: augment(detail.tgroupBehaviours, [Keying.config({\n            mode: 'flow',\n            selector: detail.markers.itemSelector\n          })]),\n        domModification: { attributes: { role: 'toolbar' } }\n      };\n    };\n    var ToolbarGroup = composite$1({\n      name: 'ToolbarGroup',\n      configFields: schema$l(),\n      partFields: parts$8(),\n      factory: factory$a\n    });\n\n    var schema$m = constant([\n      field$1('splitToolbarBehaviours', [Coupling]),\n      state$1('builtGroups', function () {\n        return Cell([]);\n      })\n    ]);\n    var spec = function (detail, components, spec, externals, extras) {\n      var toolbarToggleEvent = 'alloy.toolbar.toggle';\n      var doSetGroups = function (toolbar, groups) {\n        var built = map(groups, toolbar.getSystem().build);\n        detail.builtGroups.set(built);\n      };\n      var setGroups = function (toolbar, groups) {\n        doSetGroups(toolbar, groups);\n        extras.apis.refresh(toolbar);\n      };\n      var getMoreButton = function (toolbar) {\n        return getPart(toolbar, detail, 'overflow-button');\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: augment(detail.splitToolbarBehaviours, [\n          Coupling.config({\n            others: __assign(__assign({}, extras.coupling), {\n              overflowGroup: function (toolbar) {\n                return ToolbarGroup.sketch(__assign(__assign({}, externals['overflow-group']()), {\n                  items: [Button.sketch(__assign(__assign({}, externals['overflow-button']()), {\n                      action: function (_button) {\n                        emit(toolbar, toolbarToggleEvent);\n                      }\n                    }))]\n                }));\n              }\n            })\n          }),\n          config('toolbar-toggle-events', [run(toolbarToggleEvent, function (toolbar) {\n              extras.apis.toggle(toolbar);\n            })])\n        ]),\n        apis: __assign({\n          setGroups: setGroups,\n          getMoreButton: function (toolbar) {\n            return getMoreButton(toolbar);\n          }\n        }, extras.apis),\n        domModification: { attributes: { role: 'group' } }\n      };\n    };\n\n    var schema$n = constant([\n      markers(['overflowToggledClass']),\n      strict$1('getAnchor'),\n      optionFunction('getOverflowBounds'),\n      strict$1('lazySink')\n    ].concat(schema$m()));\n    var parts$9 = constant([\n      required({\n        factory: Toolbar,\n        schema: schema$k(),\n        name: 'primary'\n      }),\n      external$1({\n        factory: Toolbar,\n        schema: schema$k(),\n        name: 'overflow',\n        overrides: function (detail) {\n          return {\n            toolbarBehaviours: derive$1([Keying.config({\n                mode: 'cyclic',\n                onEscape: function (comp) {\n                  getPart(comp, detail, 'overflow-button').each(Focusing.focus);\n                  return Option.none();\n                }\n              })])\n          };\n        }\n      }),\n      external$1({\n        name: 'overflow-button',\n        overrides: function (detail) {\n          return {\n            dom: { attributes: { 'aria-haspopup': 'true' } },\n            buttonBehaviours: derive$1([Toggling.config({\n                toggleClass: detail.markers.overflowToggledClass,\n                aria: { mode: 'expanded' },\n                toggleOnExecute: false\n              })])\n          };\n        }\n      }),\n      external$1({ name: 'overflow-group' })\n    ]);\n\n    var toggleToolbar = function (toolbar, detail, externals) {\n      var sandbox = Coupling.getCoupled(toolbar, 'sandbox');\n      if (Sandboxing.isOpen(sandbox)) {\n        Sandboxing.close(sandbox);\n      } else {\n        Sandboxing.open(sandbox, externals.overflow());\n      }\n    };\n    var isOpen$1 = function (over) {\n      return over.getSystem().isConnected();\n    };\n    var position$2 = function (toolbar, detail, overf) {\n      var sink = detail.lazySink(toolbar).getOrDie();\n      var anchor = detail.getAnchor(toolbar);\n      var bounds = detail.getOverflowBounds.map(function (bounder) {\n        return bounder();\n      });\n      Positioning.positionWithinBounds(sink, anchor, overf, bounds);\n    };\n    var refresh$1 = function (toolbar, detail) {\n      var overflow = Sandboxing.getState(Coupling.getCoupled(toolbar, 'sandbox'));\n      refresh(toolbar, detail, overflow, isOpen$1);\n      overflow.each(function (overf) {\n        return position$2(toolbar, detail, overf);\n      });\n    };\n    var reposition$1 = function (toolbar, detail) {\n      var overflow = Sandboxing.getState(Coupling.getCoupled(toolbar, 'sandbox'));\n      overflow.each(function (overf) {\n        return position$2(toolbar, detail, overf);\n      });\n    };\n    var makeSandbox$1 = function (toolbar, detail) {\n      var ariaOwner = manager();\n      var onOpen = function (sandbox, overf) {\n        refresh$1(toolbar, detail);\n        getPart(toolbar, detail, 'overflow-button').each(function (button) {\n          Toggling.on(button);\n          ariaOwner.link(button.element());\n        });\n        Keying.focusIn(overf);\n      };\n      var onClose = function () {\n        getPart(toolbar, detail, 'overflow-button').each(function (button) {\n          Toggling.off(button);\n          Focusing.focus(button);\n          ariaOwner.unlink(button.element());\n        });\n      };\n      return {\n        dom: {\n          tag: 'div',\n          attributes: { id: ariaOwner.id() }\n        },\n        behaviours: derive$1([\n          Keying.config({\n            mode: 'special',\n            onEscape: function (comp) {\n              Sandboxing.close(comp);\n              return Option.some(true);\n            }\n          }),\n          Sandboxing.config({\n            onOpen: onOpen,\n            onClose: onClose,\n            isPartOf: function (container, data, queryElem) {\n              return isPartOf(data, queryElem) || isPartOf(toolbar, queryElem);\n            },\n            getAttachPoint: function () {\n              return detail.lazySink(toolbar).getOrDie();\n            }\n          }),\n          Receiving.config({\n            channels: __assign({}, receivingChannel$1({\n              isExtraPart: constant(false),\n              doReposition: function () {\n                return reposition$1(toolbar, detail);\n              }\n            }))\n          })\n        ])\n      };\n    };\n    var factory$b = function (detail, components, spec$1, externals) {\n      return spec(detail, components, spec$1, externals, {\n        coupling: {\n          sandbox: function (toolbar) {\n            return makeSandbox$1(toolbar, detail);\n          }\n        },\n        apis: {\n          refresh: function (toolbar) {\n            return refresh$1(toolbar, detail);\n          },\n          toggle: function (toolbar) {\n            return toggleToolbar(toolbar, detail, externals);\n          },\n          getOverflow: function (toolbar) {\n            return Sandboxing.getState(Coupling.getCoupled(toolbar, 'sandbox'));\n          },\n          reposition: function (toolbar) {\n            return reposition$1(toolbar, detail);\n          }\n        }\n      });\n    };\n    var SplitFloatingToolbar = composite$1({\n      name: 'SplitFloatingToolbar',\n      configFields: schema$n(),\n      partFields: parts$9(),\n      factory: factory$b,\n      apis: {\n        setGroups: function (apis, toolbar, groups) {\n          apis.setGroups(toolbar, groups);\n        },\n        refresh: function (apis, toolbar) {\n          apis.refresh(toolbar);\n        },\n        reposition: function (apis, toolbar) {\n          apis.reposition(toolbar);\n        },\n        getMoreButton: function (apis, toolbar) {\n          return apis.getMoreButton(toolbar);\n        },\n        getOverflow: function (apis, toolbar) {\n          return apis.getOverflow(toolbar);\n        },\n        toggle: function (apis, toolbar) {\n          apis.toggle(toolbar);\n        }\n      }\n    });\n\n    var getAnimationRoot = function (component, slideConfig) {\n      return slideConfig.getAnimationRoot.fold(function () {\n        return component.element();\n      }, function (get) {\n        return get(component);\n      });\n    };\n\n    var getDimensionProperty = function (slideConfig) {\n      return slideConfig.dimension.property;\n    };\n    var getDimension = function (slideConfig, elem) {\n      return slideConfig.dimension.getDimension(elem);\n    };\n    var disableTransitions = function (component, slideConfig) {\n      var root = getAnimationRoot(component, slideConfig);\n      remove$5(root, [\n        slideConfig.shrinkingClass,\n        slideConfig.growingClass\n      ]);\n    };\n    var setShrunk = function (component, slideConfig) {\n      remove$4(component.element(), slideConfig.openClass);\n      add$2(component.element(), slideConfig.closedClass);\n      set$2(component.element(), getDimensionProperty(slideConfig), '0px');\n      reflow(component.element());\n    };\n    var setGrown = function (component, slideConfig) {\n      remove$4(component.element(), slideConfig.closedClass);\n      add$2(component.element(), slideConfig.openClass);\n      remove$6(component.element(), getDimensionProperty(slideConfig));\n    };\n    var doImmediateShrink = function (component, slideConfig, slideState, _calculatedSize) {\n      slideState.setCollapsed();\n      set$2(component.element(), getDimensionProperty(slideConfig), getDimension(slideConfig, component.element()));\n      reflow(component.element());\n      disableTransitions(component, slideConfig);\n      setShrunk(component, slideConfig);\n      slideConfig.onStartShrink(component);\n      slideConfig.onShrunk(component);\n    };\n    var doStartShrink = function (component, slideConfig, slideState, calculatedSize) {\n      var size = calculatedSize.getOrThunk(function () {\n        return getDimension(slideConfig, component.element());\n      });\n      slideState.setCollapsed();\n      set$2(component.element(), getDimensionProperty(slideConfig), size);\n      reflow(component.element());\n      var root = getAnimationRoot(component, slideConfig);\n      remove$4(root, slideConfig.growingClass);\n      add$2(root, slideConfig.shrinkingClass);\n      setShrunk(component, slideConfig);\n      slideConfig.onStartShrink(component);\n    };\n    var doStartSmartShrink = function (component, slideConfig, slideState) {\n      var size = getDimension(slideConfig, component.element());\n      var shrinker = size === '0px' ? doImmediateShrink : doStartShrink;\n      shrinker(component, slideConfig, slideState, Option.some(size));\n    };\n    var doStartGrow = function (component, slideConfig, slideState) {\n      var root = getAnimationRoot(component, slideConfig);\n      var wasShrinking = has$2(root, slideConfig.shrinkingClass);\n      var beforeSize = getDimension(slideConfig, component.element());\n      setGrown(component, slideConfig);\n      var fullSize = getDimension(slideConfig, component.element());\n      var startPartialGrow = function () {\n        set$2(component.element(), getDimensionProperty(slideConfig), beforeSize);\n        reflow(component.element());\n      };\n      var startCompleteGrow = function () {\n        setShrunk(component, slideConfig);\n      };\n      var setStartSize = wasShrinking ? startPartialGrow : startCompleteGrow;\n      setStartSize();\n      remove$4(root, slideConfig.shrinkingClass);\n      add$2(root, slideConfig.growingClass);\n      setGrown(component, slideConfig);\n      set$2(component.element(), getDimensionProperty(slideConfig), fullSize);\n      slideState.setExpanded();\n      slideConfig.onStartGrow(component);\n    };\n    var refresh$2 = function (component, slideConfig, slideState) {\n      if (slideState.isExpanded()) {\n        remove$6(component.element(), getDimensionProperty(slideConfig));\n        var fullSize = getDimension(slideConfig, component.element());\n        set$2(component.element(), getDimensionProperty(slideConfig), fullSize);\n      }\n    };\n    var grow = function (component, slideConfig, slideState) {\n      if (!slideState.isExpanded()) {\n        doStartGrow(component, slideConfig, slideState);\n      }\n    };\n    var shrink = function (component, slideConfig, slideState) {\n      if (slideState.isExpanded()) {\n        doStartSmartShrink(component, slideConfig, slideState);\n      }\n    };\n    var immediateShrink = function (component, slideConfig, slideState) {\n      if (slideState.isExpanded()) {\n        doImmediateShrink(component, slideConfig, slideState);\n      }\n    };\n    var hasGrown = function (component, slideConfig, slideState) {\n      return slideState.isExpanded();\n    };\n    var hasShrunk = function (component, slideConfig, slideState) {\n      return slideState.isCollapsed();\n    };\n    var isGrowing = function (component, slideConfig, slideState) {\n      var root = getAnimationRoot(component, slideConfig);\n      return has$2(root, slideConfig.growingClass) === true;\n    };\n    var isShrinking = function (component, slideConfig, slideState) {\n      var root = getAnimationRoot(component, slideConfig);\n      return has$2(root, slideConfig.shrinkingClass) === true;\n    };\n    var isTransitioning = function (component, slideConfig, slideState) {\n      return isGrowing(component, slideConfig) === true || isShrinking(component, slideConfig) === true;\n    };\n    var toggleGrow = function (component, slideConfig, slideState) {\n      var f = slideState.isExpanded() ? doStartSmartShrink : doStartGrow;\n      f(component, slideConfig, slideState);\n    };\n\n    var SlidingApis = /*#__PURE__*/Object.freeze({\n        refresh: refresh$2,\n        grow: grow,\n        shrink: shrink,\n        immediateShrink: immediateShrink,\n        hasGrown: hasGrown,\n        hasShrunk: hasShrunk,\n        isGrowing: isGrowing,\n        isShrinking: isShrinking,\n        isTransitioning: isTransitioning,\n        toggleGrow: toggleGrow,\n        disableTransitions: disableTransitions\n    });\n\n    var exhibit$6 = function (base, slideConfig) {\n      var expanded = slideConfig.expanded;\n      return expanded ? nu$6({\n        classes: [slideConfig.openClass],\n        styles: {}\n      }) : nu$6({\n        classes: [slideConfig.closedClass],\n        styles: wrap$1(slideConfig.dimension.property, '0px')\n      });\n    };\n    var events$d = function (slideConfig, slideState) {\n      return derive([runOnSource(transitionend(), function (component, simulatedEvent) {\n          var raw = simulatedEvent.event().raw();\n          if (raw.propertyName === slideConfig.dimension.property) {\n            disableTransitions(component, slideConfig);\n            if (slideState.isExpanded()) {\n              remove$6(component.element(), slideConfig.dimension.property);\n            }\n            var notify = slideState.isExpanded() ? slideConfig.onGrown : slideConfig.onShrunk;\n            notify(component);\n          }\n        })]);\n    };\n\n    var ActiveSliding = /*#__PURE__*/Object.freeze({\n        exhibit: exhibit$6,\n        events: events$d\n    });\n\n    var SlidingSchema = [\n      strict$1('closedClass'),\n      strict$1('openClass'),\n      strict$1('shrinkingClass'),\n      strict$1('growingClass'),\n      option('getAnimationRoot'),\n      onHandler('onShrunk'),\n      onHandler('onStartShrink'),\n      onHandler('onGrown'),\n      onHandler('onStartGrow'),\n      defaulted$1('expanded', false),\n      strictOf('dimension', choose$1('property', {\n        width: [\n          output('property', 'width'),\n          output('getDimension', function (elem) {\n            return get$7(elem) + 'px';\n          })\n        ],\n        height: [\n          output('property', 'height'),\n          output('getDimension', function (elem) {\n            return get$6(elem) + 'px';\n          })\n        ]\n      }))\n    ];\n\n    var init$9 = function (spec) {\n      var state = Cell(spec.expanded);\n      var readState = function () {\n        return 'expanded: ' + state.get();\n      };\n      return nu$5({\n        isExpanded: function () {\n          return state.get() === true;\n        },\n        isCollapsed: function () {\n          return state.get() === false;\n        },\n        setCollapsed: curry(state.set, false),\n        setExpanded: curry(state.set, true),\n        readState: readState\n      });\n    };\n\n    var SlidingState = /*#__PURE__*/Object.freeze({\n        init: init$9\n    });\n\n    var Sliding = create$1({\n      fields: SlidingSchema,\n      name: 'sliding',\n      active: ActiveSliding,\n      apis: SlidingApis,\n      state: SlidingState\n    });\n\n    var schema$o = constant([\n      markers([\n        'closedClass',\n        'openClass',\n        'shrinkingClass',\n        'growingClass',\n        'overflowToggledClass'\n      ]),\n      onHandler('onOpened'),\n      onHandler('onClosed')\n    ].concat(schema$m()));\n    var parts$a = constant([\n      required({\n        factory: Toolbar,\n        schema: schema$k(),\n        name: 'primary'\n      }),\n      required({\n        factory: Toolbar,\n        schema: schema$k(),\n        name: 'overflow',\n        overrides: function (detail) {\n          return {\n            toolbarBehaviours: derive$1([\n              Sliding.config({\n                dimension: { property: 'height' },\n                closedClass: detail.markers.closedClass,\n                openClass: detail.markers.openClass,\n                shrinkingClass: detail.markers.shrinkingClass,\n                growingClass: detail.markers.growingClass,\n                onShrunk: function (comp) {\n                  getPart(comp, detail, 'overflow-button').each(function (button) {\n                    Toggling.off(button);\n                    Focusing.focus(button);\n                  });\n                  detail.onClosed(comp);\n                },\n                onGrown: function (comp) {\n                  Keying.focusIn(comp);\n                  detail.onOpened(comp);\n                },\n                onStartGrow: function (comp) {\n                  getPart(comp, detail, 'overflow-button').each(Toggling.on);\n                }\n              }),\n              Keying.config({\n                mode: 'acyclic',\n                onEscape: function (comp) {\n                  getPart(comp, detail, 'overflow-button').each(Focusing.focus);\n                  return Option.some(true);\n                }\n              })\n            ])\n          };\n        }\n      }),\n      external$1({\n        name: 'overflow-button',\n        overrides: function (detail) {\n          return {\n            buttonBehaviours: derive$1([Toggling.config({\n                toggleClass: detail.markers.overflowToggledClass,\n                aria: { mode: 'pressed' },\n                toggleOnExecute: false\n              })])\n          };\n        }\n      }),\n      external$1({ name: 'overflow-group' })\n    ]);\n\n    var toggleToolbar$1 = function (toolbar, detail) {\n      getPart(toolbar, detail, 'overflow').each(function (overf) {\n        refresh$3(toolbar, detail);\n        Sliding.toggleGrow(overf);\n      });\n    };\n    var isOpen$2 = function (overf) {\n      return Sliding.hasGrown(overf);\n    };\n    var refresh$3 = function (toolbar, detail) {\n      var overflow = getPart(toolbar, detail, 'overflow');\n      refresh(toolbar, detail, overflow, isOpen$2);\n      overflow.each(Sliding.refresh);\n    };\n    var factory$c = function (detail, components, spec$1, externals) {\n      return spec(detail, components, spec$1, externals, {\n        coupling: {},\n        apis: {\n          refresh: function (toolbar) {\n            return refresh$3(toolbar, detail);\n          },\n          toggle: function (toolbar) {\n            return toggleToolbar$1(toolbar, detail);\n          },\n          getOverflow: function (toolbar) {\n            return getPart(toolbar, detail, 'overflow');\n          }\n        }\n      });\n    };\n    var SplitSlidingToolbar = composite$1({\n      name: 'SplitSlidingToolbar',\n      configFields: schema$o(),\n      partFields: parts$a(),\n      factory: factory$c,\n      apis: {\n        setGroups: function (apis, toolbar, groups) {\n          apis.setGroups(toolbar, groups);\n        },\n        refresh: function (apis, toolbar) {\n          apis.refresh(toolbar);\n        },\n        getMoreButton: function (apis, toolbar) {\n          return apis.getMoreButton(toolbar);\n        },\n        getOverflow: function (apis, toolbar) {\n          return apis.getOverflow(toolbar);\n        },\n        toggle: function (apis, toolbar) {\n          apis.toggle(toolbar);\n        }\n      }\n    });\n\n    var toolbarHeightChange = constant(generate$1('toolbar-height-change'));\n\n    var ReadOnlyChannel = 'silver.readonly';\n    var ReadOnlyDataSchema = objOf([strictBoolean('readonly')]);\n    var setDisabledAll = function (element, state) {\n      all('*', element.element()).forEach(function (elm) {\n        element.getSystem().getByDom(elm).each(function (comp) {\n          if (comp.hasConfigured(Disabling)) {\n            Disabling.set(comp, state);\n          }\n        });\n      });\n    };\n    var broadcastReadonly = function (uiComponents, readonly) {\n      var outerContainer = uiComponents.outerContainer;\n      var target = outerContainer.element();\n      if (readonly) {\n        uiComponents.mothership.broadcastOn([dismissPopups()], { target: target });\n        uiComponents.uiMothership.broadcastOn([dismissPopups()], { target: target });\n      }\n      uiComponents.mothership.broadcastOn([ReadOnlyChannel], { readonly: readonly });\n      uiComponents.uiMothership.broadcastOn([ReadOnlyChannel], { readonly: readonly });\n    };\n    var toggleToReadOnly = function (uiComponents, readonly) {\n      var outerContainer = uiComponents.outerContainer;\n      broadcastReadonly(uiComponents, readonly);\n      all('*', outerContainer.element()).forEach(function (elm) {\n        outerContainer.getSystem().getByDom(elm).each(function (comp) {\n          if (comp.hasConfigured(Disabling)) {\n            Disabling.set(comp, readonly);\n          }\n        });\n      });\n    };\n    var setupReadonlyModeSwitch = function (editor, uiComponents) {\n      editor.on('init', function () {\n        if (editor.readonly) {\n          toggleToReadOnly(uiComponents, true);\n        }\n      });\n      editor.on('SwitchMode', function () {\n        return toggleToReadOnly(uiComponents, editor.readonly);\n      });\n      if (isReadOnly(editor)) {\n        editor.setMode('readonly');\n      }\n    };\n    var createReadonlyReceivingForOverflow = function (getOverflow) {\n      var _a;\n      return Receiving.config({\n        channels: (_a = {}, _a[ReadOnlyChannel] = {\n          schema: ReadOnlyDataSchema,\n          onReceive: function (comp, data) {\n            getOverflow(comp).each(function (toolbar) {\n              setDisabledAll(toolbar, data.readonly);\n            });\n          }\n        }, _a)\n      });\n    };\n\n    var renderToolbarGroupCommon = function (toolbarGroup) {\n      var attributes = toolbarGroup.title.fold(function () {\n        return {};\n      }, function (title) {\n        return { attributes: { title: title } };\n      });\n      return {\n        dom: __assign({\n          tag: 'div',\n          classes: ['tox-toolbar__group']\n        }, attributes),\n        components: [ToolbarGroup.parts().items({})],\n        items: toolbarGroup.items,\n        markers: { itemSelector: '*:not(.tox-split-button) > .tox-tbtn:not([disabled]), .tox-split-button:not([disabled]), .tox-toolbar-nav-js:not([disabled])' },\n        tgroupBehaviours: derive$1([\n          Tabstopping.config({}),\n          Focusing.config({})\n        ])\n      };\n    };\n    var renderToolbarGroup = function (toolbarGroup) {\n      return ToolbarGroup.sketch(renderToolbarGroupCommon(toolbarGroup));\n    };\n    var getToolbarbehaviours = function (toolbarSpec, modeName, getOverflow) {\n      var onAttached = runOnAttached(function (component) {\n        var groups = map(toolbarSpec.initGroups, renderToolbarGroup);\n        Toolbar.setGroups(component, groups);\n      });\n      return derive$1([\n        Keying.config({\n          mode: modeName,\n          onEscape: toolbarSpec.onEscape,\n          selector: '.tox-toolbar__group'\n        }),\n        config('toolbar-events', [onAttached]),\n        createReadonlyReceivingForOverflow(getOverflow)\n      ]);\n    };\n    var renderMoreToolbarCommon = function (toolbarSpec, getOverflow) {\n      var modeName = toolbarSpec.cyclicKeying ? 'cyclic' : 'acyclic';\n      return {\n        uid: toolbarSpec.uid,\n        dom: {\n          tag: 'div',\n          classes: ['tox-toolbar-overlord']\n        },\n        parts: {\n          'overflow-group': renderToolbarGroupCommon({\n            title: Option.none(),\n            items: []\n          }),\n          'overflow-button': renderIconButtonSpec({\n            name: 'more',\n            icon: Option.some('more-drawer'),\n            disabled: false,\n            tooltip: Option.some('More...'),\n            primary: false,\n            borderless: false\n          }, Option.none(), toolbarSpec.backstage.shared.providers)\n        },\n        splitToolbarBehaviours: getToolbarbehaviours(toolbarSpec, modeName, getOverflow)\n      };\n    };\n    var renderFloatingMoreToolbar = function (toolbarSpec) {\n      var baseSpec = renderMoreToolbarCommon(toolbarSpec, SplitFloatingToolbar.getOverflow);\n      var overflowXOffset = 4;\n      var primary = SplitFloatingToolbar.parts().primary({\n        dom: {\n          tag: 'div',\n          classes: ['tox-toolbar__primary']\n        }\n      });\n      return SplitFloatingToolbar.sketch(__assign(__assign({}, baseSpec), {\n        lazySink: toolbarSpec.getSink,\n        getAnchor: function () {\n          return toolbarSpec.backstage.shared.anchors.toolbarOverflow();\n        },\n        getOverflowBounds: function () {\n          var headerElem = toolbarSpec.moreDrawerData.lazyHeader().element();\n          var headerBounds = absolute$1(headerElem);\n          var docElem = documentElement(headerElem);\n          var docBounds = absolute$1(docElem);\n          return bounds$1(headerBounds.x() + overflowXOffset, docBounds.y(), headerBounds.width() - overflowXOffset * 2, docBounds.height());\n        },\n        parts: __assign(__assign({}, baseSpec.parts), {\n          overflow: {\n            dom: {\n              tag: 'div',\n              classes: ['tox-toolbar__overflow']\n            }\n          }\n        }),\n        components: [primary],\n        markers: { overflowToggledClass: 'tox-tbtn--enabled' }\n      }));\n    };\n    var renderSlidingMoreToolbar = function (toolbarSpec) {\n      var primary = SplitSlidingToolbar.parts().primary({\n        dom: {\n          tag: 'div',\n          classes: ['tox-toolbar__primary']\n        }\n      });\n      var overflow = SplitSlidingToolbar.parts().overflow({\n        dom: {\n          tag: 'div',\n          classes: ['tox-toolbar__overflow']\n        }\n      });\n      var baseSpec = renderMoreToolbarCommon(toolbarSpec, SplitSlidingToolbar.getOverflow);\n      return SplitSlidingToolbar.sketch(__assign(__assign({}, baseSpec), {\n        components: [\n          primary,\n          overflow\n        ],\n        markers: {\n          openClass: 'tox-toolbar__overflow--open',\n          closedClass: 'tox-toolbar__overflow--closed',\n          growingClass: 'tox-toolbar__overflow--growing',\n          shrinkingClass: 'tox-toolbar__overflow--shrinking',\n          overflowToggledClass: 'tox-tbtn--enabled'\n        },\n        onOpened: function (comp) {\n          comp.getSystem().broadcastOn([toolbarHeightChange()], { type: 'opened' });\n        },\n        onClosed: function (comp) {\n          comp.getSystem().broadcastOn([toolbarHeightChange()], { type: 'closed' });\n        }\n      }));\n    };\n    var renderToolbar = function (toolbarSpec) {\n      var modeName = toolbarSpec.cyclicKeying ? 'cyclic' : 'acyclic';\n      return Toolbar.sketch({\n        uid: toolbarSpec.uid,\n        dom: {\n          tag: 'div',\n          classes: ['tox-toolbar'].concat(toolbarSpec.type === ToolbarDrawer.scrolling ? ['tox-toolbar--scrolling'] : [])\n        },\n        components: [Toolbar.parts().groups({})],\n        toolbarBehaviours: getToolbarbehaviours(toolbarSpec, modeName, constant(Option.none()))\n      });\n    };\n\n    var baseToolbarButtonFields = [\n      defaultedBoolean('disabled', false),\n      optionString('tooltip'),\n      optionString('icon'),\n      optionString('text'),\n      defaultedFunction('onSetup', function () {\n        return noop;\n      })\n    ];\n    var toolbarButtonSchema = objOf([\n      strictString('type'),\n      strictFunction('onAction')\n    ].concat(baseToolbarButtonFields));\n    var createToolbarButton = function (spec) {\n      return asRaw('toolbarbutton', toolbarButtonSchema, spec);\n    };\n\n    var baseMenuButtonFields = [\n      optionString('text'),\n      optionString('tooltip'),\n      optionString('icon'),\n      strictFunction('fetch'),\n      defaultedFunction('onSetup', function () {\n        return noop;\n      })\n    ];\n\n    var MenuButtonSchema = objOf(__spreadArrays([strictString('type')], baseMenuButtonFields));\n    var createMenuButton = function (spec) {\n      return asRaw('menubutton', MenuButtonSchema, spec);\n    };\n\n    var splitButtonSchema = objOf([\n      strictString('type'),\n      optionString('tooltip'),\n      optionString('icon'),\n      optionString('text'),\n      optionFunction('select'),\n      strictFunction('fetch'),\n      defaultedFunction('onSetup', function () {\n        return noop;\n      }),\n      defaultedStringEnum('presets', 'normal', [\n        'normal',\n        'color',\n        'listpreview'\n      ]),\n      defaulted$1('columns', 1),\n      strictFunction('onAction'),\n      strictFunction('onItemAction')\n    ]);\n    var createSplitButton = function (spec) {\n      return asRaw('SplitButton', splitButtonSchema, spec);\n    };\n\n    var baseToolbarToggleButtonFields = [defaultedBoolean('active', false)].concat(baseToolbarButtonFields);\n    var toggleButtonSchema = objOf(baseToolbarToggleButtonFields.concat([\n      strictString('type'),\n      strictFunction('onAction')\n    ]));\n    var createToggleButton = function (spec) {\n      return asRaw('ToggleButton', toggleButtonSchema, spec);\n    };\n\n    var contextBarFields = [\n      defaultedFunction('predicate', function () {\n        return false;\n      }),\n      defaultedStringEnum('scope', 'node', [\n        'node',\n        'editor'\n      ]),\n      defaultedStringEnum('position', 'selection', [\n        'node',\n        'selection',\n        'line'\n      ])\n    ];\n    var contextButtonFields = baseToolbarButtonFields.concat([\n      defaulted$1('type', 'contextformbutton'),\n      defaulted$1('primary', false),\n      strictFunction('onAction'),\n      state$1('original', identity)\n    ]);\n    var contextToggleButtonFields = baseToolbarToggleButtonFields.concat([\n      defaulted$1('type', 'contextformbutton'),\n      defaulted$1('primary', false),\n      strictFunction('onAction'),\n      state$1('original', identity)\n    ]);\n    var launchButtonFields = baseToolbarButtonFields.concat([defaulted$1('type', 'contextformbutton')]);\n    var launchToggleButtonFields = baseToolbarToggleButtonFields.concat([defaulted$1('type', 'contextformtogglebutton')]);\n    var toggleOrNormal = choose$1('type', {\n      contextformbutton: contextButtonFields,\n      contextformtogglebutton: contextToggleButtonFields\n    });\n    var contextFormSchema = objOf([\n      defaulted$1('type', 'contextform'),\n      defaultedFunction('initValue', function () {\n        return '';\n      }),\n      optionString('label'),\n      strictArrayOf('commands', toggleOrNormal),\n      optionOf('launch', choose$1('type', {\n        contextformbutton: launchButtonFields,\n        contextformtogglebutton: launchToggleButtonFields\n      }))\n    ].concat(contextBarFields));\n    var contextToolbarSchema = objOf([\n      defaulted$1('type', 'contexttoolbar'),\n      strictString('items')\n    ].concat(contextBarFields));\n    var createContextToolbar = function (spec) {\n      return asRaw('ContextToolbar', contextToolbarSchema, spec);\n    };\n    var createContextForm = function (spec) {\n      return asRaw('ContextForm', contextFormSchema, spec);\n    };\n\n    var getState$2 = function (component, replaceConfig, reflectState) {\n      return reflectState;\n    };\n\n    var ReflectingApis = /*#__PURE__*/Object.freeze({\n        getState: getState$2\n    });\n\n    var events$e = function (reflectingConfig, reflectingState) {\n      var update = function (component, data) {\n        reflectingConfig.updateState.each(function (updateState) {\n          var newState = updateState(component, data);\n          reflectingState.set(newState);\n        });\n        reflectingConfig.renderComponents.each(function (renderComponents) {\n          var newComponents = renderComponents(data, reflectingState.get());\n          var newChildren = map(newComponents, component.getSystem().build);\n          replaceChildren(component, newChildren);\n        });\n      };\n      return derive([\n        run(receive(), function (component, message) {\n          var channel = reflectingConfig.channel;\n          if (contains(message.channels(), channel)) {\n            update(component, message.data());\n          }\n        }),\n        runOnAttached(function (comp, se) {\n          reflectingConfig.initialData.each(function (rawData) {\n            update(comp, rawData);\n          });\n        })\n      ]);\n    };\n\n    var ActiveReflecting = /*#__PURE__*/Object.freeze({\n        events: events$e\n    });\n\n    var init$a = function (spec) {\n      var cell = Cell(Option.none());\n      var set = function (optS) {\n        return cell.set(optS);\n      };\n      var clear = function () {\n        return cell.set(Option.none());\n      };\n      var get = function () {\n        return cell.get();\n      };\n      var readState = function () {\n        return cell.get().fold(function () {\n          return 'none';\n        }, function (x) {\n          return x;\n        });\n      };\n      return {\n        readState: readState,\n        get: get,\n        set: set,\n        clear: clear\n      };\n    };\n\n    var ReflectingState = /*#__PURE__*/Object.freeze({\n        init: init$a\n    });\n\n    var ReflectingSchema = [\n      strict$1('channel'),\n      option('renderComponents'),\n      option('updateState'),\n      option('initialData')\n    ];\n\n    var Reflecting = create$1({\n      fields: ReflectingSchema,\n      name: 'reflecting',\n      active: ActiveReflecting,\n      apis: ReflectingApis,\n      state: ReflectingState\n    });\n\n    var schema$p = constant([\n      strict$1('toggleClass'),\n      strict$1('fetch'),\n      onStrictHandler('onExecute'),\n      defaulted$1('getHotspot', Option.some),\n      defaulted$1('getAnchorOverrides', constant({})),\n      defaulted$1('layouts', Option.none()),\n      onStrictHandler('onItemExecute'),\n      option('lazySink'),\n      strict$1('dom'),\n      onHandler('onOpen'),\n      field$1('splitDropdownBehaviours', [\n        Coupling,\n        Keying,\n        Focusing\n      ]),\n      defaulted$1('matchWidth', false),\n      defaulted$1('useMinWidth', false),\n      defaulted$1('eventOrder', {}),\n      option('role')\n    ].concat(sandboxFields()));\n    var arrowPart = required({\n      factory: Button,\n      schema: [strict$1('dom')],\n      name: 'arrow',\n      defaults: function (detail) {\n        return { buttonBehaviours: derive$1([Focusing.revoke()]) };\n      },\n      overrides: function (detail) {\n        return {\n          dom: {\n            tag: 'span',\n            attributes: { role: 'presentation' }\n          },\n          action: function (arrow) {\n            arrow.getSystem().getByUid(detail.uid).each(emitExecute);\n          },\n          buttonBehaviours: derive$1([Toggling.config({\n              toggleOnExecute: false,\n              toggleClass: detail.toggleClass\n            })])\n        };\n      }\n    });\n    var buttonPart = required({\n      factory: Button,\n      schema: [strict$1('dom')],\n      name: 'button',\n      defaults: function (detail) {\n        return { buttonBehaviours: derive$1([Focusing.revoke()]) };\n      },\n      overrides: function (detail) {\n        return {\n          dom: {\n            tag: 'span',\n            attributes: { role: 'presentation' }\n          },\n          action: function (btn) {\n            btn.getSystem().getByUid(detail.uid).each(function (splitDropdown) {\n              detail.onExecute(splitDropdown, btn);\n            });\n          }\n        };\n      }\n    });\n    var parts$b = constant([\n      arrowPart,\n      buttonPart,\n      optional({\n        factory: {\n          sketch: function (spec) {\n            return {\n              uid: spec.uid,\n              dom: {\n                tag: 'span',\n                styles: { display: 'none' },\n                attributes: { 'aria-hidden': 'true' },\n                innerHtml: spec.text\n              }\n            };\n          }\n        },\n        schema: [strict$1('text')],\n        name: 'aria-descriptor'\n      }),\n      external$1({\n        schema: [tieredMenuMarkers()],\n        name: 'menu',\n        defaults: function (detail) {\n          return {\n            onExecute: function (tmenu, item) {\n              tmenu.getSystem().getByUid(detail.uid).each(function (splitDropdown) {\n                detail.onItemExecute(splitDropdown, tmenu, item);\n              });\n            }\n          };\n        }\n      }),\n      partType()\n    ]);\n\n    var factory$d = function (detail, components, spec, externals) {\n      var switchToMenu = function (sandbox) {\n        Composing.getCurrent(sandbox).each(function (current) {\n          Highlighting.highlightFirst(current);\n          Keying.focusIn(current);\n        });\n      };\n      var action = function (component) {\n        var onOpenSync = switchToMenu;\n        togglePopup(detail, function (x) {\n          return x;\n        }, component, externals, onOpenSync, HighlightOnOpen.HighlightFirst).get(noop);\n      };\n      var openMenu = function (comp) {\n        action(comp);\n        return Option.some(true);\n      };\n      var executeOnButton = function (comp) {\n        var button = getPartOrDie(comp, detail, 'button');\n        emitExecute(button);\n        return Option.some(true);\n      };\n      var buttonEvents = merge(derive([runOnAttached(function (component, simulatedEvent) {\n          var ariaDescriptor = getPart(component, detail, 'aria-descriptor');\n          ariaDescriptor.each(function (descriptor) {\n            var descriptorId = generate$1('aria');\n            set$1(descriptor.element(), 'id', descriptorId);\n            set$1(component.element(), 'aria-describedby', descriptorId);\n          });\n        })]), events$7(Option.some(action)));\n      var apis = {\n        repositionMenus: function (comp) {\n          if (Toggling.isOn(comp)) {\n            repositionMenus(comp);\n          }\n        }\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        apis: apis,\n        eventOrder: __assign(__assign({}, detail.eventOrder), {\n          'alloy.execute': [\n            'disabling',\n            'toggling',\n            'alloy.base.behaviour'\n          ]\n        }),\n        events: buttonEvents,\n        behaviours: augment(detail.splitDropdownBehaviours, [\n          Coupling.config({\n            others: {\n              sandbox: function (hotspot) {\n                var arrow = getPartOrDie(hotspot, detail, 'arrow');\n                var extras = {\n                  onOpen: function () {\n                    Toggling.on(arrow);\n                    Toggling.on(hotspot);\n                  },\n                  onClose: function () {\n                    Toggling.off(arrow);\n                    Toggling.off(hotspot);\n                  }\n                };\n                return makeSandbox(detail, hotspot, extras);\n              }\n            }\n          }),\n          Keying.config({\n            mode: 'special',\n            onSpace: executeOnButton,\n            onEnter: executeOnButton,\n            onDown: openMenu\n          }),\n          Focusing.config({}),\n          Toggling.config({\n            toggleOnExecute: false,\n            aria: { mode: 'expanded' }\n          })\n        ]),\n        domModification: {\n          attributes: {\n            'role': detail.role.getOr('button'),\n            'aria-haspopup': true\n          }\n        }\n      };\n    };\n    var SplitDropdown = composite$1({\n      name: 'SplitDropdown',\n      configFields: schema$p(),\n      partFields: parts$b(),\n      factory: factory$d,\n      apis: {\n        repositionMenus: function (apis, comp) {\n          return apis.repositionMenus(comp);\n        }\n      }\n    });\n\n    var getButtonApi = function (component) {\n      return {\n        isDisabled: function () {\n          return Disabling.isDisabled(component);\n        },\n        setDisabled: function (state) {\n          return Disabling.set(component, state);\n        }\n      };\n    };\n    var getToggleApi = function (component) {\n      return {\n        setActive: function (state) {\n          Toggling.set(component, state);\n        },\n        isActive: function () {\n          return Toggling.isOn(component);\n        },\n        isDisabled: function () {\n          return Disabling.isDisabled(component);\n        },\n        setDisabled: function (state) {\n          return Disabling.set(component, state);\n        }\n      };\n    };\n    var getTooltipAttributes = function (tooltip, providersBackstage) {\n      return tooltip.map(function (tooltip) {\n        return {\n          'aria-label': providersBackstage.translate(tooltip),\n          'title': providersBackstage.translate(tooltip)\n        };\n      }).getOr({});\n    };\n    var focusButtonEvent = generate$1('focus-button');\n    var rtlIcon$1 = [\n      'checklist',\n      'ordered-list'\n    ];\n    var rtlTransform$1 = [\n      'indent',\n      'outdent',\n      'table-insert-column-after',\n      'table-insert-column-before',\n      'unordered-list'\n    ];\n    var renderCommonStructure = function (icon, text, tooltip, receiver, behaviours, providersBackstage) {\n      var _a;\n      var getIconName = function (iconName) {\n        return global$5.isRtl() && contains(rtlIcon$1, iconName) ? iconName + '-rtl' : iconName;\n      };\n      var needsRtlClass = global$5.isRtl() && icon.exists(function (name) {\n        return contains(rtlTransform$1, name);\n      });\n      return {\n        dom: {\n          tag: 'button',\n          classes: ['tox-tbtn'].concat(text.isSome() ? ['tox-tbtn--select'] : []).concat(needsRtlClass ? ['tox-tbtn__icon-rtl'] : []),\n          attributes: getTooltipAttributes(tooltip, providersBackstage)\n        },\n        components: componentRenderPipeline([\n          icon.map(function (iconName) {\n            return renderIconFromPack(getIconName(iconName), providersBackstage.icons);\n          }),\n          text.map(function (text) {\n            return renderLabel$1(text, 'tox-tbtn', providersBackstage);\n          })\n        ]),\n        eventOrder: (_a = {}, _a[mousedown()] = [\n          'focusing',\n          'alloy.base.behaviour',\n          'common-button-display-events'\n        ], _a),\n        buttonBehaviours: derive$1([config('common-button-display-events', [run(mousedown(), function (button, se) {\n              se.event().prevent();\n              emit(button, focusButtonEvent);\n            })])].concat(receiver.map(function (r) {\n          return Reflecting.config({\n            channel: r,\n            initialData: {\n              icon: icon,\n              text: text\n            },\n            renderComponents: function (data, _state) {\n              return componentRenderPipeline([\n                data.icon.map(function (iconName) {\n                  return renderIconFromPack(getIconName(iconName), providersBackstage.icons);\n                }),\n                data.text.map(function (text) {\n                  return renderLabel$1(text, 'tox-tbtn', providersBackstage);\n                })\n              ]);\n            }\n          });\n        }).toArray()).concat(behaviours.getOr([])))\n      };\n    };\n    var renderCommonToolbarButton = function (spec, specialisation, providersBackstage) {\n      var editorOffCell = Cell(noop);\n      var structure = renderCommonStructure(spec.icon, spec.text, spec.tooltip, Option.none(), Option.none(), providersBackstage);\n      return Button.sketch({\n        dom: structure.dom,\n        components: structure.components,\n        eventOrder: toolbarButtonEventOrder,\n        buttonBehaviours: derive$1([\n          config('toolbar-button-events', [\n            onToolbarButtonExecute({\n              onAction: spec.onAction,\n              getApi: specialisation.getApi\n            }),\n            onControlAttached(specialisation, editorOffCell),\n            onControlDetached(specialisation, editorOffCell)\n          ]),\n          DisablingConfigs.toolbarButton(spec.disabled)\n        ].concat(specialisation.toolbarButtonBehaviours))\n      });\n    };\n    var renderToolbarButton = function (spec, providersBackstage) {\n      return renderToolbarButtonWith(spec, providersBackstage, []);\n    };\n    var renderToolbarButtonWith = function (spec, providersBackstage, bonusEvents) {\n      return renderCommonToolbarButton(spec, {\n        toolbarButtonBehaviours: [].concat(bonusEvents.length > 0 ? [config('toolbarButtonWith', bonusEvents)] : []),\n        getApi: getButtonApi,\n        onSetup: spec.onSetup\n      }, providersBackstage);\n    };\n    var renderToolbarToggleButton = function (spec, providersBackstage) {\n      return renderToolbarToggleButtonWith(spec, providersBackstage, []);\n    };\n    var renderToolbarToggleButtonWith = function (spec, providersBackstage, bonusEvents) {\n      return deepMerge(renderCommonToolbarButton(spec, {\n        toolbarButtonBehaviours: [\n          Replacing.config({}),\n          Toggling.config({\n            toggleClass: 'tox-tbtn--enabled',\n            aria: { mode: 'pressed' },\n            toggleOnExecute: false\n          })\n        ].concat(bonusEvents.length > 0 ? [config('toolbarToggleButtonWith', bonusEvents)] : []),\n        getApi: getToggleApi,\n        onSetup: spec.onSetup\n      }, providersBackstage));\n    };\n    var fetchChoices = function (getApi, spec, providersBackstage) {\n      return function (comp) {\n        return Future.nu(function (callback) {\n          return spec.fetch(callback);\n        }).map(function (items) {\n          return Option.from(createTieredDataFrom(deepMerge(createPartialChoiceMenu(generate$1('menu-value'), items, function (value) {\n            spec.onItemAction(getApi(comp), value);\n          }, spec.columns, spec.presets, ItemResponse$1.CLOSE_ON_EXECUTE, spec.select.getOr(function () {\n            return false;\n          }), providersBackstage), {\n            movement: deriveMenuMovement(spec.columns, spec.presets),\n            menuBehaviours: SimpleBehaviours.unnamedEvents(spec.columns !== 'auto' ? [] : [runOnAttached(function (comp, se) {\n                detectSize(comp, 4, classForPreset(spec.presets)).each(function (_a) {\n                  var numRows = _a.numRows, numColumns = _a.numColumns;\n                  Keying.setGridSize(comp, numRows, numColumns);\n                });\n              })])\n          })));\n        });\n      };\n    };\n    var renderSplitButton = function (spec, sharedBackstage) {\n      var _a;\n      var displayChannel = generate$1('channel-update-split-dropdown-display');\n      var getApi = function (comp) {\n        return {\n          isDisabled: function () {\n            return Disabling.isDisabled(comp);\n          },\n          setDisabled: function (state) {\n            return Disabling.set(comp, state);\n          },\n          setIconFill: function (id, value) {\n            descendant$1(comp.element(), 'svg path[id=\"' + id + '\"], rect[id=\"' + id + '\"]').each(function (underlinePath) {\n              set$1(underlinePath, 'fill', value);\n            });\n          },\n          setIconStroke: function (id, value) {\n            descendant$1(comp.element(), 'svg path[id=\"' + id + '\"], rect[id=\"' + id + '\"]').each(function (underlinePath) {\n              set$1(underlinePath, 'stroke', value);\n            });\n          },\n          setActive: function (state) {\n            set$1(comp.element(), 'aria-pressed', state);\n            descendant$1(comp.element(), 'span').each(function (button) {\n              comp.getSystem().getByDom(button).each(function (buttonComp) {\n                return Toggling.set(buttonComp, state);\n              });\n            });\n          },\n          isActive: function () {\n            return descendant$1(comp.element(), 'span').exists(function (button) {\n              return comp.getSystem().getByDom(button).exists(Toggling.isOn);\n            });\n          }\n        };\n      };\n      var editorOffCell = Cell(noop);\n      var specialisation = {\n        getApi: getApi,\n        onSetup: spec.onSetup\n      };\n      return SplitDropdown.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-split-button'],\n          attributes: merge({ 'aria-pressed': false }, getTooltipAttributes(spec.tooltip, sharedBackstage.providers))\n        },\n        onExecute: function (button) {\n          spec.onAction(getApi(button));\n        },\n        onItemExecute: function (a, b, c) {\n        },\n        splitDropdownBehaviours: derive$1([\n          DisablingConfigs.splitButton(false),\n          config('split-dropdown-events', [\n            run(focusButtonEvent, Focusing.focus),\n            onControlAttached(specialisation, editorOffCell),\n            onControlDetached(specialisation, editorOffCell)\n          ]),\n          Unselecting.config({})\n        ]),\n        eventOrder: (_a = {}, _a[attachedToDom()] = [\n          'alloy.base.behaviour',\n          'split-dropdown-events'\n        ], _a),\n        toggleClass: 'tox-tbtn--enabled',\n        lazySink: sharedBackstage.getSink,\n        fetch: fetchChoices(getApi, spec, sharedBackstage.providers),\n        parts: { menu: part(false, spec.columns, spec.presets) },\n        components: [\n          SplitDropdown.parts().button(renderCommonStructure(spec.icon, spec.text, Option.none(), Option.some(displayChannel), Option.some([Toggling.config({\n              toggleClass: 'tox-tbtn--enabled',\n              toggleOnExecute: false\n            })]), sharedBackstage.providers)),\n          SplitDropdown.parts().arrow({\n            dom: {\n              tag: 'button',\n              classes: [\n                'tox-tbtn',\n                'tox-split-button__chevron'\n              ],\n              innerHtml: get$c('chevron-down', sharedBackstage.providers.icons)\n            }\n          }),\n          SplitDropdown.parts()['aria-descriptor']({ text: sharedBackstage.providers.translate('To open the popup, press Shift+Enter') })\n        ]\n      });\n    };\n\n    var getFormApi = function (input) {\n      return {\n        hide: function () {\n          return emit(input, sandboxClose());\n        },\n        getValue: function () {\n          return Representing.getValue(input);\n        }\n      };\n    };\n    var runOnExecute$1 = function (memInput, original) {\n      return run(internalToolbarButtonExecute, function (comp, se) {\n        var input = memInput.get(comp);\n        var formApi = getFormApi(input);\n        original.onAction(formApi, se.event().buttonApi());\n      });\n    };\n    var renderContextButton = function (memInput, button, extras) {\n      var _a = button.original, primary = _a.primary, rest = __rest(_a, ['primary']);\n      var bridged = getOrDie(createToolbarButton(__assign(__assign({}, rest), {\n        type: 'button',\n        onAction: function () {\n        }\n      })));\n      return renderToolbarButtonWith(bridged, extras.backstage.shared.providers, [runOnExecute$1(memInput, button)]);\n    };\n    var renderContextToggleButton = function (memInput, button, extras) {\n      var _a = button.original, primary = _a.primary, rest = __rest(_a, ['primary']);\n      var bridged = getOrDie(createToggleButton(__assign(__assign({}, rest), {\n        type: 'togglebutton',\n        onAction: function () {\n        }\n      })));\n      return renderToolbarToggleButtonWith(bridged, extras.backstage.shared.providers, [runOnExecute$1(memInput, button)]);\n    };\n    var generateOne$1 = function (memInput, button, providersBackstage) {\n      var extras = { backstage: { shared: { providers: providersBackstage } } };\n      if (button.type === 'contextformtogglebutton') {\n        return renderContextToggleButton(memInput, button, extras);\n      } else {\n        return renderContextButton(memInput, button, extras);\n      }\n    };\n    var generate$7 = function (memInput, buttons, providersBackstage) {\n      var mementos = map(buttons, function (button) {\n        return record(generateOne$1(memInput, button, providersBackstage));\n      });\n      var asSpecs = function () {\n        return map(mementos, function (mem) {\n          return mem.asSpec();\n        });\n      };\n      var findPrimary = function (compInSystem) {\n        return findMap(buttons, function (button, i) {\n          if (button.primary) {\n            return Option.from(mementos[i]).bind(function (mem) {\n              return mem.getOpt(compInSystem);\n            }).filter(not(Disabling.isDisabled));\n          } else {\n            return Option.none();\n          }\n        });\n      };\n      return {\n        asSpecs: asSpecs,\n        findPrimary: findPrimary\n      };\n    };\n\n    var renderContextForm = function (toolbarType, ctx, backstage) {\n      var inputAttributes = ctx.label.fold(function () {\n        return {};\n      }, function (label) {\n        return { 'aria-label': label };\n      });\n      var memInput = record(Input.sketch({\n        inputClasses: [\n          'tox-toolbar-textfield',\n          'tox-toolbar-nav-js'\n        ],\n        data: ctx.initValue(),\n        inputAttributes: inputAttributes,\n        selectOnFocus: true,\n        inputBehaviours: derive$1([Keying.config({\n            mode: 'special',\n            onEnter: function (input) {\n              return commands.findPrimary(input).map(function (primary) {\n                emitExecute(primary);\n                return true;\n              });\n            },\n            onLeft: function (comp, se) {\n              se.cut();\n              return Option.none();\n            },\n            onRight: function (comp, se) {\n              se.cut();\n              return Option.none();\n            }\n          })])\n      }));\n      var commands = generate$7(memInput, ctx.commands, backstage.shared.providers);\n      return renderToolbar({\n        type: toolbarType,\n        uid: generate$1('context-toolbar'),\n        initGroups: [\n          {\n            title: Option.none(),\n            items: [memInput.asSpec()]\n          },\n          {\n            title: Option.none(),\n            items: commands.asSpecs()\n          }\n        ],\n        onEscape: Option.none,\n        cyclicKeying: true,\n        backstage: backstage,\n        getSink: function () {\n          return Result.error('');\n        }\n      });\n    };\n    var ContextForm = { renderContextForm: renderContextForm };\n\n    var getHorizontalBounds = function (contentAreaBox, viewportBounds) {\n      var x = Math.max(viewportBounds.x(), contentAreaBox.x());\n      var contentBoxWidth = contentAreaBox.right() - x;\n      var maxViewportWidth = viewportBounds.width() - (x - viewportBounds.x());\n      var width = Math.min(contentBoxWidth, maxViewportWidth);\n      return {\n        x: x,\n        width: width\n      };\n    };\n    var getIframeBounds = function (editor, contentAreaBox, viewportBounds) {\n      var _a = getHorizontalBounds(contentAreaBox, viewportBounds), x = _a.x, width = _a.width;\n      var container = Element.fromDom(editor.getContainer());\n      var header = descendant$1(container, '.tox-editor-header').getOr(container);\n      var containerBox = box(container);\n      var headerBox = box(header);\n      var y = Math.max(viewportBounds.y(), contentAreaBox.y(), headerBox.bottom());\n      var contentBoxHeight = containerBox.bottom() - y;\n      var maxViewportHeight = viewportBounds.height() - (y - viewportBounds.y());\n      var height = Math.min(contentBoxHeight, maxViewportHeight);\n      return bounds$1(x, y, width, height);\n    };\n    var getInlineBounds = function (editor, contentAreaBox, viewportBounds) {\n      var _a = getHorizontalBounds(contentAreaBox, viewportBounds), x = _a.x, width = _a.width;\n      var container = Element.fromDom(editor.getContainer());\n      var header = descendant$1(container, '.tox-editor-header').getOr(container);\n      var headerBox = box(header);\n      var vpHeight = viewportBounds.height();\n      var vpTop = viewportBounds.y();\n      if (headerBox.y() >= contentAreaBox.bottom()) {\n        var bottom = Math.min(vpHeight + vpTop, headerBox.y());\n        var height = bottom - vpTop;\n        return bounds$1(x, vpTop, width, height);\n      } else {\n        var y = Math.max(vpTop, headerBox.bottom());\n        var height = vpHeight - (y - vpTop);\n        return bounds$1(x, y, width, height);\n      }\n    };\n    var getDistractionFreeBounds = function (_editor, contentAreaBox, viewportBounds) {\n      var _a = getHorizontalBounds(contentAreaBox, viewportBounds), x = _a.x, width = _a.width;\n      return bounds$1(x, viewportBounds.y(), width, viewportBounds.height());\n    };\n    var getContextToolbarBounds = function (editor) {\n      var toolbarOrMenubarEnabled = isMenubarEnabled(editor) || isToolbarEnabled(editor) || isMultipleToolbars(editor);\n      var viewportBounds = getBounds(domGlobals.window);\n      var contentAreaBox = box(Element.fromDom(editor.getContentAreaContainer()));\n      if (editor.inline && !toolbarOrMenubarEnabled) {\n        return getDistractionFreeBounds(editor, contentAreaBox, viewportBounds);\n      } else if (editor.inline) {\n        return getInlineBounds(editor, contentAreaBox, viewportBounds);\n      } else {\n        return getIframeBounds(editor, contentAreaBox, viewportBounds);\n      }\n    };\n\n    var ancestor$2 = function (scope, transform, isRoot) {\n      var element = scope.dom();\n      var stop = isFunction(isRoot) ? isRoot : constant(false);\n      while (element.parentNode) {\n        element = element.parentNode;\n        var el = Element.fromDom(element);\n        var transformed = transform(el);\n        if (transformed.isSome()) {\n          return transformed;\n        } else if (stop(el)) {\n          break;\n        }\n      }\n      return Option.none();\n    };\n\n    var matchTargetWith = function (elem, toolbars) {\n      return findMap(toolbars, function (toolbarApi) {\n        return toolbarApi.predicate(elem.dom()) ? Option.some({\n          toolbarApi: toolbarApi,\n          elem: elem\n        }) : Option.none();\n      });\n    };\n    var lookup$1 = function (scopes, editor) {\n      var isRoot = function (elem) {\n        return elem.dom() === editor.getBody();\n      };\n      var startNode = Element.fromDom(editor.selection.getNode());\n      return matchTargetWith(startNode, scopes.inNodeScope).orThunk(function () {\n        return matchTargetWith(startNode, scopes.inEditorScope).orThunk(function () {\n          return ancestor$2(startNode, function (elem) {\n            return matchTargetWith(elem, scopes.inNodeScope);\n          }, isRoot);\n        });\n      });\n    };\n    var ToolbarLookup = { lookup: lookup$1 };\n\n    var categorise = function (contextToolbars, navigate) {\n      var forms = {};\n      var inNodeScope = [];\n      var inEditorScope = [];\n      var formNavigators = {};\n      var lookupTable = {};\n      var registerForm = function (key, toolbarApi) {\n        var contextForm = getOrDie(createContextForm(toolbarApi));\n        forms[key] = contextForm;\n        contextForm.launch.map(function (launch) {\n          formNavigators['form:' + key + ''] = __assign(__assign({}, toolbarApi.launch), {\n            type: launch.type === 'contextformtogglebutton' ? 'togglebutton' : 'button',\n            onAction: function () {\n              navigate(contextForm);\n            }\n          });\n        });\n        if (contextForm.scope === 'editor') {\n          inEditorScope.push(contextForm);\n        } else {\n          inNodeScope.push(contextForm);\n        }\n        lookupTable[key] = contextForm;\n      };\n      var registerToolbar = function (key, toolbarApi) {\n        createContextToolbar(toolbarApi).each(function (contextToolbar) {\n          if (toolbarApi.scope === 'editor') {\n            inEditorScope.push(contextToolbar);\n          } else {\n            inNodeScope.push(contextToolbar);\n          }\n          lookupTable[key] = contextToolbar;\n        });\n      };\n      var keys$1 = keys(contextToolbars);\n      each(keys$1, function (key) {\n        var toolbarApi = contextToolbars[key];\n        if (toolbarApi.type === 'contextform') {\n          registerForm(key, toolbarApi);\n        } else if (toolbarApi.type === 'contexttoolbar') {\n          registerToolbar(key, toolbarApi);\n        }\n      });\n      return {\n        forms: forms,\n        inNodeScope: inNodeScope,\n        inEditorScope: inEditorScope,\n        lookupTable: lookupTable,\n        formNavigators: formNavigators\n      };\n    };\n    var ToolbarScopes = { categorise: categorise };\n\n    var forwardSlideEvent = generate$1('forward-slide');\n    var backSlideEvent = generate$1('backward-slide');\n    var changeSlideEvent = generate$1('change-slide-event');\n    var resizingClass = 'tox-pop--resizing';\n    var renderContextToolbar = function (spec) {\n      var stack = Cell([]);\n      return InlineView.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-pop']\n        },\n        fireDismissalEventInstead: { event: 'doNotDismissYet' },\n        onShow: function (comp) {\n          stack.set([]);\n          InlineView.getContent(comp).each(function (c) {\n            remove$6(c.element(), 'visibility');\n          });\n          remove$4(comp.element(), resizingClass);\n          remove$6(comp.element(), 'width');\n        },\n        inlineBehaviours: derive$1([\n          config('context-toolbar-events', [\n            runOnSource(transitionend(), function (comp, se) {\n              InlineView.getContent(comp).each(function (c) {\n              });\n              remove$4(comp.element(), resizingClass);\n              remove$6(comp.element(), 'width');\n            }),\n            run(changeSlideEvent, function (comp, se) {\n              remove$6(comp.element(), 'width');\n              var currentWidth = get$7(comp.element());\n              InlineView.setContent(comp, se.event().contents());\n              add$2(comp.element(), resizingClass);\n              var newWidth = get$7(comp.element());\n              set$2(comp.element(), 'width', currentWidth + 'px');\n              InlineView.getContent(comp).each(function (newContents) {\n                se.event().focus().bind(function (f) {\n                  focus$1(f);\n                  return search(comp.element());\n                }).orThunk(function () {\n                  Keying.focusIn(newContents);\n                  return active();\n                });\n              });\n              global$2.setTimeout(function () {\n                set$2(comp.element(), 'width', newWidth + 'px');\n              }, 0);\n            }),\n            run(forwardSlideEvent, function (comp, se) {\n              InlineView.getContent(comp).each(function (oldContents) {\n                stack.set(stack.get().concat([{\n                    bar: oldContents,\n                    focus: active()\n                  }]));\n              });\n              emitWith(comp, changeSlideEvent, {\n                contents: se.event().forwardContents(),\n                focus: Option.none()\n              });\n            }),\n            run(backSlideEvent, function (comp, se) {\n              last(stack.get()).each(function (last) {\n                stack.set(stack.get().slice(0, stack.get().length - 1));\n                emitWith(comp, changeSlideEvent, {\n                  contents: premade$1(last.bar),\n                  focus: last.focus\n                });\n              });\n            })\n          ]),\n          Keying.config({\n            mode: 'special',\n            onEscape: function (comp) {\n              return last(stack.get()).fold(function () {\n                return spec.onEscape();\n              }, function (_) {\n                emit(comp, backSlideEvent);\n                return Option.some(true);\n              });\n            }\n          })\n        ]),\n        lazySink: function () {\n          return Result.value(spec.sink);\n        }\n      });\n    };\n\n    var onSetupFormatToggle = function (editor, name) {\n      return function (api) {\n        var unbindCell = Cell(Option.none());\n        var init = function () {\n          api.setActive(editor.formatter.match(name));\n          var unbind = editor.formatter.formatChanged(name, api.setActive).unbind;\n          unbindCell.set(Option.some(unbind));\n        };\n        editor.initialized ? init() : editor.on('init', init);\n        return function () {\n          return unbindCell.get().each(function (unbind) {\n            return unbind();\n          });\n        };\n      };\n    };\n    var onActionToggleFormat = function (editor) {\n      return function (rawItem) {\n        return function () {\n          editor.undoManager.transact(function () {\n            editor.focus();\n            editor.execCommand('mceToggleFormat', false, rawItem.format);\n          });\n        };\n      };\n    };\n\n    var generateSelectItems = function (_editor, backstage, spec) {\n      var generateItem = function (rawItem, response, disabled, value) {\n        var translatedText = backstage.shared.providers.translate(rawItem.title);\n        if (rawItem.type === 'separator') {\n          return Option.some({\n            type: 'separator',\n            text: translatedText\n          });\n        } else if (rawItem.type === 'submenu') {\n          var items = bind(rawItem.getStyleItems(), function (si) {\n            return validate(si, response, value);\n          });\n          if (response === 0 && items.length <= 0) {\n            return Option.none();\n          } else {\n            return Option.some({\n              type: 'nestedmenuitem',\n              text: translatedText,\n              disabled: items.length <= 0,\n              getSubmenuItems: function () {\n                return bind(rawItem.getStyleItems(), function (si) {\n                  return validate(si, response, value);\n                });\n              }\n            });\n          }\n        } else {\n          return Option.some(__assign({\n            type: 'togglemenuitem',\n            text: translatedText,\n            active: rawItem.isSelected(value),\n            disabled: disabled,\n            onAction: spec.onAction(rawItem)\n          }, rawItem.getStylePreview().fold(function () {\n            return {};\n          }, function (preview) {\n            return { meta: { style: preview } };\n          })));\n        }\n      };\n      var validate = function (item, response, value) {\n        var invalid = item.type === 'formatter' && spec.isInvalid(item);\n        if (response === 0) {\n          return invalid ? [] : generateItem(item, response, false, value).toArray();\n        } else {\n          return generateItem(item, response, invalid, value).toArray();\n        }\n      };\n      var validateItems = function (preItems) {\n        var value = spec.getCurrentValue();\n        var response = spec.shouldHide ? 0 : 1;\n        return bind(preItems, function (item) {\n          return validate(item, response, value);\n        });\n      };\n      var getFetch = function (backstage, getStyleItems) {\n        return function (callback) {\n          var preItems = getStyleItems();\n          var items = validateItems(preItems);\n          var menu = build$2(items, ItemResponse$1.CLOSE_ON_EXECUTE, backstage, false);\n          callback(menu);\n        };\n      };\n      return {\n        validateItems: validateItems,\n        getFetch: getFetch\n      };\n    };\n    var createMenuItems = function (editor, backstage, spec) {\n      var dataset = spec.dataset;\n      var getStyleItems = dataset.type === 'basic' ? function () {\n        return map(dataset.data, function (d) {\n          return processBasic(d, spec.isSelectedFor, spec.getPreviewFor);\n        });\n      } : dataset.getData;\n      return {\n        items: generateSelectItems(editor, backstage, spec),\n        getStyleItems: getStyleItems\n      };\n    };\n    var createSelectButton = function (editor, backstage, spec) {\n      var _a = createMenuItems(editor, backstage, spec), items = _a.items, getStyleItems = _a.getStyleItems;\n      var getApi = function (comp) {\n        return {\n          getComponent: function () {\n            return comp;\n          }\n        };\n      };\n      var onSetup = function (api) {\n        spec.setInitialValue.each(function (f) {\n          return f(api.getComponent());\n        });\n        return spec.nodeChangeHandler.map(function (f) {\n          var handler = f(api.getComponent());\n          editor.on('NodeChange', handler);\n          return function () {\n            editor.off('NodeChange', handler);\n          };\n        }).getOr(noop);\n      };\n      return renderCommonDropdown({\n        text: spec.icon.isSome() ? Option.none() : Option.some(''),\n        icon: spec.icon,\n        tooltip: Option.from(spec.tooltip),\n        role: Option.none(),\n        fetch: items.getFetch(backstage, getStyleItems),\n        onSetup: onSetup,\n        getApi: getApi,\n        columns: 1,\n        presets: 'normal',\n        classes: spec.icon.isSome() ? [] : ['bespoke'],\n        dropdownBehaviours: []\n      }, 'tox-tbtn', backstage.shared);\n    };\n\n    var process = function (rawFormats) {\n      return map(rawFormats, function (item) {\n        var title = item, format = item;\n        var values = item.split('=');\n        if (values.length > 1) {\n          title = values[0];\n          format = values[1];\n        }\n        return {\n          title: title,\n          format: format\n        };\n      });\n    };\n    var buildBasicStaticDataset = function (data) {\n      return {\n        type: 'basic',\n        data: data\n      };\n    };\n    var Delimiter;\n    (function (Delimiter) {\n      Delimiter[Delimiter['SemiColon'] = 0] = 'SemiColon';\n      Delimiter[Delimiter['Space'] = 1] = 'Space';\n    }(Delimiter || (Delimiter = {})));\n    var split = function (rawFormats, delimiter) {\n      if (delimiter === Delimiter.SemiColon) {\n        return rawFormats.replace(/;$/, '').split(';');\n      } else {\n        return rawFormats.split(' ');\n      }\n    };\n    var buildBasicSettingsDataset = function (editor, settingName, defaults, delimiter) {\n      var rawFormats = readOptFrom$1(editor.settings, settingName).getOr(defaults);\n      var data = process(split(rawFormats, delimiter));\n      return {\n        type: 'basic',\n        data: data\n      };\n    };\n\n    var alignMenuItems = [\n      {\n        title: 'Left',\n        icon: 'align-left',\n        format: 'alignleft'\n      },\n      {\n        title: 'Center',\n        icon: 'align-center',\n        format: 'aligncenter'\n      },\n      {\n        title: 'Right',\n        icon: 'align-right',\n        format: 'alignright'\n      },\n      {\n        title: 'Justify',\n        icon: 'align-justify',\n        format: 'alignjustify'\n      }\n    ];\n    var getSpec = function (editor) {\n      var getMatchingValue = function () {\n        return find(alignMenuItems, function (item) {\n          return editor.formatter.match(item.format);\n        });\n      };\n      var isSelectedFor = function (format) {\n        return function () {\n          return editor.formatter.match(format);\n        };\n      };\n      var getPreviewFor = function (_format) {\n        return function () {\n          return Option.none();\n        };\n      };\n      var updateSelectMenuIcon = function (comp) {\n        var match = getMatchingValue();\n        var alignment = match.fold(function () {\n          return 'left';\n        }, function (item) {\n          return item.title.toLowerCase();\n        });\n        emitWith(comp, updateMenuIcon, { icon: 'align-' + alignment });\n      };\n      var nodeChangeHandler = Option.some(function (comp) {\n        return function () {\n          return updateSelectMenuIcon(comp);\n        };\n      });\n      var setInitialValue = Option.some(function (comp) {\n        return updateSelectMenuIcon(comp);\n      });\n      var dataset = buildBasicStaticDataset(alignMenuItems);\n      return {\n        tooltip: 'Align',\n        icon: Option.some('align-left'),\n        isSelectedFor: isSelectedFor,\n        getCurrentValue: constant(Option.none()),\n        getPreviewFor: getPreviewFor,\n        onAction: onActionToggleFormat(editor),\n        setInitialValue: setInitialValue,\n        nodeChangeHandler: nodeChangeHandler,\n        dataset: dataset,\n        shouldHide: false,\n        isInvalid: function (item) {\n          return !editor.formatter.canApply(item.format);\n        }\n      };\n    };\n    var createAlignSelect = function (editor, backstage) {\n      return createSelectButton(editor, backstage, getSpec(editor));\n    };\n    var alignSelectMenu = function (editor, backstage) {\n      var menuItems = createMenuItems(editor, backstage, getSpec(editor));\n      editor.ui.registry.addNestedMenuItem('align', {\n        text: backstage.shared.providers.translate('Align'),\n        getSubmenuItems: function () {\n          return menuItems.items.validateItems(menuItems.getStyleItems());\n        }\n      });\n    };\n\n    var defaultFontsFormats = 'Andale Mono=andale mono,monospace;' + 'Arial=arial,helvetica,sans-serif;' + 'Arial Black=arial black,sans-serif;' + 'Book Antiqua=book antiqua,palatino,serif;' + 'Comic Sans MS=comic sans ms,sans-serif;' + 'Courier New=courier new,courier,monospace;' + 'Georgia=georgia,palatino,serif;' + 'Helvetica=helvetica,arial,sans-serif;' + 'Impact=impact,sans-serif;' + 'Symbol=symbol;' + 'Tahoma=tahoma,arial,helvetica,sans-serif;' + 'Terminal=terminal,monaco,monospace;' + 'Times New Roman=times new roman,times,serif;' + 'Trebuchet MS=trebuchet ms,geneva,sans-serif;' + 'Verdana=verdana,geneva,sans-serif;' + 'Webdings=webdings;' + 'Wingdings=wingdings,zapf dingbats';\n    var systemStackFonts = [\n      '-apple-system',\n      'Segoe UI',\n      'Roboto',\n      'Helvetica Neue',\n      'sans-serif'\n    ];\n    var splitFonts = function (fontFamily) {\n      var fonts = fontFamily.split(/\\s*,\\s*/);\n      return map(fonts, function (font) {\n        return font.replace(/^['\"]+|['\"]+$/g, '');\n      });\n    };\n    var isSystemFontStack = function (fontFamily) {\n      var matchesSystemStack = function () {\n        var fonts = splitFonts(fontFamily.toLowerCase());\n        return forall(systemStackFonts, function (font) {\n          return fonts.indexOf(font.toLowerCase()) > -1;\n        });\n      };\n      return fontFamily.indexOf('-apple-system') === 0 && matchesSystemStack();\n    };\n    var getSpec$1 = function (editor) {\n      var getMatchingValue = function () {\n        var getFirstFont = function (fontFamily) {\n          return fontFamily ? splitFonts(fontFamily)[0] : '';\n        };\n        var fontFamily = editor.queryCommandValue('FontName');\n        var items = dataset.data;\n        var font = fontFamily ? fontFamily.toLowerCase() : '';\n        var matchOpt = find(items, function (item) {\n          var format = item.format;\n          return format.toLowerCase() === font || getFirstFont(format).toLowerCase() === getFirstFont(font).toLowerCase();\n        }).orThunk(function () {\n          if (isSystemFontStack(font)) {\n            return Option.from({\n              title: 'System Font',\n              format: font\n            });\n          } else {\n            return Option.none();\n          }\n        });\n        return {\n          matchOpt: matchOpt,\n          font: fontFamily\n        };\n      };\n      var isSelectedFor = function (item) {\n        return function (valueOpt) {\n          return valueOpt.exists(function (value) {\n            return value.format === item;\n          });\n        };\n      };\n      var getCurrentValue = function () {\n        var matchOpt = getMatchingValue().matchOpt;\n        return matchOpt;\n      };\n      var getPreviewFor = function (item) {\n        return function () {\n          return Option.some({\n            tag: 'div',\n            styleAttr: item.indexOf('dings') === -1 ? 'font-family:' + item : ''\n          });\n        };\n      };\n      var onAction = function (rawItem) {\n        return function () {\n          editor.undoManager.transact(function () {\n            editor.focus();\n            editor.execCommand('FontName', false, rawItem.format);\n          });\n        };\n      };\n      var updateSelectMenuText = function (comp) {\n        var _a = getMatchingValue(), matchOpt = _a.matchOpt, font = _a.font;\n        var text = matchOpt.fold(function () {\n          return font;\n        }, function (item) {\n          return item.title;\n        });\n        emitWith(comp, updateMenuText, { text: text });\n      };\n      var nodeChangeHandler = Option.some(function (comp) {\n        return function () {\n          return updateSelectMenuText(comp);\n        };\n      });\n      var setInitialValue = Option.some(function (comp) {\n        return updateSelectMenuText(comp);\n      });\n      var dataset = buildBasicSettingsDataset(editor, 'font_formats', defaultFontsFormats, Delimiter.SemiColon);\n      return {\n        tooltip: 'Fonts',\n        icon: Option.none(),\n        isSelectedFor: isSelectedFor,\n        getCurrentValue: getCurrentValue,\n        getPreviewFor: getPreviewFor,\n        onAction: onAction,\n        setInitialValue: setInitialValue,\n        nodeChangeHandler: nodeChangeHandler,\n        dataset: dataset,\n        shouldHide: false,\n        isInvalid: function () {\n          return false;\n        }\n      };\n    };\n    var createFontSelect = function (editor, backstage) {\n      return createSelectButton(editor, backstage, getSpec$1(editor));\n    };\n    var fontSelectMenu = function (editor, backstage) {\n      var menuItems = createMenuItems(editor, backstage, getSpec$1(editor));\n      editor.ui.registry.addNestedMenuItem('fontformats', {\n        text: backstage.shared.providers.translate('Fonts'),\n        getSubmenuItems: function () {\n          return menuItems.items.validateItems(menuItems.getStyleItems());\n        }\n      });\n    };\n\n    var defaultFontsizeFormats = '8pt 10pt 12pt 14pt 18pt 24pt 36pt';\n    var legacyFontSizes = {\n      '8pt': '1',\n      '10pt': '2',\n      '12pt': '3',\n      '14pt': '4',\n      '18pt': '5',\n      '24pt': '6',\n      '36pt': '7'\n    };\n    var round$1 = function (number, precision) {\n      var factor = Math.pow(10, precision);\n      return Math.round(number * factor) / factor;\n    };\n    var toPt = function (fontSize, precision) {\n      if (/[0-9.]+px$/.test(fontSize)) {\n        return round$1(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt';\n      }\n      return fontSize;\n    };\n    var toLegacy = function (fontSize) {\n      return get(legacyFontSizes, fontSize).getOr('');\n    };\n    var getSpec$2 = function (editor) {\n      var getMatchingValue = function () {\n        var matchOpt = Option.none();\n        var items = dataset.data;\n        var px = editor.queryCommandValue('FontSize');\n        if (px) {\n          var _loop_1 = function (precision) {\n            var pt = toPt(px, precision);\n            var legacy = toLegacy(pt);\n            matchOpt = find(items, function (item) {\n              return item.format === px || item.format === pt || item.format === legacy;\n            });\n          };\n          for (var precision = 3; matchOpt.isNone() && precision >= 0; precision--) {\n            _loop_1(precision);\n          }\n        }\n        return {\n          matchOpt: matchOpt,\n          px: px\n        };\n      };\n      var isSelectedFor = function (item) {\n        return function (valueOpt) {\n          return valueOpt.exists(function (value) {\n            return value.format === item;\n          });\n        };\n      };\n      var getCurrentValue = function () {\n        var matchOpt = getMatchingValue().matchOpt;\n        return matchOpt;\n      };\n      var getPreviewFor = constant(constant(Option.none()));\n      var onAction = function (rawItem) {\n        return function () {\n          editor.undoManager.transact(function () {\n            editor.focus();\n            editor.execCommand('FontSize', false, rawItem.format);\n          });\n        };\n      };\n      var updateSelectMenuText = function (comp) {\n        var _a = getMatchingValue(), matchOpt = _a.matchOpt, px = _a.px;\n        var text = matchOpt.fold(function () {\n          return px;\n        }, function (match) {\n          return match.title;\n        });\n        emitWith(comp, updateMenuText, { text: text });\n      };\n      var nodeChangeHandler = Option.some(function (comp) {\n        return function () {\n          return updateSelectMenuText(comp);\n        };\n      });\n      var setInitialValue = Option.some(function (comp) {\n        return updateSelectMenuText(comp);\n      });\n      var dataset = buildBasicSettingsDataset(editor, 'fontsize_formats', defaultFontsizeFormats, Delimiter.Space);\n      return {\n        tooltip: 'Font sizes',\n        icon: Option.none(),\n        isSelectedFor: isSelectedFor,\n        getPreviewFor: getPreviewFor,\n        getCurrentValue: getCurrentValue,\n        onAction: onAction,\n        setInitialValue: setInitialValue,\n        nodeChangeHandler: nodeChangeHandler,\n        dataset: dataset,\n        shouldHide: false,\n        isInvalid: function () {\n          return false;\n        }\n      };\n    };\n    var createFontsizeSelect = function (editor, backstage) {\n      return createSelectButton(editor, backstage, getSpec$2(editor));\n    };\n    var fontsizeSelectMenu = function (editor, backstage) {\n      var menuItems = createMenuItems(editor, backstage, getSpec$2(editor));\n      editor.ui.registry.addNestedMenuItem('fontsizes', {\n        text: 'Font sizes',\n        getSubmenuItems: function () {\n          return menuItems.items.validateItems(menuItems.getStyleItems());\n        }\n      });\n    };\n\n    var findNearest = function (editor, getStyles, parents) {\n      var styles = getStyles();\n      return findMap(parents, function (parent) {\n        return find(styles, function (fmt) {\n          return editor.formatter.matchNode(parent, fmt.format);\n        });\n      }).orThunk(function () {\n        if (editor.formatter.match('p')) {\n          return Option.some({\n            title: 'Paragraph',\n            format: 'p'\n          });\n        }\n        return Option.none();\n      });\n    };\n    var getCurrentSelectionParents = function (editor) {\n      var currentNode = editor.selection.getStart(true) || editor.getBody();\n      return editor.dom.getParents(currentNode, function () {\n        return true;\n      }, editor.getBody());\n    };\n\n    var defaultBlocks = 'Paragraph=p;' + 'Heading 1=h1;' + 'Heading 2=h2;' + 'Heading 3=h3;' + 'Heading 4=h4;' + 'Heading 5=h5;' + 'Heading 6=h6;' + 'Preformatted=pre';\n    var getSpec$3 = function (editor) {\n      var getMatchingValue = function (nodeChangeEvent) {\n        return findNearest(editor, function () {\n          return dataset.data;\n        }, nodeChangeEvent);\n      };\n      var isSelectedFor = function (format) {\n        return function () {\n          return editor.formatter.match(format);\n        };\n      };\n      var getPreviewFor = function (format) {\n        return function () {\n          var fmt = editor.formatter.get(format);\n          return Option.some({\n            tag: fmt.length > 0 ? fmt[0].inline || fmt[0].block || 'div' : 'div',\n            styleAttr: editor.formatter.getCssText(format)\n          });\n        };\n      };\n      var updateSelectMenuText = function (parents, comp) {\n        var detectedFormat = getMatchingValue(parents);\n        var text = detectedFormat.fold(function () {\n          return 'Paragraph';\n        }, function (fmt) {\n          return fmt.title;\n        });\n        emitWith(comp, updateMenuText, { text: text });\n      };\n      var nodeChangeHandler = Option.some(function (comp) {\n        return function (e) {\n          return updateSelectMenuText(e.parents, comp);\n        };\n      });\n      var setInitialValue = Option.some(function (comp) {\n        var parents = getCurrentSelectionParents(editor);\n        updateSelectMenuText(parents, comp);\n      });\n      var dataset = buildBasicSettingsDataset(editor, 'block_formats', defaultBlocks, Delimiter.SemiColon);\n      return {\n        tooltip: 'Blocks',\n        icon: Option.none(),\n        isSelectedFor: isSelectedFor,\n        getCurrentValue: constant(Option.none()),\n        getPreviewFor: getPreviewFor,\n        onAction: onActionToggleFormat(editor),\n        setInitialValue: setInitialValue,\n        nodeChangeHandler: nodeChangeHandler,\n        dataset: dataset,\n        shouldHide: false,\n        isInvalid: function (item) {\n          return !editor.formatter.canApply(item.format);\n        }\n      };\n    };\n    var createFormatSelect = function (editor, backstage) {\n      return createSelectButton(editor, backstage, getSpec$3(editor));\n    };\n    var formatSelectMenu = function (editor, backstage) {\n      var menuItems = createMenuItems(editor, backstage, getSpec$3(editor));\n      editor.ui.registry.addNestedMenuItem('blockformats', {\n        text: 'Blocks',\n        getSubmenuItems: function () {\n          return menuItems.items.validateItems(menuItems.getStyleItems());\n        }\n      });\n    };\n\n    var getSpec$4 = function (editor, dataset) {\n      var isSelectedFor = function (format) {\n        return function () {\n          return editor.formatter.match(format);\n        };\n      };\n      var getPreviewFor = function (format) {\n        return function () {\n          var fmt = editor.formatter.get(format);\n          return fmt !== undefined ? Option.some({\n            tag: fmt.length > 0 ? fmt[0].inline || fmt[0].block || 'div' : 'div',\n            styleAttr: editor.formatter.getCssText(format)\n          }) : Option.none();\n        };\n      };\n      var updateSelectMenuText = function (parents, comp) {\n        var getFormatItems = function (fmt) {\n          var subs = fmt.items;\n          return subs !== undefined && subs.length > 0 ? bind(subs, getFormatItems) : [{\n              title: fmt.title,\n              format: fmt.format\n            }];\n        };\n        var flattenedItems = bind(getStyleFormats(editor), getFormatItems);\n        var detectedFormat = findNearest(editor, function () {\n          return flattenedItems;\n        }, parents);\n        var text = detectedFormat.fold(function () {\n          return 'Paragraph';\n        }, function (fmt) {\n          return fmt.title;\n        });\n        emitWith(comp, updateMenuText, { text: text });\n      };\n      var nodeChangeHandler = Option.some(function (comp) {\n        return function (e) {\n          return updateSelectMenuText(e.parents, comp);\n        };\n      });\n      var setInitialValue = Option.some(function (comp) {\n        var parents = getCurrentSelectionParents(editor);\n        updateSelectMenuText(parents, comp);\n      });\n      return {\n        tooltip: 'Formats',\n        icon: Option.none(),\n        isSelectedFor: isSelectedFor,\n        getCurrentValue: constant(Option.none()),\n        getPreviewFor: getPreviewFor,\n        onAction: onActionToggleFormat(editor),\n        setInitialValue: setInitialValue,\n        nodeChangeHandler: nodeChangeHandler,\n        shouldHide: editor.getParam('style_formats_autohide', false, 'boolean'),\n        isInvalid: function (item) {\n          return !editor.formatter.canApply(item.format);\n        },\n        dataset: dataset\n      };\n    };\n    var createStyleSelect = function (editor, backstage) {\n      var dataset = __assign({ type: 'advanced' }, backstage.styleselect);\n      return createSelectButton(editor, backstage, getSpec$4(editor, dataset));\n    };\n    var styleSelectMenu = function (editor, backstage) {\n      var dataset = __assign({ type: 'advanced' }, backstage.styleselect);\n      var menuItems = createMenuItems(editor, backstage, getSpec$4(editor, dataset));\n      editor.ui.registry.addNestedMenuItem('formats', {\n        text: 'Formats',\n        getSubmenuItems: function () {\n          return menuItems.items.validateItems(menuItems.getStyleItems());\n        }\n      });\n    };\n\n    var defaultToolbar = [\n      {\n        name: 'history',\n        items: [\n          'undo',\n          'redo'\n        ]\n      },\n      {\n        name: 'styles',\n        items: ['styleselect']\n      },\n      {\n        name: 'formatting',\n        items: [\n          'bold',\n          'italic'\n        ]\n      },\n      {\n        name: 'alignment',\n        items: [\n          'alignleft',\n          'aligncenter',\n          'alignright',\n          'alignjustify'\n        ]\n      },\n      {\n        name: 'indentation',\n        items: [\n          'outdent',\n          'indent'\n        ]\n      },\n      {\n        name: 'permanent pen',\n        items: ['permanentpen']\n      },\n      {\n        name: 'comments',\n        items: ['addcomment']\n      }\n    ];\n    var renderFromBridge = function (bridgeBuilder, render) {\n      return function (spec, extras) {\n        var internal = bridgeBuilder(spec).mapError(function (errInfo) {\n          return formatError(errInfo);\n        }).getOrDie();\n        return render(internal, extras);\n      };\n    };\n    var types = {\n      button: renderFromBridge(createToolbarButton, function (s, extras) {\n        return renderToolbarButton(s, extras.backstage.shared.providers);\n      }),\n      togglebutton: renderFromBridge(createToggleButton, function (s, extras) {\n        return renderToolbarToggleButton(s, extras.backstage.shared.providers);\n      }),\n      menubutton: renderFromBridge(createMenuButton, function (s, extras) {\n        return renderMenuButton(s, 'tox-tbtn', extras.backstage, Option.none());\n      }),\n      splitbutton: renderFromBridge(createSplitButton, function (s, extras) {\n        return renderSplitButton(s, extras.backstage.shared);\n      }),\n      styleSelectButton: function (editor, extras) {\n        return createStyleSelect(editor, extras.backstage);\n      },\n      fontsizeSelectButton: function (editor, extras) {\n        return createFontsizeSelect(editor, extras.backstage);\n      },\n      fontSelectButton: function (editor, extras) {\n        return createFontSelect(editor, extras.backstage);\n      },\n      formatButton: function (editor, extras) {\n        return createFormatSelect(editor, extras.backstage);\n      },\n      alignMenuButton: function (editor, extras) {\n        return createAlignSelect(editor, extras.backstage);\n      }\n    };\n    var extractFrom = function (spec, extras) {\n      return get(types, spec.type).fold(function () {\n        domGlobals.console.error('skipping button defined by', spec);\n        return Option.none();\n      }, function (render) {\n        return Option.some(render(spec, extras));\n      });\n    };\n    var bespokeButtons = {\n      styleselect: types.styleSelectButton,\n      fontsizeselect: types.fontsizeSelectButton,\n      fontselect: types.fontSelectButton,\n      formatselect: types.formatButton,\n      align: types.alignMenuButton\n    };\n    var removeUnusedDefaults = function (buttons) {\n      var filteredItemGroups = map(defaultToolbar, function (group) {\n        var items = filter(group.items, function (subItem) {\n          return has(buttons, subItem) || has(bespokeButtons, subItem);\n        });\n        return {\n          name: group.name,\n          items: items\n        };\n      });\n      return filter(filteredItemGroups, function (group) {\n        return group.items.length > 0;\n      });\n    };\n    var convertStringToolbar = function (strToolbar) {\n      var groupsStrings = strToolbar.split('|');\n      return map(groupsStrings, function (g) {\n        return { items: g.trim().split(' ') };\n      });\n    };\n    var isToolbarGroupSettingArray = function (toolbar) {\n      return isArrayOf(toolbar, function (t) {\n        return has(t, 'name') && has(t, 'items');\n      });\n    };\n    var createToolbar = function (toolbarConfig) {\n      var toolbar = toolbarConfig.toolbar;\n      var buttons = toolbarConfig.buttons;\n      if (toolbar === false) {\n        return [];\n      } else if (toolbar === undefined || toolbar === true) {\n        return removeUnusedDefaults(buttons);\n      } else if (isString(toolbar)) {\n        return convertStringToolbar(toolbar);\n      } else if (isToolbarGroupSettingArray(toolbar)) {\n        return toolbar;\n      } else {\n        domGlobals.console.error('Toolbar type should be string, string[], boolean or ToolbarGroup[]');\n        return [];\n      }\n    };\n    var lookupButton = function (editor, buttons, toolbarItem, extras, prefixes) {\n      return get(buttons, toolbarItem.toLowerCase()).orThunk(function () {\n        return prefixes.bind(function (ps) {\n          return findMap(ps, function (prefix) {\n            return get(buttons, prefix + toolbarItem.toLowerCase());\n          });\n        });\n      }).fold(function () {\n        return get(bespokeButtons, toolbarItem.toLowerCase()).map(function (r) {\n          return r(editor, extras);\n        }).orThunk(function () {\n          return Option.none();\n        });\n      }, function (spec) {\n        return extractFrom(spec, extras);\n      });\n    };\n    var identifyButtons = function (editor, toolbarConfig, extras, prefixes) {\n      var toolbarGroups = createToolbar(toolbarConfig);\n      var groups = map(toolbarGroups, function (group) {\n        var items = bind(group.items, function (toolbarItem) {\n          return toolbarItem.trim().length === 0 ? [] : lookupButton(editor, toolbarConfig.buttons, toolbarItem, extras, prefixes).toArray();\n        });\n        return {\n          title: Option.from(editor.translate(group.name)),\n          items: items\n        };\n      });\n      return filter(groups, function (group) {\n        return group.items.length > 0;\n      });\n    };\n\n    var bubbleSize = 12;\n    var bubbleAlignments$1 = {\n      valignCentre: [],\n      alignCentre: [],\n      alignLeft: ['tox-pop--align-left'],\n      alignRight: ['tox-pop--align-right'],\n      right: ['tox-pop--right'],\n      left: ['tox-pop--left'],\n      bottom: ['tox-pop--bottom'],\n      top: ['tox-pop--top']\n    };\n    var anchorOverrides = {\n      maxHeightFunction: expandable(),\n      maxWidthFunction: expandable$1()\n    };\n    var desktopAnchorSpecLayouts = {\n      onLtr: function () {\n        return [\n          north$1,\n          south$1,\n          northeast$1,\n          southeast$1,\n          northwest$1,\n          southwest$1,\n          north$3,\n          south$3,\n          northeast$3,\n          southeast$3,\n          northwest$3,\n          southwest$3\n        ];\n      },\n      onRtl: function () {\n        return [\n          north$1,\n          south$1,\n          northwest$1,\n          southwest$1,\n          northeast$1,\n          southeast$1,\n          north$3,\n          south$3,\n          northwest$3,\n          southwest$3,\n          northeast$3,\n          southeast$3\n        ];\n      }\n    };\n    var mobileAnchorSpecLayouts = {\n      onLtr: function () {\n        return [\n          south$1,\n          southeast$1,\n          southwest$1,\n          northeast$1,\n          northwest$1,\n          north$1,\n          north$3,\n          south$3,\n          northeast$3,\n          southeast$3,\n          northwest$3,\n          southwest$3\n        ];\n      },\n      onRtl: function () {\n        return [\n          south$1,\n          southwest$1,\n          southeast$1,\n          northwest$1,\n          northeast$1,\n          north$1,\n          north$3,\n          south$3,\n          northwest$3,\n          southwest$3,\n          northeast$3,\n          southeast$3\n        ];\n      }\n    };\n    var getAnchorLayout = function (position, isTouch) {\n      if (position === 'line') {\n        return {\n          bubble: nu$8(bubbleSize, 0, bubbleAlignments$1),\n          layouts: {\n            onLtr: function () {\n              return [east$1];\n            },\n            onRtl: function () {\n              return [west$1];\n            }\n          },\n          overrides: anchorOverrides\n        };\n      } else {\n        return {\n          bubble: nu$8(0, bubbleSize, bubbleAlignments$1),\n          layouts: isTouch ? mobileAnchorSpecLayouts : desktopAnchorSpecLayouts,\n          overrides: anchorOverrides\n        };\n      }\n    };\n    var register$4 = function (editor, registryContextToolbars, sink, extras) {\n      var isTouch = detect$3().deviceType.isTouch;\n      var contextbar = build$1(renderContextToolbar({\n        sink: sink,\n        onEscape: function () {\n          editor.focus();\n          return Option.some(true);\n        }\n      }));\n      var getBounds = function () {\n        return getContextToolbarBounds(editor);\n      };\n      var isRangeOverlapping = function (aTop, aBottom, bTop, bBottom) {\n        return Math.max(aTop, bTop) <= Math.min(aBottom, bBottom);\n      };\n      var getLastElementVerticalBound = function () {\n        var nodeBounds = lastElement.get().map(function (ele) {\n          return ele.getBoundingClientRect();\n        }).getOrThunk(function () {\n          return editor.selection.getRng().getBoundingClientRect();\n        });\n        var diffTop = editor.inline ? get$8().top() : absolute$1(Element.fromDom(editor.getBody())).y();\n        return {\n          y: nodeBounds.top + diffTop,\n          bottom: nodeBounds.bottom + diffTop\n        };\n      };\n      var shouldContextToolbarHide = function () {\n        if (isTouch() && extras.backstage.isContextMenuOpen()) {\n          return true;\n        }\n        var lastElementBounds = getLastElementVerticalBound();\n        var contextToolbarBounds = getBounds();\n        return !isRangeOverlapping(lastElementBounds.y, lastElementBounds.bottom, contextToolbarBounds.y(), contextToolbarBounds.bottom());\n      };\n      var forceHide = function () {\n        InlineView.hide(contextbar);\n      };\n      var hideOrRepositionIfNecessary = function () {\n        lastAnchor.get().each(function (anchor) {\n          var contextBarEle = contextbar.element();\n          remove$6(contextBarEle, 'display');\n          if (shouldContextToolbarHide()) {\n            set$2(contextBarEle, 'display', 'none');\n          } else {\n            Positioning.positionWithinBounds(sink, anchor, contextbar, Option.some(getBounds()));\n          }\n        });\n      };\n      var lastAnchor = Cell(Option.none());\n      var lastElement = Cell(Option.none());\n      var timer = Cell(null);\n      var wrapInPopDialog = function (toolbarSpec) {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-pop__dialog']\n          },\n          components: [toolbarSpec],\n          behaviours: derive$1([\n            Keying.config({ mode: 'acyclic' }),\n            config('pop-dialog-wrap-events', [\n              runOnAttached(function (comp) {\n                editor.shortcuts.add('ctrl+F9', 'focus statusbar', function () {\n                  return Keying.focusIn(comp);\n                });\n              }),\n              runOnDetached(function (comp) {\n                editor.shortcuts.remove('ctrl+F9');\n              })\n            ])\n          ])\n        };\n      };\n      var getScopes = cached(function () {\n        return ToolbarScopes.categorise(registryContextToolbars, function (toolbarApi) {\n          var alloySpec = buildToolbar(toolbarApi);\n          emitWith(contextbar, forwardSlideEvent, { forwardContents: wrapInPopDialog(alloySpec) });\n        });\n      });\n      var buildToolbar = function (ctx) {\n        var buttons = editor.ui.registry.getAll().buttons;\n        var toolbarType = getToolbarDrawer(editor) === ToolbarDrawer.scrolling ? ToolbarDrawer.scrolling : ToolbarDrawer.default;\n        var scopes = getScopes();\n        return ctx.type === 'contexttoolbar' ? function () {\n          var allButtons = merge(buttons, scopes.formNavigators);\n          var initGroups = identifyButtons(editor, {\n            buttons: allButtons,\n            toolbar: ctx.items\n          }, extras, Option.some(['form:']));\n          return renderToolbar({\n            type: toolbarType,\n            uid: generate$1('context-toolbar'),\n            initGroups: initGroups,\n            onEscape: Option.none,\n            cyclicKeying: true,\n            backstage: extras.backstage,\n            getSink: function () {\n              return Result.error('');\n            }\n          });\n        }() : function () {\n          return ContextForm.renderContextForm(toolbarType, ctx, extras.backstage);\n        }();\n      };\n      editor.on(showContextToolbarEvent, function (e) {\n        var scopes = getScopes();\n        readOptFrom$1(scopes.lookupTable, e.toolbarKey).each(function (ctx) {\n          launchContext(ctx, e.target === editor ? Option.none() : Option.some(e));\n          InlineView.getContent(contextbar).each(Keying.focusIn);\n        });\n      });\n      var getAnchor = function (position, element) {\n        var anchorage = position === 'node' ? extras.backstage.shared.anchors.node(element) : extras.backstage.shared.anchors.cursor();\n        return deepMerge(anchorage, getAnchorLayout(position, isTouch()));\n      };\n      var launchContext = function (toolbarApi, elem) {\n        clearTimer();\n        if (isTouch() && extras.backstage.isContextMenuOpen()) {\n          return;\n        }\n        var toolbarSpec = buildToolbar(toolbarApi);\n        var sElem = elem.map(Element.fromDom);\n        var anchor = getAnchor(toolbarApi.position, sElem);\n        lastAnchor.set(Option.some(anchor));\n        lastElement.set(elem);\n        var contextBarEle = contextbar.element();\n        remove$6(contextBarEle, 'display');\n        InlineView.showWithinBounds(contextbar, anchor, wrapInPopDialog(toolbarSpec), function () {\n          return Option.some(getBounds());\n        });\n        if (shouldContextToolbarHide()) {\n          set$2(contextBarEle, 'display', 'none');\n        }\n      };\n      var launchContextToolbar = function () {\n        var scopes = getScopes();\n        ToolbarLookup.lookup(scopes, editor).fold(function () {\n          lastAnchor.set(Option.none());\n          InlineView.hide(contextbar);\n        }, function (info) {\n          launchContext(info.toolbarApi, Option.some(info.elem.dom()));\n        });\n      };\n      var clearTimer = function () {\n        var current = timer.get();\n        if (current !== null) {\n          global$2.clearTimeout(current);\n          timer.set(null);\n        }\n      };\n      var resetTimer = function (t) {\n        clearTimer();\n        timer.set(t);\n      };\n      editor.on('init', function () {\n        editor.on(hideContextToolbarEvent, forceHide);\n        editor.on('ScrollContent ScrollWindow longpress', hideOrRepositionIfNecessary);\n        editor.on('click keyup SetContent ObjectResized ResizeEditor', function (e) {\n          resetTimer(global$2.setEditorTimeout(editor, launchContextToolbar, 0));\n        });\n        editor.on('focusout', function (e) {\n          global$2.setEditorTimeout(editor, function () {\n            if (search(sink.element()).isNone() && search(contextbar.element()).isNone()) {\n              lastAnchor.set(Option.none());\n              InlineView.hide(contextbar);\n            }\n          }, 0);\n        });\n        editor.on('SwitchMode', function () {\n          if (editor.readonly) {\n            lastAnchor.set(Option.none());\n            InlineView.hide(contextbar);\n          }\n        });\n        editor.on('NodeChange', function (e) {\n          search(contextbar.element()).fold(function () {\n            resetTimer(global$2.setEditorTimeout(editor, launchContextToolbar, 0));\n          }, function (_) {\n          });\n        });\n      });\n    };\n    var ContextToolbar = { register: register$4 };\n\n    var setup$4 = function (editor, mothership, uiMothership) {\n      var broadcastEvent = function (name, evt) {\n        each([\n          mothership,\n          uiMothership\n        ], function (ship) {\n          ship.broadcastEvent(name, evt);\n        });\n      };\n      var broadcastOn = function (channel, message) {\n        each([\n          mothership,\n          uiMothership\n        ], function (ship) {\n          ship.broadcastOn([channel], message);\n        });\n      };\n      var fireDismissPopups = function (evt) {\n        return broadcastOn(dismissPopups(), { target: evt.target() });\n      };\n      var onTouchstart = bind$3(Element.fromDom(domGlobals.document), 'touchstart', fireDismissPopups);\n      var onTouchmove = bind$3(Element.fromDom(domGlobals.document), 'touchmove', function (evt) {\n        return broadcastEvent(documentTouchmove(), evt);\n      });\n      var onTouchend = bind$3(Element.fromDom(domGlobals.document), 'touchend', function (evt) {\n        return broadcastEvent(documentTouchend(), evt);\n      });\n      var onMousedown = bind$3(Element.fromDom(domGlobals.document), 'mousedown', fireDismissPopups);\n      var onMouseup = bind$3(Element.fromDom(domGlobals.document), 'mouseup', function (evt) {\n        if (evt.raw().button === 0) {\n          broadcastOn(mouseReleased(), { target: evt.target() });\n        }\n      });\n      var onContentClick = function (raw) {\n        return broadcastOn(dismissPopups(), { target: Element.fromDom(raw.target) });\n      };\n      var onContentMouseup = function (raw) {\n        if (raw.button === 0) {\n          broadcastOn(mouseReleased(), { target: Element.fromDom(raw.target) });\n        }\n      };\n      var onWindowScroll = function (evt) {\n        return broadcastEvent(windowScroll(), fromRawEvent$1(evt));\n      };\n      var onWindowResize = function (evt) {\n        broadcastOn(repositionPopups(), {});\n        broadcastEvent(windowResize(), fromRawEvent$1(evt));\n      };\n      var onEditorResize = function () {\n        return broadcastOn(repositionPopups(), {});\n      };\n      editor.on('PostRender', function () {\n        editor.on('click', onContentClick);\n        editor.on('tap', onContentClick);\n        editor.on('mouseup', onContentMouseup);\n        editor.on('ScrollWindow', onWindowScroll);\n        editor.on('ResizeWindow', onWindowResize);\n        editor.on('ResizeEditor', onEditorResize);\n      });\n      editor.on('remove', function () {\n        editor.off('click', onContentClick);\n        editor.off('tap', onContentClick);\n        editor.off('mouseup', onContentMouseup);\n        editor.off('ScrollWindow', onWindowScroll);\n        editor.off('ResizeWindow', onWindowResize);\n        editor.off('ResizeEditor', onEditorResize);\n        onMousedown.unbind();\n        onTouchstart.unbind();\n        onTouchmove.unbind();\n        onTouchend.unbind();\n        onMouseup.unbind();\n      });\n      editor.on('detach', function () {\n        detachSystem(mothership);\n        detachSystem(uiMothership);\n        mothership.destroy();\n        uiMothership.destroy();\n      });\n    };\n    var Events$1 = { setup: setup$4 };\n\n    var parts$c = AlloyParts;\n    var partType$1 = PartType;\n\n    var schema$q = constant([\n      defaulted$1('shell', false),\n      strict$1('makeItem'),\n      defaulted$1('setupItem', noop),\n      SketchBehaviours.field('listBehaviours', [Replacing])\n    ]);\n    var customListDetail = function (detail) {\n      return { behaviours: derive$1([Replacing.config({})]) };\n    };\n    var itemsPart = optional({\n      name: 'items',\n      overrides: customListDetail\n    });\n    var parts$d = constant([itemsPart]);\n    var name$2 = constant('CustomList');\n\n    var factory$e = function (detail, components, spec, external) {\n      var setItems = function (list, items) {\n        getListContainer(list).fold(function () {\n          domGlobals.console.error('Custom List was defined to not be a shell, but no item container was specified in components');\n          throw new Error('Custom List was defined to not be a shell, but no item container was specified in components');\n        }, function (container) {\n          var itemComps = Replacing.contents(container);\n          var numListsRequired = items.length;\n          var numListsToAdd = numListsRequired - itemComps.length;\n          var itemsToAdd = numListsToAdd > 0 ? range(numListsToAdd, function () {\n            return detail.makeItem();\n          }) : [];\n          var itemsToRemove = itemComps.slice(numListsRequired);\n          each(itemsToRemove, function (item) {\n            return Replacing.remove(container, item);\n          });\n          each(itemsToAdd, function (item) {\n            return Replacing.append(container, item);\n          });\n          var builtLists = Replacing.contents(container);\n          each(builtLists, function (item, i) {\n            detail.setupItem(list, item, items[i], i);\n          });\n        });\n      };\n      var extra = detail.shell ? {\n        behaviours: [Replacing.config({})],\n        components: []\n      } : {\n        behaviours: [],\n        components: components\n      };\n      var getListContainer = function (component) {\n        return detail.shell ? Option.some(component) : getPart(component, detail, 'items');\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: extra.components,\n        behaviours: augment(detail.listBehaviours, extra.behaviours),\n        apis: { setItems: setItems }\n      };\n    };\n    var CustomList = composite$1({\n      name: name$2(),\n      configFields: schema$q(),\n      partFields: parts$d(),\n      factory: factory$e,\n      apis: {\n        setItems: function (apis, list, items) {\n          apis.setItems(list, items);\n        }\n      }\n    });\n\n    var getOrigin = function (element) {\n      var isFixed = getRaw(element, 'position').is('fixed');\n      var offsetParent$1 = isFixed ? Option.none() : offsetParent(element);\n      return offsetParent$1.orThunk(function () {\n        var marker = Element.fromTag('span');\n        before(element, marker);\n        var offsetParent$1 = offsetParent(marker);\n        remove(marker);\n        return offsetParent$1;\n      }).map(absolute).getOrThunk(function () {\n        return Position(0, 0);\n      });\n    };\n\n    var adt$c = Adt.generate([\n      {\n        offset: [\n          'x',\n          'y'\n        ]\n      },\n      {\n        absolute: [\n          'x',\n          'y'\n        ]\n      },\n      {\n        fixed: [\n          'x',\n          'y'\n        ]\n      }\n    ]);\n    var subtract = function (change) {\n      return function (point) {\n        return point.translate(-change.left(), -change.top());\n      };\n    };\n    var add$4 = function (change) {\n      return function (point) {\n        return point.translate(change.left(), change.top());\n      };\n    };\n    var transform$1 = function (changes) {\n      return function (x, y) {\n        return foldl(changes, function (rest, f) {\n          return f(rest);\n        }, Position(x, y));\n      };\n    };\n    var asFixed = function (coord, scroll, origin) {\n      return coord.fold(transform$1([\n        add$4(origin),\n        subtract(scroll)\n      ]), transform$1([subtract(scroll)]), transform$1([]));\n    };\n    var asAbsolute = function (coord, scroll, origin) {\n      return coord.fold(transform$1([add$4(origin)]), transform$1([]), transform$1([add$4(scroll)]));\n    };\n    var asOffset = function (coord, scroll, origin) {\n      return coord.fold(transform$1([]), transform$1([subtract(origin)]), transform$1([\n        add$4(scroll),\n        subtract(origin)\n      ]));\n    };\n    var withinRange = function (coord1, coord2, xRange, yRange, scroll, origin) {\n      var a1 = asAbsolute(coord1, scroll, origin);\n      var a2 = asAbsolute(coord2, scroll, origin);\n      return Math.abs(a1.left() - a2.left()) <= xRange && Math.abs(a1.top() - a2.top()) <= yRange;\n    };\n    var getDeltas = function (coord1, coord2, xRange, yRange, scroll, origin) {\n      var a1 = asAbsolute(coord1, scroll, origin);\n      var a2 = asAbsolute(coord2, scroll, origin);\n      var left = Math.abs(a1.left() - a2.left());\n      var top = Math.abs(a1.top() - a2.top());\n      return Position(left, top);\n    };\n    var toStyles = function (coord, scroll, origin) {\n      return coord.fold(function (x, y) {\n        return {\n          position: 'absolute',\n          left: x + 'px',\n          top: y + 'px'\n        };\n      }, function (x, y) {\n        return {\n          position: 'absolute',\n          left: x - origin.left() + 'px',\n          top: y - origin.top() + 'px'\n        };\n      }, function (x, y) {\n        return {\n          position: 'fixed',\n          left: x + 'px',\n          top: y + 'px'\n        };\n      });\n    };\n    var translate$2 = function (coord, deltaX, deltaY) {\n      return coord.fold(function (x, y) {\n        return adt$c.offset(x + deltaX, y + deltaY);\n      }, function (x, y) {\n        return adt$c.absolute(x + deltaX, y + deltaY);\n      }, function (x, y) {\n        return adt$c.fixed(x + deltaX, y + deltaY);\n      });\n    };\n    var absorb = function (partialCoord, originalCoord, scroll, origin) {\n      var absorbOne = function (stencil, nu) {\n        return function (optX, optY) {\n          var original = stencil(originalCoord, scroll, origin);\n          return nu(optX.getOr(original.left()), optY.getOr(original.top()));\n        };\n      };\n      return partialCoord.fold(absorbOne(asOffset, adt$c.offset), absorbOne(asAbsolute, adt$c.absolute), absorbOne(asFixed, adt$c.fixed));\n    };\n    var offset = adt$c.offset;\n    var absolute$3 = adt$c.absolute;\n    var fixed$1 = adt$c.fixed;\n\n    var morphAdt = Adt.generate([\n      { static: [] },\n      {\n        absolute: [\n          'x',\n          'y'\n        ]\n      },\n      {\n        fixed: [\n          'x',\n          'y'\n        ]\n      }\n    ]);\n    var appear = function (component, contextualInfo) {\n      var elem = component.element();\n      add$2(elem, contextualInfo.transitionClass);\n      remove$4(elem, contextualInfo.fadeOutClass);\n      add$2(elem, contextualInfo.fadeInClass);\n      contextualInfo.onShow(component);\n    };\n    var disappear = function (component, contextualInfo) {\n      var elem = component.element();\n      add$2(elem, contextualInfo.transitionClass);\n      remove$4(elem, contextualInfo.fadeInClass);\n      add$2(elem, contextualInfo.fadeOutClass);\n      contextualInfo.onHide(component);\n    };\n    var isPartiallyVisible = function (box, viewport) {\n      return box.y() < viewport.bottom() && box.bottom() > viewport.y();\n    };\n    var isTopCompletelyVisible = function (box, viewport) {\n      return box.y() >= viewport.y();\n    };\n    var isBottomCompletelyVisible = function (box, viewport) {\n      return box.bottom() <= viewport.bottom();\n    };\n    var isVisibleForModes = function (modes, box, viewport) {\n      return forall(modes, function (mode) {\n        switch (mode) {\n        case 'bottom':\n          return isBottomCompletelyVisible(box, viewport);\n        case 'top':\n          return isTopCompletelyVisible(box, viewport);\n        }\n      });\n    };\n    var getAttr = function (elem, attr) {\n      return has$1(elem, attr) ? Option.some(parseInt(get$2(elem, attr), 10)) : Option.none();\n    };\n    var getPrior = function (elem, dockInfo) {\n      return getAttr(elem, dockInfo.leftAttr).bind(function (left) {\n        return getAttr(elem, dockInfo.topAttr).map(function (top) {\n          var w = get$7(elem);\n          var h = get$6(elem);\n          return bounds$1(left, top, w, h);\n        });\n      });\n    };\n    var setPrior = function (elem, dockInfo, absLeft, absTop, position) {\n      set$1(elem, dockInfo.leftAttr, absLeft);\n      set$1(elem, dockInfo.topAttr, absTop);\n      set$1(elem, dockInfo.positionAttr, position);\n    };\n    var clearPrior = function (elem, dockInfo) {\n      remove$1(elem, dockInfo.leftAttr);\n      remove$1(elem, dockInfo.topAttr);\n      remove$1(elem, dockInfo.positionAttr);\n    };\n    var revertToOriginal = function (elem, dockInfo, box) {\n      var position = get$2(elem, dockInfo.positionAttr);\n      clearPrior(elem, dockInfo);\n      switch (position) {\n      case 'static':\n        return Option.some(morphAdt.static());\n      case 'absolute':\n        return Option.some(morphAdt.absolute(box.x(), box.y()));\n      default:\n        return Option.none();\n      }\n    };\n    var morphToOriginal = function (elem, dockInfo, viewport) {\n      return getPrior(elem, dockInfo).filter(function (box) {\n        return isVisibleForModes(dockInfo.modes, box, viewport);\n      }).bind(function (box) {\n        return revertToOriginal(elem, dockInfo, box);\n      });\n    };\n    var morphToFixed = function (elem, dockInfo, viewport, scroll, lazyOrigin) {\n      var box$1 = box(elem);\n      if (!isVisibleForModes(dockInfo.modes, box$1, viewport)) {\n        var origin = lazyOrigin();\n        var position = get$4(elem, 'position');\n        setPrior(elem, dockInfo, box$1.x(), box$1.y(), position);\n        var coord = absolute$3(box$1.x(), box$1.y());\n        var asFixed$1 = asFixed(coord, scroll, origin);\n        var viewportPt = absolute$3(viewport.x(), viewport.y());\n        var fixedViewport = asFixed(viewportPt, scroll, origin);\n        var fixedY = box$1.y() <= viewport.y() ? fixedViewport.top() : fixedViewport.top() + viewport.height() - box$1.height();\n        return Option.some(morphAdt.fixed(asFixed$1.left(), fixedY));\n      } else {\n        return Option.none();\n      }\n    };\n    var getMorph = function (component, dockInfo, viewport, scroll, lazyOrigin) {\n      var elem = component.element();\n      var isDocked = getRaw(elem, 'position').is('fixed');\n      return isDocked ? morphToOriginal(elem, dockInfo, viewport) : morphToFixed(elem, dockInfo, viewport, scroll, lazyOrigin);\n    };\n    var getMorphToOriginal = function (component, dockInfo) {\n      var elem = component.element();\n      return getPrior(elem, dockInfo).bind(function (box) {\n        return revertToOriginal(elem, dockInfo, box);\n      });\n    };\n\n    var morphToStatic = function (component, config) {\n      each([\n        'left',\n        'top',\n        'position'\n      ], function (prop) {\n        return remove$6(component.element(), prop);\n      });\n      config.onUndocked(component);\n    };\n    var morphToCoord = function (component, config, scroll, origin, morph) {\n      var styles = toStyles(morph, scroll, origin);\n      setAll$1(component.element(), styles);\n      var method = styles.position === 'fixed' ? config.onDocked : config.onUndocked;\n      method(component);\n    };\n    var updateVisibility = function (component, config, state, viewport, morphToDocked) {\n      if (morphToDocked === void 0) {\n        morphToDocked = false;\n      }\n      config.contextual.each(function (contextInfo) {\n        contextInfo.lazyContext(component).each(function (box) {\n          var isVisible = isPartiallyVisible(box, viewport);\n          if (isVisible !== state.isVisible()) {\n            state.setVisible(isVisible);\n            if (morphToDocked && !isVisible) {\n              add$3(component.element(), [contextInfo.fadeOutClass]);\n              contextInfo.onHide(component);\n            } else {\n              var method = isVisible ? appear : disappear;\n              method(component, contextInfo);\n            }\n          }\n        });\n      });\n    };\n    var refreshInternal = function (component, config, state) {\n      var viewport = config.lazyViewport(component);\n      var elem = component.element();\n      var doc = owner(elem);\n      var scroll = get$8(doc);\n      var lazyOrigin = cached(function () {\n        return getOrigin(elem);\n      });\n      var isDocked = state.isDocked();\n      if (isDocked) {\n        updateVisibility(component, config, state, viewport);\n      }\n      getMorph(component, config, viewport, scroll, lazyOrigin).each(function (morph) {\n        state.setDocked(!isDocked);\n        morph.fold(function () {\n          return morphToStatic(component, config);\n        }, function (x, y) {\n          return morphToCoord(component, config, scroll, lazyOrigin(), absolute$3(x, y));\n        }, function (x, y) {\n          updateVisibility(component, config, state, viewport, true);\n          morphToCoord(component, config, scroll, lazyOrigin(), fixed$1(x, y));\n        });\n      });\n    };\n    var resetInternal = function (component, config, state) {\n      var elem = component.element();\n      state.setDocked(false);\n      getMorphToOriginal(component, config).each(function (morph) {\n        morph.fold(function () {\n          return morphToStatic(component, config);\n        }, function (x, y) {\n          var doc = owner(elem);\n          var scroll = get$8(doc);\n          var origin = getOrigin(elem);\n          morphToCoord(component, config, scroll, origin, absolute$3(x, y));\n        }, noop);\n      });\n      state.setVisible(true);\n      config.contextual.each(function (contextInfo) {\n        remove$5(elem, [\n          contextInfo.fadeInClass,\n          contextInfo.fadeOutClass,\n          contextInfo.transitionClass\n        ]);\n        contextInfo.onShow(component);\n      });\n      refresh$4(component, config, state);\n    };\n    var refresh$4 = function (component, config, state) {\n      if (component.getSystem().isConnected()) {\n        refreshInternal(component, config, state);\n      }\n    };\n    var reset = function (component, config, state) {\n      if (state.isDocked()) {\n        resetInternal(component, config, state);\n      }\n    };\n    var isDocked = function (component, config, state) {\n      return state.isDocked();\n    };\n\n    var DockingApis = /*#__PURE__*/Object.freeze({\n        refresh: refresh$4,\n        reset: reset,\n        isDocked: isDocked\n    });\n\n    var events$f = function (dockInfo, dockState) {\n      return derive([\n        runOnSource(transitionend(), function (component, simulatedEvent) {\n          dockInfo.contextual.each(function (contextInfo) {\n            if (has$2(component.element(), contextInfo.transitionClass)) {\n              remove$5(component.element(), [\n                contextInfo.transitionClass,\n                contextInfo.fadeInClass\n              ]);\n              var notify = dockState.isVisible() ? contextInfo.onShown : contextInfo.onHidden;\n              notify(component);\n            }\n            simulatedEvent.stop();\n          });\n        }),\n        run(windowScroll(), function (component, _) {\n          refresh$4(component, dockInfo, dockState);\n        }),\n        run(windowResize(), function (component, _) {\n          reset(component, dockInfo, dockState);\n        })\n      ]);\n    };\n\n    var ActiveDocking = /*#__PURE__*/Object.freeze({\n        events: events$f\n    });\n\n    var DockingSchema = [\n      optionObjOf('contextual', [\n        strictString('fadeInClass'),\n        strictString('fadeOutClass'),\n        strictString('transitionClass'),\n        strictFunction('lazyContext'),\n        onHandler('onShow'),\n        onHandler('onShown'),\n        onHandler('onHide'),\n        onHandler('onHidden')\n      ]),\n      defaultedFunction('lazyViewport', win),\n      strictString('leftAttr'),\n      strictString('topAttr'),\n      strictString('positionAttr'),\n      defaultedArrayOf('modes', [\n        'top',\n        'bottom'\n      ], string),\n      onHandler('onDocked'),\n      onHandler('onUndocked')\n    ];\n\n    var init$b = function () {\n      var docked = Cell(false);\n      var visible = Cell(true);\n      var readState = function () {\n        return 'docked:  ' + docked.get() + ', visible: ' + visible.get();\n      };\n      return nu$5({\n        isDocked: function () {\n          return docked.get();\n        },\n        setDocked: function (state) {\n          return docked.set(state);\n        },\n        isVisible: function () {\n          return visible.get();\n        },\n        setVisible: function (state) {\n          return visible.set(state);\n        },\n        readState: readState\n      });\n    };\n\n    var DockingState = /*#__PURE__*/Object.freeze({\n        init: init$b\n    });\n\n    var Docking = create$1({\n      fields: DockingSchema,\n      name: 'docking',\n      active: ActiveDocking,\n      apis: DockingApis,\n      state: DockingState\n    });\n\n    var visibility = {\n      fadeInClass: 'tox-editor-dock-fadein',\n      fadeOutClass: 'tox-editor-dock-fadeout',\n      transitionClass: 'tox-editor-dock-transition'\n    };\n    var editorStickyOnClass = 'tox-tinymce--toolbar-sticky-on';\n    var editorStickyOffClass = 'tox-tinymce--toolbar-sticky-off';\n    var updateIframeContentFlow = function (header) {\n      var elm = header.element();\n      parent(elm).each(function (parentElem) {\n        if (Docking.isDocked(header)) {\n          var parentWidth = get$7(parentElem);\n          set$2(elm, 'width', parentWidth + 'px');\n          var headerHeight = getOuter$1(elm);\n          set$2(parentElem, 'padding-top', headerHeight + 'px');\n        } else {\n          remove$6(elm, 'width');\n          remove$6(parentElem, 'padding-top');\n        }\n      });\n    };\n    var updateSinkVisibility = function (sinkElem, visible) {\n      if (visible) {\n        remove$4(sinkElem, visibility.fadeOutClass);\n        add$3(sinkElem, [\n          visibility.transitionClass,\n          visibility.fadeInClass\n        ]);\n      } else {\n        remove$4(sinkElem, visibility.fadeInClass);\n        add$3(sinkElem, [\n          visibility.fadeOutClass,\n          visibility.transitionClass\n        ]);\n      }\n    };\n    var updateEditorClasses = function (editor, docked) {\n      var editorContainer = Element.fromDom(editor.getContainer());\n      if (docked) {\n        add$2(editorContainer, editorStickyOnClass);\n        remove$4(editorContainer, editorStickyOffClass);\n      } else {\n        add$2(editorContainer, editorStickyOffClass);\n        remove$4(editorContainer, editorStickyOnClass);\n      }\n    };\n    var restoreFocus = function (headerElem, focusedElem) {\n      var ownerDoc = owner(focusedElem);\n      active(ownerDoc).filter(function (activeElm) {\n        return !eq(focusedElem, activeElm);\n      }).filter(function (activeElm) {\n        return eq(activeElm, Element.fromDom(ownerDoc.dom().body)) || contains$2(headerElem, activeElm);\n      }).each(function () {\n        return focus$1(focusedElem);\n      });\n    };\n    var findFocusedElem = function (rootElm, lazySink) {\n      return search(rootElm).orThunk(function () {\n        return lazySink().toOption().bind(function (sink) {\n          return search(sink.element());\n        });\n      });\n    };\n    var setup$5 = function (editor, lazyHeader) {\n      if (!editor.inline) {\n        editor.on('ResizeWindow ResizeEditor ResizeContent', function () {\n          lazyHeader().each(updateIframeContentFlow);\n        });\n        editor.on('SkinLoaded', function () {\n          lazyHeader().each(Docking.reset);\n        });\n        editor.on('FullscreenStateChanged', function () {\n          lazyHeader().each(Docking.refresh);\n        });\n      }\n      editor.on('PostRender', function () {\n        updateEditorClasses(editor, false);\n      });\n    };\n    var isDocked$1 = function (lazyHeader) {\n      return lazyHeader().map(Docking.isDocked).getOr(false);\n    };\n    var getIframeBehaviours = function () {\n      var _a;\n      return [Receiving.config({ channels: (_a = {}, _a[toolbarHeightChange()] = { onReceive: updateIframeContentFlow }, _a) })];\n    };\n    var getBehaviours$2 = function (editor, lazySink) {\n      var focusedElm = Cell(Option.none());\n      var runOnSinkElement = function (f) {\n        lazySink().each(function (sink) {\n          return f(sink.element());\n        });\n      };\n      var onDockingSwitch = function (comp) {\n        if (!editor.inline) {\n          updateIframeContentFlow(comp);\n        }\n        updateEditorClasses(editor, Docking.isDocked(comp));\n        comp.getSystem().broadcastOn([repositionPopups()], {});\n        lazySink().each(function (sink) {\n          return sink.getSystem().broadcastOn([repositionPopups()], {});\n        });\n      };\n      var additionalBehaviours = editor.inline ? [] : getIframeBehaviours();\n      return __spreadArrays([\n        Focusing.config({}),\n        Docking.config({\n          leftAttr: 'data-dock-left',\n          topAttr: 'data-dock-top',\n          positionAttr: 'data-dock-pos',\n          contextual: __assign({\n            lazyContext: function (comp) {\n              var headerHeight = getOuter$1(comp.element());\n              var container = editor.inline ? editor.getContentAreaContainer() : editor.getContainer();\n              var box$1 = box(Element.fromDom(container));\n              var boxHeight = box$1.height() - headerHeight;\n              return Option.some(bounds$1(box$1.x(), box$1.y(), box$1.width(), boxHeight));\n            },\n            onShow: function () {\n              runOnSinkElement(function (elem) {\n                return updateSinkVisibility(elem, true);\n              });\n            },\n            onShown: function (comp) {\n              runOnSinkElement(function (elem) {\n                return remove$5(elem, [\n                  visibility.transitionClass,\n                  visibility.fadeInClass\n                ]);\n              });\n              focusedElm.get().each(function (elem) {\n                restoreFocus(comp.element(), elem);\n                focusedElm.set(Option.none());\n              });\n            },\n            onHide: function (comp) {\n              focusedElm.set(findFocusedElem(comp.element(), lazySink));\n              runOnSinkElement(function (elem) {\n                return updateSinkVisibility(elem, false);\n              });\n            },\n            onHidden: function () {\n              runOnSinkElement(function (elem) {\n                return remove$5(elem, [visibility.transitionClass]);\n              });\n            }\n          }, visibility),\n          modes: ['top'],\n          onDocked: onDockingSwitch,\n          onUndocked: onDockingSwitch\n        })\n      ], additionalBehaviours);\n    };\n\n    var StickyHeader = /*#__PURE__*/Object.freeze({\n        setup: setup$5,\n        isDocked: isDocked$1,\n        getBehaviours: getBehaviours$2\n    });\n\n    var setup$6 = noop;\n    var isDocked$2 = never;\n    var getBehaviours$3 = constant([]);\n\n    var StaticHeader = /*#__PURE__*/Object.freeze({\n        setup: setup$6,\n        isDocked: isDocked$2,\n        getBehaviours: getBehaviours$3\n    });\n\n    var renderHeader = function (spec) {\n      var editor = spec.editor;\n      var getBehaviours = spec.sticky ? getBehaviours$2 : getBehaviours$3;\n      return {\n        uid: spec.uid,\n        dom: spec.dom,\n        components: spec.components,\n        behaviours: derive$1(getBehaviours(editor, spec.getSink))\n      };\n    };\n\n    var factory$f = function (detail, spec) {\n      var setMenus = function (comp, menus) {\n        var newMenus = map(menus, function (m) {\n          var buttonSpec = {\n            type: 'menubutton',\n            text: m.text,\n            fetch: function (callback) {\n              callback(m.getItems());\n            }\n          };\n          var internal = createMenuButton(buttonSpec).mapError(function (errInfo) {\n            return formatError(errInfo);\n          }).getOrDie();\n          return renderMenuButton(internal, 'tox-mbtn', spec.backstage, Option.some('menuitem'));\n        });\n        Replacing.set(comp, newMenus);\n      };\n      var apis = {\n        focus: Keying.focusIn,\n        setMenus: setMenus\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: [],\n        behaviours: derive$1([\n          Replacing.config({}),\n          config('menubar-events', [\n            runOnAttached(function (component) {\n              detail.onSetup(component);\n            }),\n            run(mouseover(), function (comp, se) {\n              descendant$1(comp.element(), '.' + 'tox-mbtn--active').each(function (activeButton) {\n                closest$3(se.event().target(), '.' + 'tox-mbtn').each(function (hoveredButton) {\n                  if (!eq(activeButton, hoveredButton)) {\n                    comp.getSystem().getByDom(activeButton).each(function (activeComp) {\n                      comp.getSystem().getByDom(hoveredButton).each(function (hoveredComp) {\n                        Dropdown.expand(hoveredComp);\n                        Dropdown.close(activeComp);\n                        Focusing.focus(hoveredComp);\n                      });\n                    });\n                  }\n                });\n              });\n            }),\n            run(focusShifted(), function (comp, se) {\n              se.event().prevFocus().bind(function (prev) {\n                return comp.getSystem().getByDom(prev).toOption();\n              }).each(function (prev) {\n                se.event().newFocus().bind(function (nu) {\n                  return comp.getSystem().getByDom(nu).toOption();\n                }).each(function (nu) {\n                  if (Dropdown.isOpen(prev)) {\n                    Dropdown.expand(nu);\n                    Dropdown.close(prev);\n                  }\n                });\n              });\n            })\n          ]),\n          Keying.config({\n            mode: 'flow',\n            selector: '.' + 'tox-mbtn',\n            onEscape: function (comp) {\n              detail.onEscape(comp);\n              return Option.some(true);\n            }\n          }),\n          Tabstopping.config({})\n        ]),\n        apis: apis,\n        domModification: { attributes: { role: 'menubar' } }\n      };\n    };\n    var SilverMenubar = single$2({\n      factory: factory$f,\n      name: 'silver.Menubar',\n      configFields: [\n        strict$1('dom'),\n        strict$1('uid'),\n        strict$1('onEscape'),\n        strict$1('backstage'),\n        defaulted$1('onSetup', noop)\n      ],\n      apis: {\n        focus: function (apis, comp) {\n          apis.focus(comp);\n        },\n        setMenus: function (apis, comp, menus) {\n          apis.setMenus(comp, menus);\n        }\n      }\n    });\n\n    var owner$4 = 'container';\n    var schema$r = [field$1('slotBehaviours', [])];\n    var getPartName$1 = function (name) {\n      return '<alloy.field.' + name + '>';\n    };\n    var sketch$2 = function (sSpec) {\n      var parts = function () {\n        var record = [];\n        var slot = function (name, config) {\n          record.push(name);\n          return generateOne(owner$4, getPartName$1(name), config);\n        };\n        return {\n          slot: slot,\n          record: function () {\n            return record;\n          }\n        };\n      }();\n      var spec = sSpec(parts);\n      var partNames = parts.record();\n      var fieldParts = map(partNames, function (n) {\n        return required({\n          name: n,\n          pname: getPartName$1(n)\n        });\n      });\n      return composite(owner$4, schema$r, fieldParts, make$7, spec);\n    };\n    var make$7 = function (detail, components, spec) {\n      var getSlotNames = function (_) {\n        return getAllPartNames(detail);\n      };\n      var getSlot = function (container, key) {\n        return getPart(container, detail, key);\n      };\n      var onSlot = function (f, def) {\n        if (def === void 0) {\n          def = undefined;\n        }\n        return function (container, key) {\n          return getPart(container, detail, key).map(function (slot) {\n            return f(slot, key);\n          }).getOr(def);\n        };\n      };\n      var onSlots = function (f) {\n        return function (container, keys) {\n          each(keys, function (key) {\n            return f(container, key);\n          });\n        };\n      };\n      var doShowing = function (comp, key) {\n        return get$2(comp.element(), 'aria-hidden') !== 'true';\n      };\n      var doShow = function (comp, key) {\n        if (!doShowing(comp)) {\n          var element = comp.element();\n          remove$6(element, 'display');\n          remove$1(element, 'aria-hidden');\n          emitWith(comp, slotVisibility(), {\n            name: key,\n            visible: true\n          });\n        }\n      };\n      var doHide = function (comp, key) {\n        if (doShowing(comp)) {\n          var element = comp.element();\n          set$2(element, 'display', 'none');\n          set$1(element, 'aria-hidden', 'true');\n          emitWith(comp, slotVisibility(), {\n            name: key,\n            visible: false\n          });\n        }\n      };\n      var isShowing = onSlot(doShowing, false);\n      var hideSlot = onSlot(doHide);\n      var hideSlots = onSlots(hideSlot);\n      var hideAllSlots = function (container) {\n        return hideSlots(container, getSlotNames());\n      };\n      var showSlot = onSlot(doShow);\n      var apis = {\n        getSlotNames: getSlotNames,\n        getSlot: getSlot,\n        isShowing: isShowing,\n        hideSlot: hideSlot,\n        hideAllSlots: hideAllSlots,\n        showSlot: showSlot\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: get$b(detail.slotBehaviours),\n        apis: apis\n      };\n    };\n    var slotApis = map$1({\n      getSlotNames: function (apis, c) {\n        return apis.getSlotNames(c);\n      },\n      getSlot: function (apis, c, key) {\n        return apis.getSlot(c, key);\n      },\n      isShowing: function (apis, c, key) {\n        return apis.isShowing(c, key);\n      },\n      hideSlot: function (apis, c, key) {\n        return apis.hideSlot(c, key);\n      },\n      hideAllSlots: function (apis, c) {\n        return apis.hideAllSlots(c);\n      },\n      showSlot: function (apis, c, key) {\n        return apis.showSlot(c, key);\n      }\n    }, makeApi);\n    var SlotContainer = __assign(__assign({}, slotApis), { sketch: sketch$2 });\n\n    var sidebarSchema = objOf([\n      optionString('icon'),\n      optionString('tooltip'),\n      defaultedFunction('onShow', noop),\n      defaultedFunction('onHide', noop),\n      defaultedFunction('onSetup', function () {\n        return noop;\n      })\n    ]);\n    var createSidebar = function (spec) {\n      return asRaw('sidebar', sidebarSchema, spec);\n    };\n\n    var setup$7 = function (editor) {\n      var sidebars = editor.ui.registry.getAll().sidebars;\n      each(keys(sidebars), function (name) {\n        var spec = sidebars[name];\n        var isActive = function () {\n          return Option.from(editor.queryCommandValue('ToggleSidebar')).is(name);\n        };\n        editor.ui.registry.addToggleButton(name, {\n          icon: spec.icon,\n          tooltip: spec.tooltip,\n          onAction: function (buttonApi) {\n            editor.execCommand('ToggleSidebar', false, name);\n            buttonApi.setActive(isActive());\n          },\n          onSetup: function (buttonApi) {\n            var handleToggle = function () {\n              return buttonApi.setActive(isActive());\n            };\n            editor.on('ToggleSidebar', handleToggle);\n            return function () {\n              editor.off('ToggleSidebar', handleToggle);\n            };\n          }\n        });\n      });\n    };\n    var getApi = function (comp) {\n      return {\n        element: function () {\n          return comp.element().dom();\n        }\n      };\n    };\n    var makePanels = function (parts, panelConfigs) {\n      var specs = map(keys(panelConfigs), function (name) {\n        var spec = panelConfigs[name];\n        var bridged = getOrDie(createSidebar(spec));\n        return {\n          name: name,\n          getApi: getApi,\n          onSetup: bridged.onSetup,\n          onShow: bridged.onShow,\n          onHide: bridged.onHide\n        };\n      });\n      return map(specs, function (spec) {\n        var editorOffCell = Cell(noop);\n        return parts.slot(spec.name, {\n          dom: {\n            tag: 'div',\n            classes: ['tox-sidebar__pane']\n          },\n          behaviours: SimpleBehaviours.unnamedEvents([\n            onControlAttached(spec, editorOffCell),\n            onControlDetached(spec, editorOffCell),\n            run(slotVisibility(), function (sidepanel, se) {\n              var data = se.event();\n              var optSidePanelSpec = find(specs, function (config) {\n                return config.name === data.name();\n              });\n              optSidePanelSpec.each(function (sidePanelSpec) {\n                var handler = data.visible() ? sidePanelSpec.onShow : sidePanelSpec.onHide;\n                handler(sidePanelSpec.getApi(sidepanel));\n              });\n            })\n          ])\n        });\n      });\n    };\n    var makeSidebar = function (panelConfigs) {\n      return SlotContainer.sketch(function (parts) {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-sidebar__pane-container']\n          },\n          components: makePanels(parts, panelConfigs),\n          slotBehaviours: SimpleBehaviours.unnamedEvents([runOnAttached(function (slotContainer) {\n              return SlotContainer.hideAllSlots(slotContainer);\n            })])\n        };\n      });\n    };\n    var setSidebar = function (sidebar, panelConfigs) {\n      var optSlider = Composing.getCurrent(sidebar);\n      optSlider.each(function (slider) {\n        return Replacing.set(slider, [makeSidebar(panelConfigs)]);\n      });\n    };\n    var toggleSidebar = function (sidebar, name) {\n      var optSlider = Composing.getCurrent(sidebar);\n      optSlider.each(function (slider) {\n        var optSlotContainer = Composing.getCurrent(slider);\n        optSlotContainer.each(function (slotContainer) {\n          if (Sliding.hasGrown(slider)) {\n            if (SlotContainer.isShowing(slotContainer, name)) {\n              Sliding.shrink(slider);\n            } else {\n              SlotContainer.hideAllSlots(slotContainer);\n              SlotContainer.showSlot(slotContainer, name);\n            }\n          } else {\n            SlotContainer.hideAllSlots(slotContainer);\n            SlotContainer.showSlot(slotContainer, name);\n            Sliding.grow(slider);\n          }\n        });\n      });\n    };\n    var whichSidebar = function (sidebar) {\n      var optSlider = Composing.getCurrent(sidebar);\n      return optSlider.bind(function (slider) {\n        var sidebarOpen = Sliding.isGrowing(slider) || Sliding.hasGrown(slider);\n        if (sidebarOpen) {\n          var optSlotContainer = Composing.getCurrent(slider);\n          return optSlotContainer.bind(function (slotContainer) {\n            return find(SlotContainer.getSlotNames(slotContainer), function (name) {\n              return SlotContainer.isShowing(slotContainer, name);\n            });\n          });\n        } else {\n          return Option.none();\n        }\n      });\n    };\n    var fixSize = generate$1('FixSizeEvent');\n    var autoSize = generate$1('AutoSizeEvent');\n    var renderSidebar = function (spec) {\n      return {\n        uid: spec.uid,\n        dom: {\n          tag: 'div',\n          classes: ['tox-sidebar'],\n          attributes: { role: 'complementary' }\n        },\n        components: [{\n            dom: {\n              tag: 'div',\n              classes: ['tox-sidebar__slider']\n            },\n            components: [],\n            behaviours: derive$1([\n              Tabstopping.config({}),\n              Focusing.config({}),\n              Sliding.config({\n                dimension: { property: 'width' },\n                closedClass: 'tox-sidebar--sliding-closed',\n                openClass: 'tox-sidebar--sliding-open',\n                shrinkingClass: 'tox-sidebar--sliding-shrinking',\n                growingClass: 'tox-sidebar--sliding-growing',\n                onShrunk: function (slider) {\n                  var optSlotContainer = Composing.getCurrent(slider);\n                  optSlotContainer.each(SlotContainer.hideAllSlots);\n                  emit(slider, autoSize);\n                },\n                onGrown: function (slider) {\n                  emit(slider, autoSize);\n                },\n                onStartGrow: function (slider) {\n                  emitWith(slider, fixSize, { width: getRaw(slider.element(), 'width').getOr('') });\n                },\n                onStartShrink: function (slider) {\n                  emitWith(slider, fixSize, { width: get$7(slider.element()) + 'px' });\n                }\n              }),\n              Replacing.config({}),\n              Composing.config({\n                find: function (comp) {\n                  var children = Replacing.contents(comp);\n                  return head(children);\n                }\n              })\n            ])\n          }],\n        behaviours: derive$1([\n          ComposingConfigs.childAt(0),\n          config('sidebar-sliding-events', [\n            run(fixSize, function (comp, se) {\n              set$2(comp.element(), 'width', se.event().width());\n            }),\n            run(autoSize, function (comp, se) {\n              remove$6(comp.element(), 'width');\n            })\n          ])\n        ])\n      };\n    };\n\n    var renderSpinner = function (providerBackstage) {\n      return {\n        dom: {\n          tag: 'div',\n          attributes: { 'aria-label': providerBackstage.translate('Loading...') },\n          classes: ['tox-throbber__busy-spinner']\n        },\n        components: [{ dom: fromHtml$2('<div class=\"tox-spinner\"><div></div><div></div><div></div></div>') }],\n        behaviours: derive$1([\n          Keying.config({\n            mode: 'special',\n            onTab: function () {\n              return Option.some(true);\n            },\n            onShiftTab: function () {\n              return Option.some(true);\n            }\n          }),\n          Focusing.config({})\n        ])\n      };\n    };\n    var toggleThrobber = function (comp, state, providerBackstage) {\n      var element = comp.element();\n      if (state === true) {\n        Replacing.set(comp, [renderSpinner(providerBackstage)]);\n        remove$6(element, 'display');\n        remove$1(element, 'aria-hidden');\n      } else {\n        Replacing.set(comp, []);\n        set$2(element, 'display', 'none');\n        set$1(element, 'aria-hidden', 'true');\n      }\n    };\n    var renderThrobber = function (spec) {\n      return {\n        uid: spec.uid,\n        dom: {\n          tag: 'div',\n          attributes: { 'aria-hidden': 'true' },\n          classes: ['tox-throbber'],\n          styles: { display: 'none' }\n        },\n        behaviours: derive$1([Replacing.config({})]),\n        components: []\n      };\n    };\n    var setup$8 = function (editor, lazyThrobber, sharedBackstage) {\n      var throbberState = Cell(false);\n      var timer = Cell(Option.none());\n      var toggle = function (state) {\n        if (state !== throbberState.get()) {\n          toggleThrobber(lazyThrobber(), state, sharedBackstage.providers);\n          throbberState.set(state);\n        }\n      };\n      editor.on('ProgressState', function (e) {\n        timer.get().each(global$2.clearTimeout);\n        if (isNumber(e.time)) {\n          var timerId = global$2.setEditorTimeout(editor, function () {\n            return toggle(e.state);\n          }, e.time);\n          timer.set(Option.some(timerId));\n        } else {\n          toggle(e.state);\n          timer.set(Option.none());\n        }\n      });\n    };\n\n    var factory$g = function (detail, components, spec) {\n      var apis = {\n        getSocket: function (comp) {\n          return parts$c.getPart(comp, detail, 'socket');\n        },\n        setSidebar: function (comp, panelConfigs) {\n          parts$c.getPart(comp, detail, 'sidebar').each(function (sidebar) {\n            return setSidebar(sidebar, panelConfigs);\n          });\n        },\n        toggleSidebar: function (comp, name) {\n          parts$c.getPart(comp, detail, 'sidebar').each(function (sidebar) {\n            return toggleSidebar(sidebar, name);\n          });\n        },\n        whichSidebar: function (comp) {\n          return parts$c.getPart(comp, detail, 'sidebar').bind(whichSidebar).getOrNull();\n        },\n        getHeader: function (comp) {\n          return parts$c.getPart(comp, detail, 'header');\n        },\n        getToolbar: function (comp) {\n          return parts$c.getPart(comp, detail, 'toolbar');\n        },\n        setToolbar: function (comp, groups) {\n          parts$c.getPart(comp, detail, 'toolbar').each(function (toolbar) {\n            toolbar.getApis().setGroups(toolbar, groups);\n          });\n        },\n        setToolbars: function (comp, toolbars) {\n          parts$c.getPart(comp, detail, 'multiple-toolbar').each(function (mToolbar) {\n            CustomList.setItems(mToolbar, toolbars);\n          });\n        },\n        refreshToolbar: function (comp) {\n          var toolbar = parts$c.getPart(comp, detail, 'toolbar');\n          toolbar.each(function (toolbar) {\n            return toolbar.getApis().refresh(toolbar);\n          });\n        },\n        getMoreButton: function (comp) {\n          var toolbar = parts$c.getPart(comp, detail, 'toolbar');\n          return toolbar.bind(function (toolbar) {\n            return toolbar.getApis().getMoreButton(toolbar);\n          });\n        },\n        getThrobber: function (comp) {\n          return parts$c.getPart(comp, detail, 'throbber');\n        },\n        focusToolbar: function (comp) {\n          var optToolbar = parts$c.getPart(comp, detail, 'toolbar').orThunk(function () {\n            return parts$c.getPart(comp, detail, 'multiple-toolbar');\n          });\n          optToolbar.each(function (toolbar) {\n            Keying.focusIn(toolbar);\n          });\n        },\n        setMenubar: function (comp, menus) {\n          parts$c.getPart(comp, detail, 'menubar').each(function (menubar) {\n            SilverMenubar.setMenus(menubar, menus);\n          });\n        },\n        focusMenubar: function (comp) {\n          parts$c.getPart(comp, detail, 'menubar').each(function (menubar) {\n            SilverMenubar.focus(menubar);\n          });\n        }\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        apis: apis,\n        behaviours: detail.behaviours\n      };\n    };\n    var partMenubar = partType$1.optional({\n      factory: SilverMenubar,\n      name: 'menubar',\n      schema: [strict$1('backstage')]\n    });\n    var toolbarFactory = function (spec) {\n      if (spec.split === ToolbarDrawer.sliding) {\n        return renderSlidingMoreToolbar;\n      } else if (spec.split === ToolbarDrawer.floating) {\n        return renderFloatingMoreToolbar;\n      } else {\n        return renderToolbar;\n      }\n    };\n    var partMultipleToolbar = partType$1.optional({\n      factory: {\n        sketch: function (spec) {\n          return CustomList.sketch({\n            uid: spec.uid,\n            dom: spec.dom,\n            listBehaviours: derive$1([Keying.config({\n                mode: 'acyclic',\n                selector: '.tox-toolbar'\n              })]),\n            makeItem: function () {\n              return renderToolbar({\n                type: spec.split,\n                uid: generate$1('multiple-toolbar-item'),\n                backstage: spec.backstage,\n                cyclicKeying: false,\n                getSink: spec.getSink,\n                initGroups: [],\n                onEscape: function () {\n                  return Option.none();\n                }\n              });\n            },\n            setupItem: function (mToolbar, tc, data, index) {\n              Toolbar.setGroups(tc, data);\n            },\n            shell: true\n          });\n        }\n      },\n      name: 'multiple-toolbar',\n      schema: [\n        strict$1('dom'),\n        strict$1('onEscape')\n      ]\n    });\n    var partToolbar = partType$1.optional({\n      factory: {\n        sketch: function (spec) {\n          var renderer = toolbarFactory(spec);\n          var toolbarSpec = {\n            type: spec.split,\n            uid: spec.uid,\n            onEscape: function () {\n              spec.onEscape();\n              return Option.some(true);\n            },\n            cyclicKeying: false,\n            initGroups: [],\n            getSink: spec.getSink,\n            backstage: spec.backstage,\n            moreDrawerData: {\n              lazyToolbar: spec.lazyToolbar,\n              lazyMoreButton: spec.lazyMoreButton,\n              lazyHeader: spec.lazyHeader\n            }\n          };\n          return renderer(toolbarSpec);\n        }\n      },\n      name: 'toolbar',\n      schema: [\n        strict$1('dom'),\n        strict$1('onEscape'),\n        strict$1('getSink')\n      ]\n    });\n    var partHeader = partType$1.optional({\n      factory: { sketch: renderHeader },\n      name: 'header',\n      schema: [strict$1('dom')]\n    });\n    var partSocket = partType$1.optional({\n      name: 'socket',\n      schema: [strict$1('dom')]\n    });\n    var partSidebar = partType$1.optional({\n      factory: { sketch: renderSidebar },\n      name: 'sidebar',\n      schema: [strict$1('dom')]\n    });\n    var partThrobber = partType$1.optional({\n      factory: { sketch: renderThrobber },\n      name: 'throbber',\n      schema: [strict$1('dom')]\n    });\n    var OuterContainer = composite$1({\n      name: 'OuterContainer',\n      factory: factory$g,\n      configFields: [\n        strict$1('dom'),\n        strict$1('behaviours')\n      ],\n      partFields: [\n        partHeader,\n        partMenubar,\n        partToolbar,\n        partMultipleToolbar,\n        partSocket,\n        partSidebar,\n        partThrobber\n      ],\n      apis: {\n        getSocket: function (apis, comp) {\n          return apis.getSocket(comp);\n        },\n        setSidebar: function (apis, comp, panelConfigs) {\n          apis.setSidebar(comp, panelConfigs);\n        },\n        toggleSidebar: function (apis, comp, name) {\n          apis.toggleSidebar(comp, name);\n        },\n        whichSidebar: function (apis, comp) {\n          return apis.whichSidebar(comp);\n        },\n        getHeader: function (apis, comp) {\n          return apis.getHeader(comp);\n        },\n        getToolbar: function (apis, comp) {\n          return apis.getToolbar(comp);\n        },\n        setToolbar: function (apis, comp, grps) {\n          var groups = map(grps, function (grp) {\n            return renderToolbarGroup(grp);\n          });\n          apis.setToolbar(comp, groups);\n        },\n        setToolbars: function (apis, comp, ts) {\n          var renderedToolbars = map(ts, function (g) {\n            return map(g, renderToolbarGroup);\n          });\n          apis.setToolbars(comp, renderedToolbars);\n        },\n        getMoreButton: function (apis, comp) {\n          return apis.getMoreButton(comp);\n        },\n        refreshToolbar: function (apis, comp) {\n          return apis.refreshToolbar(comp);\n        },\n        getThrobber: function (apis, comp) {\n          return apis.getThrobber(comp);\n        },\n        setMenubar: function (apis, comp, menus) {\n          apis.setMenubar(comp, menus);\n        },\n        focusMenubar: function (apis, comp) {\n          apis.focusMenubar(comp);\n        },\n        focusToolbar: function (apis, comp) {\n          apis.focusToolbar(comp);\n        }\n      }\n    });\n\n    var defaultMenubar = 'file edit view insert format tools table help';\n    var defaultMenus = {\n      file: {\n        title: 'File',\n        items: 'newdocument restoredraft | preview | print | deleteallconversations'\n      },\n      edit: {\n        title: 'Edit',\n        items: 'undo redo | cut copy paste pastetext | selectall | searchreplace'\n      },\n      view: {\n        title: 'View',\n        items: 'code | visualaid visualchars visualblocks | spellchecker | preview fullscreen | showcomments'\n      },\n      insert: {\n        title: 'Insert',\n        items: 'image link media addcomment pageembed template codesample inserttable | charmap emoticons hr | pagebreak nonbreaking anchor toc | insertdatetime'\n      },\n      format: {\n        title: 'Format',\n        items: 'bold italic underline strikethrough superscript subscript codeformat | formats blockformats fontformats fontsizes align | forecolor backcolor | removeformat'\n      },\n      tools: {\n        title: 'Tools',\n        items: 'spellchecker spellcheckerlanguage | a11ycheck code wordcount'\n      },\n      table: {\n        title: 'Table',\n        items: 'inserttable | cell row column | advtablesort | tableprops deletetable'\n      },\n      help: {\n        title: 'Help',\n        items: 'help'\n      }\n    };\n    var make$8 = function (menu, registry, editor) {\n      var removedMenuItems = getRemovedMenuItems(editor).split(/[ ,]/);\n      return {\n        text: menu.title,\n        getItems: function () {\n          return bind(menu.items, function (i) {\n            var itemName = i.toLowerCase();\n            if (itemName.trim().length === 0) {\n              return [];\n            } else if (exists(removedMenuItems, function (removedMenuItem) {\n                return removedMenuItem === itemName;\n              })) {\n              return [];\n            } else if (itemName === 'separator' || itemName === '|') {\n              return [{ type: 'separator' }];\n            } else if (registry.menuItems[itemName]) {\n              return [registry.menuItems[itemName]];\n            } else {\n              return [];\n            }\n          });\n        }\n      };\n    };\n    var parseItemsString = function (items) {\n      if (typeof items === 'string') {\n        return items.split(' ');\n      }\n      return items;\n    };\n    var identifyMenus = function (editor, registry) {\n      var rawMenuData = merge(defaultMenus, registry.menus);\n      var userDefinedMenus = keys(registry.menus).length > 0;\n      var menubar = registry.menubar === undefined || registry.menubar === true ? parseItemsString(defaultMenubar) : parseItemsString(registry.menubar === false ? '' : registry.menubar);\n      var validMenus = filter(menubar, function (menuName) {\n        return userDefinedMenus ? registry.menus.hasOwnProperty(menuName) && registry.menus[menuName].hasOwnProperty('items') || defaultMenus.hasOwnProperty(menuName) : defaultMenus.hasOwnProperty(menuName);\n      });\n      var menus = map(validMenus, function (menuName) {\n        var menuData = rawMenuData[menuName];\n        return make$8({\n          title: menuData.title,\n          items: parseItemsString(menuData.items)\n        }, registry, editor);\n      });\n      return filter(menus, function (menu) {\n        var isNotSeparator = function (item) {\n          return item.type !== 'separator';\n        };\n        return menu.getItems().length > 0 && exists(menu.getItems(), isNotSeparator);\n      });\n    };\n\n    var fireSkinLoaded$1 = function (editor) {\n      var done = function () {\n        editor._skinLoaded = true;\n        Events.fireSkinLoaded(editor);\n      };\n      return function () {\n        if (editor.initialized) {\n          done();\n        } else {\n          editor.on('init', done);\n        }\n      };\n    };\n    var SkinLoaded = { fireSkinLoaded: fireSkinLoaded$1 };\n\n    var loadSkin = function (isInline, editor) {\n      var skinUrl = getSkinUrl(editor);\n      var skinUiCss;\n      if (skinUrl) {\n        skinUiCss = skinUrl + '/skin.min.css';\n        editor.contentCSS.push(skinUrl + (isInline ? '/content.inline' : '/content') + '.min.css');\n      }\n      if (isSkinDisabled(editor) === false && skinUiCss) {\n        global$7.DOM.styleSheetLoader.load(skinUiCss, SkinLoaded.fireSkinLoaded(editor));\n      } else {\n        SkinLoaded.fireSkinLoaded(editor)();\n      }\n    };\n    var iframe = curry(loadSkin, false);\n    var inline = curry(loadSkin, true);\n\n    var setToolbar = function (editor, uiComponents, rawUiConfig, backstage) {\n      var comp = uiComponents.outerContainer;\n      var toolbarConfig = rawUiConfig.toolbar;\n      var toolbarButtonsConfig = rawUiConfig.buttons;\n      if (isArrayOf(toolbarConfig, isString)) {\n        var toolbars = toolbarConfig.map(function (t) {\n          var config = {\n            toolbar: t,\n            buttons: toolbarButtonsConfig\n          };\n          return identifyButtons(editor, config, { backstage: backstage }, Option.none());\n        });\n        OuterContainer.setToolbars(comp, toolbars);\n      } else {\n        OuterContainer.setToolbar(comp, identifyButtons(editor, rawUiConfig, { backstage: backstage }, Option.none()));\n      }\n    };\n\n    var DOM = global$7.DOM;\n    var detection = detect$3();\n    var isiOS12 = detection.os.isiOS() && detection.os.version.major <= 12;\n    var setupEvents = function (editor) {\n      var contentWindow = editor.getWin();\n      var initialDocEle = editor.getDoc().documentElement;\n      var lastWindowDimensions = Cell(Position(contentWindow.innerWidth, contentWindow.innerHeight));\n      var lastDocumentDimensions = Cell(Position(initialDocEle.offsetWidth, initialDocEle.offsetHeight));\n      var resize = function (e) {\n        var docEle = editor.getDoc().documentElement;\n        var outer = lastWindowDimensions.get();\n        var inner = lastDocumentDimensions.get();\n        if (outer.left() !== contentWindow.innerWidth || outer.top() !== contentWindow.innerHeight) {\n          lastWindowDimensions.set(Position(contentWindow.innerWidth, contentWindow.innerHeight));\n          Events.fireResizeContent(editor, e);\n        } else if (inner.left() !== docEle.offsetWidth || inner.top() !== docEle.offsetHeight) {\n          lastDocumentDimensions.set(Position(docEle.offsetWidth, docEle.offsetHeight));\n          Events.fireResizeContent(editor, e);\n        }\n      };\n      var scroll = function (e) {\n        return Events.fireScrollContent(editor, e);\n      };\n      DOM.bind(contentWindow, 'resize', resize);\n      DOM.bind(contentWindow, 'scroll', scroll);\n      var elementLoad = capture$1(Element.fromDom(editor.getBody()), 'load', resize);\n      editor.on('remove', function () {\n        elementLoad.unbind();\n        DOM.unbind(contentWindow, 'resize', resize);\n        DOM.unbind(contentWindow, 'scroll', scroll);\n      });\n    };\n    var render = function (editor, uiComponents, rawUiConfig, backstage, args) {\n      var lastToolbarWidth = Cell(0);\n      iframe(editor);\n      attachSystemAfter(Element.fromDom(args.targetNode), uiComponents.mothership);\n      attachSystem(body(), uiComponents.uiMothership);\n      editor.on('PostRender', function () {\n        setToolbar(editor, uiComponents, rawUiConfig, backstage);\n        lastToolbarWidth.set(editor.getWin().innerWidth);\n        OuterContainer.setMenubar(uiComponents.outerContainer, identifyMenus(editor, rawUiConfig));\n        OuterContainer.setSidebar(uiComponents.outerContainer, rawUiConfig.sidebar);\n        setupEvents(editor);\n      });\n      var socket = OuterContainer.getSocket(uiComponents.outerContainer).getOrDie('Could not find expected socket element');\n      if (isiOS12 === true) {\n        setAll$1(socket.element(), {\n          'overflow': 'scroll',\n          '-webkit-overflow-scrolling': 'touch'\n        });\n        var limit = first$1(function () {\n          editor.fire('ScrollContent');\n        }, 20);\n        bind$3(socket.element(), 'scroll', limit.throttle);\n      }\n      setupReadonlyModeSwitch(editor, uiComponents);\n      editor.addCommand('ToggleSidebar', function (ui, value) {\n        OuterContainer.toggleSidebar(uiComponents.outerContainer, value);\n        editor.fire('ToggleSidebar');\n      });\n      editor.addQueryValueHandler('ToggleSidebar', function () {\n        return OuterContainer.whichSidebar(uiComponents.outerContainer);\n      });\n      var drawer = getToolbarDrawer(editor);\n      var refreshDrawer = function () {\n        OuterContainer.refreshToolbar(uiComponents.outerContainer);\n      };\n      if (drawer === ToolbarDrawer.sliding || drawer === ToolbarDrawer.floating) {\n        editor.on('ResizeWindow ResizeEditor ResizeContent', function () {\n          var width = editor.getWin().innerWidth;\n          if (width !== lastToolbarWidth.get()) {\n            refreshDrawer();\n            lastToolbarWidth.set(width);\n          }\n        });\n      }\n      return {\n        iframeContainer: socket.element().dom(),\n        editorContainer: uiComponents.outerContainer.element().dom()\n      };\n    };\n    var Iframe = { render: render };\n\n    var parseToInt = function (val) {\n      var re = /^[0-9\\.]+(|px)$/i;\n      if (re.test('' + val)) {\n        return Option.some(parseInt('' + val, 10));\n      }\n      return Option.none();\n    };\n    var numToPx = function (val) {\n      return isNumber(val) ? val + 'px' : val;\n    };\n    var calcCappedSize = function (size, minSize, maxSize) {\n      var minOverride = minSize.filter(function (min) {\n        return size < min;\n      });\n      var maxOverride = maxSize.filter(function (max) {\n        return size > max;\n      });\n      return minOverride.or(maxOverride).getOr(size);\n    };\n    var Utils = {\n      calcCappedSize: calcCappedSize,\n      parseToInt: parseToInt,\n      numToPx: numToPx\n    };\n\n    var getHeight$1 = function (editor) {\n      var baseHeight = getHeightSetting(editor);\n      var minHeight = getMinHeightSetting(editor);\n      var maxHeight = getMaxHeightSetting(editor);\n      return Utils.parseToInt(baseHeight).map(function (height) {\n        return Utils.calcCappedSize(height, minHeight, maxHeight);\n      });\n    };\n    var getHeightWithFallback = function (editor) {\n      var height = getHeight$1(editor);\n      return height.getOr(getHeightSetting(editor));\n    };\n    var getWidth$1 = function (editor) {\n      var baseWidth = getWidthSetting(editor);\n      var minWidth = getMinWidthSetting(editor);\n      var maxWidth = getMaxWidthSetting(editor);\n      return Utils.parseToInt(baseWidth).map(function (width) {\n        return Utils.calcCappedSize(width, minWidth, maxWidth);\n      });\n    };\n    var getWidthWithFallback = function (editor) {\n      var width = getWidth$1(editor);\n      return width.getOr(getWidthSetting(editor));\n    };\n\n    var render$1 = function (editor, uiComponents, rawUiConfig, backstage, args) {\n      var floatContainer;\n      var DOM = global$7.DOM;\n      var useFixedToolbarContainer = useFixedContainer(editor);\n      var isSticky = isStickyToolbar(editor);\n      var targetElm = Element.fromDom(args.targetNode);\n      var editorMaxWidthOpt = getMaxWidthSetting(editor).or(getWidth$1(editor));\n      var splitSetting = getToolbarDrawer(editor);\n      var split = splitSetting === ToolbarDrawer.sliding || splitSetting === ToolbarDrawer.floating;\n      inline(editor);\n      var updateChromePosition = function (toolbar) {\n        var offset = split ? toolbar.fold(function () {\n          return 0;\n        }, function (tbar) {\n          return tbar.components().length > 1 ? get$6(tbar.components()[1].element()) : 0;\n        }) : 0;\n        var location = absolute(targetElm);\n        var top = location.top() - get$6(floatContainer.element()) + offset;\n        setAll$1(uiComponents.outerContainer.element(), {\n          position: 'absolute',\n          top: Math.round(top) + 'px',\n          left: Math.round(location.left()) + 'px'\n        });\n        var maxWidth = editorMaxWidthOpt.getOrThunk(function () {\n          var bodyMargin = Utils.parseToInt(get$4(body(), 'margin-left')).getOr(0);\n          return get$7(body()) - location.left() + bodyMargin;\n        });\n        set$2(floatContainer.element(), 'max-width', maxWidth + 'px');\n      };\n      var updateChromeUi = function (resetDocking) {\n        if (resetDocking === void 0) {\n          resetDocking = false;\n        }\n        if (split) {\n          OuterContainer.refreshToolbar(uiComponents.outerContainer);\n        }\n        if (!useFixedToolbarContainer) {\n          var toolbar = OuterContainer.getToolbar(uiComponents.outerContainer);\n          updateChromePosition(toolbar);\n        }\n        if (isSticky) {\n          resetDocking ? Docking.reset(floatContainer) : Docking.refresh(floatContainer);\n        }\n      };\n      var show = function () {\n        set$2(uiComponents.outerContainer.element(), 'display', 'flex');\n        DOM.addClass(editor.getBody(), 'mce-edit-focus');\n        remove$6(uiComponents.uiMothership.element(), 'display');\n        updateChromeUi();\n      };\n      var hide = function () {\n        if (uiComponents.outerContainer) {\n          set$2(uiComponents.outerContainer.element(), 'display', 'none');\n          DOM.removeClass(editor.getBody(), 'mce-edit-focus');\n        }\n        set$2(uiComponents.uiMothership.element(), 'display', 'none');\n      };\n      var render = function () {\n        if (floatContainer) {\n          show();\n          return;\n        }\n        floatContainer = OuterContainer.getHeader(uiComponents.outerContainer).getOrDie();\n        var uiContainer = getUiContainer(editor);\n        attachSystem(uiContainer, uiComponents.mothership);\n        attachSystem(uiContainer, uiComponents.uiMothership);\n        setToolbar(editor, uiComponents, rawUiConfig, backstage);\n        OuterContainer.setMenubar(uiComponents.outerContainer, identifyMenus(editor, rawUiConfig));\n        show();\n        editor.on('activate', show);\n        editor.on('deactivate', hide);\n        editor.on('NodeChange SkinLoaded ResizeWindow', function () {\n          if (!editor.hidden) {\n            updateChromeUi(true);\n          }\n        });\n        editor.nodeChanged();\n      };\n      editor.on('focus', render);\n      editor.on('blur hide', hide);\n      editor.on('init', function () {\n        if (editor.hasFocus()) {\n          render();\n        }\n      });\n      setupReadonlyModeSwitch(editor, uiComponents);\n      return { editorContainer: uiComponents.outerContainer.element().dom() };\n    };\n    var Inline = { render: render$1 };\n\n    var register$5 = function (editor) {\n      var alignToolbarButtons = [\n        {\n          name: 'alignleft',\n          text: 'Align left',\n          cmd: 'JustifyLeft',\n          icon: 'align-left'\n        },\n        {\n          name: 'aligncenter',\n          text: 'Align center',\n          cmd: 'JustifyCenter',\n          icon: 'align-center'\n        },\n        {\n          name: 'alignright',\n          text: 'Align right',\n          cmd: 'JustifyRight',\n          icon: 'align-right'\n        },\n        {\n          name: 'alignjustify',\n          text: 'Justify',\n          cmd: 'JustifyFull',\n          icon: 'align-justify'\n        }\n      ];\n      global$e.each(alignToolbarButtons, function (item) {\n        editor.ui.registry.addToggleButton(item.name, {\n          tooltip: item.text,\n          onAction: function () {\n            return editor.execCommand(item.cmd);\n          },\n          icon: item.icon,\n          onSetup: onSetupFormatToggle(editor, item.name)\n        });\n      });\n      var alignNoneToolbarButton = {\n        name: 'alignnone',\n        text: 'No alignment',\n        cmd: 'JustifyNone',\n        icon: 'align-none'\n      };\n      editor.ui.registry.addButton(alignNoneToolbarButton.name, {\n        tooltip: alignNoneToolbarButton.text,\n        onAction: function () {\n          return editor.execCommand(alignNoneToolbarButton.cmd);\n        },\n        icon: alignNoneToolbarButton.icon\n      });\n    };\n    var AlignmentButtons = { register: register$5 };\n\n    var toggleFormat = function (editor, fmt) {\n      return function () {\n        editor.execCommand('mceToggleFormat', false, fmt);\n      };\n    };\n    var registerFormatButtons = function (editor) {\n      global$e.each([\n        {\n          name: 'bold',\n          text: 'Bold',\n          icon: 'bold'\n        },\n        {\n          name: 'italic',\n          text: 'Italic',\n          icon: 'italic'\n        },\n        {\n          name: 'underline',\n          text: 'Underline',\n          icon: 'underline'\n        },\n        {\n          name: 'strikethrough',\n          text: 'Strikethrough',\n          icon: 'strike-through'\n        },\n        {\n          name: 'subscript',\n          text: 'Subscript',\n          icon: 'subscript'\n        },\n        {\n          name: 'superscript',\n          text: 'Superscript',\n          icon: 'superscript'\n        }\n      ], function (btn, idx) {\n        editor.ui.registry.addToggleButton(btn.name, {\n          tooltip: btn.text,\n          icon: btn.icon,\n          onSetup: onSetupFormatToggle(editor, btn.name),\n          onAction: toggleFormat(editor, btn.name)\n        });\n      });\n      for (var i = 1; i <= 6; i++) {\n        var name = 'h' + i;\n        editor.ui.registry.addToggleButton(name, {\n          text: name.toUpperCase(),\n          tooltip: 'Heading ' + i,\n          onSetup: onSetupFormatToggle(editor, name),\n          onAction: toggleFormat(editor, name)\n        });\n      }\n    };\n    var registerCommandButtons = function (editor) {\n      global$e.each([\n        {\n          name: 'cut',\n          text: 'Cut',\n          action: 'Cut',\n          icon: 'cut'\n        },\n        {\n          name: 'copy',\n          text: 'Copy',\n          action: 'Copy',\n          icon: 'copy'\n        },\n        {\n          name: 'paste',\n          text: 'Paste',\n          action: 'Paste',\n          icon: 'paste'\n        },\n        {\n          name: 'help',\n          text: 'Help',\n          action: 'mceHelp',\n          icon: 'help'\n        },\n        {\n          name: 'selectall',\n          text: 'Select all',\n          action: 'SelectAll',\n          icon: 'select-all'\n        },\n        {\n          name: 'newdocument',\n          text: 'New document',\n          action: 'mceNewDocument',\n          icon: 'new-document'\n        },\n        {\n          name: 'removeformat',\n          text: 'Clear formatting',\n          action: 'RemoveFormat',\n          icon: 'remove-formatting'\n        },\n        {\n          name: 'remove',\n          text: 'Remove',\n          action: 'Delete',\n          icon: 'remove'\n        }\n      ], function (btn) {\n        editor.ui.registry.addButton(btn.name, {\n          tooltip: btn.text,\n          icon: btn.icon,\n          onAction: function () {\n            return editor.execCommand(btn.action);\n          }\n        });\n      });\n    };\n    var registerCommandToggleButtons = function (editor) {\n      global$e.each([{\n          name: 'blockquote',\n          text: 'Blockquote',\n          action: 'mceBlockQuote',\n          icon: 'quote'\n        }], function (btn) {\n        editor.ui.registry.addToggleButton(btn.name, {\n          tooltip: btn.text,\n          icon: btn.icon,\n          onAction: function () {\n            return editor.execCommand(btn.action);\n          },\n          onSetup: onSetupFormatToggle(editor, btn.name)\n        });\n      });\n    };\n    var registerButtons = function (editor) {\n      registerFormatButtons(editor);\n      registerCommandButtons(editor);\n      registerCommandToggleButtons(editor);\n    };\n    var registerMenuItems = function (editor) {\n      global$e.each([\n        {\n          name: 'bold',\n          text: 'Bold',\n          action: 'Bold',\n          icon: 'bold',\n          shortcut: 'Meta+B'\n        },\n        {\n          name: 'italic',\n          text: 'Italic',\n          action: 'Italic',\n          icon: 'italic',\n          shortcut: 'Meta+I'\n        },\n        {\n          name: 'underline',\n          text: 'Underline',\n          action: 'Underline',\n          icon: 'underline',\n          shortcut: 'Meta+U'\n        },\n        {\n          name: 'strikethrough',\n          text: 'Strikethrough',\n          action: 'Strikethrough',\n          icon: 'strike-through',\n          shortcut: ''\n        },\n        {\n          name: 'subscript',\n          text: 'Subscript',\n          action: 'Subscript',\n          icon: 'subscript',\n          shortcut: ''\n        },\n        {\n          name: 'superscript',\n          text: 'Superscript',\n          action: 'Superscript',\n          icon: 'superscript',\n          shortcut: ''\n        },\n        {\n          name: 'removeformat',\n          text: 'Clear formatting',\n          action: 'RemoveFormat',\n          icon: 'remove-formatting',\n          shortcut: ''\n        },\n        {\n          name: 'newdocument',\n          text: 'New document',\n          action: 'mceNewDocument',\n          icon: 'new-document',\n          shortcut: ''\n        },\n        {\n          name: 'cut',\n          text: 'Cut',\n          action: 'Cut',\n          icon: 'cut',\n          shortcut: 'Meta+X'\n        },\n        {\n          name: 'copy',\n          text: 'Copy',\n          action: 'Copy',\n          icon: 'copy',\n          shortcut: 'Meta+C'\n        },\n        {\n          name: 'paste',\n          text: 'Paste',\n          action: 'Paste',\n          icon: 'paste',\n          shortcut: 'Meta+V'\n        },\n        {\n          name: 'selectall',\n          text: 'Select all',\n          action: 'SelectAll',\n          icon: 'select-all',\n          shortcut: 'Meta+A'\n        }\n      ], function (btn) {\n        editor.ui.registry.addMenuItem(btn.name, {\n          text: btn.text,\n          icon: btn.icon,\n          shortcut: btn.shortcut,\n          onAction: function () {\n            return editor.execCommand(btn.action);\n          }\n        });\n      });\n      editor.ui.registry.addMenuItem('codeformat', {\n        text: 'Code',\n        icon: 'sourcecode',\n        onAction: toggleFormat(editor, 'code')\n      });\n    };\n    var register$6 = function (editor) {\n      registerButtons(editor);\n      registerMenuItems(editor);\n    };\n    var SimpleControls = { register: register$6 };\n\n    var toggleUndoRedoState = function (api, editor, type) {\n      var checkState = function () {\n        return editor.undoManager ? editor.undoManager[type]() : false;\n      };\n      var onUndoStateChange = function () {\n        api.setDisabled(editor.readonly || !checkState());\n      };\n      api.setDisabled(!checkState());\n      editor.on('Undo Redo AddUndo TypingUndo ClearUndos SwitchMode', onUndoStateChange);\n      return function () {\n        return editor.off('Undo Redo AddUndo TypingUndo ClearUndos SwitchMode', onUndoStateChange);\n      };\n    };\n    var registerMenuItems$1 = function (editor) {\n      editor.ui.registry.addMenuItem('undo', {\n        text: 'Undo',\n        icon: 'undo',\n        shortcut: 'Meta+Z',\n        onSetup: function (api) {\n          return toggleUndoRedoState(api, editor, 'hasUndo');\n        },\n        onAction: function () {\n          return editor.execCommand('undo');\n        }\n      });\n      editor.ui.registry.addMenuItem('redo', {\n        text: 'Redo',\n        icon: 'redo',\n        shortcut: 'Meta+Y',\n        onSetup: function (api) {\n          return toggleUndoRedoState(api, editor, 'hasRedo');\n        },\n        onAction: function () {\n          return editor.execCommand('redo');\n        }\n      });\n    };\n    var registerButtons$1 = function (editor) {\n      editor.ui.registry.addButton('undo', {\n        tooltip: 'Undo',\n        icon: 'undo',\n        onSetup: function (api) {\n          return toggleUndoRedoState(api, editor, 'hasUndo');\n        },\n        onAction: function () {\n          return editor.execCommand('undo');\n        }\n      });\n      editor.ui.registry.addButton('redo', {\n        tooltip: 'Redo',\n        icon: 'redo',\n        onSetup: function (api) {\n          return toggleUndoRedoState(api, editor, 'hasRedo');\n        },\n        onAction: function () {\n          return editor.execCommand('redo');\n        }\n      });\n    };\n    var register$7 = function (editor) {\n      registerMenuItems$1(editor);\n      registerButtons$1(editor);\n    };\n    var UndoRedo = { register: register$7 };\n\n    var toggleVisualAidState = function (api, editor) {\n      api.setActive(editor.hasVisual);\n      var onVisualAid = function (e) {\n        api.setActive(e.hasVisual);\n      };\n      editor.on('VisualAid', onVisualAid);\n      return function () {\n        return editor.off('VisualAid', onVisualAid);\n      };\n    };\n    var registerMenuItems$2 = function (editor) {\n      editor.ui.registry.addToggleMenuItem('visualaid', {\n        text: 'Visual aids',\n        onSetup: function (api) {\n          return toggleVisualAidState(api, editor);\n        },\n        onAction: function () {\n          editor.execCommand('mceToggleVisualAid');\n        }\n      });\n    };\n    var registerToolbarButton = function (editor) {\n      editor.ui.registry.addButton('visualaid', {\n        tooltip: 'Visual aids',\n        text: 'Visual aids',\n        onAction: function () {\n          return editor.execCommand('mceToggleVisualAid');\n        }\n      });\n    };\n    var register$8 = function (editor) {\n      registerToolbarButton(editor);\n      registerMenuItems$2(editor);\n    };\n    var VisualAid = { register: register$8 };\n\n    var toggleOutdentState = function (api, editor) {\n      api.setDisabled(!editor.queryCommandState('outdent'));\n      var onNodeChange = function () {\n        api.setDisabled(!editor.queryCommandState('outdent'));\n      };\n      editor.on('NodeChange', onNodeChange);\n      return function () {\n        return editor.off('NodeChange', onNodeChange);\n      };\n    };\n    var registerButtons$2 = function (editor) {\n      editor.ui.registry.addButton('outdent', {\n        tooltip: 'Decrease indent',\n        icon: 'outdent',\n        onSetup: function (api) {\n          return toggleOutdentState(api, editor);\n        },\n        onAction: function () {\n          return editor.execCommand('outdent');\n        }\n      });\n      editor.ui.registry.addButton('indent', {\n        tooltip: 'Increase indent',\n        icon: 'indent',\n        onAction: function () {\n          return editor.execCommand('indent');\n        }\n      });\n    };\n    var register$9 = function (editor) {\n      registerButtons$2(editor);\n    };\n    var IndentOutdent = { register: register$9 };\n\n    var register$a = function (editor, backstage) {\n      alignSelectMenu(editor, backstage);\n      fontSelectMenu(editor, backstage);\n      styleSelectMenu(editor, backstage);\n      formatSelectMenu(editor, backstage);\n      fontsizeSelectMenu(editor, backstage);\n    };\n    var ComplexControls = { register: register$a };\n\n    var setup$9 = function (editor, backstage) {\n      AlignmentButtons.register(editor);\n      SimpleControls.register(editor);\n      ComplexControls.register(editor, backstage);\n      UndoRedo.register(editor);\n      ColorSwatch.register(editor);\n      VisualAid.register(editor);\n      IndentOutdent.register(editor);\n    };\n    var FormatControls = { setup: setup$9 };\n\n    var nu$d = function (x, y) {\n      return {\n        anchor: 'makeshift',\n        x: x,\n        y: y\n      };\n    };\n    var transpose$1 = function (pos, dx, dy) {\n      return nu$d(pos.x + dx, pos.y + dy);\n    };\n    var isTouchEvent$1 = function (e) {\n      return e.type === 'longpress' || e.type.indexOf('touch') === 0;\n    };\n    var fromPageXY = function (e) {\n      if (isTouchEvent$1(e)) {\n        var touch = e.touches[0];\n        return nu$d(touch.pageX, touch.pageY);\n      } else {\n        return nu$d(e.pageX, e.pageY);\n      }\n    };\n    var fromClientXY = function (e) {\n      if (isTouchEvent$1(e)) {\n        var touch = e.touches[0];\n        return nu$d(touch.clientX, touch.clientY);\n      } else {\n        return nu$d(e.clientX, e.clientY);\n      }\n    };\n    var transposeContentAreaContainer = function (element, pos) {\n      var containerPos = global$7.DOM.getPos(element);\n      return transpose$1(pos, containerPos.x, containerPos.y);\n    };\n    var getPointAnchor = function (editor, e) {\n      if (e.type === 'contextmenu') {\n        if (editor.inline) {\n          return fromPageXY(e);\n        } else {\n          return transposeContentAreaContainer(editor.getContentAreaContainer(), fromClientXY(e));\n        }\n      } else {\n        return getSelectionAnchor(editor);\n      }\n    };\n    var getSelectionAnchor = function (editor) {\n      return {\n        anchor: 'selection',\n        root: Element.fromDom(editor.selection.getNode())\n      };\n    };\n    var getNodeAnchor$1 = function (editor) {\n      return {\n        anchor: 'node',\n        node: Option.some(Element.fromDom(editor.selection.getNode())),\n        root: Element.fromDom(editor.getBody())\n      };\n    };\n\n    var getAnchorSpec = function (editor, e, isTriggeredByKeyboardEvent) {\n      return isTriggeredByKeyboardEvent ? getNodeAnchor$1(editor) : getPointAnchor(editor, e);\n    };\n    var initAndShow = function (editor, e, buildMenu, backstage, contextmenu, isTriggeredByKeyboardEvent) {\n      var items = buildMenu();\n      var anchorSpec = getAnchorSpec(editor, e, isTriggeredByKeyboardEvent);\n      build$2(items, ItemResponse$1.CLOSE_ON_EXECUTE, backstage, false).map(function (menuData) {\n        e.preventDefault();\n        InlineView.showMenuAt(contextmenu, anchorSpec, {\n          menu: { markers: markers$1('normal') },\n          data: menuData\n        });\n      });\n    };\n\n    var layouts = {\n      onLtr: function () {\n        return [\n          south$1,\n          southeast$1,\n          southwest$1,\n          northeast$1,\n          northwest$1,\n          north$1,\n          north$3,\n          south$3,\n          northeast$3,\n          southeast$3,\n          northwest$3,\n          southwest$3\n        ];\n      },\n      onRtl: function () {\n        return [\n          south$1,\n          southwest$1,\n          southeast$1,\n          northwest$1,\n          northeast$1,\n          north$1,\n          north$3,\n          south$3,\n          northwest$3,\n          southwest$3,\n          northeast$3,\n          southeast$3\n        ];\n      }\n    };\n    var bubbleSize$1 = 12;\n    var bubbleAlignments$2 = {\n      valignCentre: [],\n      alignCentre: [],\n      alignLeft: ['tox-pop--align-left'],\n      alignRight: ['tox-pop--align-right'],\n      right: ['tox-pop--right'],\n      left: ['tox-pop--left'],\n      bottom: ['tox-pop--bottom'],\n      top: ['tox-pop--top']\n    };\n    var isTouchWithinSelection = function (editor, e) {\n      var selection = editor.selection;\n      if (selection.isCollapsed() || e.touches.length < 1) {\n        return false;\n      } else {\n        var touch_1 = e.touches[0];\n        var rng = selection.getRng();\n        var rngRectOpt = getFirstRect$1(editor.getWin(), Selection.domRange(rng));\n        return rngRectOpt.exists(function (rngRect) {\n          return rngRect.left() <= touch_1.clientX && rngRect.right() >= touch_1.clientX && rngRect.top() <= touch_1.clientY && rngRect.bottom() >= touch_1.clientY;\n        });\n      }\n    };\n    var getAnchorSpec$1 = function (editor, isTriggeredByKeyboardEvent) {\n      var anchorSpec = isTriggeredByKeyboardEvent ? getNodeAnchor$1(editor) : getSelectionAnchor(editor);\n      return __assign({\n        bubble: nu$8(0, bubbleSize$1, bubbleAlignments$2),\n        layouts: layouts,\n        overrides: {\n          maxWidthFunction: expandable$1(),\n          maxHeightFunction: expandable()\n        }\n      }, anchorSpec);\n    };\n    var setupiOSOverrides = function (editor) {\n      var originalSelection = editor.selection.getRng();\n      var selectionReset = function () {\n        global$2.setEditorTimeout(editor, function () {\n          editor.selection.setRng(originalSelection);\n        }, 10);\n        unbindEventListeners();\n      };\n      editor.once('touchend', selectionReset);\n      var preventMousedown = function (e) {\n        e.preventDefault();\n        e.stopImmediatePropagation();\n      };\n      editor.on('mousedown', preventMousedown, true);\n      var clearSelectionReset = function () {\n        return unbindEventListeners();\n      };\n      editor.once('longpresscancel', clearSelectionReset);\n      var unbindEventListeners = function () {\n        editor.off('touchend', selectionReset);\n        editor.off('longpresscancel', clearSelectionReset);\n        editor.off('mousedown', preventMousedown);\n      };\n    };\n    var show = function (editor, e, items, backstage, contextmenu, isTriggeredByKeyboardEvent) {\n      var anchorSpec = getAnchorSpec$1(editor, isTriggeredByKeyboardEvent);\n      build$2(items, ItemResponse$1.CLOSE_ON_EXECUTE, backstage, true).map(function (menuData) {\n        e.preventDefault();\n        InlineView.showMenuWithinBounds(contextmenu, anchorSpec, {\n          menu: { markers: markers$1('normal') },\n          data: menuData,\n          type: 'horizontal'\n        }, function () {\n          return Option.some(getContextToolbarBounds(editor));\n        });\n        editor.fire(hideContextToolbarEvent);\n      });\n    };\n    var initAndShow$1 = function (editor, e, buildMenu, backstage, contextmenu, isTriggeredByKeyboardEvent) {\n      var detection = detect$3();\n      var isiOS = detection.os.isiOS();\n      var isOSX = detection.os.isOSX();\n      var isAndroid = detection.os.isAndroid();\n      var open = function () {\n        var items = buildMenu();\n        show(editor, e, items, backstage, contextmenu, isTriggeredByKeyboardEvent);\n      };\n      if ((isOSX || isiOS) && !isTriggeredByKeyboardEvent) {\n        var openiOS_1 = function () {\n          setupiOSOverrides(editor);\n          open();\n        };\n        if (isTouchWithinSelection(editor, e)) {\n          openiOS_1();\n        } else {\n          editor.once('selectionchange', openiOS_1);\n          editor.once('touchend', function () {\n            return editor.off('selectionchange', openiOS_1);\n          });\n        }\n      } else {\n        if (isAndroid && !isTriggeredByKeyboardEvent) {\n          editor.selection.setCursorLocation(e.target, 0);\n        }\n        open();\n      }\n    };\n\n    var patchPipeConfig = function (config) {\n      return typeof config === 'string' ? config.split(/[ ,]/) : config;\n    };\n    var shouldNeverUseNative = function (editor) {\n      return editor.settings.contextmenu_never_use_native || false;\n    };\n    var getMenuItems = function (editor, name, defaultItems) {\n      var contextMenus = editor.ui.registry.getAll().contextMenus;\n      return get(editor.settings, name).map(patchPipeConfig).getOrThunk(function () {\n        return filter(patchPipeConfig(defaultItems), function (item) {\n          return has(contextMenus, item);\n        });\n      });\n    };\n    var isContextMenuDisabled = function (editor) {\n      return editor.getParam('contextmenu') === false;\n    };\n    var getContextMenu = function (editor) {\n      return getMenuItems(editor, 'contextmenu', 'link linkchecker image imagetools table spellchecker configurepermanentpen');\n    };\n    var Settings$1 = {\n      shouldNeverUseNative: shouldNeverUseNative,\n      getContextMenu: getContextMenu,\n      isContextMenuDisabled: isContextMenuDisabled\n    };\n\n    var isSeparator$1 = function (item) {\n      return isString(item) ? item === '|' : item.type === 'separator';\n    };\n    var separator$3 = { type: 'separator' };\n    var makeContextItem = function (item) {\n      if (isString(item)) {\n        return item;\n      } else {\n        switch (item.type) {\n        case 'separator':\n          return separator$3;\n        case 'submenu':\n          return {\n            type: 'nestedmenuitem',\n            text: item.text,\n            icon: item.icon,\n            getSubmenuItems: function () {\n              var items = item.getSubmenuItems();\n              if (isString(items)) {\n                return items;\n              } else {\n                return map(items, makeContextItem);\n              }\n            }\n          };\n        default:\n          return {\n            type: 'menuitem',\n            text: item.text,\n            icon: item.icon,\n            onAction: noarg(item.onAction)\n          };\n        }\n      }\n    };\n    var addContextMenuGroup = function (xs, groupItems) {\n      if (groupItems.length === 0) {\n        return xs;\n      }\n      var lastMenuItem = last(xs).filter(function (item) {\n        return !isSeparator$1(item);\n      });\n      var before = lastMenuItem.fold(function () {\n        return [];\n      }, function (_) {\n        return [separator$3];\n      });\n      return xs.concat(before).concat(groupItems).concat([separator$3]);\n    };\n    var generateContextMenu = function (contextMenus, menuConfig, selectedElement) {\n      var sections = foldl(menuConfig, function (acc, name) {\n        if (has(contextMenus, name)) {\n          var items = contextMenus[name].update(selectedElement);\n          if (isString(items)) {\n            return addContextMenuGroup(acc, items.split(' '));\n          } else if (items.length > 0) {\n            var allItems = map(items, makeContextItem);\n            return addContextMenuGroup(acc, allItems);\n          } else {\n            return acc;\n          }\n        } else {\n          return acc.concat([name]);\n        }\n      }, []);\n      if (sections.length > 0 && isSeparator$1(sections[sections.length - 1])) {\n        sections.pop();\n      }\n      return sections;\n    };\n    var isNativeOverrideKeyEvent = function (editor, e) {\n      return e.ctrlKey && !Settings$1.shouldNeverUseNative(editor);\n    };\n    var setup$a = function (editor, lazySink, backstage) {\n      var detection = detect$3();\n      var isTouch = detection.deviceType.isTouch;\n      var contextmenu = build$1(InlineView.sketch({\n        dom: { tag: 'div' },\n        lazySink: lazySink,\n        onEscape: function () {\n          return editor.focus();\n        },\n        onShow: function () {\n          return backstage.setContextMenuState(true);\n        },\n        onHide: function () {\n          return backstage.setContextMenuState(false);\n        },\n        fireDismissalEventInstead: {},\n        inlineBehaviours: derive$1([config('dismissContextMenu', [run(dismissRequested(), function (comp, se) {\n              Sandboxing.close(comp);\n              editor.focus();\n            })])])\n      }));\n      var hideContextMenu = function (_e) {\n        return InlineView.hide(contextmenu);\n      };\n      var showContextMenu = function (e) {\n        var isLongpress = e.type === 'longpress';\n        if (Settings$1.shouldNeverUseNative(editor)) {\n          e.preventDefault();\n        }\n        if (isNativeOverrideKeyEvent(editor, e) || Settings$1.isContextMenuDisabled(editor)) {\n          return;\n        }\n        var isTriggeredByKeyboardEvent = !isLongpress && (e.button !== 2 || e.target === editor.getBody());\n        var buildMenu = function () {\n          var selectedElement = isTriggeredByKeyboardEvent ? editor.selection.getStart(true) : e.target;\n          var registry = editor.ui.registry.getAll();\n          var menuConfig = Settings$1.getContextMenu(editor);\n          return generateContextMenu(registry.contextMenus, menuConfig, selectedElement);\n        };\n        var initAndShow$2 = isTouch() ? initAndShow$1 : initAndShow;\n        initAndShow$2(editor, e, buildMenu, backstage, contextmenu, isTriggeredByKeyboardEvent);\n      };\n      editor.on('init', function () {\n        var hideEvents = 'ResizeEditor ScrollContent ScrollWindow longpresscancel' + (isTouch() ? '' : ' ResizeWindow');\n        editor.on(hideEvents, hideContextMenu);\n        editor.on(isTouch() ? 'longpress' : 'longpress contextmenu', showContextMenu);\n      });\n    };\n\n    var initialAttribute = 'data-initial-z-index';\n    var resetZIndex = function (blocker) {\n      parent(blocker.element()).filter(isElement).each(function (root) {\n        var initZIndex = get$2(root, initialAttribute);\n        if (has$1(root, initialAttribute)) {\n          set$2(root, 'z-index', initZIndex);\n        } else {\n          remove$6(root, 'z-index');\n        }\n        remove$1(root, initialAttribute);\n      });\n    };\n    var changeZIndex = function (blocker) {\n      parent(blocker.element()).filter(isElement).each(function (root) {\n        getRaw(root, 'z-index').each(function (zindex) {\n          set$1(root, initialAttribute, zindex);\n        });\n        set$2(root, 'z-index', get$4(blocker.element(), 'z-index'));\n      });\n    };\n    var instigate = function (anyComponent, blocker) {\n      anyComponent.getSystem().addToGui(blocker);\n      changeZIndex(blocker);\n    };\n    var discard = function (blocker) {\n      resetZIndex(blocker);\n      blocker.getSystem().removeFromGui(blocker);\n    };\n    var createComponent = function (component, blockerClass, blockerEvents) {\n      return component.getSystem().build(Container.sketch({\n        dom: {\n          styles: {\n            'left': '0px',\n            'top': '0px',\n            'width': '100%',\n            'height': '100%',\n            'position': 'fixed',\n            'z-index': '1000000000000000'\n          },\n          classes: [blockerClass]\n        },\n        events: blockerEvents\n      }));\n    };\n\n    var SnapSchema = optionObjOf('snaps', [\n      strict$1('getSnapPoints'),\n      onHandler('onSensor'),\n      strict$1('leftAttr'),\n      strict$1('topAttr'),\n      defaulted$1('lazyViewport', win),\n      defaulted$1('mustSnap', false)\n    ]);\n\n    var schema$s = [\n      defaulted$1('useFixed', never),\n      strict$1('blockerClass'),\n      defaulted$1('getTarget', identity),\n      defaulted$1('onDrag', noop),\n      defaulted$1('repositionTarget', true),\n      defaulted$1('onDrop', noop),\n      defaultedFunction('getBounds', win),\n      SnapSchema\n    ];\n\n    var get$d = function (component, snapsInfo) {\n      var element = component.element();\n      var x = parseInt(get$2(element, snapsInfo.leftAttr), 10);\n      var y = parseInt(get$2(element, snapsInfo.topAttr), 10);\n      return isNaN(x) || isNaN(y) ? Option.none() : Option.some(Position(x, y));\n    };\n    var set$8 = function (component, snapsInfo, pt) {\n      var element = component.element();\n      set$1(element, snapsInfo.leftAttr, pt.left() + 'px');\n      set$1(element, snapsInfo.topAttr, pt.top() + 'px');\n    };\n    var clear = function (component, snapsInfo) {\n      var element = component.element();\n      remove$1(element, snapsInfo.leftAttr);\n      remove$1(element, snapsInfo.topAttr);\n    };\n\n    var getCoords = function (component, snapInfo, coord, delta) {\n      return get$d(component, snapInfo).fold(function () {\n        return coord;\n      }, function (fixed) {\n        return fixed$1(fixed.left() + delta.left(), fixed.top() + delta.top());\n      });\n    };\n    var moveOrSnap = function (component, snapInfo, coord, delta, scroll, origin) {\n      var newCoord = getCoords(component, snapInfo, coord, delta);\n      var snap = snapInfo.mustSnap ? findClosestSnap(component, snapInfo, newCoord, scroll, origin) : findSnap(component, snapInfo, newCoord, scroll, origin);\n      var fixedCoord = asFixed(newCoord, scroll, origin);\n      set$8(component, snapInfo, fixedCoord);\n      return snap.fold(function () {\n        return {\n          coord: fixed$1(fixedCoord.left(), fixedCoord.top()),\n          extra: Option.none()\n        };\n      }, function (spanned) {\n        return {\n          coord: spanned.output(),\n          extra: spanned.extra()\n        };\n      });\n    };\n    var stopDrag = function (component, snapInfo) {\n      clear(component, snapInfo);\n    };\n    var findMatchingSnap = function (snaps, newCoord, scroll, origin) {\n      return findMap(snaps, function (snap) {\n        var sensor = snap.sensor();\n        var inRange = withinRange(newCoord, sensor, snap.range().left(), snap.range().top(), scroll, origin);\n        return inRange ? Option.some({\n          output: constant(absorb(snap.output(), newCoord, scroll, origin)),\n          extra: snap.extra\n        }) : Option.none();\n      });\n    };\n    var findClosestSnap = function (component, snapInfo, newCoord, scroll, origin) {\n      var snaps = snapInfo.getSnapPoints(component);\n      var matchSnap = findMatchingSnap(snaps, newCoord, scroll, origin);\n      return matchSnap.orThunk(function () {\n        var bestSnap = foldl(snaps, function (acc, snap) {\n          var sensor = snap.sensor();\n          var deltas = getDeltas(newCoord, sensor, snap.range().left(), snap.range().top(), scroll, origin);\n          return acc.deltas.fold(function () {\n            return {\n              deltas: Option.some(deltas),\n              snap: Option.some(snap)\n            };\n          }, function (bestDeltas) {\n            var currAvg = (deltas.left() + deltas.top()) / 2;\n            var bestAvg = (bestDeltas.left() + bestDeltas.top()) / 2;\n            if (currAvg <= bestAvg) {\n              return {\n                deltas: Option.some(deltas),\n                snap: Option.some(snap)\n              };\n            } else {\n              return acc;\n            }\n          });\n        }, {\n          deltas: Option.none(),\n          snap: Option.none()\n        });\n        return bestSnap.snap.map(function (snap) {\n          return {\n            output: constant(absorb(snap.output(), newCoord, scroll, origin)),\n            extra: snap.extra\n          };\n        });\n      });\n    };\n    var findSnap = function (component, snapInfo, newCoord, scroll, origin) {\n      var snaps = snapInfo.getSnapPoints(component);\n      return findMatchingSnap(snaps, newCoord, scroll, origin);\n    };\n    var snapTo = function (snap, scroll, origin) {\n      return {\n        coord: absorb(snap.output(), snap.output(), scroll, origin),\n        extra: snap.extra()\n      };\n    };\n\n    var getCurrentCoord = function (target) {\n      return lift3(getRaw(target, 'left'), getRaw(target, 'top'), getRaw(target, 'position'), function (left, top, position) {\n        var nu = position === 'fixed' ? fixed$1 : offset;\n        return nu(parseInt(left, 10), parseInt(top, 10));\n      }).getOrThunk(function () {\n        var location = absolute(target);\n        return absolute$3(location.left(), location.top());\n      });\n    };\n    var clampCoords = function (component, coords, scroll, origin, startData) {\n      var bounds = startData.bounds;\n      var absoluteCoord = asAbsolute(coords, scroll, origin);\n      var newX = cap(absoluteCoord.left(), bounds.x(), bounds.x() + bounds.width() - startData.width);\n      var newY = cap(absoluteCoord.top(), bounds.y(), bounds.y() + bounds.height() - startData.height);\n      var newCoords = absolute$3(newX, newY);\n      return coords.fold(function () {\n        var offset$1 = asOffset(newCoords, scroll, origin);\n        return offset(offset$1.left(), offset$1.top());\n      }, function () {\n        return newCoords;\n      }, function () {\n        var fixed = asFixed(newCoords, scroll, origin);\n        return fixed$1(fixed.left(), fixed.top());\n      });\n    };\n    var calcNewCoord = function (component, optSnaps, currentCoord, scroll, origin, delta, startData) {\n      var newCoord = optSnaps.fold(function () {\n        var translated = translate$2(currentCoord, delta.left(), delta.top());\n        var fixedCoord = asFixed(translated, scroll, origin);\n        return fixed$1(fixedCoord.left(), fixedCoord.top());\n      }, function (snapInfo) {\n        var snapping = moveOrSnap(component, snapInfo, currentCoord, delta, scroll, origin);\n        snapping.extra.each(function (extra) {\n          snapInfo.onSensor(component, extra);\n        });\n        return snapping.coord;\n      });\n      return clampCoords(component, newCoord, scroll, origin, startData);\n    };\n    var dragBy = function (component, dragConfig, startData, delta) {\n      var target = dragConfig.getTarget(component.element());\n      if (dragConfig.repositionTarget) {\n        var doc = owner(component.element());\n        var scroll = get$8(doc);\n        var origin = getOrigin(target);\n        var currentCoord = getCurrentCoord(target);\n        var newCoord = calcNewCoord(component, dragConfig.snaps, currentCoord, scroll, origin, delta, startData);\n        var styles = toStyles(newCoord, scroll, origin);\n        setAll$1(target, styles);\n      }\n      dragConfig.onDrag(component, target, delta);\n    };\n\n    var calcStartData = function (dragConfig, comp) {\n      return {\n        bounds: dragConfig.getBounds(),\n        height: getOuter$1(comp.element()),\n        width: getOuter$2(comp.element())\n      };\n    };\n    var move$1 = function (component, dragConfig, dragState, dragMode, event) {\n      var delta = dragState.update(dragMode, event);\n      var dragStartData = dragState.getStartData().getOrThunk(function () {\n        return calcStartData(dragConfig, component);\n      });\n      delta.each(function (dlt) {\n        dragBy(component, dragConfig, dragStartData, dlt);\n      });\n    };\n    var stop = function (component, blocker, dragConfig, dragState) {\n      blocker.each(discard);\n      dragConfig.snaps.each(function (snapInfo) {\n        stopDrag(component, snapInfo);\n      });\n      var target = dragConfig.getTarget(component.element());\n      dragState.reset();\n      dragConfig.onDrop(component, target);\n    };\n    var handlers = function (events) {\n      return function (dragConfig, dragState) {\n        var updateStartState = function (comp) {\n          dragState.setStartData(calcStartData(dragConfig, comp));\n        };\n        return derive(__spreadArrays([run(windowScroll(), function (comp) {\n            dragState.getStartData().each(function () {\n              return updateStartState(comp);\n            });\n          })], events(dragConfig, dragState, updateStartState)));\n      };\n    };\n\n    var init$c = function (dragApi) {\n      return derive([\n        run(mousedown(), dragApi.forceDrop),\n        run(mouseup(), dragApi.drop),\n        run(mousemove(), function (comp, simulatedEvent) {\n          dragApi.move(simulatedEvent.event());\n        }),\n        run(mouseout(), dragApi.delayDrop)\n      ]);\n    };\n\n    var getData$1 = function (event) {\n      return Option.from(Position(event.x(), event.y()));\n    };\n    var getDelta$1 = function (old, nu) {\n      return Position(nu.left() - old.left(), nu.top() - old.top());\n    };\n\n    var MouseData = /*#__PURE__*/Object.freeze({\n        getData: getData$1,\n        getDelta: getDelta$1\n    });\n\n    var events$g = function (dragConfig, dragState, updateStartState) {\n      return [run(mousedown(), function (component, simulatedEvent) {\n          var raw = simulatedEvent.event().raw();\n          if (raw.button !== 0) {\n            return;\n          }\n          simulatedEvent.stop();\n          var stop$1 = function () {\n            return stop(component, Option.some(blocker), dragConfig, dragState);\n          };\n          var delayDrop = DelayedFunction(stop$1, 200);\n          var dragApi = {\n            drop: stop$1,\n            delayDrop: delayDrop.schedule,\n            forceDrop: stop$1,\n            move: function (event) {\n              delayDrop.cancel();\n              move$1(component, dragConfig, dragState, MouseData, event);\n            }\n          };\n          var blocker = createComponent(component, dragConfig.blockerClass, init$c(dragApi));\n          var start = function () {\n            updateStartState(component);\n            instigate(component, blocker);\n          };\n          start();\n        })];\n    };\n    var schema$t = __spreadArrays(schema$s, [output('dragger', { handlers: handlers(events$g) })]);\n\n    var init$d = function (dragApi) {\n      return derive([\n        run(touchstart(), dragApi.forceDrop),\n        run(touchend(), dragApi.drop),\n        run(touchcancel(), dragApi.drop),\n        run(touchmove(), function (comp, simulatedEvent) {\n          dragApi.move(simulatedEvent.event());\n        })\n      ]);\n    };\n\n    var getDataFrom = function (touches) {\n      var touch = touches[0];\n      return Option.some(Position(touch.clientX, touch.clientY));\n    };\n    var getData$2 = function (event) {\n      var raw = event.raw();\n      var touches = raw.touches;\n      return touches.length === 1 ? getDataFrom(touches) : Option.none();\n    };\n    var getDelta$2 = function (old, nu) {\n      return Position(nu.left() - old.left(), nu.top() - old.top());\n    };\n\n    var TouchData = /*#__PURE__*/Object.freeze({\n        getData: getData$2,\n        getDelta: getDelta$2\n    });\n\n    var events$h = function (dragConfig, dragState, updateStartState) {\n      var blockerCell = Cell(Option.none());\n      return [\n        run(touchstart(), function (component, simulatedEvent) {\n          simulatedEvent.stop();\n          var stop$1 = function () {\n            stop(component, blockerCell.get(), dragConfig, dragState);\n            blockerCell.set(Option.none());\n          };\n          var dragApi = {\n            drop: stop$1,\n            delayDrop: function () {\n            },\n            forceDrop: stop$1,\n            move: function (event) {\n              move$1(component, dragConfig, dragState, TouchData, event);\n            }\n          };\n          var blocker = createComponent(component, dragConfig.blockerClass, init$d(dragApi));\n          blockerCell.set(Option.some(blocker));\n          var start = function () {\n            updateStartState(component);\n            instigate(component, blocker);\n          };\n          start();\n        }),\n        run(touchmove(), function (component, simulatedEvent) {\n          simulatedEvent.stop();\n          move$1(component, dragConfig, dragState, TouchData, simulatedEvent.event());\n        }),\n        run(touchend(), function (component, simulatedEvent) {\n          simulatedEvent.stop();\n          stop(component, blockerCell.get(), dragConfig, dragState);\n          blockerCell.set(Option.none());\n        }),\n        run(touchcancel(), function (component) {\n          stop(component, blockerCell.get(), dragConfig, dragState);\n          blockerCell.set(Option.none());\n        })\n      ];\n    };\n    var schema$u = __spreadArrays(schema$s, [output('dragger', { handlers: handlers(events$h) })]);\n\n    var events$i = function (dragConfig, dragState, updateStartState) {\n      return __spreadArrays(events$g(dragConfig, dragState, updateStartState), events$h(dragConfig, dragState, updateStartState));\n    };\n    var schema$v = __spreadArrays(schema$s, [output('dragger', { handlers: handlers(events$i) })]);\n\n    var mouse = schema$t;\n    var touch = schema$u;\n    var mouseOrTouch = schema$v;\n\n    var DraggingBranches = /*#__PURE__*/Object.freeze({\n        mouse: mouse,\n        touch: touch,\n        mouseOrTouch: mouseOrTouch\n    });\n\n    var init$e = function () {\n      var previous = Option.none();\n      var startData = Option.none();\n      var reset = function () {\n        previous = Option.none();\n        startData = Option.none();\n      };\n      var calculateDelta = function (mode, nu) {\n        var result = previous.map(function (old) {\n          return mode.getDelta(old, nu);\n        });\n        previous = Option.some(nu);\n        return result;\n      };\n      var update = function (mode, dragEvent) {\n        return mode.getData(dragEvent).bind(function (nuData) {\n          return calculateDelta(mode, nuData);\n        });\n      };\n      var setStartData = function (data) {\n        startData = Option.some(data);\n      };\n      var getStartData = function () {\n        return startData;\n      };\n      var readState = constant({});\n      return nu$5({\n        readState: readState,\n        reset: reset,\n        update: update,\n        getStartData: getStartData,\n        setStartData: setStartData\n      });\n    };\n\n    var DragState = /*#__PURE__*/Object.freeze({\n        init: init$e\n    });\n\n    var snapTo$1 = function (component, dragConfig, _state, snap) {\n      var target = dragConfig.getTarget(component.element());\n      if (dragConfig.repositionTarget) {\n        var doc = owner(component.element());\n        var scroll = get$8(doc);\n        var origin = getOrigin(target);\n        var snapPin = snapTo(snap, scroll, origin);\n        var styles = toStyles(snapPin.coord, scroll, origin);\n        setAll$1(target, styles);\n      }\n    };\n\n    var DraggingApis = /*#__PURE__*/Object.freeze({\n        snapTo: snapTo$1\n    });\n\n    var Dragging = createModes$1({\n      branchKey: 'mode',\n      branches: DraggingBranches,\n      name: 'dragging',\n      active: {\n        events: function (dragConfig, dragState) {\n          var dragger = dragConfig.dragger;\n          return dragger.handlers(dragConfig, dragState);\n        }\n      },\n      extra: {\n        snap: MixedBag([\n          'sensor',\n          'range',\n          'output'\n        ], ['extra'])\n      },\n      state: DragState,\n      apis: DraggingApis\n    });\n\n    var platform$1 = detect$3();\n    var snapWidth = 40;\n    var snapOffset = snapWidth / 2;\n    var calcSnap = function (selectorOpt, td, x, y, width, height) {\n      return selectorOpt.fold(function () {\n        return Dragging.snap({\n          sensor: absolute$3(x - snapOffset, y - snapOffset),\n          range: Position(width, height),\n          output: absolute$3(Option.some(x), Option.some(y)),\n          extra: { td: td }\n        });\n      }, function (selectorHandle) {\n        var sensorLeft = x - snapOffset;\n        var sensorTop = y - snapOffset;\n        var sensorWidth = snapWidth;\n        var sensorHeight = snapWidth;\n        var rect = selectorHandle.element().dom().getBoundingClientRect();\n        return Dragging.snap({\n          sensor: absolute$3(sensorLeft, sensorTop),\n          range: Position(sensorWidth, sensorHeight),\n          output: absolute$3(Option.some(x - rect.width / 2), Option.some(y - rect.height / 2)),\n          extra: { td: td }\n        });\n      });\n    };\n    var getSnapsConfig = function (getSnapPoints, cell, onChange) {\n      var isSameCell = function (cellOpt, td) {\n        return cellOpt.exists(function (currentTd) {\n          return eq(currentTd, td);\n        });\n      };\n      return {\n        getSnapPoints: getSnapPoints,\n        leftAttr: 'data-drag-left',\n        topAttr: 'data-drag-top',\n        onSensor: function (component, extra) {\n          var td = extra.td;\n          if (!isSameCell(cell.get(), td)) {\n            cell.set(Option.some(td));\n            onChange(td);\n          }\n        },\n        mustSnap: true\n      };\n    };\n    var createSelector = function (snaps) {\n      return record(Button.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-selector']\n        },\n        buttonBehaviours: derive$1([\n          Dragging.config({\n            mode: 'mouseOrTouch',\n            blockerClass: 'blocker',\n            snaps: snaps\n          }),\n          Unselecting.config({})\n        ]),\n        eventOrder: {\n          mousedown: [\n            'dragging',\n            'alloy.base.behaviour'\n          ],\n          touchstart: [\n            'dragging',\n            'alloy.base.behaviour'\n          ]\n        }\n      }));\n    };\n    var setup$b = function (editor, sink) {\n      var tlTds = Cell([]);\n      var brTds = Cell([]);\n      var isVisible = Cell(false);\n      var startCell = Cell(Option.none());\n      var finishCell = Cell(Option.none());\n      var getTopLeftSnap = function (td) {\n        var box = absolute$1(td);\n        return calcSnap(memTopLeft.getOpt(sink), td, box.x(), box.y(), box.width(), box.height());\n      };\n      var getTopLeftSnaps = function () {\n        return map(tlTds.get(), function (td) {\n          return getTopLeftSnap(td);\n        });\n      };\n      var getBottomRightSnap = function (td) {\n        var box = absolute$1(td);\n        return calcSnap(memBottomRight.getOpt(sink), td, box.right(), box.bottom(), box.width(), box.height());\n      };\n      var getBottomRightSnaps = function () {\n        return map(brTds.get(), function (td) {\n          return getBottomRightSnap(td);\n        });\n      };\n      var topLeftSnaps = getSnapsConfig(getTopLeftSnaps, startCell, function (start) {\n        finishCell.get().each(function (finish) {\n          editor.fire('TableSelectorChange', {\n            start: start,\n            finish: finish\n          });\n        });\n      });\n      var bottomRightSnaps = getSnapsConfig(getBottomRightSnaps, finishCell, function (finish) {\n        startCell.get().each(function (start) {\n          editor.fire('TableSelectorChange', {\n            start: start,\n            finish: finish\n          });\n        });\n      });\n      var memTopLeft = createSelector(topLeftSnaps);\n      var memBottomRight = createSelector(bottomRightSnaps);\n      var topLeft = build$1(memTopLeft.asSpec());\n      var bottomRight = build$1(memBottomRight.asSpec());\n      var showOrHideHandle = function (selector, cell, isAbove, isBelow) {\n        var cellRect = cell.dom().getBoundingClientRect();\n        remove$6(selector.element(), 'display');\n        var viewportHeight = defaultView(Element.fromDom(editor.getBody())).dom().innerHeight;\n        var aboveViewport = isAbove(cellRect);\n        var belowViewport = isBelow(cellRect, viewportHeight);\n        if (aboveViewport || belowViewport) {\n          set$2(selector.element(), 'display', 'none');\n        }\n      };\n      var snapTo = function (selector, cell, getSnapConfig, pos) {\n        var snap = getSnapConfig(cell);\n        Dragging.snapTo(selector, snap);\n        var isAbove = function (rect) {\n          return rect[pos] < 0;\n        };\n        var isBelow = function (rect, viewportHeight) {\n          return rect[pos] > viewportHeight;\n        };\n        showOrHideHandle(selector, cell, isAbove, isBelow);\n      };\n      var snapTopLeft = function (cell) {\n        return snapTo(topLeft, cell, getTopLeftSnap, 'top');\n      };\n      var snapLastTopLeft = function () {\n        return startCell.get().each(snapTopLeft);\n      };\n      var snapBottomRight = function (cell) {\n        return snapTo(bottomRight, cell, getBottomRightSnap, 'bottom');\n      };\n      var snapLastBottomRight = function () {\n        return finishCell.get().each(snapBottomRight);\n      };\n      if (platform$1.deviceType.isTouch()) {\n        editor.on('TableSelectionChange', function (e) {\n          if (!isVisible.get()) {\n            attach$1(sink, topLeft);\n            attach$1(sink, bottomRight);\n            isVisible.set(true);\n          }\n          startCell.set(Option.some(e.start));\n          finishCell.set(Option.some(e.finish));\n          e.otherCells.each(function (otherCells) {\n            tlTds.set(otherCells.upOrLeftCells);\n            brTds.set(otherCells.downOrRightCells);\n            snapTopLeft(e.start);\n            snapBottomRight(e.finish);\n          });\n        });\n        editor.on('ResizeEditor ResizeWindow ScrollContent', function () {\n          snapLastTopLeft();\n          snapLastBottomRight();\n        });\n        editor.on('TableSelectionClear', function () {\n          if (isVisible.get()) {\n            detach(topLeft);\n            detach(bottomRight);\n            isVisible.set(false);\n          }\n          startCell.set(Option.none());\n          finishCell.set(Option.none());\n        });\n      }\n    };\n    var TableSelectorHandles = { setup: setup$b };\n\n    var ResizeTypes;\n    (function (ResizeTypes) {\n      ResizeTypes[ResizeTypes['None'] = 0] = 'None';\n      ResizeTypes[ResizeTypes['Both'] = 1] = 'Both';\n      ResizeTypes[ResizeTypes['Vertical'] = 2] = 'Vertical';\n    }(ResizeTypes || (ResizeTypes = {})));\n    var getDimensions = function (editor, deltas, resizeType, originalHeight, originalWidth) {\n      var dimensions = {};\n      dimensions.height = Utils.calcCappedSize(originalHeight + deltas.top(), getMinHeightSetting(editor), getMaxHeightSetting(editor));\n      if (resizeType === ResizeTypes.Both) {\n        dimensions.width = Utils.calcCappedSize(originalWidth + deltas.left(), getMinWidthSetting(editor), getMaxWidthSetting(editor));\n      }\n      return dimensions;\n    };\n    var resize$3 = function (editor, deltas, resizeType) {\n      var container = Element.fromDom(editor.getContainer());\n      var dimensions = getDimensions(editor, deltas, resizeType, get$6(container), get$7(container));\n      each$1(dimensions, function (val, dim) {\n        return set$2(container, dim, Utils.numToPx(val));\n      });\n      Events.fireResizeEditor(editor);\n    };\n\n    var isHidden$1 = function (elm) {\n      if (elm.nodeType === 1) {\n        if (elm.nodeName === 'BR' || !!elm.getAttribute('data-mce-bogus')) {\n          return true;\n        }\n        if (elm.getAttribute('data-mce-type') === 'bookmark') {\n          return true;\n        }\n      }\n      return false;\n    };\n    var renderElementPath = function (editor, settings) {\n      if (!settings.delimiter) {\n        settings.delimiter = '\\xBB';\n      }\n      var getDataPath = function (data) {\n        var parts = data || [];\n        var newPathElements = map(parts, function (part, index) {\n          return Button.sketch({\n            dom: {\n              tag: 'div',\n              classes: ['tox-statusbar__path-item'],\n              attributes: {\n                'role': 'button',\n                'data-index': index,\n                'tab-index': -1,\n                'aria-level': index + 1\n              },\n              innerHtml: part.name\n            },\n            action: function (btn) {\n              editor.focus();\n              editor.selection.select(part.element);\n              editor.nodeChanged();\n            }\n          });\n        });\n        var divider = {\n          dom: {\n            tag: 'div',\n            classes: ['tox-statusbar__path-divider'],\n            attributes: { 'aria-hidden': true },\n            innerHtml: ' ' + settings.delimiter + ' '\n          }\n        };\n        return foldl(newPathElements.slice(1), function (acc, element) {\n          var newAcc = acc;\n          newAcc.push(divider);\n          newAcc.push(element);\n          return newAcc;\n        }, [newPathElements[0]]);\n      };\n      var updatePath = function (parents) {\n        var newPath = [];\n        var i = parents.length;\n        while (i-- > 0) {\n          var parent = parents[i];\n          if (parent.nodeType === 1 && !isHidden$1(parent)) {\n            var args = editor.fire('ResolveName', {\n              name: parent.nodeName.toLowerCase(),\n              target: parent\n            });\n            if (!args.isDefaultPrevented()) {\n              newPath.push({\n                name: args.name,\n                element: parent\n              });\n            }\n            if (args.isPropagationStopped()) {\n              break;\n            }\n          }\n        }\n        return newPath;\n      };\n      return {\n        dom: {\n          tag: 'div',\n          classes: ['tox-statusbar__path'],\n          attributes: { role: 'navigation' }\n        },\n        behaviours: derive$1([\n          Keying.config({\n            mode: 'flow',\n            selector: 'div[role=button]'\n          }),\n          Tabstopping.config({}),\n          Replacing.config({}),\n          config('elementPathEvents', [runOnAttached(function (comp, e) {\n              editor.shortcuts.add('alt+F11', 'focus statusbar elementpath', function () {\n                return Keying.focusIn(comp);\n              });\n              editor.on('NodeChange', function (e) {\n                var newPath = updatePath(e.parents);\n                if (newPath.length > 0) {\n                  Replacing.set(comp, getDataPath(newPath));\n                }\n              });\n            })])\n        ]),\n        components: []\n      };\n    };\n    var ElementPath = { renderElementPath: renderElementPath };\n\n    var renderWordCount = function (editor, providersBackstage) {\n      var replaceCountText = function (comp, count, mode) {\n        return Replacing.set(comp, [text(providersBackstage.translate([\n            '{0} ' + mode,\n            count[mode]\n          ]))]);\n      };\n      return Button.sketch({\n        dom: {\n          tag: 'button',\n          classes: ['tox-statusbar__wordcount']\n        },\n        components: [],\n        buttonBehaviours: derive$1([\n          Tabstopping.config({}),\n          Replacing.config({}),\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: {\n                mode: 'words',\n                count: {\n                  words: 0,\n                  characters: 0\n                }\n              }\n            }\n          }),\n          config('wordcount-events', [\n            runOnExecute(function (comp) {\n              var currentVal = Representing.getValue(comp);\n              var newMode = currentVal.mode === 'words' ? 'characters' : 'words';\n              Representing.setValue(comp, {\n                mode: newMode,\n                count: currentVal.count\n              });\n              replaceCountText(comp, currentVal.count, newMode);\n            }),\n            runOnAttached(function (comp) {\n              editor.on('wordCountUpdate', function (e) {\n                var mode = Representing.getValue(comp).mode;\n                Representing.setValue(comp, {\n                  mode: mode,\n                  count: e.wordCount\n                });\n                replaceCountText(comp, e.wordCount, mode);\n              });\n            })\n          ])\n        ])\n      });\n    };\n\n    var renderStatusbar = function (editor, providersBackstage) {\n      var renderResizeHandlerIcon = function (resizeType) {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-statusbar__resize-handle'],\n            attributes: { title: providersBackstage.translate('Resize') },\n            innerHtml: get$c('resize-handle', providersBackstage.icons)\n          },\n          behaviours: derive$1([Dragging.config({\n              mode: 'mouse',\n              repositionTarget: false,\n              onDrag: function (comp, target, delta) {\n                resize$3(editor, delta, resizeType);\n              },\n              blockerClass: 'tox-blocker'\n            })])\n        };\n      };\n      var renderBranding = function () {\n        var label = global$5.translate([\n          'Powered by {0}',\n          'Tiny'\n        ]);\n        var linkHtml = '<a href=\"https://www.tiny.cloud/?utm_campaign=editor_referral&amp;utm_medium=poweredby&amp;utm_source=tinymce&amp;utm_content=v5\" rel=\"noopener\" target=\"_blank\" tabindex=\"-1\" aria-label=\"' + label + '\">' + label + '</a>';\n        return {\n          dom: {\n            tag: 'span',\n            classes: ['tox-statusbar__branding'],\n            innerHtml: linkHtml\n          }\n        };\n      };\n      var getResizeType = function (editor) {\n        var fallback = !contains$1(editor.settings.plugins, 'autoresize');\n        var resize = editor.getParam('resize', fallback);\n        if (resize === false) {\n          return ResizeTypes.None;\n        } else if (resize === 'both') {\n          return ResizeTypes.Both;\n        } else {\n          return ResizeTypes.Vertical;\n        }\n      };\n      var getTextComponents = function () {\n        var components = [];\n        if (editor.getParam('elementpath', true, 'boolean')) {\n          components.push(ElementPath.renderElementPath(editor, {}));\n        }\n        if (contains$1(editor.settings.plugins, 'wordcount')) {\n          components.push(renderWordCount(editor, providersBackstage));\n        }\n        if (editor.getParam('branding', true, 'boolean')) {\n          components.push(renderBranding());\n        }\n        if (components.length > 0) {\n          return [{\n              dom: {\n                tag: 'div',\n                classes: ['tox-statusbar__text-container']\n              },\n              components: components\n            }];\n        }\n        return [];\n      };\n      var getComponents = function () {\n        var components = getTextComponents();\n        var resizeType = getResizeType(editor);\n        if (resizeType !== ResizeTypes.None) {\n          components.push(renderResizeHandlerIcon(resizeType));\n        }\n        return components;\n      };\n      return {\n        dom: {\n          tag: 'div',\n          classes: ['tox-statusbar']\n        },\n        components: getComponents()\n      };\n    };\n\n    var setup$c = function (editor) {\n      var isInline = editor.inline;\n      var mode = isInline ? Inline : Iframe;\n      var header = isStickyToolbar(editor) ? StickyHeader : StaticHeader;\n      var lazyOuterContainer = Option.none();\n      var platform = detect$3();\n      var isIE = platform.browser.isIE();\n      var platformClasses = isIE ? ['tox-platform-ie'] : [];\n      var isTouch = platform.deviceType.isTouch();\n      var touchPlatformClass = 'tox-platform-touch';\n      var deviceClasses = isTouch ? [touchPlatformClass] : [];\n      var dirAttributes = global$5.isRtl() ? { attributes: { dir: 'rtl' } } : {};\n      var lazyHeader = function () {\n        return lazyOuterContainer.bind(OuterContainer.getHeader);\n      };\n      var sink = build$1({\n        dom: __assign({\n          tag: 'div',\n          classes: [\n            'tox',\n            'tox-silver-sink',\n            'tox-tinymce-aux'\n          ].concat(platformClasses).concat(deviceClasses)\n        }, dirAttributes),\n        behaviours: derive$1([Positioning.config({\n            useFixed: function () {\n              return header.isDocked(lazyHeader);\n            }\n          })])\n      });\n      var lazySink = function () {\n        return Result.value(sink);\n      };\n      var memAnchorBar = record({\n        dom: {\n          tag: 'div',\n          classes: ['tox-anchorbar']\n        }\n      });\n      var lazyAnchorBar = function () {\n        return lazyOuterContainer.bind(function (container) {\n          return memAnchorBar.getOpt(container);\n        }).getOrDie('Could not find a anchor bar element');\n      };\n      var lazyMoreButton = function () {\n        return lazyOuterContainer.bind(function (container) {\n          return OuterContainer.getMoreButton(container);\n        }).getOrDie('Could not find more button element');\n      };\n      var lazyToolbar = function () {\n        return lazyOuterContainer.bind(function (container) {\n          return OuterContainer.getToolbar(container);\n        }).getOrDie('Could not find more toolbar element');\n      };\n      var lazyThrobber = function () {\n        return lazyOuterContainer.bind(function (container) {\n          return OuterContainer.getThrobber(container);\n        }).getOrDie('Could not find throbber element');\n      };\n      var backstage = init$8(sink, editor, lazyAnchorBar, lazyMoreButton);\n      var partMenubar = OuterContainer.parts().menubar({\n        dom: {\n          tag: 'div',\n          classes: ['tox-menubar']\n        },\n        backstage: backstage,\n        onEscape: function () {\n          editor.focus();\n        }\n      });\n      var toolbarDrawer = getToolbarDrawer(editor);\n      var partToolbar = OuterContainer.parts().toolbar({\n        dom: {\n          tag: 'div',\n          classes: ['tox-toolbar']\n        },\n        getSink: lazySink,\n        backstage: backstage,\n        onEscape: function () {\n          editor.focus();\n        },\n        split: toolbarDrawer,\n        lazyToolbar: lazyToolbar,\n        lazyMoreButton: lazyMoreButton,\n        lazyHeader: function () {\n          return lazyHeader().getOrDie('Could not find header element');\n        }\n      });\n      var partMultipleToolbar = OuterContainer.parts()['multiple-toolbar']({\n        dom: {\n          tag: 'div',\n          classes: ['tox-toolbar-overlord']\n        },\n        onEscape: function () {\n        },\n        split: toolbarDrawer\n      });\n      var partSocket = OuterContainer.parts().socket({\n        dom: {\n          tag: 'div',\n          classes: ['tox-edit-area']\n        }\n      });\n      var partSidebar = OuterContainer.parts().sidebar({\n        dom: {\n          tag: 'div',\n          classes: ['tox-sidebar']\n        }\n      });\n      var partThrobber = OuterContainer.parts().throbber({\n        dom: {\n          tag: 'div',\n          classes: ['tox-throbber']\n        },\n        backstage: backstage\n      });\n      var sb = editor.getParam('statusbar', true, 'boolean');\n      var statusbar = sb && !isInline ? Option.some(renderStatusbar(editor, backstage.shared.providers)) : Option.none();\n      var socketSidebarContainer = {\n        dom: {\n          tag: 'div',\n          classes: ['tox-sidebar-wrap']\n        },\n        components: [\n          partSocket,\n          partSidebar\n        ]\n      };\n      var hasMultipleToolbar = isMultipleToolbars(editor);\n      var hasToolbar = isToolbarEnabled(editor);\n      var hasMenubar = isMenubarEnabled(editor);\n      var getPartToolbar = function () {\n        if (hasMultipleToolbar) {\n          return [partMultipleToolbar];\n        } else if (hasToolbar) {\n          return [partToolbar];\n        } else {\n          return [];\n        }\n      };\n      var partHeader = OuterContainer.parts().header({\n        dom: {\n          tag: 'div',\n          classes: ['tox-editor-header']\n        },\n        components: flatten([\n          hasMenubar ? [partMenubar] : [],\n          getPartToolbar(),\n          useFixedContainer(editor) ? [] : [memAnchorBar.asSpec()]\n        ]),\n        sticky: isStickyToolbar(editor),\n        editor: editor,\n        getSink: lazySink\n      });\n      var editorComponents = flatten([\n        [partHeader],\n        isInline ? [] : [socketSidebarContainer]\n      ]);\n      var editorContainer = {\n        dom: {\n          tag: 'div',\n          classes: ['tox-editor-container']\n        },\n        components: editorComponents\n      };\n      var containerComponents = flatten([\n        [editorContainer],\n        isInline ? [] : statusbar.toArray(),\n        [partThrobber]\n      ]);\n      var isHidden = isDistractionFree(editor);\n      var attributes = __assign(__assign({ role: 'application' }, global$5.isRtl() ? { dir: 'rtl' } : {}), isHidden ? { 'aria-hidden': 'true' } : {});\n      var outerContainer = build$1(OuterContainer.sketch({\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox',\n            'tox-tinymce'\n          ].concat(isInline ? ['tox-tinymce-inline'] : []).concat(deviceClasses).concat(platformClasses),\n          styles: __assign({ visibility: 'hidden' }, isHidden ? {\n            opacity: '0',\n            border: '0'\n          } : {}),\n          attributes: attributes\n        },\n        components: containerComponents,\n        behaviours: derive$1([Keying.config({\n            mode: 'cyclic',\n            selector: '.tox-menubar, .tox-toolbar, .tox-toolbar__primary, .tox-toolbar__overflow--open, .tox-sidebar__overflow--open, .tox-statusbar__path, .tox-statusbar__wordcount, .tox-statusbar__branding a'\n          })])\n      }));\n      lazyOuterContainer = Option.some(outerContainer);\n      editor.shortcuts.add('alt+F9', 'focus menubar', function () {\n        OuterContainer.focusMenubar(outerContainer);\n      });\n      editor.shortcuts.add('alt+F10', 'focus toolbar', function () {\n        OuterContainer.focusToolbar(outerContainer);\n      });\n      var mothership = takeover(outerContainer);\n      var uiMothership = takeover(sink);\n      Events$1.setup(editor, mothership, uiMothership);\n      TouchEvents.setup(editor);\n      var getUi = function () {\n        var channels = {\n          broadcastAll: uiMothership.broadcast,\n          broadcastOn: uiMothership.broadcastOn,\n          register: function () {\n          }\n        };\n        return { channels: channels };\n      };\n      var setEditorSize = function () {\n        var parsedHeight = Utils.numToPx(getHeightWithFallback(editor));\n        var parsedWidth = Utils.numToPx(getWidthWithFallback(editor));\n        if (!editor.inline) {\n          if (isValidValue('div', 'width', parsedWidth)) {\n            set$2(outerContainer.element(), 'width', parsedWidth);\n          }\n          if (isValidValue('div', 'height', parsedHeight)) {\n            set$2(outerContainer.element(), 'height', parsedHeight);\n          } else {\n            set$2(outerContainer.element(), 'height', '200px');\n          }\n        }\n        return parsedHeight;\n      };\n      var renderUI = function () {\n        header.setup(editor, lazyHeader);\n        FormatControls.setup(editor, backstage);\n        setup$a(editor, lazySink, backstage);\n        setup$7(editor);\n        setup$8(editor, lazyThrobber, backstage.shared);\n        var _a = editor.ui.registry.getAll(), buttons = _a.buttons, menuItems = _a.menuItems, contextToolbars = _a.contextToolbars, sidebars = _a.sidebars;\n        var toolbarOpt = getMultipleToolbarsSetting(editor);\n        var rawUiConfig = {\n          menuItems: menuItems,\n          menus: !editor.settings.menu ? {} : map$1(editor.settings.menu, function (menu) {\n            return merge(menu, { items: menu.items });\n          }),\n          menubar: editor.settings.menubar,\n          toolbar: toolbarOpt.getOrThunk(function () {\n            return editor.getParam('toolbar', true);\n          }),\n          buttons: buttons,\n          sidebar: sidebars\n        };\n        ContextToolbar.register(editor, contextToolbars, sink, { backstage: backstage });\n        TableSelectorHandles.setup(editor, sink);\n        var elm = editor.getElement();\n        var height = setEditorSize();\n        var uiComponents = {\n          mothership: mothership,\n          uiMothership: uiMothership,\n          outerContainer: outerContainer\n        };\n        var args = {\n          targetNode: elm,\n          height: height\n        };\n        return mode.render(editor, uiComponents, rawUiConfig, backstage, args);\n      };\n      return {\n        mothership: mothership,\n        uiMothership: uiMothership,\n        backstage: backstage,\n        renderUI: renderUI,\n        getUi: getUi\n      };\n    };\n    var Render = { setup: setup$c };\n\n    var describedBy = function (describedElement, describeElement) {\n      var describeId = Option.from(get$2(describedElement, 'id')).fold(function () {\n        var id = generate$1('dialog-describe');\n        set$1(describeElement, 'id', id);\n        return id;\n      }, identity);\n      set$1(describedElement, 'aria-describedby', describeId);\n    };\n\n    var AriaLabel = {\n      labelledBy: function (labelledElement, labelElement) {\n        var labelId = Option.from(get$2(labelledElement, 'id')).fold(function () {\n          var id = generate$1('dialog-label');\n          set$1(labelElement, 'id', id);\n          return id;\n        }, identity);\n        set$1(labelledElement, 'aria-labelledby', labelId);\n      }\n    };\n\n    var schema$w = constant([\n      strict$1('lazySink'),\n      option('dragBlockClass'),\n      defaultedFunction('getBounds', win),\n      defaulted$1('useTabstopAt', constant(true)),\n      defaulted$1('eventOrder', {}),\n      field$1('modalBehaviours', [Keying]),\n      onKeyboardHandler('onExecute'),\n      onStrictKeyboardHandler('onEscape')\n    ]);\n    var basic = { sketch: identity };\n    var parts$e = constant([\n      optional({\n        name: 'draghandle',\n        overrides: function (detail, spec) {\n          return {\n            behaviours: derive$1([Dragging.config({\n                mode: 'mouse',\n                getTarget: function (handle) {\n                  return ancestor$1(handle, '[role=\"dialog\"]').getOr(handle);\n                },\n                blockerClass: detail.dragBlockClass.getOrDie(new Error('The drag blocker class was not specified for a dialog with a drag handle: \\n' + JSON.stringify(spec, null, 2)).message),\n                getBounds: detail.getDragBounds\n              })])\n          };\n        }\n      }),\n      required({\n        schema: [strict$1('dom')],\n        name: 'title'\n      }),\n      required({\n        factory: basic,\n        schema: [strict$1('dom')],\n        name: 'close'\n      }),\n      required({\n        factory: basic,\n        schema: [strict$1('dom')],\n        name: 'body'\n      }),\n      optional({\n        factory: basic,\n        schema: [strict$1('dom')],\n        name: 'footer'\n      }),\n      external$1({\n        factory: {\n          sketch: function (spec, detail) {\n            return __assign(__assign({}, spec), {\n              dom: detail.dom,\n              components: detail.components\n            });\n          }\n        },\n        schema: [\n          defaulted$1('dom', {\n            tag: 'div',\n            styles: {\n              position: 'fixed',\n              left: '0px',\n              top: '0px',\n              right: '0px',\n              bottom: '0px'\n            }\n          }),\n          defaulted$1('components', [])\n        ],\n        name: 'blocker'\n      })\n    ]);\n\n    var factory$h = function (detail, components, spec, externals) {\n      var dialogBusyEvent = generate$1('alloy.dialog.busy');\n      var dialogIdleEvent = generate$1('alloy.dialog.idle');\n      var busyBehaviours = derive$1([\n        Keying.config({\n          mode: 'special',\n          onTab: function () {\n            return Option.some(true);\n          },\n          onShiftTab: function () {\n            return Option.some(true);\n          }\n        }),\n        Focusing.config({})\n      ]);\n      var showDialog = function (dialog) {\n        var sink = detail.lazySink(dialog).getOrDie();\n        var busyComp = Cell(Option.none());\n        var externalBlocker = externals.blocker();\n        var blocker = sink.getSystem().build(__assign(__assign({}, externalBlocker), {\n          components: externalBlocker.components.concat([premade$1(dialog)]),\n          behaviours: derive$1([\n            Focusing.config({}),\n            config('dialog-blocker-events', [\n              runOnSource(focusin(), function () {\n                Keying.focusIn(dialog);\n              }),\n              run(dialogIdleEvent, function (blocker, se) {\n                if (has$1(dialog.element(), 'aria-busy')) {\n                  remove$1(dialog.element(), 'aria-busy');\n                  busyComp.get().each(function (bc) {\n                    return Replacing.remove(dialog, bc);\n                  });\n                }\n              }),\n              run(dialogBusyEvent, function (blocker, se) {\n                set$1(dialog.element(), 'aria-busy', 'true');\n                var getBusySpec = se.event().getBusySpec();\n                busyComp.get().each(function (bc) {\n                  Replacing.remove(dialog, bc);\n                });\n                var busySpec = getBusySpec(dialog, busyBehaviours);\n                var busy = blocker.getSystem().build(busySpec);\n                busyComp.set(Option.some(busy));\n                Replacing.append(dialog, premade$1(busy));\n                if (busy.hasConfigured(Keying)) {\n                  Keying.focusIn(busy);\n                }\n              })\n            ])\n          ])\n        }));\n        attach$1(sink, blocker);\n        Keying.focusIn(dialog);\n      };\n      var hideDialog = function (dialog) {\n        parent(dialog.element()).each(function (blockerDom) {\n          dialog.getSystem().getByDom(blockerDom).each(function (blocker) {\n            detach(blocker);\n          });\n        });\n      };\n      var getDialogBody = function (dialog) {\n        return getPartOrDie(dialog, detail, 'body');\n      };\n      var getDialogFooter = function (dialog) {\n        return getPartOrDie(dialog, detail, 'footer');\n      };\n      var setBusy = function (dialog, getBusySpec) {\n        emitWith(dialog, dialogBusyEvent, { getBusySpec: getBusySpec });\n      };\n      var setIdle = function (dialog) {\n        emit(dialog, dialogIdleEvent);\n      };\n      var modalEventsId = generate$1('modal-events');\n      var eventOrder = __assign(__assign({}, detail.eventOrder), { 'alloy.system.attached': [modalEventsId].concat(detail.eventOrder['alloy.system.attached'] || []) });\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        apis: {\n          show: showDialog,\n          hide: hideDialog,\n          getBody: getDialogBody,\n          getFooter: getDialogFooter,\n          setIdle: setIdle,\n          setBusy: setBusy\n        },\n        eventOrder: eventOrder,\n        domModification: {\n          attributes: {\n            'role': 'dialog',\n            'aria-modal': 'true'\n          }\n        },\n        behaviours: augment(detail.modalBehaviours, [\n          Replacing.config({}),\n          Keying.config({\n            mode: 'cyclic',\n            onEnter: detail.onExecute,\n            onEscape: detail.onEscape,\n            useTabstopAt: detail.useTabstopAt\n          }),\n          config(modalEventsId, [runOnAttached(function (c) {\n              AriaLabel.labelledBy(c.element(), getPartOrDie(c, detail, 'title').element());\n              describedBy(c.element(), getPartOrDie(c, detail, 'body').element());\n            })])\n        ])\n      };\n    };\n    var ModalDialog = composite$1({\n      name: 'ModalDialog',\n      configFields: schema$w(),\n      partFields: parts$e(),\n      factory: factory$h,\n      apis: {\n        show: function (apis, dialog) {\n          apis.show(dialog);\n        },\n        hide: function (apis, dialog) {\n          apis.hide(dialog);\n        },\n        getBody: function (apis, dialog) {\n          return apis.getBody(dialog);\n        },\n        getFooter: function (apis, dialog) {\n          return apis.getFooter(dialog);\n        },\n        setBusy: function (apis, dialog, getBusySpec) {\n          apis.setBusy(dialog, getBusySpec);\n        },\n        setIdle: function (apis, dialog) {\n          apis.setIdle(dialog);\n        }\n      }\n    });\n\n    var alertBannerFields = [\n      strictString('type'),\n      strictString('text'),\n      strictStringEnum('level', [\n        'info',\n        'warn',\n        'error',\n        'success'\n      ]),\n      strictString('icon'),\n      defaulted$1('url', '')\n    ];\n    var alertBannerSchema = objOf(alertBannerFields);\n\n    var createBarFields = function (itemsField) {\n      return [\n        strictString('type'),\n        itemsField\n      ];\n    };\n\n    var buttonFields = [\n      strictString('type'),\n      strictString('text'),\n      defaultedBoolean('disabled', false),\n      defaultedBoolean('primary', false),\n      field('name', 'name', defaultedThunk(function () {\n        return generate$1('button-name');\n      }), string),\n      optionString('icon'),\n      defaultedBoolean('borderless', false)\n    ];\n    var buttonSchema = objOf(buttonFields);\n\n    var checkboxFields = [\n      strictString('type'),\n      strictString('name'),\n      strictString('label'),\n      defaultedBoolean('disabled', false)\n    ];\n    var checkboxSchema = objOf(checkboxFields);\n    var checkboxDataProcessor = boolean;\n\n    var formComponentFields = [\n      strictString('type'),\n      strictString('name')\n    ];\n    var formComponentWithLabelFields = formComponentFields.concat([optionString('label')]);\n\n    var colorInputFields = formComponentWithLabelFields;\n    var colorInputSchema = objOf(colorInputFields);\n    var colorInputDataProcessor = string;\n\n    var colorPickerFields = formComponentWithLabelFields;\n    var colorPickerSchema = objOf(colorPickerFields);\n    var colorPickerDataProcessor = string;\n\n    var dropZoneFields = formComponentWithLabelFields;\n    var dropZoneSchema = objOf(dropZoneFields);\n    var dropZoneDataProcessor = arrOfVal();\n\n    var createGridFields = function (itemsField) {\n      return [\n        strictString('type'),\n        strictNumber('columns'),\n        itemsField\n      ];\n    };\n\n    var iframeFields = formComponentWithLabelFields.concat([defaultedBoolean('sandboxed', true)]);\n    var iframeSchema = objOf(iframeFields);\n    var iframeDataProcessor = string;\n\n    var inputFields = formComponentWithLabelFields.concat([\n      optionString('inputMode'),\n      optionString('placeholder'),\n      defaultedBoolean('maximized', false),\n      defaultedBoolean('disabled', false)\n    ]);\n    var inputSchema = objOf(inputFields);\n    var inputDataProcessor = string;\n\n    var selectBoxFields = formComponentWithLabelFields.concat([\n      strictArrayOfObj('items', [\n        strictString('text'),\n        strictString('value')\n      ]),\n      defaultedNumber('size', 1),\n      defaultedBoolean('disabled', false)\n    ]);\n    var selectBoxSchema = objOf(selectBoxFields);\n    var selectBoxDataProcessor = string;\n\n    var sizeInputFields = formComponentWithLabelFields.concat([\n      defaultedBoolean('constrain', true),\n      defaultedBoolean('disabled', false)\n    ]);\n    var sizeInputSchema = objOf(sizeInputFields);\n    var sizeInputDataProcessor = objOf([\n      strictString('width'),\n      strictString('height')\n    ]);\n\n    var textAreaFields = formComponentWithLabelFields.concat([\n      optionString('placeholder'),\n      defaultedBoolean('maximized', false),\n      defaultedBoolean('disabled', false)\n    ]);\n    var textAreaSchema = objOf(textAreaFields);\n    var textAreaDataProcessor = string;\n\n    var urlInputFields = formComponentWithLabelFields.concat([\n      defaultedStringEnum('filetype', 'file', [\n        'image',\n        'media',\n        'file'\n      ]),\n      defaulted$1('disabled', false)\n    ]);\n    var urlInputSchema = objOf(urlInputFields);\n    var urlInputDataProcessor = objOf([\n      strictString('value'),\n      defaulted$1('meta', {})\n    ]);\n\n    var customEditorFields = formComponentFields.concat([\n      defaultedString('tag', 'textarea'),\n      strictString('scriptId'),\n      strictString('scriptUrl'),\n      defaultedPostMsg('settings', undefined)\n    ]);\n    var customEditorFieldsOld = formComponentFields.concat([\n      defaultedString('tag', 'textarea'),\n      strictFunction('init')\n    ]);\n    var customEditorSchema = valueOf(function (v) {\n      return asRaw('customeditor.old', objOfOnly(customEditorFieldsOld), v).orThunk(function () {\n        return asRaw('customeditor.new', objOfOnly(customEditorFields), v);\n      });\n    });\n    var customEditorDataProcessor = string;\n\n    var htmlPanelFields = [\n      strictString('type'),\n      strictString('html'),\n      defaultedStringEnum('presets', 'presentation', [\n        'presentation',\n        'document'\n      ])\n    ];\n    var htmlPanelSchema = objOf(htmlPanelFields);\n\n    var imageToolsFields = formComponentWithLabelFields.concat([strictOf('currentState', objOf([\n        strict$1('blob'),\n        strictString('url')\n      ]))]);\n    var imageToolsSchema = objOf(imageToolsFields);\n\n    var collectionFields = formComponentWithLabelFields.concat([defaulted$1('columns', 'auto')]);\n    var collectionSchema = objOf(collectionFields);\n    var collectionDataProcessor = arrOfObj$1([\n      strictString('value'),\n      strictString('text'),\n      strictString('icon')\n    ]);\n\n    var createLabelFields = function (itemsField) {\n      return [\n        strictString('type'),\n        strictString('label'),\n        itemsField\n      ];\n    };\n\n    var tableFields = [\n      strictString('type'),\n      strictArrayOf('header', string),\n      strictArrayOf('cells', arrOf(string))\n    ];\n    var tableSchema = objOf(tableFields);\n\n    var createItemsField = function (name) {\n      return field('items', 'items', strict(), arrOf(valueOf(function (v) {\n        return asRaw('Checking item of ' + name, itemSchema$2, v).fold(function (sErr) {\n          return Result.error(formatError(sErr));\n        }, function (passValue) {\n          return Result.value(passValue);\n        });\n      })));\n    };\n    var itemSchema$2 = valueThunkOf(function () {\n      return chooseProcessor('type', {\n        alertbanner: alertBannerSchema,\n        bar: objOf(createBarFields(createItemsField('bar'))),\n        button: buttonSchema,\n        checkbox: checkboxSchema,\n        colorinput: colorInputSchema,\n        colorpicker: colorPickerSchema,\n        dropzone: dropZoneSchema,\n        grid: objOf(createGridFields(createItemsField('grid'))),\n        iframe: iframeSchema,\n        input: inputSchema,\n        selectbox: selectBoxSchema,\n        sizeinput: sizeInputSchema,\n        textarea: textAreaSchema,\n        urlinput: urlInputSchema,\n        customeditor: customEditorSchema,\n        htmlpanel: htmlPanelSchema,\n        imagetools: imageToolsSchema,\n        collection: collectionSchema,\n        label: objOf(createLabelFields(createItemsField('label'))),\n        table: tableSchema,\n        panel: panelSchema\n      });\n    });\n    var panelFields = [\n      strictString('type'),\n      defaulted$1('classes', []),\n      strictArrayOf('items', itemSchema$2)\n    ];\n    var panelSchema = objOf(panelFields);\n\n    var tabFields = [\n      field('name', 'name', defaultedThunk(function () {\n        return generate$1('tab-name');\n      }), string),\n      strictString('title'),\n      strictArrayOf('items', itemSchema$2)\n    ];\n    var tabPanelFields = [\n      strictString('type'),\n      strictArrayOfObj('tabs', tabFields)\n    ];\n    var tabPanelSchema = objOf(tabPanelFields);\n\n    var dialogToggleMenuItemSchema = objOf([\n      strictString('type'),\n      strictString('name'),\n      defaultedBoolean('active', false)\n    ].concat(commonMenuItemFields));\n    var dialogToggleMenuItemDataProcessor = boolean;\n\n    var baseButtonFields = [\n      field('name', 'name', defaultedThunk(function () {\n        return generate$1('button-name');\n      }), string),\n      optionString('icon'),\n      defaultedStringEnum('align', 'end', [\n        'start',\n        'end'\n      ]),\n      defaultedBoolean('primary', false),\n      defaultedBoolean('disabled', false)\n    ];\n    var dialogButtonFields = __spreadArrays(baseButtonFields, [strictString('text')]);\n    var normalButtonFields = __spreadArrays([strictStringEnum('type', [\n        'submit',\n        'cancel',\n        'custom'\n      ])], dialogButtonFields);\n    var menuButtonFields = __spreadArrays([\n      strictStringEnum('type', ['menu']),\n      optionString('text'),\n      optionString('tooltip'),\n      optionString('icon'),\n      strictArrayOf('items', dialogToggleMenuItemSchema),\n      defaultedFunction('onSetup', function () {\n        return noop;\n      })\n    ], baseButtonFields);\n    var dialogButtonSchema = choose$1('type', {\n      submit: normalButtonFields,\n      cancel: normalButtonFields,\n      custom: normalButtonFields,\n      menu: menuButtonFields\n    });\n\n    var dialogButtonFields$1 = dialogButtonFields;\n    var dialogButtonSchema$1 = dialogButtonSchema;\n    var dialogSchema = objOf([\n      strictString('title'),\n      strictOf('body', chooseProcessor('type', {\n        panel: panelSchema,\n        tabpanel: tabPanelSchema\n      })),\n      defaultedString('size', 'normal'),\n      strictArrayOf('buttons', dialogButtonSchema$1),\n      defaulted$1('initialData', {}),\n      defaultedFunction('onAction', noop),\n      defaultedFunction('onChange', noop),\n      defaultedFunction('onSubmit', noop),\n      defaultedFunction('onClose', noop),\n      defaultedFunction('onCancel', noop),\n      defaulted$1('onTabChange', noop)\n    ]);\n    var createDialog = function (spec) {\n      return asRaw('dialog', dialogSchema, spec);\n    };\n\n    var getAllObjects = function (obj) {\n      if (isObject(obj)) {\n        return [obj].concat(bind(values(obj), getAllObjects));\n      } else if (isArray(obj)) {\n        return bind(obj, getAllObjects);\n      } else {\n        return [];\n      }\n    };\n\n    var isNamedItem = function (obj) {\n      return isString(obj.type) && isString(obj.name);\n    };\n    var dataProcessors = {\n      checkbox: checkboxDataProcessor,\n      colorinput: colorInputDataProcessor,\n      colorpicker: colorPickerDataProcessor,\n      dropzone: dropZoneDataProcessor,\n      input: inputDataProcessor,\n      iframe: iframeDataProcessor,\n      sizeinput: sizeInputDataProcessor,\n      selectbox: selectBoxDataProcessor,\n      size: sizeInputDataProcessor,\n      textarea: textAreaDataProcessor,\n      urlinput: urlInputDataProcessor,\n      customeditor: customEditorDataProcessor,\n      collection: collectionDataProcessor,\n      togglemenuitem: dialogToggleMenuItemDataProcessor\n    };\n    var getDataProcessor = function (item) {\n      return Option.from(dataProcessors[item.type]);\n    };\n    var getNamedItems = function (structure) {\n      return filter(getAllObjects(structure), isNamedItem);\n    };\n\n    var createDataValidator = function (structure) {\n      var namedItems = getNamedItems(structure);\n      var fields = bind(namedItems, function (item) {\n        return getDataProcessor(item).fold(function () {\n          return [];\n        }, function (schema) {\n          return [strictOf(item.name, schema)];\n        });\n      });\n      return objOf(fields);\n    };\n\n    var urlDialogButtonSchema = objOf(__spreadArrays([strictStringEnum('type', [\n        'cancel',\n        'custom'\n      ])], dialogButtonFields$1));\n    var urlDialogSchema = objOf([\n      strictString('title'),\n      strictString('url'),\n      optionNumber('height'),\n      optionNumber('width'),\n      optionArrayOf('buttons', urlDialogButtonSchema),\n      defaultedFunction('onAction', noop),\n      defaultedFunction('onCancel', noop),\n      defaultedFunction('onClose', noop),\n      defaultedFunction('onMessage', noop)\n    ]);\n    var createUrlDialog = function (spec) {\n      return asRaw('dialog', urlDialogSchema, spec);\n    };\n\n    var extract$1 = function (structure) {\n      var internalDialog = getOrDie(createDialog(structure));\n      var dataValidator = createDataValidator(structure);\n      var initialData = structure.initialData;\n      return {\n        internalDialog: internalDialog,\n        dataValidator: dataValidator,\n        initialData: initialData\n      };\n    };\n    var DialogManager = {\n      open: function (factory, structure) {\n        var extraction = extract$1(structure);\n        return factory(extraction.internalDialog, extraction.initialData, extraction.dataValidator);\n      },\n      openUrl: function (factory, structure) {\n        var internalDialog = getOrDie(createUrlDialog(structure));\n        return factory(internalDialog);\n      },\n      redial: function (structure) {\n        return extract$1(structure);\n      }\n    };\n\n    var value$3 = function () {\n      var subject = Cell(Option.none());\n      var clear = function () {\n        subject.set(Option.none());\n      };\n      var set = function (s) {\n        subject.set(Option.some(s));\n      };\n      var on = function (f) {\n        subject.get().each(f);\n      };\n      var isSet = function () {\n        return subject.get().isSome();\n      };\n      return {\n        clear: clear,\n        set: set,\n        isSet: isSet,\n        on: on\n      };\n    };\n\n    var toValidValues = function (values) {\n      var errors = [];\n      var result = {};\n      each$1(values, function (value, name) {\n        value.fold(function () {\n          errors.push(name);\n        }, function (v) {\n          result[name] = v;\n        });\n      });\n      return errors.length > 0 ? Result.error(errors) : Result.value(result);\n    };\n\n    var renderBodyPanel = function (spec, backstage) {\n      var memForm = record(Form.sketch(function (parts) {\n        return {\n          dom: {\n            tag: 'div',\n            classes: ['tox-form'].concat(spec.classes)\n          },\n          components: map(spec.items, function (item) {\n            return interpretInForm(parts, item, backstage);\n          })\n        };\n      }));\n      return {\n        dom: {\n          tag: 'div',\n          classes: ['tox-dialog__body']\n        },\n        components: [{\n            dom: {\n              tag: 'div',\n              classes: ['tox-dialog__body-content']\n            },\n            components: [memForm.asSpec()]\n          }],\n        behaviours: derive$1([\n          Keying.config({\n            mode: 'acyclic',\n            useTabstopAt: not(NavigableObject.isPseudoStop)\n          }),\n          ComposingConfigs.memento(memForm),\n          RepresentingConfigs.memento(memForm, {\n            postprocess: function (formValue) {\n              return toValidValues(formValue).fold(function (err) {\n                domGlobals.console.error(err);\n                return {};\n              }, function (vals) {\n                return vals;\n              });\n            }\n          })\n        ])\n      };\n    };\n\n    var factory$i = function (detail, spec) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: detail.components,\n        events: events$7(detail.action),\n        behaviours: augment(detail.tabButtonBehaviours, [\n          Focusing.config({}),\n          Keying.config({\n            mode: 'execution',\n            useSpace: true,\n            useEnter: true\n          }),\n          Representing.config({\n            store: {\n              mode: 'memory',\n              initialValue: detail.value\n            }\n          })\n        ]),\n        domModification: detail.domModification\n      };\n    };\n    var TabButton = single$2({\n      name: 'TabButton',\n      configFields: [\n        defaulted$1('uid', undefined),\n        strict$1('value'),\n        field('dom', 'dom', mergeWithThunk(function (spec) {\n          return {\n            attributes: {\n              'role': 'tab',\n              'id': generate$1('aria'),\n              'aria-selected': 'false'\n            }\n          };\n        }), anyValue$1()),\n        option('action'),\n        defaulted$1('domModification', {}),\n        field$1('tabButtonBehaviours', [\n          Focusing,\n          Keying,\n          Representing\n        ]),\n        strict$1('view')\n      ],\n      factory: factory$i\n    });\n\n    var schema$x = constant([\n      strict$1('tabs'),\n      strict$1('dom'),\n      defaulted$1('clickToDismiss', false),\n      field$1('tabbarBehaviours', [\n        Highlighting,\n        Keying\n      ]),\n      markers([\n        'tabClass',\n        'selectedClass'\n      ])\n    ]);\n    var tabsPart = group({\n      factory: TabButton,\n      name: 'tabs',\n      unit: 'tab',\n      overrides: function (barDetail, tabSpec) {\n        var dismissTab$1 = function (tabbar, button) {\n          Highlighting.dehighlight(tabbar, button);\n          emitWith(tabbar, dismissTab(), {\n            tabbar: tabbar,\n            button: button\n          });\n        };\n        var changeTab$1 = function (tabbar, button) {\n          Highlighting.highlight(tabbar, button);\n          emitWith(tabbar, changeTab(), {\n            tabbar: tabbar,\n            button: button\n          });\n        };\n        return {\n          action: function (button) {\n            var tabbar = button.getSystem().getByUid(barDetail.uid).getOrDie();\n            var activeButton = Highlighting.isHighlighted(tabbar, button);\n            var response = function () {\n              if (activeButton && barDetail.clickToDismiss) {\n                return dismissTab$1;\n              } else if (!activeButton) {\n                return changeTab$1;\n              } else {\n                return noop;\n              }\n            }();\n            response(tabbar, button);\n          },\n          domModification: { classes: [barDetail.markers.tabClass] }\n        };\n      }\n    });\n    var parts$f = constant([tabsPart]);\n\n    var factory$j = function (detail, components, spec, externals) {\n      return {\n        'uid': detail.uid,\n        'dom': detail.dom,\n        'components': components,\n        'debug.sketcher': 'Tabbar',\n        'domModification': { attributes: { role: 'tablist' } },\n        'behaviours': augment(detail.tabbarBehaviours, [\n          Highlighting.config({\n            highlightClass: detail.markers.selectedClass,\n            itemClass: detail.markers.tabClass,\n            onHighlight: function (tabbar, tab) {\n              set$1(tab.element(), 'aria-selected', 'true');\n            },\n            onDehighlight: function (tabbar, tab) {\n              set$1(tab.element(), 'aria-selected', 'false');\n            }\n          }),\n          Keying.config({\n            mode: 'flow',\n            getInitial: function (tabbar) {\n              return Highlighting.getHighlighted(tabbar).map(function (tab) {\n                return tab.element();\n              });\n            },\n            selector: '.' + detail.markers.tabClass,\n            executeOnMove: true\n          })\n        ])\n      };\n    };\n    var Tabbar = composite$1({\n      name: 'Tabbar',\n      configFields: schema$x(),\n      partFields: parts$f(),\n      factory: factory$j\n    });\n\n    var factory$k = function (detail, spec) {\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        behaviours: augment(detail.tabviewBehaviours, [Replacing.config({})]),\n        domModification: { attributes: { role: 'tabpanel' } }\n      };\n    };\n    var Tabview = single$2({\n      name: 'Tabview',\n      configFields: [field$1('tabviewBehaviours', [Replacing])],\n      factory: factory$k\n    });\n\n    var schema$y = constant([\n      defaulted$1('selectFirst', true),\n      onHandler('onChangeTab'),\n      onHandler('onDismissTab'),\n      defaulted$1('tabs', []),\n      field$1('tabSectionBehaviours', [])\n    ]);\n    var barPart = required({\n      factory: Tabbar,\n      schema: [\n        strict$1('dom'),\n        strictObjOf('markers', [\n          strict$1('tabClass'),\n          strict$1('selectedClass')\n        ])\n      ],\n      name: 'tabbar',\n      defaults: function (detail) {\n        return { tabs: detail.tabs };\n      }\n    });\n    var viewPart = required({\n      factory: Tabview,\n      name: 'tabview'\n    });\n    var parts$g = constant([\n      barPart,\n      viewPart\n    ]);\n\n    var factory$l = function (detail, components, spec, externals) {\n      var changeTab$1 = function (button) {\n        var tabValue = Representing.getValue(button);\n        getPart(button, detail, 'tabview').each(function (tabview) {\n          var tabWithValue = find(detail.tabs, function (t) {\n            return t.value === tabValue;\n          });\n          tabWithValue.each(function (tabData) {\n            var panel = tabData.view();\n            set$1(tabview.element(), 'aria-labelledby', get$2(button.element(), 'id'));\n            Replacing.set(tabview, panel);\n            detail.onChangeTab(tabview, button, panel);\n          });\n        });\n      };\n      var changeTabBy = function (section, byPred) {\n        getPart(section, detail, 'tabbar').each(function (tabbar) {\n          byPred(tabbar).each(emitExecute);\n        });\n      };\n      return {\n        uid: detail.uid,\n        dom: detail.dom,\n        components: components,\n        behaviours: get$b(detail.tabSectionBehaviours),\n        events: derive(flatten([\n          detail.selectFirst ? [runOnAttached(function (section, simulatedEvent) {\n              changeTabBy(section, Highlighting.getFirst);\n            })] : [],\n          [\n            run(changeTab(), function (section, simulatedEvent) {\n              var button = simulatedEvent.event().button();\n              changeTab$1(button);\n            }),\n            run(dismissTab(), function (section, simulatedEvent) {\n              var button = simulatedEvent.event().button();\n              detail.onDismissTab(section, button);\n            })\n          ]\n        ])),\n        apis: {\n          getViewItems: function (section) {\n            return getPart(section, detail, 'tabview').map(function (tabview) {\n              return Replacing.contents(tabview);\n            }).getOr([]);\n          },\n          showTab: function (section, tabKey) {\n            var getTabIfNotActive = function (tabbar) {\n              var candidates = Highlighting.getCandidates(tabbar);\n              var optTab = find(candidates, function (c) {\n                return Representing.getValue(c) === tabKey;\n              });\n              return optTab.filter(function (tab) {\n                return !Highlighting.isHighlighted(tabbar, tab);\n              });\n            };\n            changeTabBy(section, getTabIfNotActive);\n          }\n        }\n      };\n    };\n    var TabSection = composite$1({\n      name: 'TabSection',\n      configFields: schema$y(),\n      partFields: parts$g(),\n      factory: factory$l,\n      apis: {\n        getViewItems: function (apis, component) {\n          return apis.getViewItems(component);\n        },\n        showTab: function (apis, component, tabKey) {\n          apis.showTab(component, tabKey);\n        }\n      }\n    });\n\n    var measureHeights = function (allTabs, tabview, tabviewComp) {\n      return map(allTabs, function (tab, i) {\n        Replacing.set(tabviewComp, allTabs[i].view());\n        var rect = tabview.dom().getBoundingClientRect();\n        Replacing.set(tabviewComp, []);\n        return rect.height;\n      });\n    };\n    var getMaxHeight = function (heights) {\n      return head(sort(heights, function (a, b) {\n        if (a > b) {\n          return -1;\n        } else if (a < b) {\n          return +1;\n        } else {\n          return 0;\n        }\n      }));\n    };\n    var getMaxTabviewHeight = function (dialog, tabview, tablist) {\n      var documentElement$1 = documentElement(dialog).dom();\n      var rootElm = ancestor$1(dialog, '.tox-dialog-wrap').getOr(dialog);\n      var isFixed = get$4(rootElm, 'position') === 'fixed';\n      var maxHeight;\n      if (isFixed) {\n        maxHeight = Math.max(documentElement$1.clientHeight, domGlobals.window.innerHeight);\n      } else {\n        maxHeight = Math.max(documentElement$1.offsetHeight, documentElement$1.scrollHeight);\n      }\n      var tabviewHeight = get$6(tabview);\n      var isTabListBeside = tabview.dom().offsetLeft >= tablist.dom().offsetLeft + get$7(tablist);\n      var currentTabHeight = isTabListBeside ? Math.max(get$6(tablist), tabviewHeight) : tabviewHeight;\n      var dialogTopMargin = parseInt(get$4(dialog, 'margin-top'), 10) || 0;\n      var dialogBottomMargin = parseInt(get$4(dialog, 'margin-bottom'), 10) || 0;\n      var dialogHeight = get$6(dialog) + dialogTopMargin + dialogBottomMargin;\n      var chromeHeight = dialogHeight - currentTabHeight;\n      return maxHeight - chromeHeight;\n    };\n    var showTab = function (allTabs, comp) {\n      head(allTabs).each(function (tab) {\n        return TabSection.showTab(comp, tab.value);\n      });\n    };\n    var setTabviewHeight = function (tabview, height) {\n      set$2(tabview, 'height', height + 'px');\n      if (!detect$3().browser.isIE()) {\n        set$2(tabview, 'flex-basis', height + 'px');\n      } else {\n        remove$6(tabview, 'flex-basis');\n      }\n    };\n    var updateTabviewHeight = function (dialogBody, tabview, maxTabHeight) {\n      ancestor$1(dialogBody, '[role=\"dialog\"]').each(function (dialog) {\n        descendant$1(dialog, '[role=\"tablist\"]').each(function (tablist) {\n          maxTabHeight.get().map(function (height) {\n            set$2(tabview, 'height', '0');\n            set$2(tabview, 'flex-basis', '0');\n            return Math.min(height, getMaxTabviewHeight(dialog, tabview, tablist));\n          }).each(function (height) {\n            setTabviewHeight(tabview, height);\n          });\n        });\n      });\n    };\n    var getTabview = function (dialog) {\n      return descendant$1(dialog, '[role=\"tabpanel\"]');\n    };\n    var setMode = function (allTabs) {\n      var smartTabHeight = function () {\n        var maxTabHeight = Cell(Option.none());\n        var extraEvents = [\n          runOnAttached(function (comp) {\n            var dialog = comp.element();\n            getTabview(dialog).each(function (tabview) {\n              set$2(tabview, 'visibility', 'hidden');\n              comp.getSystem().getByDom(tabview).toOption().each(function (tabviewComp) {\n                var heights = measureHeights(allTabs, tabview, tabviewComp);\n                var maxTabHeightOpt = getMaxHeight(heights);\n                maxTabHeight.set(maxTabHeightOpt);\n              });\n              updateTabviewHeight(dialog, tabview, maxTabHeight);\n              remove$6(tabview, 'visibility');\n              showTab(allTabs, comp);\n              global$2.requestAnimationFrame(function () {\n                updateTabviewHeight(dialog, tabview, maxTabHeight);\n              });\n            });\n          }),\n          run(windowResize(), function (comp) {\n            var dialog = comp.element();\n            getTabview(dialog).each(function (tabview) {\n              updateTabviewHeight(dialog, tabview, maxTabHeight);\n            });\n          }),\n          run(formResizeEvent, function (comp, se) {\n            var dialog = comp.element();\n            getTabview(dialog).each(function (tabview) {\n              var oldFocus = active();\n              set$2(tabview, 'visibility', 'hidden');\n              var oldHeight = getRaw(tabview, 'height').map(function (h) {\n                return parseInt(h, 10);\n              });\n              remove$6(tabview, 'height');\n              remove$6(tabview, 'flex-basis');\n              var newHeight = tabview.dom().getBoundingClientRect().height;\n              var hasGrown = oldHeight.forall(function (h) {\n                return newHeight > h;\n              });\n              if (hasGrown) {\n                maxTabHeight.set(Option.from(newHeight));\n                updateTabviewHeight(dialog, tabview, maxTabHeight);\n              } else {\n                oldHeight.each(function (h) {\n                  setTabviewHeight(tabview, h);\n                });\n              }\n              remove$6(tabview, 'visibility');\n              oldFocus.each(focus$1);\n            });\n          })\n        ];\n        var selectFirst = false;\n        return {\n          extraEvents: extraEvents,\n          selectFirst: selectFirst\n        };\n      }();\n      var naiveTabHeight = function () {\n        var extraEvents = [];\n        var selectFirst = true;\n        return {\n          extraEvents: extraEvents,\n          selectFirst: selectFirst\n        };\n      }();\n      return {\n        smartTabHeight: smartTabHeight,\n        naiveTabHeight: naiveTabHeight\n      };\n    };\n\n    var SendDataToSectionChannel = 'send-data-to-section';\n    var SendDataToViewChannel = 'send-data-to-view';\n    var renderTabPanel = function (spec, backstage) {\n      var storedValue = Cell({});\n      var updateDataWithForm = function (form) {\n        var formData = Representing.getValue(form);\n        var validData = toValidValues(formData).getOr({});\n        var currentData = storedValue.get();\n        var newData = deepMerge(currentData, validData);\n        storedValue.set(newData);\n      };\n      var setDataOnForm = function (form) {\n        var tabData = storedValue.get();\n        Representing.setValue(form, tabData);\n      };\n      var oldTab = Cell(null);\n      var allTabs = map(spec.tabs, function (tab) {\n        return {\n          value: tab.name,\n          dom: {\n            tag: 'div',\n            classes: ['tox-dialog__body-nav-item'],\n            innerHtml: backstage.shared.providers.translate(tab.title)\n          },\n          view: function () {\n            return [Form.sketch(function (parts) {\n                return {\n                  dom: {\n                    tag: 'div',\n                    classes: ['tox-form']\n                  },\n                  components: map(tab.items, function (item) {\n                    return interpretInForm(parts, item, backstage);\n                  }),\n                  formBehaviours: derive$1([\n                    Keying.config({\n                      mode: 'acyclic',\n                      useTabstopAt: not(NavigableObject.isPseudoStop)\n                    }),\n                    config('TabView.form.events', [\n                      runOnAttached(setDataOnForm),\n                      runOnDetached(updateDataWithForm)\n                    ]),\n                    Receiving.config({\n                      channels: wrapAll$1([\n                        {\n                          key: SendDataToSectionChannel,\n                          value: { onReceive: updateDataWithForm }\n                        },\n                        {\n                          key: SendDataToViewChannel,\n                          value: { onReceive: setDataOnForm }\n                        }\n                      ])\n                    })\n                  ])\n                };\n              })];\n          }\n        };\n      });\n      var tabMode = setMode(allTabs).smartTabHeight;\n      return TabSection.sketch({\n        dom: {\n          tag: 'div',\n          classes: ['tox-dialog__body']\n        },\n        onChangeTab: function (section, button, _viewItems) {\n          var name = Representing.getValue(button);\n          emitWith(section, formTabChangeEvent, {\n            name: name,\n            oldName: oldTab.get()\n          });\n          oldTab.set(name);\n        },\n        tabs: allTabs,\n        components: [\n          TabSection.parts().tabbar({\n            dom: {\n              tag: 'div',\n              classes: ['tox-dialog__body-nav']\n            },\n            components: [Tabbar.parts().tabs({})],\n            markers: {\n              tabClass: 'tox-tab',\n              selectedClass: 'tox-dialog__body-nav-item--active'\n            },\n            tabbarBehaviours: derive$1([Tabstopping.config({})])\n          }),\n          TabSection.parts().tabview({\n            dom: {\n              tag: 'div',\n              classes: ['tox-dialog__body-content']\n            }\n          })\n        ],\n        selectFirst: tabMode.selectFirst,\n        tabSectionBehaviours: derive$1([\n          config('tabpanel', tabMode.extraEvents),\n          Keying.config({ mode: 'acyclic' }),\n          Composing.config({\n            find: function (comp) {\n              return head(TabSection.getViewItems(comp));\n            }\n          }),\n          Representing.config({\n            store: {\n              mode: 'manual',\n              getValue: function (tsection) {\n                tsection.getSystem().broadcastOn([SendDataToSectionChannel], {});\n                return storedValue.get();\n              },\n              setValue: function (tsection, value) {\n                storedValue.set(value);\n                tsection.getSystem().broadcastOn([SendDataToViewChannel], {});\n              }\n            }\n          })\n        ])\n      });\n    };\n\n    var dialogChannel = generate$1('update-dialog');\n    var titleChannel = generate$1('update-title');\n    var bodyChannel = generate$1('update-body');\n    var footerChannel = generate$1('update-footer');\n    var bodySendMessageChannel = generate$1('body-send-message');\n\n    var renderBody = function (spec, id, backstage, ariaAttrs) {\n      var renderComponents = function (incoming) {\n        switch (incoming.body.type) {\n        case 'tabpanel': {\n            return [renderTabPanel(incoming.body, backstage)];\n          }\n        default: {\n            return [renderBodyPanel(incoming.body, backstage)];\n          }\n        }\n      };\n      var updateState = function (_comp, incoming) {\n        return Option.some({\n          isTabPanel: function () {\n            return incoming.body.type === 'tabpanel';\n          }\n        });\n      };\n      var ariaAttributes = { 'aria-live': 'polite' };\n      return {\n        dom: {\n          tag: 'div',\n          classes: ['tox-dialog__content-js'],\n          attributes: __assign(__assign({}, id.map(function (x) {\n            return { id: x };\n          }).getOr({})), ariaAttrs ? ariaAttributes : {})\n        },\n        components: [],\n        behaviours: derive$1([\n          ComposingConfigs.childAt(0),\n          Reflecting.config({\n            channel: bodyChannel,\n            updateState: updateState,\n            renderComponents: renderComponents,\n            initialData: spec\n          })\n        ])\n      };\n    };\n    var renderInlineBody = function (spec, contentId, backstage, ariaAttrs) {\n      return renderBody(spec, Option.some(contentId), backstage, ariaAttrs);\n    };\n    var renderModalBody = function (spec, backstage) {\n      var bodySpec = renderBody(spec, Option.none(), backstage, false);\n      return ModalDialog.parts().body(bodySpec);\n    };\n    var renderIframeBody = function (spec) {\n      var bodySpec = {\n        dom: {\n          tag: 'div',\n          classes: ['tox-dialog__content-js']\n        },\n        components: [{\n            dom: {\n              tag: 'div',\n              classes: ['tox-dialog__body-iframe']\n            },\n            components: [NavigableObject.craft({\n                dom: {\n                  tag: 'iframe',\n                  attributes: { src: spec.url }\n                },\n                behaviours: derive$1([\n                  Tabstopping.config({}),\n                  Focusing.config({})\n                ])\n              })]\n          }],\n        behaviours: derive$1([Keying.config({\n            mode: 'acyclic',\n            useTabstopAt: not(NavigableObject.isPseudoStop)\n          })])\n      };\n      return ModalDialog.parts().body(bodySpec);\n    };\n\n    var initCommonEvents = function (fireApiEvent, extras) {\n      return [\n        runWithTarget(focusin(), NavigableObject.onFocus),\n        fireApiEvent(formCloseEvent, function (api, spec) {\n          extras.onClose();\n          spec.onClose();\n        }),\n        fireApiEvent(formCancelEvent, function (api, spec, _event, self) {\n          spec.onCancel(api);\n          emit(self, formCloseEvent);\n        }),\n        run(formUnblockEvent, function (c, se) {\n          return extras.onUnblock();\n        }),\n        run(formBlockEvent, function (c, se) {\n          return extras.onBlock(se.event());\n        })\n      ];\n    };\n    var initUrlDialog = function (getInstanceApi, extras) {\n      var fireApiEvent = function (eventName, f) {\n        return run(eventName, function (c, se) {\n          withSpec(c, function (spec, _c) {\n            f(getInstanceApi(), spec, se.event(), c);\n          });\n        });\n      };\n      var withSpec = function (c, f) {\n        Reflecting.getState(c).get().each(function (currentDialog) {\n          f(currentDialog, c);\n        });\n      };\n      return __spreadArrays(initCommonEvents(fireApiEvent, extras), [fireApiEvent(formActionEvent, function (api, spec, event) {\n          spec.onAction(api, { name: event.name() });\n        })]);\n    };\n    var initDialog = function (getInstanceApi, extras) {\n      var fireApiEvent = function (eventName, f) {\n        return run(eventName, function (c, se) {\n          withSpec(c, function (spec, _c) {\n            f(getInstanceApi(), spec, se.event(), c);\n          });\n        });\n      };\n      var withSpec = function (c, f) {\n        Reflecting.getState(c).get().each(function (currentDialogInit) {\n          f(currentDialogInit.internalDialog, c);\n        });\n      };\n      return __spreadArrays(initCommonEvents(fireApiEvent, extras), [\n        fireApiEvent(formSubmitEvent, function (api, spec) {\n          return spec.onSubmit(api);\n        }),\n        fireApiEvent(formChangeEvent, function (api, spec, event) {\n          spec.onChange(api, { name: event.name() });\n        }),\n        fireApiEvent(formActionEvent, function (api, spec, event, component) {\n          var focusIn = function () {\n            return Keying.focusIn(component);\n          };\n          var current = active();\n          spec.onAction(api, {\n            name: event.name(),\n            value: event.value()\n          });\n          active().fold(function () {\n            focusIn();\n          }, function (focused) {\n            if (!contains$2(component.element(), focused) || has$1(focused, 'disabled')) {\n              focusIn();\n            } else if (contains$2(focused, current.getOrNull()) && has$1(current.getOrDie(), 'disabled')) {\n              focusIn();\n            }\n          });\n        }),\n        fireApiEvent(formTabChangeEvent, function (api, spec, event) {\n          spec.onTabChange(api, {\n            newTabName: event.name(),\n            oldTabName: event.oldName()\n          });\n        }),\n        runOnDetached(function (component) {\n          var api = getInstanceApi();\n          Representing.setValue(component, api.getData());\n        })\n      ]);\n    };\n    var SilverDialogEvents = {\n      initUrlDialog: initUrlDialog,\n      initDialog: initDialog\n    };\n\n    var makeButton = function (button, backstage) {\n      return renderFooterButton(button, button.type, backstage);\n    };\n    var lookup$2 = function (compInSystem, footerButtons, buttonName) {\n      return find(footerButtons, function (button) {\n        return button.name === buttonName;\n      }).bind(function (memButton) {\n        return memButton.memento.getOpt(compInSystem);\n      });\n    };\n    var renderComponents = function (_data, state) {\n      var footerButtons = state.map(function (s) {\n        return s.footerButtons;\n      }).getOr([]);\n      var buttonGroups = partition(footerButtons, function (button) {\n        return button.align === 'start';\n      });\n      var makeGroup = function (edge, buttons) {\n        return Container.sketch({\n          dom: {\n            tag: 'div',\n            classes: ['tox-dialog__footer-' + edge]\n          },\n          components: map(buttons, function (button) {\n            return button.memento.asSpec();\n          })\n        });\n      };\n      var startButtons = makeGroup('start', buttonGroups.pass);\n      var endButtons = makeGroup('end', buttonGroups.fail);\n      return [\n        startButtons,\n        endButtons\n      ];\n    };\n    var renderFooter = function (initSpec, backstage) {\n      var updateState = function (_comp, data) {\n        var footerButtons = map(data.buttons, function (button) {\n          var memButton = record(makeButton(button, backstage));\n          return {\n            name: button.name,\n            align: button.align,\n            memento: memButton\n          };\n        });\n        var lookupByName = function (compInSystem, buttonName) {\n          return lookup$2(compInSystem, footerButtons, buttonName);\n        };\n        return Option.some({\n          lookupByName: lookupByName,\n          footerButtons: footerButtons\n        });\n      };\n      return {\n        dom: fromHtml$2('<div class=\"tox-dialog__footer\"></div>'),\n        components: [],\n        behaviours: derive$1([Reflecting.config({\n            channel: footerChannel,\n            initialData: initSpec,\n            updateState: updateState,\n            renderComponents: renderComponents\n          })])\n      };\n    };\n    var renderInlineFooter = function (initSpec, backstage) {\n      return renderFooter(initSpec, backstage);\n    };\n    var renderModalFooter = function (initSpec, backstage) {\n      return ModalDialog.parts().footer(renderFooter(initSpec, backstage));\n    };\n\n    var getCompByName = function (access, name) {\n      var root = access.getRoot();\n      if (root.getSystem().isConnected()) {\n        var form_1 = Composing.getCurrent(access.getFormWrapper()).getOr(access.getFormWrapper());\n        return Form.getField(form_1, name).fold(function () {\n          var footer = access.getFooter();\n          var footerState = Reflecting.getState(footer);\n          return footerState.get().bind(function (f) {\n            return f.lookupByName(form_1, name);\n          });\n        }, function (comp) {\n          return Option.some(comp);\n        });\n      } else {\n        return Option.none();\n      }\n    };\n    var validateData = function (access, data) {\n      var root = access.getRoot();\n      return Reflecting.getState(root).get().map(function (dialogState) {\n        return getOrDie(asRaw('data', dialogState.dataValidator, data));\n      }).getOr(data);\n    };\n    var getDialogApi = function (access, doRedial, menuItemStates) {\n      var withRoot = function (f) {\n        var root = access.getRoot();\n        if (root.getSystem().isConnected()) {\n          f(root);\n        }\n      };\n      var getData = function () {\n        var root = access.getRoot();\n        var valueComp = root.getSystem().isConnected() ? access.getFormWrapper() : root;\n        var representedValues = Representing.getValue(valueComp);\n        var menuItemCurrentState = map$1(menuItemStates, function (cell) {\n          return cell.get();\n        });\n        return __assign(__assign({}, representedValues), menuItemCurrentState);\n      };\n      var setData = function (newData) {\n        withRoot(function (_) {\n          var prevData = instanceApi.getData();\n          var mergedData = merge(prevData, newData);\n          var newInternalData = validateData(access, mergedData);\n          var form = access.getFormWrapper();\n          Representing.setValue(form, newInternalData);\n          each$1(menuItemStates, function (v, k) {\n            if (has(mergedData, k)) {\n              v.set(mergedData[k]);\n            }\n          });\n        });\n      };\n      var disable = function (name) {\n        getCompByName(access, name).each(Disabling.disable);\n      };\n      var enable = function (name) {\n        getCompByName(access, name).each(Disabling.enable);\n      };\n      var focus = function (name) {\n        getCompByName(access, name).each(Focusing.focus);\n      };\n      var block = function (message) {\n        if (!isString(message)) {\n          throw new Error('The dialogInstanceAPI.block function should be passed a blocking message of type string as an argument');\n        }\n        withRoot(function (root) {\n          emitWith(root, formBlockEvent, { message: message });\n        });\n      };\n      var unblock = function () {\n        withRoot(function (root) {\n          emit(root, formUnblockEvent);\n        });\n      };\n      var showTab = function (name) {\n        withRoot(function (_) {\n          var body = access.getBody();\n          var bodyState = Reflecting.getState(body);\n          if (bodyState.get().exists(function (b) {\n              return b.isTabPanel();\n            })) {\n            Composing.getCurrent(body).each(function (tabSection) {\n              TabSection.showTab(tabSection, name);\n            });\n          }\n        });\n      };\n      var redial = function (d) {\n        withRoot(function (root) {\n          var dialogInit = doRedial(d);\n          root.getSystem().broadcastOn([dialogChannel], dialogInit);\n          root.getSystem().broadcastOn([titleChannel], dialogInit.internalDialog);\n          root.getSystem().broadcastOn([bodyChannel], dialogInit.internalDialog);\n          root.getSystem().broadcastOn([footerChannel], dialogInit.internalDialog);\n          instanceApi.setData(dialogInit.initialData);\n        });\n      };\n      var close = function () {\n        withRoot(function (root) {\n          emit(root, formCloseEvent);\n        });\n      };\n      var instanceApi = {\n        getData: getData,\n        setData: setData,\n        disable: disable,\n        enable: enable,\n        focus: focus,\n        block: block,\n        unblock: unblock,\n        showTab: showTab,\n        redial: redial,\n        close: close\n      };\n      return instanceApi;\n    };\n\n    var isTouch = global$6.deviceType.isTouch();\n    var hiddenHeader = function (title, close) {\n      return {\n        dom: {\n          tag: 'div',\n          styles: { display: 'none' },\n          classes: ['tox-dialog__header']\n        },\n        components: [\n          title,\n          close\n        ]\n      };\n    };\n    var pClose = function (onClose, providersBackstage) {\n      return ModalDialog.parts().close(Button.sketch({\n        dom: {\n          tag: 'button',\n          classes: [\n            'tox-button',\n            'tox-button--icon',\n            'tox-button--naked'\n          ],\n          attributes: {\n            'type': 'button',\n            'aria-label': providersBackstage.translate('Close')\n          }\n        },\n        action: onClose,\n        buttonBehaviours: derive$1([Tabstopping.config({})])\n      }));\n    };\n    var pUntitled = function () {\n      return ModalDialog.parts().title({\n        dom: {\n          tag: 'div',\n          classes: ['tox-dialog__title'],\n          innerHtml: '',\n          styles: { display: 'none' }\n        }\n      });\n    };\n    var pBodyMessage = function (message, providersBackstage) {\n      return ModalDialog.parts().body({\n        dom: {\n          tag: 'div',\n          classes: ['tox-dialog__body']\n        },\n        components: [{\n            dom: {\n              tag: 'div',\n              classes: ['tox-dialog__body-content']\n            },\n            components: [{ dom: fromHtml$2('<p>' + providersBackstage.translate(message) + '</p>') }]\n          }]\n      });\n    };\n    var pFooter = function (buttons) {\n      return ModalDialog.parts().footer({\n        dom: {\n          tag: 'div',\n          classes: ['tox-dialog__footer']\n        },\n        components: buttons\n      });\n    };\n    var pFooterGroup = function (startButtons, endButtons) {\n      return [\n        Container.sketch({\n          dom: {\n            tag: 'div',\n            classes: ['tox-dialog__footer-start']\n          },\n          components: startButtons\n        }),\n        Container.sketch({\n          dom: {\n            tag: 'div',\n            classes: ['tox-dialog__footer-end']\n          },\n          components: endButtons\n        })\n      ];\n    };\n    var renderDialog = function (spec) {\n      var _a;\n      var dialogClass = 'tox-dialog';\n      var blockerClass = dialogClass + '-wrap';\n      var blockerBackdropClass = blockerClass + '__backdrop';\n      var scrollLockClass = dialogClass + '__disable-scroll';\n      return ModalDialog.sketch({\n        lazySink: spec.lazySink,\n        onEscape: function (comp) {\n          spec.onEscape(comp);\n          return Option.some(true);\n        },\n        useTabstopAt: function (elem) {\n          return !NavigableObject.isPseudoStop(elem);\n        },\n        dom: {\n          tag: 'div',\n          classes: [dialogClass].concat(spec.extraClasses),\n          styles: __assign({ position: 'relative' }, spec.extraStyles)\n        },\n        components: __spreadArrays([\n          spec.header,\n          spec.body\n        ], spec.footer.toArray()),\n        parts: {\n          blocker: {\n            dom: fromHtml$2('<div class=\"' + blockerClass + '\"></div>'),\n            components: [{\n                dom: {\n                  tag: 'div',\n                  classes: isTouch ? [\n                    blockerBackdropClass,\n                    blockerBackdropClass + '--opaque'\n                  ] : [blockerBackdropClass]\n                }\n              }]\n          }\n        },\n        dragBlockClass: blockerClass,\n        modalBehaviours: derive$1(__spreadArrays([\n          Focusing.config({}),\n          config('dialog-events', spec.dialogEvents.concat([runOnSource(focusin(), function (comp, se) {\n              Keying.focusIn(comp);\n            })])),\n          config('scroll-lock', [\n            runOnAttached(function () {\n              add$2(body(), scrollLockClass);\n            }),\n            runOnDetached(function () {\n              remove$4(body(), scrollLockClass);\n            })\n          ])\n        ], spec.extraBehaviours)),\n        eventOrder: __assign((_a = {}, _a[execute()] = ['dialog-events'], _a[attachedToDom()] = [\n          'scroll-lock',\n          'dialog-events',\n          'alloy.base.behaviour'\n        ], _a[detachedFromDom()] = [\n          'alloy.base.behaviour',\n          'dialog-events',\n          'scroll-lock'\n        ], _a), spec.eventOrder)\n      });\n    };\n\n    var renderClose = function (providersBackstage) {\n      return Button.sketch({\n        dom: {\n          tag: 'button',\n          classes: [\n            'tox-button',\n            'tox-button--icon',\n            'tox-button--naked'\n          ],\n          attributes: {\n            'type': 'button',\n            'aria-label': providersBackstage.translate('Close'),\n            'title': providersBackstage.translate('Close')\n          }\n        },\n        components: [{\n            dom: {\n              tag: 'div',\n              classes: ['tox-icon'],\n              innerHtml: '<svg width=\"24\" height=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.953 7.453L13.422 12l4.531 4.547-1.406 1.406L12 13.422l-4.547 4.531-1.406-1.406L10.578 12 6.047 7.453l1.406-1.406L12 10.578l4.547-4.531z\" fill-rule=\"evenodd\"></path></svg>'\n            }\n          }],\n        action: function (comp) {\n          emit(comp, formCancelEvent);\n        }\n      });\n    };\n    var renderTitle = function (spec, id, providersBackstage) {\n      var renderComponents = function (data) {\n        return [text(providersBackstage.translate(data.title))];\n      };\n      return {\n        dom: {\n          tag: 'div',\n          classes: ['tox-dialog__title'],\n          attributes: __assign({}, id.map(function (x) {\n            return { id: x };\n          }).getOr({}))\n        },\n        components: renderComponents(spec),\n        behaviours: derive$1([Reflecting.config({\n            channel: titleChannel,\n            renderComponents: renderComponents\n          })])\n      };\n    };\n    var renderDragHandle = function () {\n      return { dom: fromHtml$2('<div class=\"tox-dialog__draghandle\"></div>') };\n    };\n    var renderInlineHeader = function (spec, titleId, providersBackstage) {\n      return Container.sketch({\n        dom: fromHtml$2('<div class=\"tox-dialog__header\"></div>'),\n        components: [\n          renderTitle(spec, Option.some(titleId), providersBackstage),\n          renderDragHandle(),\n          renderClose(providersBackstage)\n        ],\n        containerBehaviours: derive$1([Dragging.config({\n            mode: 'mouse',\n            blockerClass: 'blocker',\n            getTarget: function (handle) {\n              return closest$3(handle, '[role=\"dialog\"]').getOrDie();\n            },\n            snaps: {\n              getSnapPoints: function () {\n                return [];\n              },\n              leftAttr: 'data-drag-left',\n              topAttr: 'data-drag-top'\n            }\n          })])\n      });\n    };\n    var renderModalHeader = function (spec, providersBackstage) {\n      var pTitle = ModalDialog.parts().title(renderTitle(spec, Option.none(), providersBackstage));\n      var pHandle = ModalDialog.parts().draghandle(renderDragHandle());\n      var pClose = ModalDialog.parts().close(renderClose(providersBackstage));\n      var components = [pTitle].concat(spec.draggable ? [pHandle] : []).concat([pClose]);\n      return Container.sketch({\n        dom: fromHtml$2('<div class=\"tox-dialog__header\"></div>'),\n        components: components\n      });\n    };\n\n    var getHeader = function (title, backstage) {\n      return renderModalHeader({\n        title: backstage.shared.providers.translate(title),\n        draggable: backstage.dialog.isDraggableModal()\n      }, backstage.shared.providers);\n    };\n    var getEventExtras = function (lazyDialog, extra) {\n      return {\n        onClose: function () {\n          return extra.closeWindow();\n        },\n        onBlock: function (blockEvent) {\n          ModalDialog.setBusy(lazyDialog(), function (d, bs) {\n            return {\n              dom: {\n                tag: 'div',\n                classes: ['tox-dialog__busy-spinner'],\n                attributes: { 'aria-label': blockEvent.message() },\n                styles: {\n                  left: '0px',\n                  right: '0px',\n                  bottom: '0px',\n                  top: '0px',\n                  position: 'absolute'\n                }\n              },\n              behaviours: bs,\n              components: [{ dom: fromHtml$2('<div class=\"tox-spinner\"><div></div><div></div><div></div></div>') }]\n            };\n          });\n        },\n        onUnblock: function () {\n          ModalDialog.setIdle(lazyDialog());\n        }\n      };\n    };\n    var renderModalDialog = function (spec, initialData, dialogEvents, backstage) {\n      var _a;\n      var updateState = function (_comp, incoming) {\n        return Option.some(incoming);\n      };\n      return build$1(renderDialog(__assign(__assign({}, spec), {\n        lazySink: backstage.shared.getSink,\n        extraBehaviours: __spreadArrays([\n          Reflecting.config({\n            channel: dialogChannel,\n            updateState: updateState,\n            initialData: initialData\n          }),\n          RepresentingConfigs.memory({})\n        ], spec.extraBehaviours),\n        onEscape: function (comp) {\n          emit(comp, formCancelEvent);\n        },\n        dialogEvents: dialogEvents,\n        eventOrder: (_a = {}, _a[receive()] = [\n          'reflecting',\n          'receiving'\n        ], _a[attachedToDom()] = [\n          'scroll-lock',\n          'reflecting',\n          'messages',\n          'dialog-events',\n          'alloy.base.behaviour'\n        ], _a[detachedFromDom()] = [\n          'alloy.base.behaviour',\n          'dialog-events',\n          'messages',\n          'reflecting',\n          'scroll-lock'\n        ], _a)\n      })));\n    };\n    var mapMenuButtons = function (buttons) {\n      var mapItems = function (button) {\n        var items = map(button.items, function (item) {\n          var cell = Cell(false);\n          return __assign(__assign({}, item), { storage: cell });\n        });\n        return __assign(__assign({}, button), { items: items });\n      };\n      return map(buttons, function (button) {\n        if (button.type === 'menu') {\n          return mapItems(button);\n        }\n        return button;\n      });\n    };\n    var extractCellsToObject = function (buttons) {\n      return foldl(buttons, function (acc, button) {\n        if (button.type === 'menu') {\n          var menuButton = button;\n          return foldl(menuButton.items, function (innerAcc, item) {\n            innerAcc[item.name] = item.storage;\n            return innerAcc;\n          }, acc);\n        }\n        return acc;\n      }, {});\n    };\n\n    var renderDialog$1 = function (dialogInit, extra, backstage) {\n      var header = getHeader(dialogInit.internalDialog.title, backstage);\n      var body = renderModalBody({ body: dialogInit.internalDialog.body }, backstage);\n      var storagedMenuButtons = mapMenuButtons(dialogInit.internalDialog.buttons);\n      var objOfCells = extractCellsToObject(storagedMenuButtons);\n      var footer = renderModalFooter({ buttons: storagedMenuButtons }, backstage);\n      var dialogEvents = SilverDialogEvents.initDialog(function () {\n        return instanceApi;\n      }, getEventExtras(function () {\n        return dialog;\n      }, extra));\n      var dialogSize = dialogInit.internalDialog.size !== 'normal' ? dialogInit.internalDialog.size === 'large' ? ['tox-dialog--width-lg'] : ['tox-dialog--width-md'] : [];\n      var spec = {\n        header: header,\n        body: body,\n        footer: Option.some(footer),\n        extraClasses: dialogSize,\n        extraBehaviours: [],\n        extraStyles: {}\n      };\n      var dialog = renderModalDialog(spec, dialogInit, dialogEvents, backstage);\n      var modalAccess = function () {\n        var getForm = function () {\n          var outerForm = ModalDialog.getBody(dialog);\n          return Composing.getCurrent(outerForm).getOr(outerForm);\n        };\n        return {\n          getRoot: function () {\n            return dialog;\n          },\n          getBody: function () {\n            return ModalDialog.getBody(dialog);\n          },\n          getFooter: function () {\n            return ModalDialog.getFooter(dialog);\n          },\n          getFormWrapper: getForm\n        };\n      }();\n      var instanceApi = getDialogApi(modalAccess, extra.redial, objOfCells);\n      return {\n        dialog: dialog,\n        instanceApi: instanceApi\n      };\n    };\n\n    var renderInlineDialog = function (dialogInit, extra, backstage, ariaAttrs) {\n      var _a, _b;\n      var dialogLabelId = generate$1('dialog-label');\n      var dialogContentId = generate$1('dialog-content');\n      var updateState = function (_comp, incoming) {\n        return Option.some(incoming);\n      };\n      var memHeader = record(renderInlineHeader({\n        title: dialogInit.internalDialog.title,\n        draggable: true\n      }, dialogLabelId, backstage.shared.providers));\n      var memBody = record(renderInlineBody({ body: dialogInit.internalDialog.body }, dialogContentId, backstage, ariaAttrs));\n      var storagedMenuButtons = mapMenuButtons(dialogInit.internalDialog.buttons);\n      var objOfCells = extractCellsToObject(storagedMenuButtons);\n      var memFooter = record(renderInlineFooter({ buttons: storagedMenuButtons }, backstage));\n      var dialogEvents = SilverDialogEvents.initDialog(function () {\n        return instanceApi;\n      }, {\n        onBlock: function () {\n        },\n        onUnblock: function () {\n        },\n        onClose: function () {\n          return extra.closeWindow();\n        }\n      });\n      var dialog = build$1({\n        dom: {\n          tag: 'div',\n          classes: [\n            'tox-dialog',\n            'tox-dialog-inline'\n          ],\n          attributes: (_a = { role: 'dialog' }, _a['aria-labelledby'] = dialogLabelId, _a['aria-describedby'] = '' + dialogContentId, _a)\n        },\n        eventOrder: (_b = {}, _b[receive()] = [\n          Reflecting.name(),\n          Receiving.name()\n        ], _b[execute()] = ['execute-on-form'], _b[attachedToDom()] = [\n          'reflecting',\n          'execute-on-form'\n        ], _b),\n        behaviours: derive$1([\n          Keying.config({\n            mode: 'cyclic',\n            onEscape: function (c) {\n              emit(c, formCloseEvent);\n              return Option.some(true);\n            },\n            useTabstopAt: function (elem) {\n              return !NavigableObject.isPseudoStop(elem) && (name(elem) !== 'button' || get$2(elem, 'disabled') !== 'disabled');\n            }\n          }),\n          Reflecting.config({\n            channel: dialogChannel,\n            updateState: updateState,\n            initialData: dialogInit\n          }),\n          Focusing.config({}),\n          config('execute-on-form', dialogEvents.concat([runOnSource(focusin(), function (comp, se) {\n              Keying.focusIn(comp);\n            })])),\n          RepresentingConfigs.memory({})\n        ]),\n        components: [\n          memHeader.asSpec(),\n          memBody.asSpec(),\n          memFooter.asSpec()\n        ]\n      });\n      var instanceApi = getDialogApi({\n        getRoot: function () {\n          return dialog;\n        },\n        getFooter: function () {\n          return memFooter.get(dialog);\n        },\n        getBody: function () {\n          return memBody.get(dialog);\n        },\n        getFormWrapper: function () {\n          var body = memBody.get(dialog);\n          return Composing.getCurrent(body).getOr(body);\n        }\n      }, extra.redial, objOfCells);\n      return {\n        dialog: dialog,\n        instanceApi: instanceApi\n      };\n    };\n\n    var global$g = tinymce.util.Tools.resolve('tinymce.util.URI');\n\n    var getUrlDialogApi = function (root) {\n      var withRoot = function (f) {\n        if (root.getSystem().isConnected()) {\n          f(root);\n        }\n      };\n      var block = function (message) {\n        if (!isString(message)) {\n          throw new Error('The urlDialogInstanceAPI.block function should be passed a blocking message of type string as an argument');\n        }\n        withRoot(function (root) {\n          emitWith(root, formBlockEvent, { message: message });\n        });\n      };\n      var unblock = function () {\n        withRoot(function (root) {\n          emit(root, formUnblockEvent);\n        });\n      };\n      var close = function () {\n        withRoot(function (root) {\n          emit(root, formCloseEvent);\n        });\n      };\n      var sendMessage = function (data) {\n        withRoot(function (root) {\n          root.getSystem().broadcastOn([bodySendMessageChannel], data);\n        });\n      };\n      return {\n        block: block,\n        unblock: unblock,\n        close: close,\n        sendMessage: sendMessage\n      };\n    };\n\n    var SUPPORTED_MESSAGE_ACTIONS = [\n      'insertContent',\n      'setContent',\n      'execCommand',\n      'close',\n      'block',\n      'unblock'\n    ];\n    var isSupportedMessage = function (data) {\n      return isObject(data) && SUPPORTED_MESSAGE_ACTIONS.indexOf(data.mceAction) !== -1;\n    };\n    var isCustomMessage = function (data) {\n      return !isSupportedMessage(data) && isObject(data) && has(data, 'mceAction');\n    };\n    var handleMessage = function (editor, api, data) {\n      switch (data.mceAction) {\n      case 'insertContent':\n        editor.insertContent(data.content);\n        break;\n      case 'setContent':\n        editor.setContent(data.content);\n        break;\n      case 'execCommand':\n        var ui = isBoolean(data.ui) ? data.ui : false;\n        editor.execCommand(data.cmd, ui, data.value);\n        break;\n      case 'close':\n        api.close();\n        break;\n      case 'block':\n        api.block(data.message);\n        break;\n      case 'unblock':\n        api.unblock();\n        break;\n      }\n    };\n    var renderUrlDialog = function (internalDialog, extra, editor, backstage) {\n      var _a;\n      var header = getHeader(internalDialog.title, backstage);\n      var body = renderIframeBody(internalDialog);\n      var footer = internalDialog.buttons.bind(function (buttons) {\n        if (buttons.length === 0) {\n          return Option.none();\n        } else {\n          return Option.some(renderModalFooter({ buttons: buttons }, backstage));\n        }\n      });\n      var dialogEvents = SilverDialogEvents.initUrlDialog(function () {\n        return instanceApi;\n      }, getEventExtras(function () {\n        return dialog;\n      }, extra));\n      var styles = __assign(__assign({}, internalDialog.height.fold(function () {\n        return {};\n      }, function (height) {\n        return {\n          'height': height + 'px',\n          'max-height': height + 'px'\n        };\n      })), internalDialog.width.fold(function () {\n        return {};\n      }, function (width) {\n        return {\n          'width': width + 'px',\n          'max-width': width + 'px'\n        };\n      }));\n      var classes = internalDialog.width.isNone() && internalDialog.height.isNone() ? ['tox-dialog--width-lg'] : [];\n      var iframeUri = new global$g(internalDialog.url, { base_uri: new global$g(domGlobals.window.location.href) });\n      var iframeDomain = iframeUri.protocol + '://' + iframeUri.host + (iframeUri.port ? ':' + iframeUri.port : '');\n      var messageHandlerUnbinder = Cell(Option.none());\n      var extraBehaviours = [\n        config('messages', [\n          runOnAttached(function () {\n            var unbind = bind$3(Element.fromDom(domGlobals.window), 'message', function (e) {\n              if (iframeUri.isSameOrigin(new global$g(e.raw().origin))) {\n                var data = e.raw().data;\n                if (isSupportedMessage(data)) {\n                  handleMessage(editor, instanceApi, data);\n                } else if (isCustomMessage(data)) {\n                  internalDialog.onMessage(instanceApi, data);\n                }\n              }\n            });\n            messageHandlerUnbinder.set(Option.some(unbind));\n          }),\n          runOnDetached(function () {\n            messageHandlerUnbinder.get().each(function (unbinder) {\n              return unbinder.unbind();\n            });\n          })\n        ]),\n        Receiving.config({\n          channels: (_a = {}, _a[bodySendMessageChannel] = {\n            onReceive: function (comp, data) {\n              descendant$1(comp.element(), 'iframe').each(function (iframeEle) {\n                var iframeWin = iframeEle.dom().contentWindow;\n                iframeWin.postMessage(data, iframeDomain);\n              });\n            }\n          }, _a)\n        })\n      ];\n      var spec = {\n        header: header,\n        body: body,\n        footer: footer,\n        extraClasses: classes,\n        extraBehaviours: extraBehaviours,\n        extraStyles: styles\n      };\n      var dialog = renderModalDialog(spec, internalDialog, dialogEvents, backstage);\n      var instanceApi = getUrlDialogApi(dialog);\n      return {\n        dialog: dialog,\n        instanceApi: instanceApi\n      };\n    };\n\n    var setup$d = function (extras) {\n      var sharedBackstage = extras.backstage.shared;\n      var open = function (message, callback) {\n        var closeDialog = function () {\n          ModalDialog.hide(alertDialog);\n          callback();\n        };\n        var memFooterClose = record(renderFooterButton({\n          name: 'close-alert',\n          text: 'OK',\n          primary: true,\n          align: 'end',\n          disabled: false,\n          icon: Option.none()\n        }, 'cancel', extras.backstage));\n        var titleSpec = pUntitled();\n        var closeSpec = pClose(closeDialog, sharedBackstage.providers);\n        var alertDialog = build$1(renderDialog({\n          lazySink: function () {\n            return sharedBackstage.getSink();\n          },\n          header: hiddenHeader(titleSpec, closeSpec),\n          body: pBodyMessage(message, sharedBackstage.providers),\n          footer: Option.some(pFooter(pFooterGroup([], [memFooterClose.asSpec()]))),\n          onEscape: closeDialog,\n          extraClasses: ['tox-alert-dialog'],\n          extraBehaviours: [],\n          extraStyles: {},\n          dialogEvents: [run(formCancelEvent, closeDialog)],\n          eventOrder: {}\n        }));\n        ModalDialog.show(alertDialog);\n        var footerCloseButton = memFooterClose.get(alertDialog);\n        Focusing.focus(footerCloseButton);\n      };\n      return { open: open };\n    };\n\n    var setup$e = function (extras) {\n      var sharedBackstage = extras.backstage.shared;\n      var open = function (message, callback) {\n        var closeDialog = function (state) {\n          ModalDialog.hide(confirmDialog);\n          callback(state);\n        };\n        var memFooterYes = record(renderFooterButton({\n          name: 'yes',\n          text: 'Yes',\n          primary: true,\n          align: 'end',\n          disabled: false,\n          icon: Option.none()\n        }, 'submit', extras.backstage));\n        var footerNo = renderFooterButton({\n          name: 'no',\n          text: 'No',\n          primary: true,\n          align: 'end',\n          disabled: false,\n          icon: Option.none()\n        }, 'cancel', extras.backstage);\n        var titleSpec = pUntitled();\n        var closeSpec = pClose(function () {\n          return closeDialog(false);\n        }, sharedBackstage.providers);\n        var confirmDialog = build$1(renderDialog({\n          lazySink: function () {\n            return sharedBackstage.getSink();\n          },\n          header: hiddenHeader(titleSpec, closeSpec),\n          body: pBodyMessage(message, sharedBackstage.providers),\n          footer: Option.some(pFooter(pFooterGroup([], [\n            footerNo,\n            memFooterYes.asSpec()\n          ]))),\n          onEscape: function () {\n            return closeDialog(false);\n          },\n          extraClasses: ['tox-confirm-dialog'],\n          extraBehaviours: [],\n          extraStyles: {},\n          dialogEvents: [\n            run(formCancelEvent, function () {\n              return closeDialog(false);\n            }),\n            run(formSubmitEvent, function () {\n              return closeDialog(true);\n            })\n          ],\n          eventOrder: {}\n        }));\n        ModalDialog.show(confirmDialog);\n        var footerYesButton = memFooterYes.get(confirmDialog);\n        Focusing.focus(footerYesButton);\n      };\n      return { open: open };\n    };\n\n    var validateData$1 = function (data, validator) {\n      return getOrDie(asRaw('data', validator, data));\n    };\n    var inlineAdditionalBehaviours = function (editor, isStickyToolbar) {\n      if (isStickyToolbar) {\n        return [];\n      } else {\n        return [Docking.config({\n            contextual: {\n              lazyContext: function () {\n                return Option.some(box(Element.fromDom(editor.getContentAreaContainer())));\n              },\n              fadeInClass: 'tox-dialog-dock-fadein',\n              fadeOutClass: 'tox-dialog-dock-fadeout',\n              transitionClass: 'tox-dialog-dock-transition'\n            },\n            leftAttr: 'data-dock-left',\n            topAttr: 'data-dock-top',\n            positionAttr: 'data-dock-pos',\n            modes: ['top']\n          })];\n      }\n    };\n    var setup$f = function (extras) {\n      var backstage = extras.backstage;\n      var editor = extras.editor;\n      var isStickyToolbar$1 = isStickyToolbar(editor);\n      var alertDialog = setup$d(extras);\n      var confirmDialog = setup$e(extras);\n      var open = function (config, params, closeWindow) {\n        if (params !== undefined && params.inline === 'toolbar') {\n          return openInlineDialog(config, backstage.shared.anchors.toolbar(), closeWindow, params.ariaAttrs);\n        } else if (params !== undefined && params.inline === 'cursor') {\n          return openInlineDialog(config, backstage.shared.anchors.cursor(), closeWindow, params.ariaAttrs);\n        } else {\n          return openModalDialog(config, closeWindow);\n        }\n      };\n      var openUrl = function (config, closeWindow) {\n        return openModalUrlDialog(config, closeWindow);\n      };\n      var openModalUrlDialog = function (config, closeWindow) {\n        var factory = function (contents) {\n          var dialog = renderUrlDialog(contents, {\n            closeWindow: function () {\n              ModalDialog.hide(dialog.dialog);\n              closeWindow(dialog.instanceApi);\n            }\n          }, editor, backstage);\n          ModalDialog.show(dialog.dialog);\n          return dialog.instanceApi;\n        };\n        return DialogManager.openUrl(factory, config);\n      };\n      var openModalDialog = function (config, closeWindow) {\n        var factory = function (contents, internalInitialData, dataValidator) {\n          var initialData = internalInitialData;\n          var dialogInit = {\n            dataValidator: dataValidator,\n            initialData: initialData,\n            internalDialog: contents\n          };\n          var dialog = renderDialog$1(dialogInit, {\n            redial: DialogManager.redial,\n            closeWindow: function () {\n              ModalDialog.hide(dialog.dialog);\n              closeWindow(dialog.instanceApi);\n            }\n          }, backstage);\n          ModalDialog.show(dialog.dialog);\n          dialog.instanceApi.setData(initialData);\n          return dialog.instanceApi;\n        };\n        return DialogManager.open(factory, config);\n      };\n      var openInlineDialog = function (config$1, anchor, closeWindow, ariaAttrs) {\n        var factory = function (contents, internalInitialData, dataValidator) {\n          var initialData = validateData$1(internalInitialData, dataValidator);\n          var inlineDialog = value$3();\n          var dialogInit = {\n            dataValidator: dataValidator,\n            initialData: initialData,\n            internalDialog: contents\n          };\n          var refreshDocking = function () {\n            return inlineDialog.on(function (dialog) {\n              Docking.refresh(dialog);\n            });\n          };\n          var dialogUi = renderInlineDialog(dialogInit, {\n            redial: DialogManager.redial,\n            closeWindow: function () {\n              inlineDialog.on(InlineView.hide);\n              editor.off('ResizeEditor', refreshDocking);\n              inlineDialog.clear();\n              closeWindow(dialogUi.instanceApi);\n            }\n          }, backstage, ariaAttrs);\n          var inlineDialogComp = build$1(InlineView.sketch({\n            lazySink: backstage.shared.getSink,\n            dom: {\n              tag: 'div',\n              classes: []\n            },\n            fireDismissalEventInstead: {},\n            inlineBehaviours: derive$1(__spreadArrays([config('window-manager-inline-events', [run(dismissRequested(), function (comp, se) {\n                  emit(dialogUi.dialog, formCancelEvent);\n                })])], inlineAdditionalBehaviours(editor, isStickyToolbar$1)))\n          }));\n          inlineDialog.set(inlineDialogComp);\n          InlineView.showWithin(inlineDialogComp, anchor, premade$1(dialogUi.dialog), Option.some(body()));\n          if (!isStickyToolbar$1) {\n            Docking.refresh(inlineDialogComp);\n            editor.on('ResizeEditor', refreshDocking);\n          }\n          dialogUi.instanceApi.setData(initialData);\n          Keying.focusIn(dialogUi.dialog);\n          return dialogUi.instanceApi;\n        };\n        return DialogManager.open(factory, config$1);\n      };\n      var confirm = function (message, callback) {\n        confirmDialog.open(message, function (state) {\n          callback(state);\n        });\n      };\n      var alert = function (message, callback) {\n        alertDialog.open(message, function () {\n          callback();\n        });\n      };\n      var close = function (instanceApi) {\n        instanceApi.close();\n      };\n      return {\n        open: open,\n        openUrl: openUrl,\n        alert: alert,\n        close: close,\n        confirm: confirm\n      };\n    };\n    var WindowManager = { setup: setup$f };\n\n    function Theme () {\n      global$1.add('silver', function (editor) {\n        var _a = Render.setup(editor), uiMothership = _a.uiMothership, backstage = _a.backstage, renderUI = _a.renderUI, getUi = _a.getUi;\n        Autocompleter.register(editor, backstage.shared);\n        var windowMgr = WindowManager.setup({\n          editor: editor,\n          backstage: backstage\n        });\n        return {\n          renderUI: renderUI,\n          getWindowManagerImpl: constant(windowMgr),\n          getNotificationManagerImpl: function () {\n            return NotificationManagerImpl(editor, { backstage: backstage }, uiMothership);\n          },\n          ui: getUi()\n        };\n      });\n    }\n\n    Theme();\n\n}(window));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack:///./node_modules/tinymce/themes/silver/theme.js?");

/***/ }),

/***/ "./node_modules/tinymce/tinymce.js":
/*!*****************************************!*\
  !*** ./node_modules/tinymce/tinymce.js ***!
  \*****************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Copyright (c) Tiny Technologies, Inc. All rights reserved.\n * Licensed under the LGPL or a commercial license.\n * For LGPL see License.txt in the project root for license information.\n * For commercial licenses see https://www.tiny.cloud/\n *\n * Version: 5.1.5 (2019-12-19)\n */\n(function (domGlobals) {\n    'use strict';\n\n    var noop = function () {\n    };\n    var compose = function (fa, fb) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return fa(fb.apply(null, args));\n      };\n    };\n    var constant = function (value) {\n      return function () {\n        return value;\n      };\n    };\n    var identity = function (x) {\n      return x;\n    };\n    function curry(fn) {\n      var initialArgs = [];\n      for (var _i = 1; _i < arguments.length; _i++) {\n        initialArgs[_i - 1] = arguments[_i];\n      }\n      return function () {\n        var restArgs = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          restArgs[_i] = arguments[_i];\n        }\n        var all = initialArgs.concat(restArgs);\n        return fn.apply(null, all);\n      };\n    }\n    var not = function (f) {\n      return function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        return !f.apply(null, args);\n      };\n    };\n    var die = function (msg) {\n      return function () {\n        throw new Error(msg);\n      };\n    };\n    var never = constant(false);\n    var always = constant(true);\n\n    var none = function () {\n      return NONE;\n    };\n    var NONE = function () {\n      var eq = function (o) {\n        return o.isNone();\n      };\n      var call = function (thunk) {\n        return thunk();\n      };\n      var id = function (n) {\n        return n;\n      };\n      var me = {\n        fold: function (n, s) {\n          return n();\n        },\n        is: never,\n        isSome: never,\n        isNone: always,\n        getOr: id,\n        getOrThunk: call,\n        getOrDie: function (msg) {\n          throw new Error(msg || 'error: getOrDie called on none.');\n        },\n        getOrNull: constant(null),\n        getOrUndefined: constant(undefined),\n        or: id,\n        orThunk: call,\n        map: none,\n        each: noop,\n        bind: none,\n        exists: never,\n        forall: always,\n        filter: none,\n        equals: eq,\n        equals_: eq,\n        toArray: function () {\n          return [];\n        },\n        toString: constant('none()')\n      };\n      if (Object.freeze) {\n        Object.freeze(me);\n      }\n      return me;\n    }();\n    var some = function (a) {\n      var constant_a = constant(a);\n      var self = function () {\n        return me;\n      };\n      var bind = function (f) {\n        return f(a);\n      };\n      var me = {\n        fold: function (n, s) {\n          return s(a);\n        },\n        is: function (v) {\n          return a === v;\n        },\n        isSome: always,\n        isNone: never,\n        getOr: constant_a,\n        getOrThunk: constant_a,\n        getOrDie: constant_a,\n        getOrNull: constant_a,\n        getOrUndefined: constant_a,\n        or: self,\n        orThunk: self,\n        map: function (f) {\n          return some(f(a));\n        },\n        each: function (f) {\n          f(a);\n        },\n        bind: bind,\n        exists: bind,\n        forall: bind,\n        filter: function (f) {\n          return f(a) ? me : NONE;\n        },\n        toArray: function () {\n          return [a];\n        },\n        toString: function () {\n          return 'some(' + a + ')';\n        },\n        equals: function (o) {\n          return o.is(a);\n        },\n        equals_: function (o, elementEq) {\n          return o.fold(never, function (b) {\n            return elementEq(a, b);\n          });\n        }\n      };\n      return me;\n    };\n    var from = function (value) {\n      return value === null || value === undefined ? NONE : some(value);\n    };\n    var Option = {\n      some: some,\n      none: none,\n      from: from\n    };\n\n    var typeOf = function (x) {\n      if (x === null) {\n        return 'null';\n      }\n      var t = typeof x;\n      if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {\n        return 'array';\n      }\n      if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {\n        return 'string';\n      }\n      return t;\n    };\n    var isType = function (type) {\n      return function (value) {\n        return typeOf(value) === type;\n      };\n    };\n    var isString = isType('string');\n    var isObject = isType('object');\n    var isArray = isType('array');\n    var isNull = isType('null');\n    var isBoolean = isType('boolean');\n    var isFunction = isType('function');\n    var isNumber = isType('number');\n\n    var nativeSlice = Array.prototype.slice;\n    var nativeIndexOf = Array.prototype.indexOf;\n    var nativePush = Array.prototype.push;\n    var rawIndexOf = function (ts, t) {\n      return nativeIndexOf.call(ts, t);\n    };\n    var indexOf = function (xs, x) {\n      var r = rawIndexOf(xs, x);\n      return r === -1 ? Option.none() : Option.some(r);\n    };\n    var contains = function (xs, x) {\n      return rawIndexOf(xs, x) > -1;\n    };\n    var exists = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return true;\n        }\n      }\n      return false;\n    };\n    var map = function (xs, f) {\n      var len = xs.length;\n      var r = new Array(len);\n      for (var i = 0; i < len; i++) {\n        var x = xs[i];\n        r[i] = f(x, i);\n      }\n      return r;\n    };\n    var each = function (xs, f) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        f(x, i);\n      }\n    };\n    var eachr = function (xs, f) {\n      for (var i = xs.length - 1; i >= 0; i--) {\n        var x = xs[i];\n        f(x, i);\n      }\n    };\n    var partition = function (xs, pred) {\n      var pass = [];\n      var fail = [];\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        var arr = pred(x, i) ? pass : fail;\n        arr.push(x);\n      }\n      return {\n        pass: pass,\n        fail: fail\n      };\n    };\n    var filter = function (xs, pred) {\n      var r = [];\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          r.push(x);\n        }\n      }\n      return r;\n    };\n    var foldr = function (xs, f, acc) {\n      eachr(xs, function (x) {\n        acc = f(acc, x);\n      });\n      return acc;\n    };\n    var foldl = function (xs, f, acc) {\n      each(xs, function (x) {\n        acc = f(acc, x);\n      });\n      return acc;\n    };\n    var find = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return Option.some(x);\n        }\n      }\n      return Option.none();\n    };\n    var findIndex = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        if (pred(x, i)) {\n          return Option.some(i);\n        }\n      }\n      return Option.none();\n    };\n    var flatten = function (xs) {\n      var r = [];\n      for (var i = 0, len = xs.length; i < len; ++i) {\n        if (!isArray(xs[i])) {\n          throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);\n        }\n        nativePush.apply(r, xs[i]);\n      }\n      return r;\n    };\n    var bind = function (xs, f) {\n      var output = map(xs, f);\n      return flatten(output);\n    };\n    var forall = function (xs, pred) {\n      for (var i = 0, len = xs.length; i < len; ++i) {\n        var x = xs[i];\n        if (pred(x, i) !== true) {\n          return false;\n        }\n      }\n      return true;\n    };\n    var reverse = function (xs) {\n      var r = nativeSlice.call(xs, 0);\n      r.reverse();\n      return r;\n    };\n    var difference = function (a1, a2) {\n      return filter(a1, function (x) {\n        return !contains(a2, x);\n      });\n    };\n    var mapToObject = function (xs, f) {\n      var r = {};\n      for (var i = 0, len = xs.length; i < len; i++) {\n        var x = xs[i];\n        r[String(x)] = f(x, i);\n      }\n      return r;\n    };\n    var sort = function (xs, comparator) {\n      var copy = nativeSlice.call(xs, 0);\n      copy.sort(comparator);\n      return copy;\n    };\n    var head = function (xs) {\n      return xs.length === 0 ? Option.none() : Option.some(xs[0]);\n    };\n    var last = function (xs) {\n      return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]);\n    };\n    var from$1 = isFunction(Array.from) ? Array.from : function (x) {\n      return nativeSlice.call(x);\n    };\n\n    var __assign = function () {\n      __assign = Object.assign || function __assign(t) {\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\n          s = arguments[i];\n          for (var p in s)\n            if (Object.prototype.hasOwnProperty.call(s, p))\n              t[p] = s[p];\n        }\n        return t;\n      };\n      return __assign.apply(this, arguments);\n    };\n    function __rest(s, e) {\n      var t = {};\n      for (var p in s)\n        if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n          t[p] = s[p];\n      if (s != null && typeof Object.getOwnPropertySymbols === 'function')\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n          if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n            t[p[i]] = s[p[i]];\n        }\n      return t;\n    }\n\n    var isNodeType = function (type) {\n      return function (node) {\n        return !!node && node.nodeType === type;\n      };\n    };\n    var isRestrictedNode = function (node) {\n      return !!node && !Object.getPrototypeOf(node);\n    };\n    var isElement = isNodeType(1);\n    var matchNodeNames = function (names) {\n      var lowercasedNames = names.map(function (s) {\n        return s.toLowerCase();\n      });\n      return function (node) {\n        if (node && node.nodeName) {\n          var nodeName = node.nodeName.toLowerCase();\n          return contains(lowercasedNames, nodeName);\n        }\n        return false;\n      };\n    };\n    var matchStyleValues = function (name, values) {\n      var items = values.toLowerCase().split(' ');\n      return function (node) {\n        var i, cssValue;\n        if (isElement(node)) {\n          for (i = 0; i < items.length; i++) {\n            var computed = node.ownerDocument.defaultView.getComputedStyle(node, null);\n            cssValue = computed ? computed.getPropertyValue(name) : null;\n            if (cssValue === items[i]) {\n              return true;\n            }\n          }\n        }\n        return false;\n      };\n    };\n    var hasPropValue = function (propName, propValue) {\n      return function (node) {\n        return isElement(node) && node[propName] === propValue;\n      };\n    };\n    var hasAttribute = function (attrName, attrValue) {\n      return function (node) {\n        return isElement(node) && node.hasAttribute(attrName);\n      };\n    };\n    var hasAttributeValue = function (attrName, attrValue) {\n      return function (node) {\n        return isElement(node) && node.getAttribute(attrName) === attrValue;\n      };\n    };\n    var isBogus = function (node) {\n      return isElement(node) && node.hasAttribute('data-mce-bogus');\n    };\n    var isBogusAll = function (node) {\n      return isElement(node) && node.getAttribute('data-mce-bogus') === 'all';\n    };\n    var isTable = function (node) {\n      return isElement(node) && node.tagName === 'TABLE';\n    };\n    var hasContentEditableState = function (value) {\n      return function (node) {\n        if (isElement(node)) {\n          if (node.contentEditable === value) {\n            return true;\n          }\n          if (node.getAttribute('data-mce-contenteditable') === value) {\n            return true;\n          }\n        }\n        return false;\n      };\n    };\n    var isTextareaOrInput = matchNodeNames([\n      'textarea',\n      'input'\n    ]);\n    var isText = isNodeType(3);\n    var isComment = isNodeType(8);\n    var isDocument = isNodeType(9);\n    var isDocumentFragment = isNodeType(11);\n    var isBr = matchNodeNames(['br']);\n    var isContentEditableTrue = hasContentEditableState('true');\n    var isContentEditableFalse = hasContentEditableState('false');\n    var NodeType = {\n      isText: isText,\n      isElement: isElement,\n      isComment: isComment,\n      isDocument: isDocument,\n      isDocumentFragment: isDocumentFragment,\n      isBr: isBr,\n      isContentEditableTrue: isContentEditableTrue,\n      isContentEditableFalse: isContentEditableFalse,\n      isRestrictedNode: isRestrictedNode,\n      matchNodeNames: matchNodeNames,\n      hasPropValue: hasPropValue,\n      hasAttribute: hasAttribute,\n      hasAttributeValue: hasAttributeValue,\n      matchStyleValues: matchStyleValues,\n      isBogus: isBogus,\n      isBogusAll: isBogusAll,\n      isTable: isTable,\n      isTextareaOrInput: isTextareaOrInput\n    };\n\n    var Cell = function (initial) {\n      var value = initial;\n      var get = function () {\n        return value;\n      };\n      var set = function (v) {\n        value = v;\n      };\n      var clone = function () {\n        return Cell(get());\n      };\n      return {\n        get: get,\n        set: set,\n        clone: clone\n      };\n    };\n\n    var firstMatch = function (regexes, s) {\n      for (var i = 0; i < regexes.length; i++) {\n        var x = regexes[i];\n        if (x.test(s)) {\n          return x;\n        }\n      }\n      return undefined;\n    };\n    var find$1 = function (regexes, agent) {\n      var r = firstMatch(regexes, agent);\n      if (!r) {\n        return {\n          major: 0,\n          minor: 0\n        };\n      }\n      var group = function (i) {\n        return Number(agent.replace(r, '$' + i));\n      };\n      return nu(group(1), group(2));\n    };\n    var detect = function (versionRegexes, agent) {\n      var cleanedAgent = String(agent).toLowerCase();\n      if (versionRegexes.length === 0) {\n        return unknown();\n      }\n      return find$1(versionRegexes, cleanedAgent);\n    };\n    var unknown = function () {\n      return nu(0, 0);\n    };\n    var nu = function (major, minor) {\n      return {\n        major: major,\n        minor: minor\n      };\n    };\n    var Version = {\n      nu: nu,\n      detect: detect,\n      unknown: unknown\n    };\n\n    var edge = 'Edge';\n    var chrome = 'Chrome';\n    var ie = 'IE';\n    var opera = 'Opera';\n    var firefox = 'Firefox';\n    var safari = 'Safari';\n    var isBrowser = function (name, current) {\n      return function () {\n        return current === name;\n      };\n    };\n    var unknown$1 = function () {\n      return nu$1({\n        current: undefined,\n        version: Version.unknown()\n      });\n    };\n    var nu$1 = function (info) {\n      var current = info.current;\n      var version = info.version;\n      return {\n        current: current,\n        version: version,\n        isEdge: isBrowser(edge, current),\n        isChrome: isBrowser(chrome, current),\n        isIE: isBrowser(ie, current),\n        isOpera: isBrowser(opera, current),\n        isFirefox: isBrowser(firefox, current),\n        isSafari: isBrowser(safari, current)\n      };\n    };\n    var Browser = {\n      unknown: unknown$1,\n      nu: nu$1,\n      edge: constant(edge),\n      chrome: constant(chrome),\n      ie: constant(ie),\n      opera: constant(opera),\n      firefox: constant(firefox),\n      safari: constant(safari)\n    };\n\n    var windows = 'Windows';\n    var ios = 'iOS';\n    var android = 'Android';\n    var linux = 'Linux';\n    var osx = 'OSX';\n    var solaris = 'Solaris';\n    var freebsd = 'FreeBSD';\n    var isOS = function (name, current) {\n      return function () {\n        return current === name;\n      };\n    };\n    var unknown$2 = function () {\n      return nu$2({\n        current: undefined,\n        version: Version.unknown()\n      });\n    };\n    var nu$2 = function (info) {\n      var current = info.current;\n      var version = info.version;\n      return {\n        current: current,\n        version: version,\n        isWindows: isOS(windows, current),\n        isiOS: isOS(ios, current),\n        isAndroid: isOS(android, current),\n        isOSX: isOS(osx, current),\n        isLinux: isOS(linux, current),\n        isSolaris: isOS(solaris, current),\n        isFreeBSD: isOS(freebsd, current)\n      };\n    };\n    var OperatingSystem = {\n      unknown: unknown$2,\n      nu: nu$2,\n      windows: constant(windows),\n      ios: constant(ios),\n      android: constant(android),\n      linux: constant(linux),\n      osx: constant(osx),\n      solaris: constant(solaris),\n      freebsd: constant(freebsd)\n    };\n\n    var DeviceType = function (os, browser, userAgent, mediaMatch) {\n      var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;\n      var isiPhone = os.isiOS() && !isiPad;\n      var isMobile = os.isiOS() || os.isAndroid();\n      var isTouch = isMobile || mediaMatch('(pointer:coarse)');\n      var isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');\n      var isPhone = isiPhone || isMobile && !isTablet;\n      var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;\n      var isDesktop = !isPhone && !isTablet && !iOSwebview;\n      return {\n        isiPad: constant(isiPad),\n        isiPhone: constant(isiPhone),\n        isTablet: constant(isTablet),\n        isPhone: constant(isPhone),\n        isTouch: constant(isTouch),\n        isAndroid: os.isAndroid,\n        isiOS: os.isiOS,\n        isWebView: constant(iOSwebview),\n        isDesktop: constant(isDesktop)\n      };\n    };\n\n    var detect$1 = function (candidates, userAgent) {\n      var agent = String(userAgent).toLowerCase();\n      return find(candidates, function (candidate) {\n        return candidate.search(agent);\n      });\n    };\n    var detectBrowser = function (browsers, userAgent) {\n      return detect$1(browsers, userAgent).map(function (browser) {\n        var version = Version.detect(browser.versionRegexes, userAgent);\n        return {\n          current: browser.name,\n          version: version\n        };\n      });\n    };\n    var detectOs = function (oses, userAgent) {\n      return detect$1(oses, userAgent).map(function (os) {\n        var version = Version.detect(os.versionRegexes, userAgent);\n        return {\n          current: os.name,\n          version: version\n        };\n      });\n    };\n    var UaString = {\n      detectBrowser: detectBrowser,\n      detectOs: detectOs\n    };\n\n    var checkRange = function (str, substr, start) {\n      if (substr === '') {\n        return true;\n      }\n      if (str.length < substr.length) {\n        return false;\n      }\n      var x = str.substr(start, start + substr.length);\n      return x === substr;\n    };\n    var contains$1 = function (str, substr) {\n      return str.indexOf(substr) !== -1;\n    };\n    var startsWith = function (str, prefix) {\n      return checkRange(str, prefix, 0);\n    };\n    var trim = function (str) {\n      return str.replace(/^\\s+|\\s+$/g, '');\n    };\n    var lTrim = function (str) {\n      return str.replace(/^\\s+/g, '');\n    };\n    var rTrim = function (str) {\n      return str.replace(/\\s+$/g, '');\n    };\n\n    var normalVersionRegex = /.*?version\\/\\ ?([0-9]+)\\.([0-9]+).*/;\n    var checkContains = function (target) {\n      return function (uastring) {\n        return contains$1(uastring, target);\n      };\n    };\n    var browsers = [\n      {\n        name: 'Edge',\n        versionRegexes: [/.*?edge\\/ ?([0-9]+)\\.([0-9]+)$/],\n        search: function (uastring) {\n          return contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit');\n        }\n      },\n      {\n        name: 'Chrome',\n        versionRegexes: [\n          /.*?chrome\\/([0-9]+)\\.([0-9]+).*/,\n          normalVersionRegex\n        ],\n        search: function (uastring) {\n          return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe');\n        }\n      },\n      {\n        name: 'IE',\n        versionRegexes: [\n          /.*?msie\\ ?([0-9]+)\\.([0-9]+).*/,\n          /.*?rv:([0-9]+)\\.([0-9]+).*/\n        ],\n        search: function (uastring) {\n          return contains$1(uastring, 'msie') || contains$1(uastring, 'trident');\n        }\n      },\n      {\n        name: 'Opera',\n        versionRegexes: [\n          normalVersionRegex,\n          /.*?opera\\/([0-9]+)\\.([0-9]+).*/\n        ],\n        search: checkContains('opera')\n      },\n      {\n        name: 'Firefox',\n        versionRegexes: [/.*?firefox\\/\\ ?([0-9]+)\\.([0-9]+).*/],\n        search: checkContains('firefox')\n      },\n      {\n        name: 'Safari',\n        versionRegexes: [\n          normalVersionRegex,\n          /.*?cpu os ([0-9]+)_([0-9]+).*/\n        ],\n        search: function (uastring) {\n          return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit');\n        }\n      }\n    ];\n    var oses = [\n      {\n        name: 'Windows',\n        search: checkContains('win'),\n        versionRegexes: [/.*?windows\\ nt\\ ?([0-9]+)\\.([0-9]+).*/]\n      },\n      {\n        name: 'iOS',\n        search: function (uastring) {\n          return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad');\n        },\n        versionRegexes: [\n          /.*?version\\/\\ ?([0-9]+)\\.([0-9]+).*/,\n          /.*cpu os ([0-9]+)_([0-9]+).*/,\n          /.*cpu iphone os ([0-9]+)_([0-9]+).*/\n        ]\n      },\n      {\n        name: 'Android',\n        search: checkContains('android'),\n        versionRegexes: [/.*?android\\ ?([0-9]+)\\.([0-9]+).*/]\n      },\n      {\n        name: 'OSX',\n        search: checkContains('os x'),\n        versionRegexes: [/.*?os\\ x\\ ?([0-9]+)_([0-9]+).*/]\n      },\n      {\n        name: 'Linux',\n        search: checkContains('linux'),\n        versionRegexes: []\n      },\n      {\n        name: 'Solaris',\n        search: checkContains('sunos'),\n        versionRegexes: []\n      },\n      {\n        name: 'FreeBSD',\n        search: checkContains('freebsd'),\n        versionRegexes: []\n      }\n    ];\n    var PlatformInfo = {\n      browsers: constant(browsers),\n      oses: constant(oses)\n    };\n\n    var detect$2 = function (userAgent, mediaMatch) {\n      var browsers = PlatformInfo.browsers();\n      var oses = PlatformInfo.oses();\n      var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);\n      var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);\n      var deviceType = DeviceType(os, browser, userAgent, mediaMatch);\n      return {\n        browser: browser,\n        os: os,\n        deviceType: deviceType\n      };\n    };\n    var PlatformDetection = { detect: detect$2 };\n\n    var mediaMatch = function (query) {\n      return domGlobals.window.matchMedia(query).matches;\n    };\n    var platform = Cell(PlatformDetection.detect(domGlobals.navigator.userAgent, mediaMatch));\n    var detect$3 = function () {\n      return platform.get();\n    };\n\n    var fromHtml = function (html, scope) {\n      var doc = scope || domGlobals.document;\n      var div = doc.createElement('div');\n      div.innerHTML = html;\n      if (!div.hasChildNodes() || div.childNodes.length > 1) {\n        domGlobals.console.error('HTML does not have a single root node', html);\n        throw new Error('HTML must have a single root node');\n      }\n      return fromDom(div.childNodes[0]);\n    };\n    var fromTag = function (tag, scope) {\n      var doc = scope || domGlobals.document;\n      var node = doc.createElement(tag);\n      return fromDom(node);\n    };\n    var fromText = function (text, scope) {\n      var doc = scope || domGlobals.document;\n      var node = doc.createTextNode(text);\n      return fromDom(node);\n    };\n    var fromDom = function (node) {\n      if (node === null || node === undefined) {\n        throw new Error('Node cannot be null or undefined');\n      }\n      return { dom: constant(node) };\n    };\n    var fromPoint = function (docElm, x, y) {\n      var doc = docElm.dom();\n      return Option.from(doc.elementFromPoint(x, y)).map(fromDom);\n    };\n    var Element = {\n      fromHtml: fromHtml,\n      fromTag: fromTag,\n      fromText: fromText,\n      fromDom: fromDom,\n      fromPoint: fromPoint\n    };\n\n    var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;\n    var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;\n    var COMMENT = domGlobals.Node.COMMENT_NODE;\n    var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;\n    var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;\n    var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;\n    var ELEMENT = domGlobals.Node.ELEMENT_NODE;\n    var TEXT = domGlobals.Node.TEXT_NODE;\n    var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;\n    var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;\n    var ENTITY = domGlobals.Node.ENTITY_NODE;\n    var NOTATION = domGlobals.Node.NOTATION_NODE;\n\n    var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();\n\n    var name = function (element) {\n      var r = element.dom().nodeName;\n      return r.toLowerCase();\n    };\n    var type = function (element) {\n      return element.dom().nodeType;\n    };\n    var isType$1 = function (t) {\n      return function (element) {\n        return type(element) === t;\n      };\n    };\n    var isElement$1 = isType$1(ELEMENT);\n    var isText$1 = isType$1(TEXT);\n\n    var keys = Object.keys;\n    var hasOwnProperty = Object.hasOwnProperty;\n    var each$1 = function (obj, f) {\n      var props = keys(obj);\n      for (var k = 0, len = props.length; k < len; k++) {\n        var i = props[k];\n        var x = obj[i];\n        f(x, i);\n      }\n    };\n    var map$1 = function (obj, f) {\n      return tupleMap(obj, function (x, i) {\n        return {\n          k: i,\n          v: f(x, i)\n        };\n      });\n    };\n    var tupleMap = function (obj, f) {\n      var r = {};\n      each$1(obj, function (x, i) {\n        var tuple = f(x, i);\n        r[tuple.k] = tuple.v;\n      });\n      return r;\n    };\n    var bifilter = function (obj, pred) {\n      var t = {};\n      var f = {};\n      each$1(obj, function (x, i) {\n        var branch = pred(x, i) ? t : f;\n        branch[i] = x;\n      });\n      return {\n        t: t,\n        f: f\n      };\n    };\n    var get = function (obj, key) {\n      return has(obj, key) ? Option.from(obj[key]) : Option.none();\n    };\n    var has = function (obj, key) {\n      return hasOwnProperty.call(obj, key);\n    };\n\n    var isSupported = function (dom) {\n      return dom.style !== undefined && isFunction(dom.style.getPropertyValue);\n    };\n\n    var inBody = function (element) {\n      var dom = isText$1(element) ? element.dom().parentNode : element.dom();\n      return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom);\n    };\n\n    var rawSet = function (dom, key, value) {\n      if (isString(value) || isBoolean(value) || isNumber(value)) {\n        dom.setAttribute(key, value + '');\n      } else {\n        domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom);\n        throw new Error('Attribute value was not simple');\n      }\n    };\n    var set = function (element, key, value) {\n      rawSet(element.dom(), key, value);\n    };\n    var setAll = function (element, attrs) {\n      var dom = element.dom();\n      each$1(attrs, function (v, k) {\n        rawSet(dom, k, v);\n      });\n    };\n    var get$1 = function (element, key) {\n      var v = element.dom().getAttribute(key);\n      return v === null ? undefined : v;\n    };\n    var has$1 = function (element, key) {\n      var dom = element.dom();\n      return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;\n    };\n    var remove = function (element, key) {\n      element.dom().removeAttribute(key);\n    };\n\n    var get$2 = function (element, property) {\n      var dom = element.dom();\n      var styles = domGlobals.window.getComputedStyle(dom);\n      var r = styles.getPropertyValue(property);\n      var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;\n      return v === null ? undefined : v;\n    };\n    var getUnsafeProperty = function (dom, property) {\n      return isSupported(dom) ? dom.style.getPropertyValue(property) : '';\n    };\n    var getRaw = function (element, property) {\n      var dom = element.dom();\n      var raw = getUnsafeProperty(dom, property);\n      return Option.from(raw).filter(function (r) {\n        return r.length > 0;\n      });\n    };\n    var reflow = function (e) {\n      return e.dom().offsetWidth;\n    };\n\n    var Immutable = function () {\n      var fields = [];\n      for (var _i = 0; _i < arguments.length; _i++) {\n        fields[_i] = arguments[_i];\n      }\n      return function () {\n        var values = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          values[_i] = arguments[_i];\n        }\n        if (fields.length !== values.length) {\n          throw new Error('Wrong number of arguments to struct. Expected \"[' + fields.length + ']\", got ' + values.length + ' arguments');\n        }\n        var struct = {};\n        each(fields, function (name, i) {\n          struct[name] = constant(values[i]);\n        });\n        return struct;\n      };\n    };\n\n    var toArray = function (target, f) {\n      var r = [];\n      var recurse = function (e) {\n        r.push(e);\n        return f(e);\n      };\n      var cur = f(target);\n      do {\n        cur = cur.bind(recurse);\n      } while (cur.isSome());\n      return r;\n    };\n    var Recurse = { toArray: toArray };\n\n    var compareDocumentPosition = function (a, b, match) {\n      return (a.compareDocumentPosition(b) & match) !== 0;\n    };\n    var documentPositionPreceding = function (a, b) {\n      return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_PRECEDING);\n    };\n    var documentPositionContainedBy = function (a, b) {\n      return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_CONTAINED_BY);\n    };\n    var Node = {\n      documentPositionPreceding: documentPositionPreceding,\n      documentPositionContainedBy: documentPositionContainedBy\n    };\n\n    var ELEMENT$1 = ELEMENT;\n    var DOCUMENT$1 = DOCUMENT;\n    var is = function (element, selector) {\n      var dom = element.dom();\n      if (dom.nodeType !== ELEMENT$1) {\n        return false;\n      } else {\n        var elem = dom;\n        if (elem.matches !== undefined) {\n          return elem.matches(selector);\n        } else if (elem.msMatchesSelector !== undefined) {\n          return elem.msMatchesSelector(selector);\n        } else if (elem.webkitMatchesSelector !== undefined) {\n          return elem.webkitMatchesSelector(selector);\n        } else if (elem.mozMatchesSelector !== undefined) {\n          return elem.mozMatchesSelector(selector);\n        } else {\n          throw new Error('Browser lacks native selectors');\n        }\n      }\n    };\n    var bypassSelector = function (dom) {\n      return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0;\n    };\n    var all = function (selector, scope) {\n      var base = scope === undefined ? domGlobals.document : scope.dom();\n      return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom);\n    };\n    var one = function (selector, scope) {\n      var base = scope === undefined ? domGlobals.document : scope.dom();\n      return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom);\n    };\n\n    var eq = function (e1, e2) {\n      return e1.dom() === e2.dom();\n    };\n    var regularContains = function (e1, e2) {\n      var d1 = e1.dom();\n      var d2 = e2.dom();\n      return d1 === d2 ? false : d1.contains(d2);\n    };\n    var ieContains = function (e1, e2) {\n      return Node.documentPositionContainedBy(e1.dom(), e2.dom());\n    };\n    var browser = detect$3().browser;\n    var contains$2 = browser.isIE() ? ieContains : regularContains;\n\n    var owner = function (element) {\n      return Element.fromDom(element.dom().ownerDocument);\n    };\n    var documentElement = function (element) {\n      return Element.fromDom(element.dom().ownerDocument.documentElement);\n    };\n    var defaultView = function (element) {\n      return Element.fromDom(element.dom().ownerDocument.defaultView);\n    };\n    var parent = function (element) {\n      return Option.from(element.dom().parentNode).map(Element.fromDom);\n    };\n    var parents = function (element, isRoot) {\n      var stop = isFunction(isRoot) ? isRoot : never;\n      var dom = element.dom();\n      var ret = [];\n      while (dom.parentNode !== null && dom.parentNode !== undefined) {\n        var rawParent = dom.parentNode;\n        var p = Element.fromDom(rawParent);\n        ret.push(p);\n        if (stop(p) === true) {\n          break;\n        } else {\n          dom = rawParent;\n        }\n      }\n      return ret;\n    };\n    var prevSibling = function (element) {\n      return Option.from(element.dom().previousSibling).map(Element.fromDom);\n    };\n    var nextSibling = function (element) {\n      return Option.from(element.dom().nextSibling).map(Element.fromDom);\n    };\n    var prevSiblings = function (element) {\n      return reverse(Recurse.toArray(element, prevSibling));\n    };\n    var nextSiblings = function (element) {\n      return Recurse.toArray(element, nextSibling);\n    };\n    var children = function (element) {\n      return map(element.dom().childNodes, Element.fromDom);\n    };\n    var child = function (element, index) {\n      var cs = element.dom().childNodes;\n      return Option.from(cs[index]).map(Element.fromDom);\n    };\n    var firstChild = function (element) {\n      return child(element, 0);\n    };\n    var lastChild = function (element) {\n      return child(element, element.dom().childNodes.length - 1);\n    };\n    var childNodesCount = function (element) {\n      return element.dom().childNodes.length;\n    };\n    var spot = Immutable('element', 'offset');\n\n    var browser$1 = detect$3().browser;\n    var firstElement = function (nodes) {\n      return find(nodes, isElement$1);\n    };\n    var getTableCaptionDeltaY = function (elm) {\n      if (browser$1.isFirefox() && name(elm) === 'table') {\n        return firstElement(children(elm)).filter(function (elm) {\n          return name(elm) === 'caption';\n        }).bind(function (caption) {\n          return firstElement(nextSiblings(caption)).map(function (body) {\n            var bodyTop = body.dom().offsetTop;\n            var captionTop = caption.dom().offsetTop;\n            var captionHeight = caption.dom().offsetHeight;\n            return bodyTop <= captionTop ? -captionHeight : 0;\n          });\n        }).getOr(0);\n      } else {\n        return 0;\n      }\n    };\n    var hasChild = function (elm, child) {\n      return elm.children && contains(elm.children, child);\n    };\n    var getPos = function (body, elm, rootElm) {\n      var x = 0, y = 0, offsetParent;\n      var doc = body.ownerDocument;\n      var pos;\n      rootElm = rootElm ? rootElm : body;\n      if (elm) {\n        if (rootElm === body && elm.getBoundingClientRect && get$2(Element.fromDom(body), 'position') === 'static') {\n          pos = elm.getBoundingClientRect();\n          x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - doc.documentElement.clientLeft;\n          y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - doc.documentElement.clientTop;\n          return {\n            x: x,\n            y: y\n          };\n        }\n        offsetParent = elm;\n        while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {\n          x += offsetParent.offsetLeft || 0;\n          y += offsetParent.offsetTop || 0;\n          offsetParent = offsetParent.offsetParent;\n        }\n        offsetParent = elm.parentNode;\n        while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {\n          x -= offsetParent.scrollLeft || 0;\n          y -= offsetParent.scrollTop || 0;\n          offsetParent = offsetParent.parentNode;\n        }\n        y += getTableCaptionDeltaY(Element.fromDom(elm));\n      }\n      return {\n        x: x,\n        y: y\n      };\n    };\n    var Position = { getPos: getPos };\n\n    var exports$1 = {}, module$1 = { exports: exports$1 };\n    (function (define, exports, module, require) {\n      (function (f) {\n        if (typeof exports === 'object' && typeof module !== 'undefined') {\n          module.exports = f();\n        } else if (typeof define === 'function' && define.amd) {\n          define([], f);\n        } else {\n          var g;\n          if (typeof window !== 'undefined') {\n            g = window;\n          } else if (typeof global !== 'undefined') {\n            g = global;\n          } else if (typeof self !== 'undefined') {\n            g = self;\n          } else {\n            g = this;\n          }\n          g.EphoxContactWrapper = f();\n        }\n      }(function () {\n        return function () {\n          function r(e, n, t) {\n            function o(i, f) {\n              if (!n[i]) {\n                if (!e[i]) {\n                  var c = 'function' == typeof require && require;\n                  if (!f && c)\n                    return c(i, !0);\n                  if (u)\n                    return u(i, !0);\n                  var a = new Error('Cannot find module \\'' + i + '\\'');\n                  throw a.code = 'MODULE_NOT_FOUND', a;\n                }\n                var p = n[i] = { exports: {} };\n                e[i][0].call(p.exports, function (r) {\n                  var n = e[i][1][r];\n                  return o(n || r);\n                }, p, p.exports, r, e, n, t);\n              }\n              return n[i].exports;\n            }\n            for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++)\n              o(t[i]);\n            return o;\n          }\n          return r;\n        }()({\n          1: [\n            function (require, module, exports) {\n              var process = module.exports = {};\n              var cachedSetTimeout;\n              var cachedClearTimeout;\n              function defaultSetTimout() {\n                throw new Error('setTimeout has not been defined');\n              }\n              function defaultClearTimeout() {\n                throw new Error('clearTimeout has not been defined');\n              }\n              (function () {\n                try {\n                  if (typeof setTimeout === 'function') {\n                    cachedSetTimeout = setTimeout;\n                  } else {\n                    cachedSetTimeout = defaultSetTimout;\n                  }\n                } catch (e) {\n                  cachedSetTimeout = defaultSetTimout;\n                }\n                try {\n                  if (typeof clearTimeout === 'function') {\n                    cachedClearTimeout = clearTimeout;\n                  } else {\n                    cachedClearTimeout = defaultClearTimeout;\n                  }\n                } catch (e) {\n                  cachedClearTimeout = defaultClearTimeout;\n                }\n              }());\n              function runTimeout(fun) {\n                if (cachedSetTimeout === setTimeout) {\n                  return setTimeout(fun, 0);\n                }\n                if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n                  cachedSetTimeout = setTimeout;\n                  return setTimeout(fun, 0);\n                }\n                try {\n                  return cachedSetTimeout(fun, 0);\n                } catch (e) {\n                  try {\n                    return cachedSetTimeout.call(null, fun, 0);\n                  } catch (e) {\n                    return cachedSetTimeout.call(this, fun, 0);\n                  }\n                }\n              }\n              function runClearTimeout(marker) {\n                if (cachedClearTimeout === clearTimeout) {\n                  return clearTimeout(marker);\n                }\n                if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n                  cachedClearTimeout = clearTimeout;\n                  return clearTimeout(marker);\n                }\n                try {\n                  return cachedClearTimeout(marker);\n                } catch (e) {\n                  try {\n                    return cachedClearTimeout.call(null, marker);\n                  } catch (e) {\n                    return cachedClearTimeout.call(this, marker);\n                  }\n                }\n              }\n              var queue = [];\n              var draining = false;\n              var currentQueue;\n              var queueIndex = -1;\n              function cleanUpNextTick() {\n                if (!draining || !currentQueue) {\n                  return;\n                }\n                draining = false;\n                if (currentQueue.length) {\n                  queue = currentQueue.concat(queue);\n                } else {\n                  queueIndex = -1;\n                }\n                if (queue.length) {\n                  drainQueue();\n                }\n              }\n              function drainQueue() {\n                if (draining) {\n                  return;\n                }\n                var timeout = runTimeout(cleanUpNextTick);\n                draining = true;\n                var len = queue.length;\n                while (len) {\n                  currentQueue = queue;\n                  queue = [];\n                  while (++queueIndex < len) {\n                    if (currentQueue) {\n                      currentQueue[queueIndex].run();\n                    }\n                  }\n                  queueIndex = -1;\n                  len = queue.length;\n                }\n                currentQueue = null;\n                draining = false;\n                runClearTimeout(timeout);\n              }\n              process.nextTick = function (fun) {\n                var args = new Array(arguments.length - 1);\n                if (arguments.length > 1) {\n                  for (var i = 1; i < arguments.length; i++) {\n                    args[i - 1] = arguments[i];\n                  }\n                }\n                queue.push(new Item(fun, args));\n                if (queue.length === 1 && !draining) {\n                  runTimeout(drainQueue);\n                }\n              };\n              function Item(fun, array) {\n                this.fun = fun;\n                this.array = array;\n              }\n              Item.prototype.run = function () {\n                this.fun.apply(null, this.array);\n              };\n              process.title = 'browser';\n              process.browser = true;\n              process.env = {};\n              process.argv = [];\n              process.version = '';\n              process.versions = {};\n              function noop() {\n              }\n              process.on = noop;\n              process.addListener = noop;\n              process.once = noop;\n              process.off = noop;\n              process.removeListener = noop;\n              process.removeAllListeners = noop;\n              process.emit = noop;\n              process.prependListener = noop;\n              process.prependOnceListener = noop;\n              process.listeners = function (name) {\n                return [];\n              };\n              process.binding = function (name) {\n                throw new Error('process.binding is not supported');\n              };\n              process.cwd = function () {\n                return '/';\n              };\n              process.chdir = function (dir) {\n                throw new Error('process.chdir is not supported');\n              };\n              process.umask = function () {\n                return 0;\n              };\n            },\n            {}\n          ],\n          2: [\n            function (require, module, exports) {\n              (function (setImmediate) {\n                (function (root) {\n                  var setTimeoutFunc = setTimeout;\n                  function noop() {\n                  }\n                  function bind(fn, thisArg) {\n                    return function () {\n                      fn.apply(thisArg, arguments);\n                    };\n                  }\n                  function Promise(fn) {\n                    if (typeof this !== 'object')\n                      throw new TypeError('Promises must be constructed via new');\n                    if (typeof fn !== 'function')\n                      throw new TypeError('not a function');\n                    this._state = 0;\n                    this._handled = false;\n                    this._value = undefined;\n                    this._deferreds = [];\n                    doResolve(fn, this);\n                  }\n                  function handle(self, deferred) {\n                    while (self._state === 3) {\n                      self = self._value;\n                    }\n                    if (self._state === 0) {\n                      self._deferreds.push(deferred);\n                      return;\n                    }\n                    self._handled = true;\n                    Promise._immediateFn(function () {\n                      var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;\n                      if (cb === null) {\n                        (self._state === 1 ? resolve : reject)(deferred.promise, self._value);\n                        return;\n                      }\n                      var ret;\n                      try {\n                        ret = cb(self._value);\n                      } catch (e) {\n                        reject(deferred.promise, e);\n                        return;\n                      }\n                      resolve(deferred.promise, ret);\n                    });\n                  }\n                  function resolve(self, newValue) {\n                    try {\n                      if (newValue === self)\n                        throw new TypeError('A promise cannot be resolved with itself.');\n                      if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {\n                        var then = newValue.then;\n                        if (newValue instanceof Promise) {\n                          self._state = 3;\n                          self._value = newValue;\n                          finale(self);\n                          return;\n                        } else if (typeof then === 'function') {\n                          doResolve(bind(then, newValue), self);\n                          return;\n                        }\n                      }\n                      self._state = 1;\n                      self._value = newValue;\n                      finale(self);\n                    } catch (e) {\n                      reject(self, e);\n                    }\n                  }\n                  function reject(self, newValue) {\n                    self._state = 2;\n                    self._value = newValue;\n                    finale(self);\n                  }\n                  function finale(self) {\n                    if (self._state === 2 && self._deferreds.length === 0) {\n                      Promise._immediateFn(function () {\n                        if (!self._handled) {\n                          Promise._unhandledRejectionFn(self._value);\n                        }\n                      });\n                    }\n                    for (var i = 0, len = self._deferreds.length; i < len; i++) {\n                      handle(self, self._deferreds[i]);\n                    }\n                    self._deferreds = null;\n                  }\n                  function Handler(onFulfilled, onRejected, promise) {\n                    this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n                    this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n                    this.promise = promise;\n                  }\n                  function doResolve(fn, self) {\n                    var done = false;\n                    try {\n                      fn(function (value) {\n                        if (done)\n                          return;\n                        done = true;\n                        resolve(self, value);\n                      }, function (reason) {\n                        if (done)\n                          return;\n                        done = true;\n                        reject(self, reason);\n                      });\n                    } catch (ex) {\n                      if (done)\n                        return;\n                      done = true;\n                      reject(self, ex);\n                    }\n                  }\n                  Promise.prototype['catch'] = function (onRejected) {\n                    return this.then(null, onRejected);\n                  };\n                  Promise.prototype.then = function (onFulfilled, onRejected) {\n                    var prom = new this.constructor(noop);\n                    handle(this, new Handler(onFulfilled, onRejected, prom));\n                    return prom;\n                  };\n                  Promise.all = function (arr) {\n                    var args = Array.prototype.slice.call(arr);\n                    return new Promise(function (resolve, reject) {\n                      if (args.length === 0)\n                        return resolve([]);\n                      var remaining = args.length;\n                      function res(i, val) {\n                        try {\n                          if (val && (typeof val === 'object' || typeof val === 'function')) {\n                            var then = val.then;\n                            if (typeof then === 'function') {\n                              then.call(val, function (val) {\n                                res(i, val);\n                              }, reject);\n                              return;\n                            }\n                          }\n                          args[i] = val;\n                          if (--remaining === 0) {\n                            resolve(args);\n                          }\n                        } catch (ex) {\n                          reject(ex);\n                        }\n                      }\n                      for (var i = 0; i < args.length; i++) {\n                        res(i, args[i]);\n                      }\n                    });\n                  };\n                  Promise.resolve = function (value) {\n                    if (value && typeof value === 'object' && value.constructor === Promise) {\n                      return value;\n                    }\n                    return new Promise(function (resolve) {\n                      resolve(value);\n                    });\n                  };\n                  Promise.reject = function (value) {\n                    return new Promise(function (resolve, reject) {\n                      reject(value);\n                    });\n                  };\n                  Promise.race = function (values) {\n                    return new Promise(function (resolve, reject) {\n                      for (var i = 0, len = values.length; i < len; i++) {\n                        values[i].then(resolve, reject);\n                      }\n                    });\n                  };\n                  Promise._immediateFn = typeof setImmediate === 'function' ? function (fn) {\n                    setImmediate(fn);\n                  } : function (fn) {\n                    setTimeoutFunc(fn, 0);\n                  };\n                  Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {\n                    if (typeof console !== 'undefined' && console) {\n                      console.warn('Possible Unhandled Promise Rejection:', err);\n                    }\n                  };\n                  Promise._setImmediateFn = function _setImmediateFn(fn) {\n                    Promise._immediateFn = fn;\n                  };\n                  Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {\n                    Promise._unhandledRejectionFn = fn;\n                  };\n                  if (typeof module !== 'undefined' && module.exports) {\n                    module.exports = Promise;\n                  } else if (!root.Promise) {\n                    root.Promise = Promise;\n                  }\n                }(this));\n              }.call(this, require('timers').setImmediate));\n            },\n            { 'timers': 3 }\n          ],\n          3: [\n            function (require, module, exports) {\n              (function (setImmediate, clearImmediate) {\n                var nextTick = require('process/browser.js').nextTick;\n                var apply = Function.prototype.apply;\n                var slice = Array.prototype.slice;\n                var immediateIds = {};\n                var nextImmediateId = 0;\n                exports.setTimeout = function () {\n                  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n                };\n                exports.setInterval = function () {\n                  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n                };\n                exports.clearTimeout = exports.clearInterval = function (timeout) {\n                  timeout.close();\n                };\n                function Timeout(id, clearFn) {\n                  this._id = id;\n                  this._clearFn = clearFn;\n                }\n                Timeout.prototype.unref = Timeout.prototype.ref = function () {\n                };\n                Timeout.prototype.close = function () {\n                  this._clearFn.call(window, this._id);\n                };\n                exports.enroll = function (item, msecs) {\n                  clearTimeout(item._idleTimeoutId);\n                  item._idleTimeout = msecs;\n                };\n                exports.unenroll = function (item) {\n                  clearTimeout(item._idleTimeoutId);\n                  item._idleTimeout = -1;\n                };\n                exports._unrefActive = exports.active = function (item) {\n                  clearTimeout(item._idleTimeoutId);\n                  var msecs = item._idleTimeout;\n                  if (msecs >= 0) {\n                    item._idleTimeoutId = setTimeout(function onTimeout() {\n                      if (item._onTimeout)\n                        item._onTimeout();\n                    }, msecs);\n                  }\n                };\n                exports.setImmediate = typeof setImmediate === 'function' ? setImmediate : function (fn) {\n                  var id = nextImmediateId++;\n                  var args = arguments.length < 2 ? false : slice.call(arguments, 1);\n                  immediateIds[id] = true;\n                  nextTick(function onNextTick() {\n                    if (immediateIds[id]) {\n                      if (args) {\n                        fn.apply(null, args);\n                      } else {\n                        fn.call(null);\n                      }\n                      exports.clearImmediate(id);\n                    }\n                  });\n                  return id;\n                };\n                exports.clearImmediate = typeof clearImmediate === 'function' ? clearImmediate : function (id) {\n                  delete immediateIds[id];\n                };\n              }.call(this, require('timers').setImmediate, require('timers').clearImmediate));\n            },\n            {\n              'process/browser.js': 1,\n              'timers': 3\n            }\n          ],\n          4: [\n            function (require, module, exports) {\n              var promisePolyfill = require('promise-polyfill');\n              var Global = function () {\n                if (typeof window !== 'undefined') {\n                  return window;\n                } else {\n                  return Function('return this;')();\n                }\n              }();\n              module.exports = { boltExport: Global.Promise || promisePolyfill };\n            },\n            { 'promise-polyfill': 2 }\n          ]\n        }, {}, [4])(4);\n      }));\n    }(undefined, exports$1, module$1, undefined));\n    var Promise = module$1.exports.boltExport;\n\n    var nu$3 = function (baseFn) {\n      var data = Option.none();\n      var callbacks = [];\n      var map = function (f) {\n        return nu$3(function (nCallback) {\n          get(function (data) {\n            nCallback(f(data));\n          });\n        });\n      };\n      var get = function (nCallback) {\n        if (isReady()) {\n          call(nCallback);\n        } else {\n          callbacks.push(nCallback);\n        }\n      };\n      var set = function (x) {\n        data = Option.some(x);\n        run(callbacks);\n        callbacks = [];\n      };\n      var isReady = function () {\n        return data.isSome();\n      };\n      var run = function (cbs) {\n        each(cbs, call);\n      };\n      var call = function (cb) {\n        data.each(function (x) {\n          domGlobals.setTimeout(function () {\n            cb(x);\n          }, 0);\n        });\n      };\n      baseFn(set);\n      return {\n        get: get,\n        map: map,\n        isReady: isReady\n      };\n    };\n    var pure = function (a) {\n      return nu$3(function (callback) {\n        callback(a);\n      });\n    };\n    var LazyValue = {\n      nu: nu$3,\n      pure: pure\n    };\n\n    var errorReporter = function (err) {\n      domGlobals.setTimeout(function () {\n        throw err;\n      }, 0);\n    };\n    var make = function (run) {\n      var get = function (callback) {\n        run().then(callback, errorReporter);\n      };\n      var map = function (fab) {\n        return make(function () {\n          return run().then(fab);\n        });\n      };\n      var bind = function (aFutureB) {\n        return make(function () {\n          return run().then(function (v) {\n            return aFutureB(v).toPromise();\n          });\n        });\n      };\n      var anonBind = function (futureB) {\n        return make(function () {\n          return run().then(function () {\n            return futureB.toPromise();\n          });\n        });\n      };\n      var toLazy = function () {\n        return LazyValue.nu(get);\n      };\n      var toCached = function () {\n        var cache = null;\n        return make(function () {\n          if (cache === null) {\n            cache = run();\n          }\n          return cache;\n        });\n      };\n      var toPromise = run;\n      return {\n        map: map,\n        bind: bind,\n        anonBind: anonBind,\n        toLazy: toLazy,\n        toCached: toCached,\n        toPromise: toPromise,\n        get: get\n      };\n    };\n    var nu$4 = function (baseFn) {\n      return make(function () {\n        return new Promise(baseFn);\n      });\n    };\n    var pure$1 = function (a) {\n      return make(function () {\n        return Promise.resolve(a);\n      });\n    };\n    var Future = {\n      nu: nu$4,\n      pure: pure$1\n    };\n\n    var par = function (asyncValues, nu) {\n      return nu(function (callback) {\n        var r = [];\n        var count = 0;\n        var cb = function (i) {\n          return function (value) {\n            r[i] = value;\n            count++;\n            if (count >= asyncValues.length) {\n              callback(r);\n            }\n          };\n        };\n        if (asyncValues.length === 0) {\n          callback([]);\n        } else {\n          each(asyncValues, function (asyncValue, i) {\n            asyncValue.get(cb(i));\n          });\n        }\n      });\n    };\n\n    var par$1 = function (futures) {\n      return par(futures, Future.nu);\n    };\n\n    var value = function (o) {\n      var is = function (v) {\n        return o === v;\n      };\n      var or = function (opt) {\n        return value(o);\n      };\n      var orThunk = function (f) {\n        return value(o);\n      };\n      var map = function (f) {\n        return value(f(o));\n      };\n      var mapError = function (f) {\n        return value(o);\n      };\n      var each = function (f) {\n        f(o);\n      };\n      var bind = function (f) {\n        return f(o);\n      };\n      var fold = function (_, onValue) {\n        return onValue(o);\n      };\n      var exists = function (f) {\n        return f(o);\n      };\n      var forall = function (f) {\n        return f(o);\n      };\n      var toOption = function () {\n        return Option.some(o);\n      };\n      return {\n        is: is,\n        isValue: always,\n        isError: never,\n        getOr: constant(o),\n        getOrThunk: constant(o),\n        getOrDie: constant(o),\n        or: or,\n        orThunk: orThunk,\n        fold: fold,\n        map: map,\n        mapError: mapError,\n        each: each,\n        bind: bind,\n        exists: exists,\n        forall: forall,\n        toOption: toOption\n      };\n    };\n    var error = function (message) {\n      var getOrThunk = function (f) {\n        return f();\n      };\n      var getOrDie = function () {\n        return die(String(message))();\n      };\n      var or = function (opt) {\n        return opt;\n      };\n      var orThunk = function (f) {\n        return f();\n      };\n      var map = function (f) {\n        return error(message);\n      };\n      var mapError = function (f) {\n        return error(f(message));\n      };\n      var bind = function (f) {\n        return error(message);\n      };\n      var fold = function (onError, _) {\n        return onError(message);\n      };\n      return {\n        is: never,\n        isValue: never,\n        isError: always,\n        getOr: identity,\n        getOrThunk: getOrThunk,\n        getOrDie: getOrDie,\n        or: or,\n        orThunk: orThunk,\n        fold: fold,\n        map: map,\n        mapError: mapError,\n        each: noop,\n        bind: bind,\n        exists: never,\n        forall: always,\n        toOption: Option.none\n      };\n    };\n    var fromOption = function (opt, err) {\n      return opt.fold(function () {\n        return error(err);\n      }, value);\n    };\n    var Result = {\n      value: value,\n      error: error,\n      fromOption: fromOption\n    };\n\n    var promise = function () {\n      function bind(fn, thisArg) {\n        return function () {\n          fn.apply(thisArg, arguments);\n        };\n      }\n      var isArray = Array.isArray || function (value) {\n        return Object.prototype.toString.call(value) === '[object Array]';\n      };\n      var Promise = function (fn) {\n        if (typeof this !== 'object') {\n          throw new TypeError('Promises must be constructed via new');\n        }\n        if (typeof fn !== 'function') {\n          throw new TypeError('not a function');\n        }\n        this._state = null;\n        this._value = null;\n        this._deferreds = [];\n        doResolve(fn, bind(resolve, this), bind(reject, this));\n      };\n      var asap = Promise.immediateFn || typeof domGlobals.setImmediate === 'function' && domGlobals.setImmediate || function (fn) {\n        domGlobals.setTimeout(fn, 1);\n      };\n      function handle(deferred) {\n        var me = this;\n        if (this._state === null) {\n          this._deferreds.push(deferred);\n          return;\n        }\n        asap(function () {\n          var cb = me._state ? deferred.onFulfilled : deferred.onRejected;\n          if (cb === null) {\n            (me._state ? deferred.resolve : deferred.reject)(me._value);\n            return;\n          }\n          var ret;\n          try {\n            ret = cb(me._value);\n          } catch (e) {\n            deferred.reject(e);\n            return;\n          }\n          deferred.resolve(ret);\n        });\n      }\n      function resolve(newValue) {\n        try {\n          if (newValue === this) {\n            throw new TypeError('A promise cannot be resolved with itself.');\n          }\n          if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {\n            var then = newValue.then;\n            if (typeof then === 'function') {\n              doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this));\n              return;\n            }\n          }\n          this._state = true;\n          this._value = newValue;\n          finale.call(this);\n        } catch (e) {\n          reject.call(this, e);\n        }\n      }\n      function reject(newValue) {\n        this._state = false;\n        this._value = newValue;\n        finale.call(this);\n      }\n      function finale() {\n        for (var i = 0, len = this._deferreds.length; i < len; i++) {\n          handle.call(this, this._deferreds[i]);\n        }\n        this._deferreds = null;\n      }\n      function Handler(onFulfilled, onRejected, resolve, reject) {\n        this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n        this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n        this.resolve = resolve;\n        this.reject = reject;\n      }\n      function doResolve(fn, onFulfilled, onRejected) {\n        var done = false;\n        try {\n          fn(function (value) {\n            if (done) {\n              return;\n            }\n            done = true;\n            onFulfilled(value);\n          }, function (reason) {\n            if (done) {\n              return;\n            }\n            done = true;\n            onRejected(reason);\n          });\n        } catch (ex) {\n          if (done) {\n            return;\n          }\n          done = true;\n          onRejected(ex);\n        }\n      }\n      Promise.prototype.catch = function (onRejected) {\n        return this.then(null, onRejected);\n      };\n      Promise.prototype.then = function (onFulfilled, onRejected) {\n        var me = this;\n        return new Promise(function (resolve, reject) {\n          handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject));\n        });\n      };\n      Promise.all = function () {\n        var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments);\n        return new Promise(function (resolve, reject) {\n          if (args.length === 0) {\n            return resolve([]);\n          }\n          var remaining = args.length;\n          function res(i, val) {\n            try {\n              if (val && (typeof val === 'object' || typeof val === 'function')) {\n                var then = val.then;\n                if (typeof then === 'function') {\n                  then.call(val, function (val) {\n                    res(i, val);\n                  }, reject);\n                  return;\n                }\n              }\n              args[i] = val;\n              if (--remaining === 0) {\n                resolve(args);\n              }\n            } catch (ex) {\n              reject(ex);\n            }\n          }\n          for (var i = 0; i < args.length; i++) {\n            res(i, args[i]);\n          }\n        });\n      };\n      Promise.resolve = function (value) {\n        if (value && typeof value === 'object' && value.constructor === Promise) {\n          return value;\n        }\n        return new Promise(function (resolve) {\n          resolve(value);\n        });\n      };\n      Promise.reject = function (value) {\n        return new Promise(function (resolve, reject) {\n          reject(value);\n        });\n      };\n      Promise.race = function (values) {\n        return new Promise(function (resolve, reject) {\n          for (var i = 0, len = values.length; i < len; i++) {\n            values[i].then(resolve, reject);\n          }\n        });\n      };\n      return Promise;\n    };\n    var promiseObj = window.Promise ? window.Promise : promise();\n\n    var requestAnimationFramePromise;\n    var requestAnimationFrame = function (callback, element) {\n      var i, requestAnimationFrameFunc = domGlobals.window.requestAnimationFrame;\n      var vendors = [\n        'ms',\n        'moz',\n        'webkit'\n      ];\n      var featurefill = function (callback) {\n        domGlobals.window.setTimeout(callback, 0);\n      };\n      for (i = 0; i < vendors.length && !requestAnimationFrameFunc; i++) {\n        requestAnimationFrameFunc = domGlobals.window[vendors[i] + 'RequestAnimationFrame'];\n      }\n      if (!requestAnimationFrameFunc) {\n        requestAnimationFrameFunc = featurefill;\n      }\n      requestAnimationFrameFunc(callback, element);\n    };\n    var wrappedSetTimeout = function (callback, time) {\n      if (typeof time !== 'number') {\n        time = 0;\n      }\n      return domGlobals.setTimeout(callback, time);\n    };\n    var wrappedSetInterval = function (callback, time) {\n      if (typeof time !== 'number') {\n        time = 1;\n      }\n      return domGlobals.setInterval(callback, time);\n    };\n    var wrappedClearTimeout = function (id) {\n      return domGlobals.clearTimeout(id);\n    };\n    var wrappedClearInterval = function (id) {\n      return domGlobals.clearInterval(id);\n    };\n    var debounce = function (callback, time) {\n      var timer, func;\n      func = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        domGlobals.clearTimeout(timer);\n        timer = wrappedSetTimeout(function () {\n          callback.apply(this, args);\n        }, time);\n      };\n      func.stop = function () {\n        domGlobals.clearTimeout(timer);\n      };\n      return func;\n    };\n    var Delay = {\n      requestAnimationFrame: function (callback, element) {\n        if (requestAnimationFramePromise) {\n          requestAnimationFramePromise.then(callback);\n          return;\n        }\n        requestAnimationFramePromise = new promiseObj(function (resolve) {\n          if (!element) {\n            element = domGlobals.document.body;\n          }\n          requestAnimationFrame(resolve, element);\n        }).then(callback);\n      },\n      setTimeout: wrappedSetTimeout,\n      setInterval: wrappedSetInterval,\n      setEditorTimeout: function (editor, callback, time) {\n        return wrappedSetTimeout(function () {\n          if (!editor.removed) {\n            callback();\n          }\n        }, time);\n      },\n      setEditorInterval: function (editor, callback, time) {\n        var timer;\n        timer = wrappedSetInterval(function () {\n          if (!editor.removed) {\n            callback();\n          } else {\n            domGlobals.clearInterval(timer);\n          }\n        }, time);\n        return timer;\n      },\n      debounce: debounce,\n      throttle: debounce,\n      clearInterval: wrappedClearInterval,\n      clearTimeout: wrappedClearTimeout\n    };\n\n    var userAgent = domGlobals.navigator.userAgent;\n    var platform$1 = detect$3();\n    var browser$2 = platform$1.browser;\n    var os = platform$1.os;\n    var deviceType = platform$1.deviceType;\n    var webkit = /WebKit/.test(userAgent) && !browser$2.isEdge();\n    var fileApi = 'FormData' in domGlobals.window && 'FileReader' in domGlobals.window && 'URL' in domGlobals.window && !!domGlobals.URL.createObjectURL;\n    var windowsPhone = userAgent.indexOf('Windows Phone') !== -1;\n    var Env = {\n      opera: browser$2.isOpera(),\n      webkit: webkit,\n      ie: browser$2.isIE() || browser$2.isEdge() ? browser$2.version.major : false,\n      gecko: browser$2.isFirefox(),\n      mac: os.isOSX() || os.isiOS(),\n      iOS: deviceType.isiPad() || deviceType.isiPhone(),\n      android: os.isAndroid(),\n      contentEditable: true,\n      transparentSrc: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',\n      caretAfter: true,\n      range: domGlobals.window.getSelection && 'Range' in domGlobals.window,\n      documentMode: browser$2.isIE() ? domGlobals.document.documentMode || 7 : 10,\n      fileApi: fileApi,\n      ceFalse: true,\n      cacheSuffix: null,\n      container: null,\n      experimentalShadowDom: false,\n      canHaveCSP: !browser$2.isIE(),\n      desktop: deviceType.isDesktop(),\n      windowsPhone: windowsPhone,\n      browser: {\n        current: browser$2.current,\n        version: browser$2.version,\n        isChrome: browser$2.isChrome,\n        isEdge: browser$2.isEdge,\n        isFirefox: browser$2.isFirefox,\n        isIE: browser$2.isIE,\n        isOpera: browser$2.isOpera,\n        isSafari: browser$2.isSafari\n      },\n      os: {\n        current: os.current,\n        version: os.version,\n        isAndroid: os.isAndroid,\n        isFreeBSD: os.isFreeBSD,\n        isiOS: os.isiOS,\n        isLinux: os.isLinux,\n        isOSX: os.isOSX,\n        isSolaris: os.isSolaris,\n        isWindows: os.isWindows\n      },\n      deviceType: {\n        isDesktop: deviceType.isDesktop,\n        isiPad: deviceType.isiPad,\n        isiPhone: deviceType.isiPhone,\n        isPhone: deviceType.isPhone,\n        isTablet: deviceType.isTablet,\n        isTouch: deviceType.isTouch,\n        isWebView: deviceType.isWebView\n      }\n    };\n\n    var isArray$1 = Array.isArray;\n    var toArray$1 = function (obj) {\n      var array = obj, i, l;\n      if (!isArray$1(obj)) {\n        array = [];\n        for (i = 0, l = obj.length; i < l; i++) {\n          array[i] = obj[i];\n        }\n      }\n      return array;\n    };\n    var each$2 = function (o, cb, s) {\n      var n, l;\n      if (!o) {\n        return 0;\n      }\n      s = s || o;\n      if (o.length !== undefined) {\n        for (n = 0, l = o.length; n < l; n++) {\n          if (cb.call(s, o[n], n, o) === false) {\n            return 0;\n          }\n        }\n      } else {\n        for (n in o) {\n          if (o.hasOwnProperty(n)) {\n            if (cb.call(s, o[n], n, o) === false) {\n              return 0;\n            }\n          }\n        }\n      }\n      return 1;\n    };\n    var map$2 = function (array, callback) {\n      var out = [];\n      each$2(array, function (item, index) {\n        out.push(callback(item, index, array));\n      });\n      return out;\n    };\n    var filter$1 = function (a, f) {\n      var o = [];\n      each$2(a, function (v, index) {\n        if (!f || f(v, index, a)) {\n          o.push(v);\n        }\n      });\n      return o;\n    };\n    var indexOf$1 = function (a, v) {\n      var i, l;\n      if (a) {\n        for (i = 0, l = a.length; i < l; i++) {\n          if (a[i] === v) {\n            return i;\n          }\n        }\n      }\n      return -1;\n    };\n    var reduce = function (collection, iteratee, accumulator, thisArg) {\n      var i = 0;\n      if (arguments.length < 3) {\n        accumulator = collection[0];\n      }\n      for (; i < collection.length; i++) {\n        accumulator = iteratee.call(thisArg, accumulator, collection[i], i);\n      }\n      return accumulator;\n    };\n    var findIndex$1 = function (array, predicate, thisArg) {\n      var i, l;\n      for (i = 0, l = array.length; i < l; i++) {\n        if (predicate.call(thisArg, array[i], i, array)) {\n          return i;\n        }\n      }\n      return -1;\n    };\n    var find$2 = function (array, predicate, thisArg) {\n      var idx = findIndex$1(array, predicate, thisArg);\n      if (idx !== -1) {\n        return array[idx];\n      }\n      return undefined;\n    };\n    var last$1 = function (collection) {\n      return collection[collection.length - 1];\n    };\n    var ArrUtils = {\n      isArray: isArray$1,\n      toArray: toArray$1,\n      each: each$2,\n      map: map$2,\n      filter: filter$1,\n      indexOf: indexOf$1,\n      reduce: reduce,\n      findIndex: findIndex$1,\n      find: find$2,\n      last: last$1\n    };\n\n    var whiteSpaceRegExp = /^\\s*|\\s*$/g;\n    var trim$1 = function (str) {\n      return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp, '');\n    };\n    var is$1 = function (obj, type) {\n      if (!type) {\n        return obj !== undefined;\n      }\n      if (type === 'array' && ArrUtils.isArray(obj)) {\n        return true;\n      }\n      return typeof obj === type;\n    };\n    var makeMap = function (items, delim, map) {\n      var i;\n      items = items || [];\n      delim = delim || ',';\n      if (typeof items === 'string') {\n        items = items.split(delim);\n      }\n      map = map || {};\n      i = items.length;\n      while (i--) {\n        map[items[i]] = {};\n      }\n      return map;\n    };\n    var hasOwnProperty$1 = function (obj, prop) {\n      return Object.prototype.hasOwnProperty.call(obj, prop);\n    };\n    var create = function (s, p, root) {\n      var self = this;\n      var sp, ns, cn, scn, c, de = 0;\n      s = /^((static) )?([\\w.]+)(:([\\w.]+))?/.exec(s);\n      cn = s[3].match(/(^|\\.)(\\w+)$/i)[2];\n      ns = self.createNS(s[3].replace(/\\.\\w+$/, ''), root);\n      if (ns[cn]) {\n        return;\n      }\n      if (s[2] === 'static') {\n        ns[cn] = p;\n        if (this.onCreate) {\n          this.onCreate(s[2], s[3], ns[cn]);\n        }\n        return;\n      }\n      if (!p[cn]) {\n        p[cn] = function () {\n        };\n        de = 1;\n      }\n      ns[cn] = p[cn];\n      self.extend(ns[cn].prototype, p);\n      if (s[5]) {\n        sp = self.resolve(s[5]).prototype;\n        scn = s[5].match(/\\.(\\w+)$/i)[1];\n        c = ns[cn];\n        if (de) {\n          ns[cn] = function () {\n            return sp[scn].apply(this, arguments);\n          };\n        } else {\n          ns[cn] = function () {\n            this.parent = sp[scn];\n            return c.apply(this, arguments);\n          };\n        }\n        ns[cn].prototype[cn] = ns[cn];\n        self.each(sp, function (f, n) {\n          ns[cn].prototype[n] = sp[n];\n        });\n        self.each(p, function (f, n) {\n          if (sp[n]) {\n            ns[cn].prototype[n] = function () {\n              this.parent = sp[n];\n              return f.apply(this, arguments);\n            };\n          } else {\n            if (n !== cn) {\n              ns[cn].prototype[n] = f;\n            }\n          }\n        });\n      }\n      self.each(p.static, function (f, n) {\n        ns[cn][n] = f;\n      });\n    };\n    var extend = function (obj, ext) {\n      var x = [];\n      for (var _i = 2; _i < arguments.length; _i++) {\n        x[_i - 2] = arguments[_i];\n      }\n      var i, l, name;\n      var args = arguments;\n      var value;\n      for (i = 1, l = args.length; i < l; i++) {\n        ext = args[i];\n        for (name in ext) {\n          if (ext.hasOwnProperty(name)) {\n            value = ext[name];\n            if (value !== undefined) {\n              obj[name] = value;\n            }\n          }\n        }\n      }\n      return obj;\n    };\n    var walk = function (o, f, n, s) {\n      s = s || this;\n      if (o) {\n        if (n) {\n          o = o[n];\n        }\n        ArrUtils.each(o, function (o, i) {\n          if (f.call(s, o, i, n) === false) {\n            return false;\n          }\n          walk(o, f, n, s);\n        });\n      }\n    };\n    var createNS = function (n, o) {\n      var i, v;\n      o = o || domGlobals.window;\n      n = n.split('.');\n      for (i = 0; i < n.length; i++) {\n        v = n[i];\n        if (!o[v]) {\n          o[v] = {};\n        }\n        o = o[v];\n      }\n      return o;\n    };\n    var resolve = function (n, o) {\n      var i, l;\n      o = o || domGlobals.window;\n      n = n.split('.');\n      for (i = 0, l = n.length; i < l; i++) {\n        o = o[n[i]];\n        if (!o) {\n          break;\n        }\n      }\n      return o;\n    };\n    var explode = function (s, d) {\n      if (!s || is$1(s, 'array')) {\n        return s;\n      }\n      return ArrUtils.map(s.split(d || ','), trim$1);\n    };\n    var _addCacheSuffix = function (url) {\n      var cacheSuffix = Env.cacheSuffix;\n      if (cacheSuffix) {\n        url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix;\n      }\n      return url;\n    };\n    var Tools = {\n      trim: trim$1,\n      isArray: ArrUtils.isArray,\n      is: is$1,\n      toArray: ArrUtils.toArray,\n      makeMap: makeMap,\n      each: ArrUtils.each,\n      map: ArrUtils.map,\n      grep: ArrUtils.filter,\n      inArray: ArrUtils.indexOf,\n      hasOwn: hasOwnProperty$1,\n      extend: extend,\n      create: create,\n      walk: walk,\n      createNS: createNS,\n      resolve: resolve,\n      explode: explode,\n      _addCacheSuffix: _addCacheSuffix\n    };\n\n    function StyleSheetLoader(document, settings) {\n      if (settings === void 0) {\n        settings = {};\n      }\n      var idCount = 0;\n      var loadedStates = {};\n      var maxLoadTime;\n      maxLoadTime = settings.maxLoadTime || 5000;\n      var _setReferrerPolicy = function (referrerPolicy) {\n        settings.referrerPolicy = referrerPolicy;\n      };\n      var appendToHead = function (node) {\n        document.getElementsByTagName('head')[0].appendChild(node);\n      };\n      var load = function (url, loadedCallback, errorCallback) {\n        var link, style, startTime, state;\n        var resolve = function (status) {\n          state.status = status;\n          state.passed = [];\n          state.failed = [];\n          if (link) {\n            link.onload = null;\n            link.onerror = null;\n            link = null;\n          }\n        };\n        var passed = function () {\n          var callbacks = state.passed;\n          var i = callbacks.length;\n          while (i--) {\n            callbacks[i]();\n          }\n          resolve(2);\n        };\n        var failed = function () {\n          var callbacks = state.failed;\n          var i = callbacks.length;\n          while (i--) {\n            callbacks[i]();\n          }\n          resolve(3);\n        };\n        var isOldWebKit = function () {\n          var webKitChunks = domGlobals.navigator.userAgent.match(/WebKit\\/(\\d*)/);\n          return !!(webKitChunks && parseInt(webKitChunks[1], 10) < 536);\n        };\n        var wait = function (testCallback, waitCallback) {\n          if (!testCallback()) {\n            if (new Date().getTime() - startTime < maxLoadTime) {\n              Delay.setTimeout(waitCallback);\n            } else {\n              failed();\n            }\n          }\n        };\n        var waitForWebKitLinkLoaded = function () {\n          wait(function () {\n            var styleSheets = document.styleSheets;\n            var styleSheet, i = styleSheets.length, owner;\n            while (i--) {\n              styleSheet = styleSheets[i];\n              owner = styleSheet.ownerNode ? styleSheet.ownerNode : styleSheet.owningElement;\n              if (owner && owner.id === link.id) {\n                passed();\n                return true;\n              }\n            }\n          }, waitForWebKitLinkLoaded);\n        };\n        var waitForGeckoLinkLoaded = function () {\n          wait(function () {\n            try {\n              var cssRules = style.sheet.cssRules;\n              passed();\n              return !!cssRules;\n            } catch (ex) {\n            }\n          }, waitForGeckoLinkLoaded);\n        };\n        url = Tools._addCacheSuffix(url);\n        if (!loadedStates[url]) {\n          state = {\n            passed: [],\n            failed: []\n          };\n          loadedStates[url] = state;\n        } else {\n          state = loadedStates[url];\n        }\n        if (loadedCallback) {\n          state.passed.push(loadedCallback);\n        }\n        if (errorCallback) {\n          state.failed.push(errorCallback);\n        }\n        if (state.status === 1) {\n          return;\n        }\n        if (state.status === 2) {\n          passed();\n          return;\n        }\n        if (state.status === 3) {\n          failed();\n          return;\n        }\n        state.status = 1;\n        link = document.createElement('link');\n        link.rel = 'stylesheet';\n        link.type = 'text/css';\n        link.id = 'u' + idCount++;\n        link.async = false;\n        link.defer = false;\n        startTime = new Date().getTime();\n        if (settings.contentCssCors) {\n          link.crossOrigin = 'anonymous';\n        }\n        if (settings.referrerPolicy) {\n          set(Element.fromDom(link), 'referrerpolicy', settings.referrerPolicy);\n        }\n        if ('onload' in link && !isOldWebKit()) {\n          link.onload = waitForWebKitLinkLoaded;\n          link.onerror = failed;\n        } else {\n          if (domGlobals.navigator.userAgent.indexOf('Firefox') > 0) {\n            style = document.createElement('style');\n            style.textContent = '@import \"' + url + '\"';\n            waitForGeckoLinkLoaded();\n            appendToHead(style);\n            return;\n          }\n          waitForWebKitLinkLoaded();\n        }\n        appendToHead(link);\n        link.href = url;\n      };\n      var loadF = function (url) {\n        return Future.nu(function (resolve) {\n          load(url, compose(resolve, constant(Result.value(url))), compose(resolve, constant(Result.error(url))));\n        });\n      };\n      var unbox = function (result) {\n        return result.fold(identity, identity);\n      };\n      var loadAll = function (urls, success, failure) {\n        par$1(map(urls, loadF)).get(function (result) {\n          var parts = partition(result, function (r) {\n            return r.isValue();\n          });\n          if (parts.fail.length > 0) {\n            failure(parts.fail.map(unbox));\n          } else {\n            success(parts.pass.map(unbox));\n          }\n        });\n      };\n      return {\n        load: load,\n        loadAll: loadAll,\n        _setReferrerPolicy: _setReferrerPolicy\n      };\n    }\n\n    var blocks = [\n      'article',\n      'aside',\n      'details',\n      'div',\n      'dt',\n      'figcaption',\n      'footer',\n      'form',\n      'fieldset',\n      'header',\n      'hgroup',\n      'html',\n      'main',\n      'nav',\n      'section',\n      'summary',\n      'body',\n      'p',\n      'dl',\n      'multicol',\n      'dd',\n      'figure',\n      'address',\n      'center',\n      'blockquote',\n      'h1',\n      'h2',\n      'h3',\n      'h4',\n      'h5',\n      'h6',\n      'listing',\n      'xmp',\n      'pre',\n      'plaintext',\n      'menu',\n      'dir',\n      'ul',\n      'ol',\n      'li',\n      'hr',\n      'table',\n      'tbody',\n      'thead',\n      'tfoot',\n      'th',\n      'tr',\n      'td',\n      'caption'\n    ];\n    var voids = [\n      'area',\n      'base',\n      'basefont',\n      'br',\n      'col',\n      'frame',\n      'hr',\n      'img',\n      'input',\n      'isindex',\n      'link',\n      'meta',\n      'param',\n      'embed',\n      'source',\n      'wbr',\n      'track'\n    ];\n    var tableCells = [\n      'td',\n      'th'\n    ];\n    var tableSections = [\n      'thead',\n      'tbody',\n      'tfoot'\n    ];\n    var textBlocks = [\n      'h1',\n      'h2',\n      'h3',\n      'h4',\n      'h5',\n      'h6',\n      'p',\n      'div',\n      'address',\n      'pre',\n      'form',\n      'blockquote',\n      'center',\n      'dir',\n      'fieldset',\n      'header',\n      'footer',\n      'article',\n      'section',\n      'hgroup',\n      'aside',\n      'nav',\n      'figure'\n    ];\n    var headings = [\n      'h1',\n      'h2',\n      'h3',\n      'h4',\n      'h5',\n      'h6'\n    ];\n    var listItems = [\n      'li',\n      'dd',\n      'dt'\n    ];\n    var lists = [\n      'ul',\n      'ol',\n      'dl'\n    ];\n    var wsElements = [\n      'pre',\n      'script',\n      'textarea',\n      'style'\n    ];\n    var lazyLookup = function (items) {\n      var lookup;\n      return function (node) {\n        lookup = lookup ? lookup : mapToObject(items, constant(true));\n        return lookup.hasOwnProperty(name(node));\n      };\n    };\n    var isHeading = lazyLookup(headings);\n    var isBlock = lazyLookup(blocks);\n    var isTable$1 = function (node) {\n      return name(node) === 'table';\n    };\n    var isInline = function (node) {\n      return isElement$1(node) && !isBlock(node);\n    };\n    var isBr$1 = function (node) {\n      return isElement$1(node) && name(node) === 'br';\n    };\n    var isTextBlock = lazyLookup(textBlocks);\n    var isList = lazyLookup(lists);\n    var isListItem = lazyLookup(listItems);\n    var isVoid = lazyLookup(voids);\n    var isTableSection = lazyLookup(tableSections);\n    var isTableCell = lazyLookup(tableCells);\n    var isWsPreserveElement = lazyLookup(wsElements);\n\n    var surroundedBySpans = function (node) {\n      var previousIsSpan = node.previousSibling && node.previousSibling.nodeName === 'SPAN';\n      var nextIsSpan = node.nextSibling && node.nextSibling.nodeName === 'SPAN';\n      return previousIsSpan && nextIsSpan;\n    };\n    var isBookmarkNode = function (node) {\n      return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';\n    };\n    var trimNode = function (dom, node) {\n      var i, children = node.childNodes;\n      if (NodeType.isElement(node) && isBookmarkNode(node)) {\n        return;\n      }\n      for (i = children.length - 1; i >= 0; i--) {\n        trimNode(dom, children[i]);\n      }\n      if (NodeType.isDocument(node) === false) {\n        if (NodeType.isText(node) && node.nodeValue.length > 0) {\n          var trimmedLength = Tools.trim(node.nodeValue).length;\n          if (dom.isBlock(node.parentNode) || trimmedLength > 0) {\n            return;\n          }\n          if (trimmedLength === 0 && surroundedBySpans(node)) {\n            return;\n          }\n        } else if (NodeType.isElement(node)) {\n          children = node.childNodes;\n          if (children.length === 1 && isBookmarkNode(children[0])) {\n            node.parentNode.insertBefore(children[0], node);\n          }\n          if (children.length || isVoid(Element.fromDom(node))) {\n            return;\n          }\n        }\n        dom.remove(node);\n      }\n      return node;\n    };\n    var TrimNode = { trimNode: trimNode };\n\n    var makeMap$1 = Tools.makeMap;\n    var namedEntities, baseEntities, reverseEntities;\n    var attrsCharsRegExp = /[&<>\\\"\\u0060\\u007E-\\uD7FF\\uE000-\\uFFEF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\n    var textCharsRegExp = /[<>&\\u007E-\\uD7FF\\uE000-\\uFFEF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\n    var rawCharsRegExp = /[<>&\\\"\\']/g;\n    var entityRegExp = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi;\n    var asciiMap = {\n      128: '\\u20AC',\n      130: '\\u201A',\n      131: '\\u0192',\n      132: '\\u201E',\n      133: '\\u2026',\n      134: '\\u2020',\n      135: '\\u2021',\n      136: '\\u02c6',\n      137: '\\u2030',\n      138: '\\u0160',\n      139: '\\u2039',\n      140: '\\u0152',\n      142: '\\u017d',\n      145: '\\u2018',\n      146: '\\u2019',\n      147: '\\u201C',\n      148: '\\u201D',\n      149: '\\u2022',\n      150: '\\u2013',\n      151: '\\u2014',\n      152: '\\u02DC',\n      153: '\\u2122',\n      154: '\\u0161',\n      155: '\\u203A',\n      156: '\\u0153',\n      158: '\\u017e',\n      159: '\\u0178'\n    };\n    baseEntities = {\n      '\"': '&quot;',\n      '\\'': '&#39;',\n      '<': '&lt;',\n      '>': '&gt;',\n      '&': '&amp;',\n      '`': '&#96;'\n    };\n    reverseEntities = {\n      '&lt;': '<',\n      '&gt;': '>',\n      '&amp;': '&',\n      '&quot;': '\"',\n      '&apos;': '\\''\n    };\n    var nativeDecode = function (text) {\n      var elm;\n      elm = Element.fromTag('div').dom();\n      elm.innerHTML = text;\n      return elm.textContent || elm.innerText || text;\n    };\n    var buildEntitiesLookup = function (items, radix) {\n      var i, chr, entity;\n      var lookup = {};\n      if (items) {\n        items = items.split(',');\n        radix = radix || 10;\n        for (i = 0; i < items.length; i += 2) {\n          chr = String.fromCharCode(parseInt(items[i], radix));\n          if (!baseEntities[chr]) {\n            entity = '&' + items[i + 1] + ';';\n            lookup[chr] = entity;\n            lookup[entity] = chr;\n          }\n        }\n        return lookup;\n      }\n    };\n    namedEntities = buildEntitiesLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);\n    var encodeRaw = function (text, attr) {\n      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {\n        return baseEntities[chr] || chr;\n      });\n    };\n    var encodeAllRaw = function (text) {\n      return ('' + text).replace(rawCharsRegExp, function (chr) {\n        return baseEntities[chr] || chr;\n      });\n    };\n    var encodeNumeric = function (text, attr) {\n      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {\n        if (chr.length > 1) {\n          return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';\n        }\n        return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';\n      });\n    };\n    var encodeNamed = function (text, attr, entities) {\n      entities = entities || namedEntities;\n      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {\n        return baseEntities[chr] || entities[chr] || chr;\n      });\n    };\n    var getEncodeFunc = function (name, entities) {\n      var entitiesMap = buildEntitiesLookup(entities) || namedEntities;\n      var encodeNamedAndNumeric = function (text, attr) {\n        return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {\n          if (baseEntities[chr] !== undefined) {\n            return baseEntities[chr];\n          }\n          if (entitiesMap[chr] !== undefined) {\n            return entitiesMap[chr];\n          }\n          if (chr.length > 1) {\n            return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';\n          }\n          return '&#' + chr.charCodeAt(0) + ';';\n        });\n      };\n      var encodeCustomNamed = function (text, attr) {\n        return encodeNamed(text, attr, entitiesMap);\n      };\n      var nameMap = makeMap$1(name.replace(/\\+/g, ','));\n      if (nameMap.named && nameMap.numeric) {\n        return encodeNamedAndNumeric;\n      }\n      if (nameMap.named) {\n        if (entities) {\n          return encodeCustomNamed;\n        }\n        return encodeNamed;\n      }\n      if (nameMap.numeric) {\n        return encodeNumeric;\n      }\n      return encodeRaw;\n    };\n    var decode = function (text) {\n      return text.replace(entityRegExp, function (all, numeric) {\n        if (numeric) {\n          if (numeric.charAt(0).toLowerCase() === 'x') {\n            numeric = parseInt(numeric.substr(1), 16);\n          } else {\n            numeric = parseInt(numeric, 10);\n          }\n          if (numeric > 65535) {\n            numeric -= 65536;\n            return String.fromCharCode(55296 + (numeric >> 10), 56320 + (numeric & 1023));\n          }\n          return asciiMap[numeric] || String.fromCharCode(numeric);\n        }\n        return reverseEntities[all] || namedEntities[all] || nativeDecode(all);\n      });\n    };\n    var Entities = {\n      encodeRaw: encodeRaw,\n      encodeAllRaw: encodeAllRaw,\n      encodeNumeric: encodeNumeric,\n      encodeNamed: encodeNamed,\n      getEncodeFunc: getEncodeFunc,\n      decode: decode\n    };\n\n    var mapCache = {}, dummyObj = {};\n    var makeMap$2 = Tools.makeMap, each$3 = Tools.each, extend$1 = Tools.extend, explode$1 = Tools.explode, inArray = Tools.inArray;\n    var split = function (items, delim) {\n      items = Tools.trim(items);\n      return items ? items.split(delim || ' ') : [];\n    };\n    var compileSchema = function (type) {\n      var schema = {};\n      var globalAttributes, blockContent;\n      var phrasingContent, flowContent, html4BlockContent, html4PhrasingContent;\n      var add = function (name, attributes, children) {\n        var ni, attributesOrder, element;\n        var arrayToMap = function (array, obj) {\n          var map = {};\n          var i, l;\n          for (i = 0, l = array.length; i < l; i++) {\n            map[array[i]] = obj || {};\n          }\n          return map;\n        };\n        children = children || [];\n        attributes = attributes || '';\n        if (typeof children === 'string') {\n          children = split(children);\n        }\n        name = split(name);\n        ni = name.length;\n        while (ni--) {\n          attributesOrder = split([\n            globalAttributes,\n            attributes\n          ].join(' '));\n          element = {\n            attributes: arrayToMap(attributesOrder),\n            attributesOrder: attributesOrder,\n            children: arrayToMap(children, dummyObj)\n          };\n          schema[name[ni]] = element;\n        }\n      };\n      var addAttrs = function (name, attributes) {\n        var ni, schemaItem, i, l;\n        name = split(name);\n        ni = name.length;\n        attributes = split(attributes);\n        while (ni--) {\n          schemaItem = schema[name[ni]];\n          for (i = 0, l = attributes.length; i < l; i++) {\n            schemaItem.attributes[attributes[i]] = {};\n            schemaItem.attributesOrder.push(attributes[i]);\n          }\n        }\n      };\n      if (mapCache[type]) {\n        return mapCache[type];\n      }\n      globalAttributes = 'id accesskey class dir lang style tabindex title role';\n      blockContent = 'address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul';\n      phrasingContent = 'a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd ' + 'label map noscript object q s samp script select small span strong sub sup ' + 'textarea u var #text #comment';\n      if (type !== 'html4') {\n        globalAttributes += ' contenteditable contextmenu draggable dropzone ' + 'hidden spellcheck translate';\n        blockContent += ' article aside details dialog figure main header footer hgroup section nav';\n        phrasingContent += ' audio canvas command datalist mark meter output picture ' + 'progress time wbr video ruby bdi keygen';\n      }\n      if (type !== 'html5-strict') {\n        globalAttributes += ' xml:lang';\n        html4PhrasingContent = 'acronym applet basefont big font strike tt';\n        phrasingContent = [\n          phrasingContent,\n          html4PhrasingContent\n        ].join(' ');\n        each$3(split(html4PhrasingContent), function (name) {\n          add(name, '', phrasingContent);\n        });\n        html4BlockContent = 'center dir isindex noframes';\n        blockContent = [\n          blockContent,\n          html4BlockContent\n        ].join(' ');\n        flowContent = [\n          blockContent,\n          phrasingContent\n        ].join(' ');\n        each$3(split(html4BlockContent), function (name) {\n          add(name, '', flowContent);\n        });\n      }\n      flowContent = flowContent || [\n        blockContent,\n        phrasingContent\n      ].join(' ');\n      add('html', 'manifest', 'head body');\n      add('head', '', 'base command link meta noscript script style title');\n      add('title hr noscript br');\n      add('base', 'href target');\n      add('link', 'href rel media hreflang type sizes hreflang');\n      add('meta', 'name http-equiv content charset');\n      add('style', 'media type scoped');\n      add('script', 'src async defer type charset');\n      add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' + 'onhashchange onload onmessage onoffline ononline onpagehide onpageshow ' + 'onpopstate onresize onscroll onstorage onunload', flowContent);\n      add('address dt dd div caption', '', flowContent);\n      add('h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn', '', phrasingContent);\n      add('blockquote', 'cite', flowContent);\n      add('ol', 'reversed start type', 'li');\n      add('ul', '', 'li');\n      add('li', 'value', flowContent);\n      add('dl', '', 'dt dd');\n      add('a', 'href target rel media hreflang type', phrasingContent);\n      add('q', 'cite', phrasingContent);\n      add('ins del', 'cite datetime', flowContent);\n      add('img', 'src sizes srcset alt usemap ismap width height');\n      add('iframe', 'src name width height', flowContent);\n      add('embed', 'src type width height');\n      add('object', 'data type typemustmatch name usemap form width height', [\n        flowContent,\n        'param'\n      ].join(' '));\n      add('param', 'name value');\n      add('map', 'name', [\n        flowContent,\n        'area'\n      ].join(' '));\n      add('area', 'alt coords shape href target rel media hreflang type');\n      add('table', 'border', 'caption colgroup thead tfoot tbody tr' + (type === 'html4' ? ' col' : ''));\n      add('colgroup', 'span', 'col');\n      add('col', 'span');\n      add('tbody thead tfoot', '', 'tr');\n      add('tr', '', 'td th');\n      add('td', 'colspan rowspan headers', flowContent);\n      add('th', 'colspan rowspan headers scope abbr', flowContent);\n      add('form', 'accept-charset action autocomplete enctype method name novalidate target', flowContent);\n      add('fieldset', 'disabled form name', [\n        flowContent,\n        'legend'\n      ].join(' '));\n      add('label', 'form for', phrasingContent);\n      add('input', 'accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate ' + 'formtarget height list max maxlength min multiple name pattern readonly required size src step type value width');\n      add('button', 'disabled form formaction formenctype formmethod formnovalidate formtarget name type value', type === 'html4' ? flowContent : phrasingContent);\n      add('select', 'disabled form multiple name required size', 'option optgroup');\n      add('optgroup', 'disabled label', 'option');\n      add('option', 'disabled label selected value');\n      add('textarea', 'cols dirname disabled form maxlength name readonly required rows wrap');\n      add('menu', 'type label', [\n        flowContent,\n        'li'\n      ].join(' '));\n      add('noscript', '', flowContent);\n      if (type !== 'html4') {\n        add('wbr');\n        add('ruby', '', [\n          phrasingContent,\n          'rt rp'\n        ].join(' '));\n        add('figcaption', '', flowContent);\n        add('mark rt rp summary bdi', '', phrasingContent);\n        add('canvas', 'width height', flowContent);\n        add('video', 'src crossorigin poster preload autoplay mediagroup loop ' + 'muted controls width height buffered', [\n          flowContent,\n          'track source'\n        ].join(' '));\n        add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' + 'buffered volume', [\n          flowContent,\n          'track source'\n        ].join(' '));\n        add('picture', '', 'img source');\n        add('source', 'src srcset type media sizes');\n        add('track', 'kind src srclang label default');\n        add('datalist', '', [\n          phrasingContent,\n          'option'\n        ].join(' '));\n        add('article section nav aside main header footer', '', flowContent);\n        add('hgroup', '', 'h1 h2 h3 h4 h5 h6');\n        add('figure', '', [\n          flowContent,\n          'figcaption'\n        ].join(' '));\n        add('time', 'datetime', phrasingContent);\n        add('dialog', 'open', flowContent);\n        add('command', 'type label icon disabled checked radiogroup command');\n        add('output', 'for form name', phrasingContent);\n        add('progress', 'value max', phrasingContent);\n        add('meter', 'value min max low high optimum', phrasingContent);\n        add('details', 'open', [\n          flowContent,\n          'summary'\n        ].join(' '));\n        add('keygen', 'autofocus challenge disabled form keytype name');\n      }\n      if (type !== 'html5-strict') {\n        addAttrs('script', 'language xml:space');\n        addAttrs('style', 'xml:space');\n        addAttrs('object', 'declare classid code codebase codetype archive standby align border hspace vspace');\n        addAttrs('embed', 'align name hspace vspace');\n        addAttrs('param', 'valuetype type');\n        addAttrs('a', 'charset name rev shape coords');\n        addAttrs('br', 'clear');\n        addAttrs('applet', 'codebase archive code object alt name width height align hspace vspace');\n        addAttrs('img', 'name longdesc align border hspace vspace');\n        addAttrs('iframe', 'longdesc frameborder marginwidth marginheight scrolling align');\n        addAttrs('font basefont', 'size color face');\n        addAttrs('input', 'usemap align');\n        addAttrs('select', 'onchange');\n        addAttrs('textarea');\n        addAttrs('h1 h2 h3 h4 h5 h6 div p legend caption', 'align');\n        addAttrs('ul', 'type compact');\n        addAttrs('li', 'type');\n        addAttrs('ol dl menu dir', 'compact');\n        addAttrs('pre', 'width xml:space');\n        addAttrs('hr', 'align noshade size width');\n        addAttrs('isindex', 'prompt');\n        addAttrs('table', 'summary width frame rules cellspacing cellpadding align bgcolor');\n        addAttrs('col', 'width align char charoff valign');\n        addAttrs('colgroup', 'width align char charoff valign');\n        addAttrs('thead', 'align char charoff valign');\n        addAttrs('tr', 'align char charoff valign bgcolor');\n        addAttrs('th', 'axis align char charoff valign nowrap bgcolor width height');\n        addAttrs('form', 'accept');\n        addAttrs('td', 'abbr axis scope align char charoff valign nowrap bgcolor width height');\n        addAttrs('tfoot', 'align char charoff valign');\n        addAttrs('tbody', 'align char charoff valign');\n        addAttrs('area', 'nohref');\n        addAttrs('body', 'background bgcolor text link vlink alink');\n      }\n      if (type !== 'html4') {\n        addAttrs('input button select textarea', 'autofocus');\n        addAttrs('input textarea', 'placeholder');\n        addAttrs('a', 'download');\n        addAttrs('link script img', 'crossorigin');\n        addAttrs('iframe', 'sandbox seamless allowfullscreen');\n      }\n      each$3(split('a form meter progress dfn'), function (name) {\n        if (schema[name]) {\n          delete schema[name].children[name];\n        }\n      });\n      delete schema.caption.children.table;\n      delete schema.script;\n      mapCache[type] = schema;\n      return schema;\n    };\n    var compileElementMap = function (value, mode) {\n      var styles;\n      if (value) {\n        styles = {};\n        if (typeof value === 'string') {\n          value = { '*': value };\n        }\n        each$3(value, function (value, key) {\n          styles[key] = styles[key.toUpperCase()] = mode === 'map' ? makeMap$2(value, /[, ]/) : explode$1(value, /[, ]/);\n        });\n      }\n      return styles;\n    };\n    function Schema(settings) {\n      var elements = {};\n      var children = {};\n      var patternElements = [];\n      var validStyles;\n      var invalidStyles;\n      var schemaItems;\n      var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, validClasses;\n      var blockElementsMap, nonEmptyElementsMap, moveCaretBeforeOnEnterElementsMap, textBlockElementsMap, textInlineElementsMap;\n      var customElementsMap = {}, specialElements = {};\n      var createLookupTable = function (option, defaultValue, extendWith) {\n        var value = settings[option];\n        if (!value) {\n          value = mapCache[option];\n          if (!value) {\n            value = makeMap$2(defaultValue, ' ', makeMap$2(defaultValue.toUpperCase(), ' '));\n            value = extend$1(value, extendWith);\n            mapCache[option] = value;\n          }\n        } else {\n          value = makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/));\n        }\n        return value;\n      };\n      settings = settings || {};\n      schemaItems = compileSchema(settings.schema);\n      if (settings.verify_html === false) {\n        settings.valid_elements = '*[*]';\n      }\n      validStyles = compileElementMap(settings.valid_styles);\n      invalidStyles = compileElementMap(settings.invalid_styles, 'map');\n      validClasses = compileElementMap(settings.valid_classes, 'map');\n      whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object code');\n      selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr');\n      shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link ' + 'meta param embed source wbr track');\n      boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize ' + 'noshade nowrap readonly selected autoplay loop controls');\n      nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object ' + 'script pre code', shortEndedElementsMap);\n      moveCaretBeforeOnEnterElementsMap = createLookupTable('move_caret_before_on_enter_elements', 'table', nonEmptyElementsMap);\n      textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' + 'blockquote center dir fieldset header footer article section hgroup aside main nav figure');\n      blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' + 'th tr td li ol ul caption dl dt dd noscript menu isindex option ' + 'datalist select optgroup figcaption details summary', textBlockElementsMap);\n      textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' + 'dfn code mark q sup sub samp');\n      each$3((settings.special || 'script noscript noframes noembed title style textarea xmp').split(' '), function (name) {\n        specialElements[name] = new RegExp('</' + name + '[^>]*>', 'gi');\n      });\n      var patternToRegExp = function (str) {\n        return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$');\n      };\n      var addValidElements = function (validElements) {\n        var ei, el, ai, al, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, prefix, outputName, globalAttributes, globalAttributesOrder, key, value;\n        var elementRuleRegExp = /^([#+\\-])?([^\\[!\\/]+)(?:\\/([^\\[!]+))?(?:(!?)\\[([^\\]]+)\\])?$/, attrRuleRegExp = /^([!\\-])?(\\w+[\\\\:]:\\w+|[^=:<]+)?(?:([=:<])(.*))?$/, hasPatternsRegExp = /[*?+]/;\n        if (validElements) {\n          validElements = split(validElements, ',');\n          if (elements['@']) {\n            globalAttributes = elements['@'].attributes;\n            globalAttributesOrder = elements['@'].attributesOrder;\n          }\n          for (ei = 0, el = validElements.length; ei < el; ei++) {\n            matches = elementRuleRegExp.exec(validElements[ei]);\n            if (matches) {\n              prefix = matches[1];\n              elementName = matches[2];\n              outputName = matches[3];\n              attrData = matches[5];\n              attributes = {};\n              attributesOrder = [];\n              element = {\n                attributes: attributes,\n                attributesOrder: attributesOrder\n              };\n              if (prefix === '#') {\n                element.paddEmpty = true;\n              }\n              if (prefix === '-') {\n                element.removeEmpty = true;\n              }\n              if (matches[4] === '!') {\n                element.removeEmptyAttrs = true;\n              }\n              if (globalAttributes) {\n                for (key in globalAttributes) {\n                  attributes[key] = globalAttributes[key];\n                }\n                attributesOrder.push.apply(attributesOrder, globalAttributesOrder);\n              }\n              if (attrData) {\n                attrData = split(attrData, '|');\n                for (ai = 0, al = attrData.length; ai < al; ai++) {\n                  matches = attrRuleRegExp.exec(attrData[ai]);\n                  if (matches) {\n                    attr = {};\n                    attrType = matches[1];\n                    attrName = matches[2].replace(/[\\\\:]:/g, ':');\n                    prefix = matches[3];\n                    value = matches[4];\n                    if (attrType === '!') {\n                      element.attributesRequired = element.attributesRequired || [];\n                      element.attributesRequired.push(attrName);\n                      attr.required = true;\n                    }\n                    if (attrType === '-') {\n                      delete attributes[attrName];\n                      attributesOrder.splice(inArray(attributesOrder, attrName), 1);\n                      continue;\n                    }\n                    if (prefix) {\n                      if (prefix === '=') {\n                        element.attributesDefault = element.attributesDefault || [];\n                        element.attributesDefault.push({\n                          name: attrName,\n                          value: value\n                        });\n                        attr.defaultValue = value;\n                      }\n                      if (prefix === ':') {\n                        element.attributesForced = element.attributesForced || [];\n                        element.attributesForced.push({\n                          name: attrName,\n                          value: value\n                        });\n                        attr.forcedValue = value;\n                      }\n                      if (prefix === '<') {\n                        attr.validValues = makeMap$2(value, '?');\n                      }\n                    }\n                    if (hasPatternsRegExp.test(attrName)) {\n                      element.attributePatterns = element.attributePatterns || [];\n                      attr.pattern = patternToRegExp(attrName);\n                      element.attributePatterns.push(attr);\n                    } else {\n                      if (!attributes[attrName]) {\n                        attributesOrder.push(attrName);\n                      }\n                      attributes[attrName] = attr;\n                    }\n                  }\n                }\n              }\n              if (!globalAttributes && elementName === '@') {\n                globalAttributes = attributes;\n                globalAttributesOrder = attributesOrder;\n              }\n              if (outputName) {\n                element.outputName = elementName;\n                elements[outputName] = element;\n              }\n              if (hasPatternsRegExp.test(elementName)) {\n                element.pattern = patternToRegExp(elementName);\n                patternElements.push(element);\n              } else {\n                elements[elementName] = element;\n              }\n            }\n          }\n        }\n      };\n      var setValidElements = function (validElements) {\n        elements = {};\n        patternElements = [];\n        addValidElements(validElements);\n        each$3(schemaItems, function (element, name) {\n          children[name] = element.children;\n        });\n      };\n      var addCustomElements = function (customElements) {\n        var customElementRegExp = /^(~)?(.+)$/;\n        if (customElements) {\n          mapCache.text_block_elements = mapCache.block_elements = null;\n          each$3(split(customElements, ','), function (rule) {\n            var matches = customElementRegExp.exec(rule), inline = matches[1] === '~', cloneName = inline ? 'span' : 'div', name = matches[2];\n            children[name] = children[cloneName];\n            customElementsMap[name] = cloneName;\n            if (!inline) {\n              blockElementsMap[name.toUpperCase()] = {};\n              blockElementsMap[name] = {};\n            }\n            if (!elements[name]) {\n              var customRule = elements[cloneName];\n              customRule = extend$1({}, customRule);\n              delete customRule.removeEmptyAttrs;\n              delete customRule.removeEmpty;\n              elements[name] = customRule;\n            }\n            each$3(children, function (element, elmName) {\n              if (element[cloneName]) {\n                children[elmName] = element = extend$1({}, children[elmName]);\n                element[name] = element[cloneName];\n              }\n            });\n          });\n        }\n      };\n      var addValidChildren = function (validChildren) {\n        var childRuleRegExp = /^([+\\-]?)(\\w+)\\[([^\\]]+)\\]$/;\n        mapCache[settings.schema] = null;\n        if (validChildren) {\n          each$3(split(validChildren, ','), function (rule) {\n            var matches = childRuleRegExp.exec(rule);\n            var parent, prefix;\n            if (matches) {\n              prefix = matches[1];\n              if (prefix) {\n                parent = children[matches[2]];\n              } else {\n                parent = children[matches[2]] = { '#comment': {} };\n              }\n              parent = children[matches[2]];\n              each$3(split(matches[3], '|'), function (child) {\n                if (prefix === '-') {\n                  delete parent[child];\n                } else {\n                  parent[child] = {};\n                }\n              });\n            }\n          });\n        }\n      };\n      var getElementRule = function (name) {\n        var element = elements[name], i;\n        if (element) {\n          return element;\n        }\n        i = patternElements.length;\n        while (i--) {\n          element = patternElements[i];\n          if (element.pattern.test(name)) {\n            return element;\n          }\n        }\n      };\n      if (!settings.valid_elements) {\n        each$3(schemaItems, function (element, name) {\n          elements[name] = {\n            attributes: element.attributes,\n            attributesOrder: element.attributesOrder\n          };\n          children[name] = element.children;\n        });\n        if (settings.schema !== 'html5') {\n          each$3(split('strong/b em/i'), function (item) {\n            item = split(item, '/');\n            elements[item[1]].outputName = item[0];\n          });\n        }\n        each$3(split('ol ul sub sup blockquote span font a table tbody tr strong em b i'), function (name) {\n          if (elements[name]) {\n            elements[name].removeEmpty = true;\n          }\n        });\n        each$3(split('p h1 h2 h3 h4 h5 h6 th td pre div address caption li'), function (name) {\n          elements[name].paddEmpty = true;\n        });\n        each$3(split('span'), function (name) {\n          elements[name].removeEmptyAttrs = true;\n        });\n      } else {\n        setValidElements(settings.valid_elements);\n      }\n      addCustomElements(settings.custom_elements);\n      addValidChildren(settings.valid_children);\n      addValidElements(settings.extended_valid_elements);\n      addValidChildren('+ol[ul|ol],+ul[ul|ol]');\n      each$3({\n        dd: 'dl',\n        dt: 'dl',\n        li: 'ul ol',\n        td: 'tr',\n        th: 'tr',\n        tr: 'tbody thead tfoot',\n        tbody: 'table',\n        thead: 'table',\n        tfoot: 'table',\n        legend: 'fieldset',\n        area: 'map',\n        param: 'video audio object'\n      }, function (parents, item) {\n        if (elements[item]) {\n          elements[item].parentsRequired = split(parents);\n        }\n      });\n      if (settings.invalid_elements) {\n        each$3(explode$1(settings.invalid_elements), function (item) {\n          if (elements[item]) {\n            delete elements[item];\n          }\n        });\n      }\n      if (!getElementRule('span')) {\n        addValidElements('span[!data-mce-type|*]');\n      }\n      var getValidStyles = function () {\n        return validStyles;\n      };\n      var getInvalidStyles = function () {\n        return invalidStyles;\n      };\n      var getValidClasses = function () {\n        return validClasses;\n      };\n      var getBoolAttrs = function () {\n        return boolAttrMap;\n      };\n      var getBlockElements = function () {\n        return blockElementsMap;\n      };\n      var getTextBlockElements = function () {\n        return textBlockElementsMap;\n      };\n      var getTextInlineElements = function () {\n        return textInlineElementsMap;\n      };\n      var getShortEndedElements = function () {\n        return shortEndedElementsMap;\n      };\n      var getSelfClosingElements = function () {\n        return selfClosingElementsMap;\n      };\n      var getNonEmptyElements = function () {\n        return nonEmptyElementsMap;\n      };\n      var getMoveCaretBeforeOnEnterElements = function () {\n        return moveCaretBeforeOnEnterElementsMap;\n      };\n      var getWhiteSpaceElements = function () {\n        return whiteSpaceElementsMap;\n      };\n      var getSpecialElements = function () {\n        return specialElements;\n      };\n      var isValidChild = function (name, child) {\n        var parent = children[name.toLowerCase()];\n        return !!(parent && parent[child.toLowerCase()]);\n      };\n      var isValid = function (name, attr) {\n        var attrPatterns, i;\n        var rule = getElementRule(name);\n        if (rule) {\n          if (attr) {\n            if (rule.attributes[attr]) {\n              return true;\n            }\n            attrPatterns = rule.attributePatterns;\n            if (attrPatterns) {\n              i = attrPatterns.length;\n              while (i--) {\n                if (attrPatterns[i].pattern.test(name)) {\n                  return true;\n                }\n              }\n            }\n          } else {\n            return true;\n          }\n        }\n        return false;\n      };\n      var getCustomElements = function () {\n        return customElementsMap;\n      };\n      return {\n        children: children,\n        elements: elements,\n        getValidStyles: getValidStyles,\n        getValidClasses: getValidClasses,\n        getBlockElements: getBlockElements,\n        getInvalidStyles: getInvalidStyles,\n        getShortEndedElements: getShortEndedElements,\n        getTextBlockElements: getTextBlockElements,\n        getTextInlineElements: getTextInlineElements,\n        getBoolAttrs: getBoolAttrs,\n        getElementRule: getElementRule,\n        getSelfClosingElements: getSelfClosingElements,\n        getNonEmptyElements: getNonEmptyElements,\n        getMoveCaretBeforeOnEnterElements: getMoveCaretBeforeOnEnterElements,\n        getWhiteSpaceElements: getWhiteSpaceElements,\n        getSpecialElements: getSpecialElements,\n        isValidChild: isValidChild,\n        isValid: isValid,\n        getCustomElements: getCustomElements,\n        addValidElements: addValidElements,\n        setValidElements: setValidElements,\n        addCustomElements: addCustomElements,\n        addValidChildren: addValidChildren\n      };\n    }\n\n    var toHex = function (match, r, g, b) {\n      var hex = function (val) {\n        val = parseInt(val, 10).toString(16);\n        return val.length > 1 ? val : '0' + val;\n      };\n      return '#' + hex(r) + hex(g) + hex(b);\n    };\n    var Styles = function (settings, schema) {\n      var rgbRegExp = /rgb\\s*\\(\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*\\)/gi;\n      var urlOrStrRegExp = /(?:url(?:(?:\\(\\s*\\\"([^\\\"]+)\\\"\\s*\\))|(?:\\(\\s*\\'([^\\']+)\\'\\s*\\))|(?:\\(\\s*([^)\\s]+)\\s*\\))))|(?:\\'([^\\']+)\\')|(?:\\\"([^\\\"]+)\\\")/gi;\n      var styleRegExp = /\\s*([^:]+):\\s*([^;]+);?/g;\n      var trimRightRegExp = /\\s+$/;\n      var i;\n      var encodingLookup = {};\n      var encodingItems;\n      var validStyles;\n      var invalidStyles;\n      var invisibleChar = '\\uFEFF';\n      settings = settings || {};\n      if (schema) {\n        validStyles = schema.getValidStyles();\n        invalidStyles = schema.getInvalidStyles();\n      }\n      encodingItems = ('\\\\\" \\\\\\' \\\\; \\\\: ; : ' + invisibleChar).split(' ');\n      for (i = 0; i < encodingItems.length; i++) {\n        encodingLookup[encodingItems[i]] = invisibleChar + i;\n        encodingLookup[invisibleChar + i] = encodingItems[i];\n      }\n      return {\n        toHex: function (color) {\n          return color.replace(rgbRegExp, toHex);\n        },\n        parse: function (css) {\n          var styles = {};\n          var matches, name, value, isEncoded;\n          var urlConverter = settings.url_converter;\n          var urlConverterScope = settings.url_converter_scope || this;\n          var compress = function (prefix, suffix, noJoin) {\n            var top, right, bottom, left;\n            top = styles[prefix + '-top' + suffix];\n            if (!top) {\n              return;\n            }\n            right = styles[prefix + '-right' + suffix];\n            if (!right) {\n              return;\n            }\n            bottom = styles[prefix + '-bottom' + suffix];\n            if (!bottom) {\n              return;\n            }\n            left = styles[prefix + '-left' + suffix];\n            if (!left) {\n              return;\n            }\n            var box = [\n              top,\n              right,\n              bottom,\n              left\n            ];\n            i = box.length - 1;\n            while (i--) {\n              if (box[i] !== box[i + 1]) {\n                break;\n              }\n            }\n            if (i > -1 && noJoin) {\n              return;\n            }\n            styles[prefix + suffix] = i === -1 ? box[0] : box.join(' ');\n            delete styles[prefix + '-top' + suffix];\n            delete styles[prefix + '-right' + suffix];\n            delete styles[prefix + '-bottom' + suffix];\n            delete styles[prefix + '-left' + suffix];\n          };\n          var canCompress = function (key) {\n            var value = styles[key], i;\n            if (!value) {\n              return;\n            }\n            value = value.split(' ');\n            i = value.length;\n            while (i--) {\n              if (value[i] !== value[0]) {\n                return false;\n              }\n            }\n            styles[key] = value[0];\n            return true;\n          };\n          var compress2 = function (target, a, b, c) {\n            if (!canCompress(a)) {\n              return;\n            }\n            if (!canCompress(b)) {\n              return;\n            }\n            if (!canCompress(c)) {\n              return;\n            }\n            styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c];\n            delete styles[a];\n            delete styles[b];\n            delete styles[c];\n          };\n          var encode = function (str) {\n            isEncoded = true;\n            return encodingLookup[str];\n          };\n          var decode = function (str, keepSlashes) {\n            if (isEncoded) {\n              str = str.replace(/\\uFEFF[0-9]/g, function (str) {\n                return encodingLookup[str];\n              });\n            }\n            if (!keepSlashes) {\n              str = str.replace(/\\\\([\\'\\\";:])/g, '$1');\n            }\n            return str;\n          };\n          var decodeSingleHexSequence = function (escSeq) {\n            return String.fromCharCode(parseInt(escSeq.slice(1), 16));\n          };\n          var decodeHexSequences = function (value) {\n            return value.replace(/\\\\[0-9a-f]+/gi, decodeSingleHexSequence);\n          };\n          var processUrl = function (match, url, url2, url3, str, str2) {\n            str = str || str2;\n            if (str) {\n              str = decode(str);\n              return '\\'' + str.replace(/\\'/g, '\\\\\\'') + '\\'';\n            }\n            url = decode(url || url2 || url3);\n            if (!settings.allow_script_urls) {\n              var scriptUrl = url.replace(/[\\s\\r\\n]+/g, '');\n              if (/(java|vb)script:/i.test(scriptUrl)) {\n                return '';\n              }\n              if (!settings.allow_svg_data_urls && /^data:image\\/svg/i.test(scriptUrl)) {\n                return '';\n              }\n            }\n            if (urlConverter) {\n              url = urlConverter.call(urlConverterScope, url, 'style');\n            }\n            return 'url(\\'' + url.replace(/\\'/g, '\\\\\\'') + '\\')';\n          };\n          if (css) {\n            css = css.replace(/[\\u0000-\\u001F]/g, '');\n            css = css.replace(/\\\\[\\\"\\';:\\uFEFF]/g, encode).replace(/\\\"[^\\\"]+\\\"|\\'[^\\']+\\'/g, function (str) {\n              return str.replace(/[;:]/g, encode);\n            });\n            while (matches = styleRegExp.exec(css)) {\n              styleRegExp.lastIndex = matches.index + matches[0].length;\n              name = matches[1].replace(trimRightRegExp, '').toLowerCase();\n              value = matches[2].replace(trimRightRegExp, '');\n              if (name && value) {\n                name = decodeHexSequences(name);\n                value = decodeHexSequences(value);\n                if (name.indexOf(invisibleChar) !== -1 || name.indexOf('\"') !== -1) {\n                  continue;\n                }\n                if (!settings.allow_script_urls && (name === 'behavior' || /expression\\s*\\(|\\/\\*|\\*\\//.test(value))) {\n                  continue;\n                }\n                if (name === 'font-weight' && value === '700') {\n                  value = 'bold';\n                } else if (name === 'color' || name === 'background-color') {\n                  value = value.toLowerCase();\n                }\n                value = value.replace(rgbRegExp, toHex);\n                value = value.replace(urlOrStrRegExp, processUrl);\n                styles[name] = isEncoded ? decode(value, true) : value;\n              }\n            }\n            compress('border', '', true);\n            compress('border', '-width');\n            compress('border', '-color');\n            compress('border', '-style');\n            compress('padding', '');\n            compress('margin', '');\n            compress2('border', 'border-width', 'border-style', 'border-color');\n            if (styles.border === 'medium none') {\n              delete styles.border;\n            }\n            if (styles['border-image'] === 'none') {\n              delete styles['border-image'];\n            }\n          }\n          return styles;\n        },\n        serialize: function (styles, elementName) {\n          var css = '', name, value;\n          var serializeStyles = function (name) {\n            var styleList, i, l, value;\n            styleList = validStyles[name];\n            if (styleList) {\n              for (i = 0, l = styleList.length; i < l; i++) {\n                name = styleList[i];\n                value = styles[name];\n                if (value) {\n                  css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';\n                }\n              }\n            }\n          };\n          var isValid = function (name, elementName) {\n            var styleMap;\n            styleMap = invalidStyles['*'];\n            if (styleMap && styleMap[name]) {\n              return false;\n            }\n            styleMap = invalidStyles[elementName];\n            if (styleMap && styleMap[name]) {\n              return false;\n            }\n            return true;\n          };\n          if (elementName && validStyles) {\n            serializeStyles('*');\n            serializeStyles(elementName);\n          } else {\n            for (name in styles) {\n              value = styles[name];\n              if (value && (!invalidStyles || isValid(name, elementName))) {\n                css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';\n              }\n            }\n          }\n          return css;\n        }\n      };\n    };\n\n    var eventExpandoPrefix = 'mce-data-';\n    var mouseEventRe = /^(?:mouse|contextmenu)|click/;\n    var deprecated = {\n      keyLocation: 1,\n      layerX: 1,\n      layerY: 1,\n      returnValue: 1,\n      webkitMovementX: 1,\n      webkitMovementY: 1,\n      keyIdentifier: 1,\n      mozPressure: 1\n    };\n    var hasIsDefaultPrevented = function (event) {\n      return event.isDefaultPrevented === returnTrue || event.isDefaultPrevented === returnFalse;\n    };\n    var returnFalse = function () {\n      return false;\n    };\n    var returnTrue = function () {\n      return true;\n    };\n    var addEvent = function (target, name, callback, capture) {\n      if (target.addEventListener) {\n        target.addEventListener(name, callback, capture || false);\n      } else if (target.attachEvent) {\n        target.attachEvent('on' + name, callback);\n      }\n    };\n    var removeEvent = function (target, name, callback, capture) {\n      if (target.removeEventListener) {\n        target.removeEventListener(name, callback, capture || false);\n      } else if (target.detachEvent) {\n        target.detachEvent('on' + name, callback);\n      }\n    };\n    var getTargetFromShadowDom = function (event, defaultTarget) {\n      if (event.composedPath) {\n        var composedPath = event.composedPath();\n        if (composedPath && composedPath.length > 0) {\n          return composedPath[0];\n        }\n      }\n      return defaultTarget;\n    };\n    var fix = function (originalEvent, data) {\n      var name;\n      var event = data || {};\n      for (name in originalEvent) {\n        if (!deprecated[name]) {\n          event[name] = originalEvent[name];\n        }\n      }\n      if (!event.target) {\n        event.target = event.srcElement || domGlobals.document;\n      }\n      if (Env.experimentalShadowDom) {\n        event.target = getTargetFromShadowDom(originalEvent, event.target);\n      }\n      if (originalEvent && mouseEventRe.test(originalEvent.type) && originalEvent.pageX === undefined && originalEvent.clientX !== undefined) {\n        var eventDoc = event.target.ownerDocument || domGlobals.document;\n        var doc = eventDoc.documentElement;\n        var body = eventDoc.body;\n        event.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);\n        event.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);\n      }\n      event.preventDefault = function () {\n        event.isDefaultPrevented = returnTrue;\n        if (originalEvent) {\n          if (originalEvent.preventDefault) {\n            originalEvent.preventDefault();\n          } else {\n            originalEvent.returnValue = false;\n          }\n        }\n      };\n      event.stopPropagation = function () {\n        event.isPropagationStopped = returnTrue;\n        if (originalEvent) {\n          if (originalEvent.stopPropagation) {\n            originalEvent.stopPropagation();\n          } else {\n            originalEvent.cancelBubble = true;\n          }\n        }\n      };\n      event.stopImmediatePropagation = function () {\n        event.isImmediatePropagationStopped = returnTrue;\n        event.stopPropagation();\n      };\n      if (hasIsDefaultPrevented(event) === false) {\n        event.isDefaultPrevented = returnFalse;\n        event.isPropagationStopped = returnFalse;\n        event.isImmediatePropagationStopped = returnFalse;\n      }\n      if (typeof event.metaKey === 'undefined') {\n        event.metaKey = false;\n      }\n      return event;\n    };\n    var bindOnReady = function (win, callback, eventUtils) {\n      var doc = win.document, event = { type: 'ready' };\n      if (eventUtils.domLoaded) {\n        callback(event);\n        return;\n      }\n      var isDocReady = function () {\n        return doc.readyState === 'complete' || doc.readyState === 'interactive' && doc.body;\n      };\n      var readyHandler = function () {\n        removeEvent(win, 'DOMContentLoaded', readyHandler);\n        removeEvent(win, 'load', readyHandler);\n        if (!eventUtils.domLoaded) {\n          eventUtils.domLoaded = true;\n          callback(event);\n        }\n      };\n      if (isDocReady()) {\n        readyHandler();\n      } else {\n        addEvent(win, 'DOMContentLoaded', readyHandler);\n      }\n      addEvent(win, 'load', readyHandler);\n    };\n    var EventUtils = function () {\n      function EventUtils() {\n        this.domLoaded = false;\n        this.events = {};\n        this.count = 1;\n        this.expando = eventExpandoPrefix + (+new Date()).toString(32);\n        this.hasMouseEnterLeave = 'onmouseenter' in domGlobals.document.documentElement;\n        this.hasFocusIn = 'onfocusin' in domGlobals.document.documentElement;\n        this.count = 1;\n      }\n      EventUtils.prototype.bind = function (target, names, callback, scope) {\n        var self = this;\n        var id, callbackList, i, name, fakeName, nativeHandler, capture;\n        var win = domGlobals.window;\n        var defaultNativeHandler = function (evt) {\n          self.executeHandlers(fix(evt || win.event), id);\n        };\n        if (!target || target.nodeType === 3 || target.nodeType === 8) {\n          return;\n        }\n        if (!target[self.expando]) {\n          id = self.count++;\n          target[self.expando] = id;\n          self.events[id] = {};\n        } else {\n          id = target[self.expando];\n        }\n        scope = scope || target;\n        var namesList = names.split(' ');\n        i = namesList.length;\n        while (i--) {\n          name = namesList[i];\n          nativeHandler = defaultNativeHandler;\n          fakeName = capture = false;\n          if (name === 'DOMContentLoaded') {\n            name = 'ready';\n          }\n          if (self.domLoaded && name === 'ready' && target.readyState === 'complete') {\n            callback.call(scope, fix({ type: name }));\n            continue;\n          }\n          if (!self.hasMouseEnterLeave) {\n            fakeName = self.mouseEnterLeave[name];\n            if (fakeName) {\n              nativeHandler = function (evt) {\n                var current, related;\n                current = evt.currentTarget;\n                related = evt.relatedTarget;\n                if (related && current.contains) {\n                  related = current.contains(related);\n                } else {\n                  while (related && related !== current) {\n                    related = related.parentNode;\n                  }\n                }\n                if (!related) {\n                  evt = fix(evt || win.event);\n                  evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter';\n                  evt.target = current;\n                  self.executeHandlers(evt, id);\n                }\n              };\n            }\n          }\n          if (!self.hasFocusIn && (name === 'focusin' || name === 'focusout')) {\n            capture = true;\n            fakeName = name === 'focusin' ? 'focus' : 'blur';\n            nativeHandler = function (evt) {\n              evt = fix(evt || win.event);\n              evt.type = evt.type === 'focus' ? 'focusin' : 'focusout';\n              self.executeHandlers(evt, id);\n            };\n          }\n          callbackList = self.events[id][name];\n          if (!callbackList) {\n            self.events[id][name] = callbackList = [{\n                func: callback,\n                scope: scope\n              }];\n            callbackList.fakeName = fakeName;\n            callbackList.capture = capture;\n            callbackList.nativeHandler = nativeHandler;\n            if (name === 'ready') {\n              bindOnReady(target, nativeHandler, self);\n            } else {\n              addEvent(target, fakeName || name, nativeHandler, capture);\n            }\n          } else {\n            if (name === 'ready' && self.domLoaded) {\n              callback(fix({ type: name }));\n            } else {\n              callbackList.push({\n                func: callback,\n                scope: scope\n              });\n            }\n          }\n        }\n        target = callbackList = 0;\n        return callback;\n      };\n      EventUtils.prototype.unbind = function (target, names, callback) {\n        var id, callbackList, i, ci, name, eventMap;\n        if (!target || target.nodeType === 3 || target.nodeType === 8) {\n          return this;\n        }\n        id = target[this.expando];\n        if (id) {\n          eventMap = this.events[id];\n          if (names) {\n            var namesList = names.split(' ');\n            i = namesList.length;\n            while (i--) {\n              name = namesList[i];\n              callbackList = eventMap[name];\n              if (callbackList) {\n                if (callback) {\n                  ci = callbackList.length;\n                  while (ci--) {\n                    if (callbackList[ci].func === callback) {\n                      var nativeHandler = callbackList.nativeHandler;\n                      var fakeName = callbackList.fakeName, capture = callbackList.capture;\n                      callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1));\n                      callbackList.nativeHandler = nativeHandler;\n                      callbackList.fakeName = fakeName;\n                      callbackList.capture = capture;\n                      eventMap[name] = callbackList;\n                    }\n                  }\n                }\n                if (!callback || callbackList.length === 0) {\n                  delete eventMap[name];\n                  removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);\n                }\n              }\n            }\n          } else {\n            for (name in eventMap) {\n              callbackList = eventMap[name];\n              removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);\n            }\n            eventMap = {};\n          }\n          for (name in eventMap) {\n            return this;\n          }\n          delete this.events[id];\n          try {\n            delete target[this.expando];\n          } catch (ex) {\n            target[this.expando] = null;\n          }\n        }\n        return this;\n      };\n      EventUtils.prototype.fire = function (target, name, args) {\n        var id;\n        if (!target || target.nodeType === 3 || target.nodeType === 8) {\n          return this;\n        }\n        var event = fix(null, args);\n        event.type = name;\n        event.target = target;\n        do {\n          id = target[this.expando];\n          if (id) {\n            this.executeHandlers(event, id);\n          }\n          target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow;\n        } while (target && !event.isPropagationStopped());\n        return this;\n      };\n      EventUtils.prototype.clean = function (target) {\n        var i, children;\n        if (!target || target.nodeType === 3 || target.nodeType === 8) {\n          return this;\n        }\n        if (target[this.expando]) {\n          this.unbind(target);\n        }\n        if (!target.getElementsByTagName) {\n          target = target.document;\n        }\n        if (target && target.getElementsByTagName) {\n          this.unbind(target);\n          children = target.getElementsByTagName('*');\n          i = children.length;\n          while (i--) {\n            target = children[i];\n            if (target[this.expando]) {\n              this.unbind(target);\n            }\n          }\n        }\n        return this;\n      };\n      EventUtils.prototype.destroy = function () {\n        this.events = {};\n      };\n      EventUtils.prototype.cancel = function (e) {\n        if (e) {\n          e.preventDefault();\n          e.stopImmediatePropagation();\n        }\n        return false;\n      };\n      EventUtils.prototype.executeHandlers = function (evt, id) {\n        var callbackList, i, l, callback;\n        var container = this.events[id];\n        callbackList = container && container[evt.type];\n        if (callbackList) {\n          for (i = 0, l = callbackList.length; i < l; i++) {\n            callback = callbackList[i];\n            if (callback && callback.func.call(callback.scope, evt) === false) {\n              evt.preventDefault();\n            }\n            if (evt.isImmediatePropagationStopped()) {\n              return;\n            }\n          }\n        }\n      };\n      EventUtils.Event = new EventUtils();\n      return EventUtils;\n    }();\n\n    var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains$3, expando = 'sizzle' + -new Date(), preferredDoc = domGlobals.window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function (a, b) {\n        if (a === b) {\n          hasDuplicate = true;\n        }\n        return 0;\n      }, strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, indexOf$2 = arr.indexOf || function (elem) {\n        var i = 0, len = this.length;\n        for (; i < len; i++) {\n          if (this[i] === elem) {\n            return i;\n          }\n        }\n        return -1;\n      }, booleans = 'checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped', whitespace = '[\\\\x20\\\\t\\\\r\\\\n\\\\f]', identifier = '(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+', attributes = '\\\\[' + whitespace + '*(' + identifier + ')(?:' + whitespace + '*([*^$|!~]?=)' + whitespace + '*(?:\\'((?:\\\\\\\\.|[^\\\\\\\\\\'])*)\\'|\"((?:\\\\\\\\.|[^\\\\\\\\\"])*)\"|(' + identifier + '))|)' + whitespace + '*\\\\]', pseudos = ':(' + identifier + ')(?:\\\\((' + '(\\'((?:\\\\\\\\.|[^\\\\\\\\\\'])*)\\'|\"((?:\\\\\\\\.|[^\\\\\\\\\"])*)\")|' + '((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|' + attributes + ')*)|' + '.*' + ')\\\\)|)', rtrim = new RegExp('^' + whitespace + '+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)' + whitespace + '+$', 'g'), rcomma = new RegExp('^' + whitespace + '*,' + whitespace + '*'), rcombinators = new RegExp('^' + whitespace + '*([>+~]|' + whitespace + ')' + whitespace + '*'), rattributeQuotes = new RegExp('=' + whitespace + '*([^\\\\]\\'\"]*?)' + whitespace + '*\\\\]', 'g'), rpseudo = new RegExp(pseudos), ridentifier = new RegExp('^' + identifier + '$'), matchExpr = {\n        ID: new RegExp('^#(' + identifier + ')'),\n        CLASS: new RegExp('^\\\\.(' + identifier + ')'),\n        TAG: new RegExp('^(' + identifier + '|[*])'),\n        ATTR: new RegExp('^' + attributes),\n        PSEUDO: new RegExp('^' + pseudos),\n        CHILD: new RegExp('^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(' + whitespace + '*(even|odd|(([+-]|)(\\\\d*)n|)' + whitespace + '*(?:([+-]|)' + whitespace + '*(\\\\d+)|))' + whitespace + '*\\\\)|)', 'i'),\n        bool: new RegExp('^(?:' + booleans + ')$', 'i'),\n        needsContext: new RegExp('^' + whitespace + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(' + whitespace + '*((?:-\\\\d)?\\\\d*)' + whitespace + '*\\\\)|)(?=[^-]|$)', 'i')\n      }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\\d$/i, rnative = /^[^{]+\\{\\s*\\[native \\w/, rquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/, rsibling = /[+~]/, rescape = /'|\\\\/g, runescape = new RegExp('\\\\\\\\([\\\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig'), funescape = function (_, escaped, escapedWhitespace) {\n        var high = '0x' + escaped - 65536;\n        return high !== high || escapedWhitespace ? escaped : high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320);\n      };\n    try {\n      push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);\n      arr[preferredDoc.childNodes.length].nodeType;\n    } catch (e) {\n      push = {\n        apply: arr.length ? function (target, els) {\n          push_native.apply(target, slice.call(els));\n        } : function (target, els) {\n          var j = target.length, i = 0;\n          while (target[j++] = els[i++]) {\n          }\n          target.length = j - 1;\n        }\n      };\n    }\n    var Sizzle = function (selector, context, results, seed) {\n      var match, elem, m, nodeType, i, groups, old, nid, newContext, newSelector;\n      if ((context ? context.ownerDocument || context : preferredDoc) !== document) {\n        setDocument(context);\n      }\n      context = context || document;\n      results = results || [];\n      if (!selector || typeof selector !== 'string') {\n        return results;\n      }\n      if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {\n        return [];\n      }\n      if (documentIsHTML && !seed) {\n        if (match = rquickExpr.exec(selector)) {\n          if (m = match[1]) {\n            if (nodeType === 9) {\n              elem = context.getElementById(m);\n              if (elem && elem.parentNode) {\n                if (elem.id === m) {\n                  results.push(elem);\n                  return results;\n                }\n              } else {\n                return results;\n              }\n            } else {\n              if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) && contains$3(context, elem) && elem.id === m) {\n                results.push(elem);\n                return results;\n              }\n            }\n          } else if (match[2]) {\n            push.apply(results, context.getElementsByTagName(selector));\n            return results;\n          } else if ((m = match[3]) && support.getElementsByClassName) {\n            push.apply(results, context.getElementsByClassName(m));\n            return results;\n          }\n        }\n        if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {\n          nid = old = expando;\n          newContext = context;\n          newSelector = nodeType === 9 && selector;\n          if (nodeType === 1 && context.nodeName.toLowerCase() !== 'object') {\n            groups = tokenize(selector);\n            if (old = context.getAttribute('id')) {\n              nid = old.replace(rescape, '\\\\$&');\n            } else {\n              context.setAttribute('id', nid);\n            }\n            nid = '[id=\\'' + nid + '\\'] ';\n            i = groups.length;\n            while (i--) {\n              groups[i] = nid + toSelector(groups[i]);\n            }\n            newContext = rsibling.test(selector) && testContext(context.parentNode) || context;\n            newSelector = groups.join(',');\n          }\n          if (newSelector) {\n            try {\n              push.apply(results, newContext.querySelectorAll(newSelector));\n              return results;\n            } catch (qsaError) {\n            } finally {\n              if (!old) {\n                context.removeAttribute('id');\n              }\n            }\n          }\n        }\n      }\n      return select(selector.replace(rtrim, '$1'), context, results, seed);\n    };\n    function createCache() {\n      var keys = [];\n      function cache(key, value) {\n        if (keys.push(key + ' ') > Expr.cacheLength) {\n          delete cache[keys.shift()];\n        }\n        return cache[key + ' '] = value;\n      }\n      return cache;\n    }\n    function markFunction(fn) {\n      fn[expando] = true;\n      return fn;\n    }\n    function siblingCheck(a, b) {\n      var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);\n      if (diff) {\n        return diff;\n      }\n      if (cur) {\n        while (cur = cur.nextSibling) {\n          if (cur === b) {\n            return -1;\n          }\n        }\n      }\n      return a ? 1 : -1;\n    }\n    function createInputPseudo(type) {\n      return function (elem) {\n        var name = elem.nodeName.toLowerCase();\n        return name === 'input' && elem.type === type;\n      };\n    }\n    function createButtonPseudo(type) {\n      return function (elem) {\n        var name = elem.nodeName.toLowerCase();\n        return (name === 'input' || name === 'button') && elem.type === type;\n      };\n    }\n    function createPositionalPseudo(fn) {\n      return markFunction(function (argument) {\n        argument = +argument;\n        return markFunction(function (seed, matches) {\n          var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length;\n          while (i--) {\n            if (seed[j = matchIndexes[i]]) {\n              seed[j] = !(matches[j] = seed[j]);\n            }\n          }\n        });\n      });\n    }\n    function testContext(context) {\n      return context && typeof context.getElementsByTagName !== strundefined && context;\n    }\n    support = Sizzle.support = {};\n    isXML = Sizzle.isXML = function (elem) {\n      var documentElement = elem && (elem.ownerDocument || elem).documentElement;\n      return documentElement ? documentElement.nodeName !== 'HTML' : false;\n    };\n    setDocument = Sizzle.setDocument = function (node) {\n      var hasCompare, doc = node ? node.ownerDocument || node : preferredDoc, parent = doc.defaultView;\n      function getTop(win) {\n        try {\n          return win.top;\n        } catch (ex) {\n        }\n        return null;\n      }\n      if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {\n        return document;\n      }\n      document = doc;\n      docElem = doc.documentElement;\n      documentIsHTML = !isXML(doc);\n      if (parent && parent !== getTop(parent)) {\n        if (parent.addEventListener) {\n          parent.addEventListener('unload', function () {\n            setDocument();\n          }, false);\n        } else if (parent.attachEvent) {\n          parent.attachEvent('onunload', function () {\n            setDocument();\n          });\n        }\n      }\n      support.attributes = true;\n      support.getElementsByTagName = true;\n      support.getElementsByClassName = rnative.test(doc.getElementsByClassName);\n      support.getById = true;\n      Expr.find.ID = function (id, context) {\n        if (typeof context.getElementById !== strundefined && documentIsHTML) {\n          var m = context.getElementById(id);\n          return m && m.parentNode ? [m] : [];\n        }\n      };\n      Expr.filter.ID = function (id) {\n        var attrId = id.replace(runescape, funescape);\n        return function (elem) {\n          return elem.getAttribute('id') === attrId;\n        };\n      };\n      Expr.find.TAG = support.getElementsByTagName ? function (tag, context) {\n        if (typeof context.getElementsByTagName !== strundefined) {\n          return context.getElementsByTagName(tag);\n        }\n      } : function (tag, context) {\n        var elem, tmp = [], i = 0, results = context.getElementsByTagName(tag);\n        if (tag === '*') {\n          while (elem = results[i++]) {\n            if (elem.nodeType === 1) {\n              tmp.push(elem);\n            }\n          }\n          return tmp;\n        }\n        return results;\n      };\n      Expr.find.CLASS = support.getElementsByClassName && function (className, context) {\n        if (documentIsHTML) {\n          return context.getElementsByClassName(className);\n        }\n      };\n      rbuggyMatches = [];\n      rbuggyQSA = [];\n      support.disconnectedMatch = true;\n      rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join('|'));\n      rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join('|'));\n      hasCompare = rnative.test(docElem.compareDocumentPosition);\n      contains$3 = hasCompare || rnative.test(docElem.contains) ? function (a, b) {\n        var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode;\n        return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));\n      } : function (a, b) {\n        if (b) {\n          while (b = b.parentNode) {\n            if (b === a) {\n              return true;\n            }\n          }\n        }\n        return false;\n      };\n      sortOrder = hasCompare ? function (a, b) {\n        if (a === b) {\n          hasDuplicate = true;\n          return 0;\n        }\n        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n        if (compare) {\n          return compare;\n        }\n        compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1;\n        if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {\n          if (a === doc || a.ownerDocument === preferredDoc && contains$3(preferredDoc, a)) {\n            return -1;\n          }\n          if (b === doc || b.ownerDocument === preferredDoc && contains$3(preferredDoc, b)) {\n            return 1;\n          }\n          return sortInput ? indexOf$2.call(sortInput, a) - indexOf$2.call(sortInput, b) : 0;\n        }\n        return compare & 4 ? -1 : 1;\n      } : function (a, b) {\n        if (a === b) {\n          hasDuplicate = true;\n          return 0;\n        }\n        var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b];\n        if (!aup || !bup) {\n          return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf$2.call(sortInput, a) - indexOf$2.call(sortInput, b) : 0;\n        } else if (aup === bup) {\n          return siblingCheck(a, b);\n        }\n        cur = a;\n        while (cur = cur.parentNode) {\n          ap.unshift(cur);\n        }\n        cur = b;\n        while (cur = cur.parentNode) {\n          bp.unshift(cur);\n        }\n        while (ap[i] === bp[i]) {\n          i++;\n        }\n        return i ? siblingCheck(ap[i], bp[i]) : ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;\n      };\n      return doc;\n    };\n    Sizzle.matches = function (expr, elements) {\n      return Sizzle(expr, null, null, elements);\n    };\n    Sizzle.matchesSelector = function (elem, expr) {\n      if ((elem.ownerDocument || elem) !== document) {\n        setDocument(elem);\n      }\n      expr = expr.replace(rattributeQuotes, '=\\'$1\\']');\n      if (support.matchesSelector && documentIsHTML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {\n        try {\n          var ret = matches.call(elem, expr);\n          if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) {\n            return ret;\n          }\n        } catch (e) {\n        }\n      }\n      return Sizzle(expr, document, null, [elem]).length > 0;\n    };\n    Sizzle.contains = function (context, elem) {\n      if ((context.ownerDocument || context) !== document) {\n        setDocument(context);\n      }\n      return contains$3(context, elem);\n    };\n    Sizzle.attr = function (elem, name) {\n      if ((elem.ownerDocument || elem) !== document) {\n        setDocument(elem);\n      }\n      var fn = Expr.attrHandle[name.toLowerCase()], val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;\n      return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;\n    };\n    Sizzle.error = function (msg) {\n      throw new Error('Syntax error, unrecognized expression: ' + msg);\n    };\n    Sizzle.uniqueSort = function (results) {\n      var elem, duplicates = [], j = 0, i = 0;\n      hasDuplicate = !support.detectDuplicates;\n      sortInput = !support.sortStable && results.slice(0);\n      results.sort(sortOrder);\n      if (hasDuplicate) {\n        while (elem = results[i++]) {\n          if (elem === results[i]) {\n            j = duplicates.push(i);\n          }\n        }\n        while (j--) {\n          results.splice(duplicates[j], 1);\n        }\n      }\n      sortInput = null;\n      return results;\n    };\n    getText = Sizzle.getText = function (elem) {\n      var node, ret = '', i = 0, nodeType = elem.nodeType;\n      if (!nodeType) {\n        while (node = elem[i++]) {\n          ret += getText(node);\n        }\n      } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {\n        if (typeof elem.textContent === 'string') {\n          return elem.textContent;\n        } else {\n          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {\n            ret += getText(elem);\n          }\n        }\n      } else if (nodeType === 3 || nodeType === 4) {\n        return elem.nodeValue;\n      }\n      return ret;\n    };\n    Expr = Sizzle.selectors = {\n      cacheLength: 50,\n      createPseudo: markFunction,\n      match: matchExpr,\n      attrHandle: {},\n      find: {},\n      relative: {\n        '>': {\n          dir: 'parentNode',\n          first: true\n        },\n        ' ': { dir: 'parentNode' },\n        '+': {\n          dir: 'previousSibling',\n          first: true\n        },\n        '~': { dir: 'previousSibling' }\n      },\n      preFilter: {\n        ATTR: function (match) {\n          match[1] = match[1].replace(runescape, funescape);\n          match[3] = (match[3] || match[4] || match[5] || '').replace(runescape, funescape);\n          if (match[2] === '~=') {\n            match[3] = ' ' + match[3] + ' ';\n          }\n          return match.slice(0, 4);\n        },\n        CHILD: function (match) {\n          match[1] = match[1].toLowerCase();\n          if (match[1].slice(0, 3) === 'nth') {\n            if (!match[3]) {\n              Sizzle.error(match[0]);\n            }\n            match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === 'even' || match[3] === 'odd'));\n            match[5] = +(match[7] + match[8] || match[3] === 'odd');\n          } else if (match[3]) {\n            Sizzle.error(match[0]);\n          }\n          return match;\n        },\n        PSEUDO: function (match) {\n          var excess, unquoted = !match[6] && match[2];\n          if (matchExpr.CHILD.test(match[0])) {\n            return null;\n          }\n          if (match[3]) {\n            match[2] = match[4] || match[5] || '';\n          } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(')', unquoted.length - excess) - unquoted.length)) {\n            match[0] = match[0].slice(0, excess);\n            match[2] = unquoted.slice(0, excess);\n          }\n          return match.slice(0, 3);\n        }\n      },\n      filter: {\n        TAG: function (nodeNameSelector) {\n          var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();\n          return nodeNameSelector === '*' ? function () {\n            return true;\n          } : function (elem) {\n            return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n          };\n        },\n        CLASS: function (className) {\n          var pattern = classCache[className + ' '];\n          return pattern || (pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)')) && classCache(className, function (elem) {\n            return pattern.test(typeof elem.className === 'string' && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute('class') || '');\n          });\n        },\n        ATTR: function (name, operator, check) {\n          return function (elem) {\n            var result = Sizzle.attr(elem, name);\n            if (result == null) {\n              return operator === '!=';\n            }\n            if (!operator) {\n              return true;\n            }\n            result += '';\n            return operator === '=' ? result === check : operator === '!=' ? result !== check : operator === '^=' ? check && result.indexOf(check) === 0 : operator === '*=' ? check && result.indexOf(check) > -1 : operator === '$=' ? check && result.slice(-check.length) === check : operator === '~=' ? (' ' + result + ' ').indexOf(check) > -1 : operator === '|=' ? result === check || result.slice(0, check.length + 1) === check + '-' : false;\n          };\n        },\n        CHILD: function (type, what, argument, first, last) {\n          var simple = type.slice(0, 3) !== 'nth', forward = type.slice(-4) !== 'last', ofType = what === 'of-type';\n          return first === 1 && last === 0 ? function (elem) {\n            return !!elem.parentNode;\n          } : function (elem, context, xml) {\n            var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? 'nextSibling' : 'previousSibling', parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType;\n            if (parent) {\n              if (simple) {\n                while (dir) {\n                  node = elem;\n                  while (node = node[dir]) {\n                    if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {\n                      return false;\n                    }\n                  }\n                  start = dir = type === 'only' && !start && 'nextSibling';\n                }\n                return true;\n              }\n              start = [forward ? parent.firstChild : parent.lastChild];\n              if (forward && useCache) {\n                outerCache = parent[expando] || (parent[expando] = {});\n                cache = outerCache[type] || [];\n                nodeIndex = cache[0] === dirruns && cache[1];\n                diff = cache[0] === dirruns && cache[2];\n                node = nodeIndex && parent.childNodes[nodeIndex];\n                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {\n                  if (node.nodeType === 1 && ++diff && node === elem) {\n                    outerCache[type] = [\n                      dirruns,\n                      nodeIndex,\n                      diff\n                    ];\n                    break;\n                  }\n                }\n              } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {\n                diff = cache[1];\n              } else {\n                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {\n                  if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {\n                    if (useCache) {\n                      (node[expando] || (node[expando] = {}))[type] = [\n                        dirruns,\n                        diff\n                      ];\n                    }\n                    if (node === elem) {\n                      break;\n                    }\n                  }\n                }\n              }\n              diff -= last;\n              return diff === first || diff % first === 0 && diff / first >= 0;\n            }\n          };\n        },\n        PSEUDO: function (pseudo, argument) {\n          var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error('unsupported pseudo: ' + pseudo);\n          if (fn[expando]) {\n            return fn(argument);\n          }\n          if (fn.length > 1) {\n            args = [\n              pseudo,\n              pseudo,\n              '',\n              argument\n            ];\n            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {\n              var idx, matched = fn(seed, argument), i = matched.length;\n              while (i--) {\n                idx = indexOf$2.call(seed, matched[i]);\n                seed[idx] = !(matches[idx] = matched[i]);\n              }\n            }) : function (elem) {\n              return fn(elem, 0, args);\n            };\n          }\n          return fn;\n        }\n      },\n      pseudos: {\n        not: markFunction(function (selector) {\n          var input = [], results = [], matcher = compile(selector.replace(rtrim, '$1'));\n          return matcher[expando] ? markFunction(function (seed, matches, context, xml) {\n            var elem, unmatched = matcher(seed, null, xml, []), i = seed.length;\n            while (i--) {\n              if (elem = unmatched[i]) {\n                seed[i] = !(matches[i] = elem);\n              }\n            }\n          }) : function (elem, context, xml) {\n            input[0] = elem;\n            matcher(input, null, xml, results);\n            return !results.pop();\n          };\n        }),\n        has: markFunction(function (selector) {\n          return function (elem) {\n            return Sizzle(selector, elem).length > 0;\n          };\n        }),\n        contains: markFunction(function (text) {\n          text = text.replace(runescape, funescape);\n          return function (elem) {\n            return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;\n          };\n        }),\n        lang: markFunction(function (lang) {\n          if (!ridentifier.test(lang || '')) {\n            Sizzle.error('unsupported lang: ' + lang);\n          }\n          lang = lang.replace(runescape, funescape).toLowerCase();\n          return function (elem) {\n            var elemLang;\n            do {\n              if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute('xml:lang') || elem.getAttribute('lang')) {\n                elemLang = elemLang.toLowerCase();\n                return elemLang === lang || elemLang.indexOf(lang + '-') === 0;\n              }\n            } while ((elem = elem.parentNode) && elem.nodeType === 1);\n            return false;\n          };\n        }),\n        target: function (elem) {\n          var hash = domGlobals.window.location && domGlobals.window.location.hash;\n          return hash && hash.slice(1) === elem.id;\n        },\n        root: function (elem) {\n          return elem === docElem;\n        },\n        focus: function (elem) {\n          return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n        },\n        enabled: function (elem) {\n          return elem.disabled === false;\n        },\n        disabled: function (elem) {\n          return elem.disabled === true;\n        },\n        checked: function (elem) {\n          var nodeName = elem.nodeName.toLowerCase();\n          return nodeName === 'input' && !!elem.checked || nodeName === 'option' && !!elem.selected;\n        },\n        selected: function (elem) {\n          if (elem.parentNode) {\n            elem.parentNode.selectedIndex;\n          }\n          return elem.selected === true;\n        },\n        empty: function (elem) {\n          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {\n            if (elem.nodeType < 6) {\n              return false;\n            }\n          }\n          return true;\n        },\n        parent: function (elem) {\n          return !Expr.pseudos.empty(elem);\n        },\n        header: function (elem) {\n          return rheader.test(elem.nodeName);\n        },\n        input: function (elem) {\n          return rinputs.test(elem.nodeName);\n        },\n        button: function (elem) {\n          var name = elem.nodeName.toLowerCase();\n          return name === 'input' && elem.type === 'button' || name === 'button';\n        },\n        text: function (elem) {\n          var attr;\n          return elem.nodeName.toLowerCase() === 'input' && elem.type === 'text' && ((attr = elem.getAttribute('type')) == null || attr.toLowerCase() === 'text');\n        },\n        first: createPositionalPseudo(function () {\n          return [0];\n        }),\n        last: createPositionalPseudo(function (matchIndexes, length) {\n          return [length - 1];\n        }),\n        eq: createPositionalPseudo(function (matchIndexes, length, argument) {\n          return [argument < 0 ? argument + length : argument];\n        }),\n        even: createPositionalPseudo(function (matchIndexes, length) {\n          var i = 0;\n          for (; i < length; i += 2) {\n            matchIndexes.push(i);\n          }\n          return matchIndexes;\n        }),\n        odd: createPositionalPseudo(function (matchIndexes, length) {\n          var i = 1;\n          for (; i < length; i += 2) {\n            matchIndexes.push(i);\n          }\n          return matchIndexes;\n        }),\n        lt: createPositionalPseudo(function (matchIndexes, length, argument) {\n          var i = argument < 0 ? argument + length : argument;\n          for (; --i >= 0;) {\n            matchIndexes.push(i);\n          }\n          return matchIndexes;\n        }),\n        gt: createPositionalPseudo(function (matchIndexes, length, argument) {\n          var i = argument < 0 ? argument + length : argument;\n          for (; ++i < length;) {\n            matchIndexes.push(i);\n          }\n          return matchIndexes;\n        })\n      }\n    };\n    Expr.pseudos.nth = Expr.pseudos.eq;\n    for (i in {\n        radio: true,\n        checkbox: true,\n        file: true,\n        password: true,\n        image: true\n      }) {\n      Expr.pseudos[i] = createInputPseudo(i);\n    }\n    for (i in {\n        submit: true,\n        reset: true\n      }) {\n      Expr.pseudos[i] = createButtonPseudo(i);\n    }\n    function setFilters() {\n    }\n    setFilters.prototype = Expr.filters = Expr.pseudos;\n    Expr.setFilters = new setFilters();\n    tokenize = Sizzle.tokenize = function (selector, parseOnly) {\n      var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + ' '];\n      if (cached) {\n        return parseOnly ? 0 : cached.slice(0);\n      }\n      soFar = selector;\n      groups = [];\n      preFilters = Expr.preFilter;\n      while (soFar) {\n        if (!matched || (match = rcomma.exec(soFar))) {\n          if (match) {\n            soFar = soFar.slice(match[0].length) || soFar;\n          }\n          groups.push(tokens = []);\n        }\n        matched = false;\n        if (match = rcombinators.exec(soFar)) {\n          matched = match.shift();\n          tokens.push({\n            value: matched,\n            type: match[0].replace(rtrim, ' ')\n          });\n          soFar = soFar.slice(matched.length);\n        }\n        for (type in Expr.filter) {\n          if (!Expr.filter.hasOwnProperty(type))\n            continue;\n          if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {\n            matched = match.shift();\n            tokens.push({\n              value: matched,\n              type: type,\n              matches: match\n            });\n            soFar = soFar.slice(matched.length);\n          }\n        }\n        if (!matched) {\n          break;\n        }\n      }\n      return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0);\n    };\n    function toSelector(tokens) {\n      var i = 0, len = tokens.length, selector = '';\n      for (; i < len; i++) {\n        selector += tokens[i].value;\n      }\n      return selector;\n    }\n    function addCombinator(matcher, combinator, base) {\n      var dir = combinator.dir, checkNonElements = base && dir === 'parentNode', doneName = done++;\n      return combinator.first ? function (elem, context, xml) {\n        while (elem = elem[dir]) {\n          if (elem.nodeType === 1 || checkNonElements) {\n            return matcher(elem, context, xml);\n          }\n        }\n      } : function (elem, context, xml) {\n        var oldCache, outerCache, newCache = [\n            dirruns,\n            doneName\n          ];\n        if (xml) {\n          while (elem = elem[dir]) {\n            if (elem.nodeType === 1 || checkNonElements) {\n              if (matcher(elem, context, xml)) {\n                return true;\n              }\n            }\n          }\n        } else {\n          while (elem = elem[dir]) {\n            if (elem.nodeType === 1 || checkNonElements) {\n              outerCache = elem[expando] || (elem[expando] = {});\n              if ((oldCache = outerCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) {\n                return newCache[2] = oldCache[2];\n              } else {\n                outerCache[dir] = newCache;\n                if (newCache[2] = matcher(elem, context, xml)) {\n                  return true;\n                }\n              }\n            }\n          }\n        }\n      };\n    }\n    function elementMatcher(matchers) {\n      return matchers.length > 1 ? function (elem, context, xml) {\n        var i = matchers.length;\n        while (i--) {\n          if (!matchers[i](elem, context, xml)) {\n            return false;\n          }\n        }\n        return true;\n      } : matchers[0];\n    }\n    function multipleContexts(selector, contexts, results) {\n      var i = 0, len = contexts.length;\n      for (; i < len; i++) {\n        Sizzle(selector, contexts[i], results);\n      }\n      return results;\n    }\n    function condense(unmatched, map, filter, context, xml) {\n      var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null;\n      for (; i < len; i++) {\n        if (elem = unmatched[i]) {\n          if (!filter || filter(elem, context, xml)) {\n            newUnmatched.push(elem);\n            if (mapped) {\n              map.push(i);\n            }\n          }\n        }\n      }\n      return newUnmatched;\n    }\n    function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {\n      if (postFilter && !postFilter[expando]) {\n        postFilter = setMatcher(postFilter);\n      }\n      if (postFinder && !postFinder[expando]) {\n        postFinder = setMatcher(postFinder, postSelector);\n      }\n      return markFunction(function (seed, results, context, xml) {\n        var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(selector || '*', context.nodeType ? [context] : context, []), matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? postFinder || (seed ? preFilter : preexisting || postFilter) ? [] : results : matcherIn;\n        if (matcher) {\n          matcher(matcherIn, matcherOut, context, xml);\n        }\n        if (postFilter) {\n          temp = condense(matcherOut, postMap);\n          postFilter(temp, [], context, xml);\n          i = temp.length;\n          while (i--) {\n            if (elem = temp[i]) {\n              matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);\n            }\n          }\n        }\n        if (seed) {\n          if (postFinder || preFilter) {\n            if (postFinder) {\n              temp = [];\n              i = matcherOut.length;\n              while (i--) {\n                if (elem = matcherOut[i]) {\n                  temp.push(matcherIn[i] = elem);\n                }\n              }\n              postFinder(null, matcherOut = [], temp, xml);\n            }\n            i = matcherOut.length;\n            while (i--) {\n              if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf$2.call(seed, elem) : preMap[i]) > -1) {\n                seed[temp] = !(results[temp] = elem);\n              }\n            }\n          }\n        } else {\n          matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);\n          if (postFinder) {\n            postFinder(null, results, matcherOut, xml);\n          } else {\n            push.apply(results, matcherOut);\n          }\n        }\n      });\n    }\n    function matcherFromTokens(tokens) {\n      var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[' '], i = leadingRelative ? 1 : 0, matchContext = addCombinator(function (elem) {\n          return elem === checkContext;\n        }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) {\n          return indexOf$2.call(checkContext, elem) > -1;\n        }, implicitRelative, true), matchers = [function (elem, context, xml) {\n            return !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));\n          }];\n      for (; i < len; i++) {\n        if (matcher = Expr.relative[tokens[i].type]) {\n          matchers = [addCombinator(elementMatcher(matchers), matcher)];\n        } else {\n          matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);\n          if (matcher[expando]) {\n            j = ++i;\n            for (; j < len; j++) {\n              if (Expr.relative[tokens[j].type]) {\n                break;\n              }\n            }\n            return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === ' ' ? '*' : '' })).replace(rtrim, '$1'), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));\n          }\n          matchers.push(matcher);\n        }\n      }\n      return elementMatcher(matchers);\n    }\n    function matcherFromGroupMatchers(elementMatchers, setMatchers) {\n      var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) {\n          var elem, j, matcher, matchedCount = 0, i = '0', unmatched = seed && [], setMatched = [], contextBackup = outermostContext, elems = seed || byElement && Expr.find.TAG('*', outermost), dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length;\n          if (outermost) {\n            outermostContext = context !== document && context;\n          }\n          for (; i !== len && (elem = elems[i]) != null; i++) {\n            if (byElement && elem) {\n              j = 0;\n              while (matcher = elementMatchers[j++]) {\n                if (matcher(elem, context, xml)) {\n                  results.push(elem);\n                  break;\n                }\n              }\n              if (outermost) {\n                dirruns = dirrunsUnique;\n              }\n            }\n            if (bySet) {\n              if (elem = !matcher && elem) {\n                matchedCount--;\n              }\n              if (seed) {\n                unmatched.push(elem);\n              }\n            }\n          }\n          matchedCount += i;\n          if (bySet && i !== matchedCount) {\n            j = 0;\n            while (matcher = setMatchers[j++]) {\n              matcher(unmatched, setMatched, context, xml);\n            }\n            if (seed) {\n              if (matchedCount > 0) {\n                while (i--) {\n                  if (!(unmatched[i] || setMatched[i])) {\n                    setMatched[i] = pop.call(results);\n                  }\n                }\n              }\n              setMatched = condense(setMatched);\n            }\n            push.apply(results, setMatched);\n            if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {\n              Sizzle.uniqueSort(results);\n            }\n          }\n          if (outermost) {\n            dirruns = dirrunsUnique;\n            outermostContext = contextBackup;\n          }\n          return unmatched;\n        };\n      return bySet ? markFunction(superMatcher) : superMatcher;\n    }\n    compile = Sizzle.compile = function (selector, match) {\n      var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + ' '];\n      if (!cached) {\n        if (!match) {\n          match = tokenize(selector);\n        }\n        i = match.length;\n        while (i--) {\n          cached = matcherFromTokens(match[i]);\n          if (cached[expando]) {\n            setMatchers.push(cached);\n          } else {\n            elementMatchers.push(cached);\n          }\n        }\n        cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));\n        cached.selector = selector;\n      }\n      return cached;\n    };\n    select = Sizzle.select = function (selector, context, results, seed) {\n      var i, tokens, token, type, find, compiled = typeof selector === 'function' && selector, match = !seed && tokenize(selector = compiled.selector || selector);\n      results = results || [];\n      if (match.length === 1) {\n        tokens = match[0] = match[0].slice(0);\n        if (tokens.length > 2 && (token = tokens[0]).type === 'ID' && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {\n          context = (Expr.find.ID(token.matches[0].replace(runescape, funescape), context) || [])[0];\n          if (!context) {\n            return results;\n          } else if (compiled) {\n            context = context.parentNode;\n          }\n          selector = selector.slice(tokens.shift().value.length);\n        }\n        i = matchExpr.needsContext.test(selector) ? 0 : tokens.length;\n        while (i--) {\n          token = tokens[i];\n          if (Expr.relative[type = token.type]) {\n            break;\n          }\n          if (find = Expr.find[type]) {\n            if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) {\n              tokens.splice(i, 1);\n              selector = seed.length && toSelector(tokens);\n              if (!selector) {\n                push.apply(results, seed);\n                return results;\n              }\n              break;\n            }\n          }\n        }\n      }\n      (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, rsibling.test(selector) && testContext(context.parentNode) || context);\n      return results;\n    };\n    support.sortStable = expando.split('').sort(sortOrder).join('') === expando;\n    support.detectDuplicates = !!hasDuplicate;\n    setDocument();\n    support.sortDetached = true;\n\n    var doc = domGlobals.document, push$1 = Array.prototype.push, slice$1 = Array.prototype.slice;\n    var rquickExpr$1 = /^(?:[^#<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)/;\n    var Event = EventUtils.Event;\n    var skipUniques = Tools.makeMap('children,contents,next,prev');\n    var isDefined = function (obj) {\n      return typeof obj !== 'undefined';\n    };\n    var isString$1 = function (obj) {\n      return typeof obj === 'string';\n    };\n    var isWindow = function (obj) {\n      return obj && obj === obj.window;\n    };\n    var createFragment = function (html, fragDoc) {\n      var frag, node, container;\n      fragDoc = fragDoc || doc;\n      container = fragDoc.createElement('div');\n      frag = fragDoc.createDocumentFragment();\n      container.innerHTML = html;\n      while (node = container.firstChild) {\n        frag.appendChild(node);\n      }\n      return frag;\n    };\n    var domManipulate = function (targetNodes, sourceItem, callback, reverse) {\n      var i;\n      if (isString$1(sourceItem)) {\n        sourceItem = createFragment(sourceItem, getElementDocument(targetNodes[0]));\n      } else if (sourceItem.length && !sourceItem.nodeType) {\n        sourceItem = DomQuery.makeArray(sourceItem);\n        if (reverse) {\n          for (i = sourceItem.length - 1; i >= 0; i--) {\n            domManipulate(targetNodes, sourceItem[i], callback, reverse);\n          }\n        } else {\n          for (i = 0; i < sourceItem.length; i++) {\n            domManipulate(targetNodes, sourceItem[i], callback, reverse);\n          }\n        }\n        return targetNodes;\n      }\n      if (sourceItem.nodeType) {\n        i = targetNodes.length;\n        while (i--) {\n          callback.call(targetNodes[i], sourceItem);\n        }\n      }\n      return targetNodes;\n    };\n    var hasClass = function (node, className) {\n      return node && className && (' ' + node.className + ' ').indexOf(' ' + className + ' ') !== -1;\n    };\n    var wrap = function (elements, wrapper, all) {\n      var lastParent, newWrapper;\n      wrapper = DomQuery(wrapper)[0];\n      elements.each(function () {\n        var self = this;\n        if (!all || lastParent !== self.parentNode) {\n          lastParent = self.parentNode;\n          newWrapper = wrapper.cloneNode(false);\n          self.parentNode.insertBefore(newWrapper, self);\n          newWrapper.appendChild(self);\n        } else {\n          newWrapper.appendChild(self);\n        }\n      });\n      return elements;\n    };\n    var numericCssMap = Tools.makeMap('fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom', ' ');\n    var booleanMap = Tools.makeMap('checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected', ' ');\n    var propFix = {\n      for: 'htmlFor',\n      class: 'className',\n      readonly: 'readOnly'\n    };\n    var cssFix = { float: 'cssFloat' };\n    var attrHooks = {}, cssHooks = {};\n    var DomQueryConstructor = function (selector, context) {\n      return new DomQuery.fn.init(selector, context);\n    };\n    var inArray$1 = function (item, array) {\n      var i;\n      if (array.indexOf) {\n        return array.indexOf(item);\n      }\n      i = array.length;\n      while (i--) {\n        if (array[i] === item) {\n          return i;\n        }\n      }\n      return -1;\n    };\n    var whiteSpaceRegExp$1 = /^\\s*|\\s*$/g;\n    var trim$2 = function (str) {\n      return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp$1, '');\n    };\n    var each$4 = function (obj, callback) {\n      var length, key, i, value;\n      if (obj) {\n        length = obj.length;\n        if (length === undefined) {\n          for (key in obj) {\n            if (obj.hasOwnProperty(key)) {\n              value = obj[key];\n              if (callback.call(value, key, value) === false) {\n                break;\n              }\n            }\n          }\n        } else {\n          for (i = 0; i < length; i++) {\n            value = obj[i];\n            if (callback.call(value, i, value) === false) {\n              break;\n            }\n          }\n        }\n      }\n      return obj;\n    };\n    var grep = function (array, callback) {\n      var out = [];\n      each$4(array, function (i, item) {\n        if (callback(item, i)) {\n          out.push(item);\n        }\n      });\n      return out;\n    };\n    var getElementDocument = function (element) {\n      if (!element) {\n        return doc;\n      }\n      if (element.nodeType === 9) {\n        return element;\n      }\n      return element.ownerDocument;\n    };\n    DomQueryConstructor.fn = DomQueryConstructor.prototype = {\n      constructor: DomQueryConstructor,\n      selector: '',\n      context: null,\n      length: 0,\n      init: function (selector, context) {\n        var self = this;\n        var match, node;\n        if (!selector) {\n          return self;\n        }\n        if (selector.nodeType) {\n          self.context = self[0] = selector;\n          self.length = 1;\n          return self;\n        }\n        if (context && context.nodeType) {\n          self.context = context;\n        } else {\n          if (context) {\n            return DomQuery(selector).attr(context);\n          }\n          self.context = context = domGlobals.document;\n        }\n        if (isString$1(selector)) {\n          self.selector = selector;\n          if (selector.charAt(0) === '<' && selector.charAt(selector.length - 1) === '>' && selector.length >= 3) {\n            match = [\n              null,\n              selector,\n              null\n            ];\n          } else {\n            match = rquickExpr$1.exec(selector);\n          }\n          if (match) {\n            if (match[1]) {\n              node = createFragment(selector, getElementDocument(context)).firstChild;\n              while (node) {\n                push$1.call(self, node);\n                node = node.nextSibling;\n              }\n            } else {\n              node = getElementDocument(context).getElementById(match[2]);\n              if (!node) {\n                return self;\n              }\n              if (node.id !== match[2]) {\n                return self.find(selector);\n              }\n              self.length = 1;\n              self[0] = node;\n            }\n          } else {\n            return DomQuery(context).find(selector);\n          }\n        } else {\n          this.add(selector, false);\n        }\n        return self;\n      },\n      toArray: function () {\n        return Tools.toArray(this);\n      },\n      add: function (items, sort) {\n        var self = this;\n        var nodes, i;\n        if (isString$1(items)) {\n          return self.add(DomQuery(items));\n        }\n        if (sort !== false) {\n          nodes = DomQuery.unique(self.toArray().concat(DomQuery.makeArray(items)));\n          self.length = nodes.length;\n          for (i = 0; i < nodes.length; i++) {\n            self[i] = nodes[i];\n          }\n        } else {\n          push$1.apply(self, DomQuery.makeArray(items));\n        }\n        return self;\n      },\n      attr: function (name, value) {\n        var self = this;\n        var hook;\n        if (typeof name === 'object') {\n          each$4(name, function (name, value) {\n            self.attr(name, value);\n          });\n        } else if (isDefined(value)) {\n          this.each(function () {\n            var hook;\n            if (this.nodeType === 1) {\n              hook = attrHooks[name];\n              if (hook && hook.set) {\n                hook.set(this, value);\n                return;\n              }\n              if (value === null) {\n                this.removeAttribute(name, 2);\n              } else {\n                this.setAttribute(name, value, 2);\n              }\n            }\n          });\n        } else {\n          if (self[0] && self[0].nodeType === 1) {\n            hook = attrHooks[name];\n            if (hook && hook.get) {\n              return hook.get(self[0], name);\n            }\n            if (booleanMap[name]) {\n              return self.prop(name) ? name : undefined;\n            }\n            value = self[0].getAttribute(name, 2);\n            if (value === null) {\n              value = undefined;\n            }\n          }\n          return value;\n        }\n        return self;\n      },\n      removeAttr: function (name) {\n        return this.attr(name, null);\n      },\n      prop: function (name, value) {\n        var self = this;\n        name = propFix[name] || name;\n        if (typeof name === 'object') {\n          each$4(name, function (name, value) {\n            self.prop(name, value);\n          });\n        } else if (isDefined(value)) {\n          this.each(function () {\n            if (this.nodeType === 1) {\n              this[name] = value;\n            }\n          });\n        } else {\n          if (self[0] && self[0].nodeType && name in self[0]) {\n            return self[0][name];\n          }\n          return value;\n        }\n        return self;\n      },\n      css: function (name, value) {\n        var self = this;\n        var elm, hook;\n        var camel = function (name) {\n          return name.replace(/-(\\D)/g, function (a, b) {\n            return b.toUpperCase();\n          });\n        };\n        var dashed = function (name) {\n          return name.replace(/[A-Z]/g, function (a) {\n            return '-' + a;\n          });\n        };\n        if (typeof name === 'object') {\n          each$4(name, function (name, value) {\n            self.css(name, value);\n          });\n        } else {\n          if (isDefined(value)) {\n            name = camel(name);\n            if (typeof value === 'number' && !numericCssMap[name]) {\n              value = value.toString() + 'px';\n            }\n            self.each(function () {\n              var style = this.style;\n              hook = cssHooks[name];\n              if (hook && hook.set) {\n                hook.set(this, value);\n                return;\n              }\n              try {\n                this.style[cssFix[name] || name] = value;\n              } catch (ex) {\n              }\n              if (value === null || value === '') {\n                if (style.removeProperty) {\n                  style.removeProperty(dashed(name));\n                } else {\n                  style.removeAttribute(name);\n                }\n              }\n            });\n          } else {\n            elm = self[0];\n            hook = cssHooks[name];\n            if (hook && hook.get) {\n              return hook.get(elm);\n            }\n            if (elm.ownerDocument.defaultView) {\n              try {\n                return elm.ownerDocument.defaultView.getComputedStyle(elm, null).getPropertyValue(dashed(name));\n              } catch (ex) {\n                return undefined;\n              }\n            } else if (elm.currentStyle) {\n              return elm.currentStyle[camel(name)];\n            } else {\n              return '';\n            }\n          }\n        }\n        return self;\n      },\n      remove: function () {\n        var self = this;\n        var node, i = this.length;\n        while (i--) {\n          node = self[i];\n          Event.clean(node);\n          if (node.parentNode) {\n            node.parentNode.removeChild(node);\n          }\n        }\n        return this;\n      },\n      empty: function () {\n        var self = this;\n        var node, i = this.length;\n        while (i--) {\n          node = self[i];\n          while (node.firstChild) {\n            node.removeChild(node.firstChild);\n          }\n        }\n        return this;\n      },\n      html: function (value) {\n        var self = this;\n        var i;\n        if (isDefined(value)) {\n          i = self.length;\n          try {\n            while (i--) {\n              self[i].innerHTML = value;\n            }\n          } catch (ex) {\n            DomQuery(self[i]).empty().append(value);\n          }\n          return self;\n        }\n        return self[0] ? self[0].innerHTML : '';\n      },\n      text: function (value) {\n        var self = this;\n        var i;\n        if (isDefined(value)) {\n          i = self.length;\n          while (i--) {\n            if ('innerText' in self[i]) {\n              self[i].innerText = value;\n            } else {\n              self[0].textContent = value;\n            }\n          }\n          return self;\n        }\n        return self[0] ? self[0].innerText || self[0].textContent : '';\n      },\n      append: function () {\n        return domManipulate(this, arguments, function (node) {\n          if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {\n            this.appendChild(node);\n          }\n        });\n      },\n      prepend: function () {\n        return domManipulate(this, arguments, function (node) {\n          if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {\n            this.insertBefore(node, this.firstChild);\n          }\n        }, true);\n      },\n      before: function () {\n        var self = this;\n        if (self[0] && self[0].parentNode) {\n          return domManipulate(self, arguments, function (node) {\n            this.parentNode.insertBefore(node, this);\n          });\n        }\n        return self;\n      },\n      after: function () {\n        var self = this;\n        if (self[0] && self[0].parentNode) {\n          return domManipulate(self, arguments, function (node) {\n            this.parentNode.insertBefore(node, this.nextSibling);\n          }, true);\n        }\n        return self;\n      },\n      appendTo: function (val) {\n        DomQuery(val).append(this);\n        return this;\n      },\n      prependTo: function (val) {\n        DomQuery(val).prepend(this);\n        return this;\n      },\n      replaceWith: function (content) {\n        return this.before(content).remove();\n      },\n      wrap: function (content) {\n        return wrap(this, content);\n      },\n      wrapAll: function (content) {\n        return wrap(this, content, true);\n      },\n      wrapInner: function (content) {\n        this.each(function () {\n          DomQuery(this).contents().wrapAll(content);\n        });\n        return this;\n      },\n      unwrap: function () {\n        return this.parent().each(function () {\n          DomQuery(this).replaceWith(this.childNodes);\n        });\n      },\n      clone: function () {\n        var result = [];\n        this.each(function () {\n          result.push(this.cloneNode(true));\n        });\n        return DomQuery(result);\n      },\n      addClass: function (className) {\n        return this.toggleClass(className, true);\n      },\n      removeClass: function (className) {\n        return this.toggleClass(className, false);\n      },\n      toggleClass: function (className, state) {\n        var self = this;\n        if (typeof className !== 'string') {\n          return self;\n        }\n        if (className.indexOf(' ') !== -1) {\n          each$4(className.split(' '), function () {\n            self.toggleClass(this, state);\n          });\n        } else {\n          self.each(function (index, node) {\n            var existingClassName, classState;\n            classState = hasClass(node, className);\n            if (classState !== state) {\n              existingClassName = node.className;\n              if (classState) {\n                node.className = trim$2((' ' + existingClassName + ' ').replace(' ' + className + ' ', ' '));\n              } else {\n                node.className += existingClassName ? ' ' + className : className;\n              }\n            }\n          });\n        }\n        return self;\n      },\n      hasClass: function (className) {\n        return hasClass(this[0], className);\n      },\n      each: function (callback) {\n        return each$4(this, callback);\n      },\n      on: function (name, callback) {\n        return this.each(function () {\n          Event.bind(this, name, callback);\n        });\n      },\n      off: function (name, callback) {\n        return this.each(function () {\n          Event.unbind(this, name, callback);\n        });\n      },\n      trigger: function (name) {\n        return this.each(function () {\n          if (typeof name === 'object') {\n            Event.fire(this, name.type, name);\n          } else {\n            Event.fire(this, name);\n          }\n        });\n      },\n      show: function () {\n        return this.css('display', '');\n      },\n      hide: function () {\n        return this.css('display', 'none');\n      },\n      slice: function () {\n        return new DomQuery(slice$1.apply(this, arguments));\n      },\n      eq: function (index) {\n        return index === -1 ? this.slice(index) : this.slice(index, +index + 1);\n      },\n      first: function () {\n        return this.eq(0);\n      },\n      last: function () {\n        return this.eq(-1);\n      },\n      find: function (selector) {\n        var i, l;\n        var ret = [];\n        for (i = 0, l = this.length; i < l; i++) {\n          DomQuery.find(selector, this[i], ret);\n        }\n        return DomQuery(ret);\n      },\n      filter: function (selector) {\n        if (typeof selector === 'function') {\n          return DomQuery(grep(this.toArray(), function (item, i) {\n            return selector(i, item);\n          }));\n        }\n        return DomQuery(DomQuery.filter(selector, this.toArray()));\n      },\n      closest: function (selector) {\n        var result = [];\n        if (selector instanceof DomQuery) {\n          selector = selector[0];\n        }\n        this.each(function (i, node) {\n          while (node) {\n            if (typeof selector === 'string' && DomQuery(node).is(selector)) {\n              result.push(node);\n              break;\n            } else if (node === selector) {\n              result.push(node);\n              break;\n            }\n            node = node.parentNode;\n          }\n        });\n        return DomQuery(result);\n      },\n      offset: function (offset) {\n        var elm, doc, docElm;\n        var x = 0, y = 0, pos;\n        if (!offset) {\n          elm = this[0];\n          if (elm) {\n            doc = elm.ownerDocument;\n            docElm = doc.documentElement;\n            if (elm.getBoundingClientRect) {\n              pos = elm.getBoundingClientRect();\n              x = pos.left + (docElm.scrollLeft || doc.body.scrollLeft) - docElm.clientLeft;\n              y = pos.top + (docElm.scrollTop || doc.body.scrollTop) - docElm.clientTop;\n            }\n          }\n          return {\n            left: x,\n            top: y\n          };\n        }\n        return this.css(offset);\n      },\n      push: push$1,\n      sort: Array.prototype.sort,\n      splice: Array.prototype.splice\n    };\n    Tools.extend(DomQueryConstructor, {\n      extend: Tools.extend,\n      makeArray: function (object) {\n        if (isWindow(object) || object.nodeType) {\n          return [object];\n        }\n        return Tools.toArray(object);\n      },\n      inArray: inArray$1,\n      isArray: Tools.isArray,\n      each: each$4,\n      trim: trim$2,\n      grep: grep,\n      find: Sizzle,\n      expr: Sizzle.selectors,\n      unique: Sizzle.uniqueSort,\n      text: Sizzle.getText,\n      contains: Sizzle.contains,\n      filter: function (expr, elems, not) {\n        var i = elems.length;\n        if (not) {\n          expr = ':not(' + expr + ')';\n        }\n        while (i--) {\n          if (elems[i].nodeType !== 1) {\n            elems.splice(i, 1);\n          }\n        }\n        if (elems.length === 1) {\n          elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [];\n        } else {\n          elems = DomQuery.find.matches(expr, elems);\n        }\n        return elems;\n      }\n    });\n    var dir = function (el, prop, until) {\n      var matched = [];\n      var cur = el[prop];\n      if (typeof until !== 'string' && until instanceof DomQuery) {\n        until = until[0];\n      }\n      while (cur && cur.nodeType !== 9) {\n        if (until !== undefined) {\n          if (cur === until) {\n            break;\n          }\n          if (typeof until === 'string' && DomQuery(cur).is(until)) {\n            break;\n          }\n        }\n        if (cur.nodeType === 1) {\n          matched.push(cur);\n        }\n        cur = cur[prop];\n      }\n      return matched;\n    };\n    var sibling = function (node, siblingName, nodeType, until) {\n      var result = [];\n      if (until instanceof DomQuery) {\n        until = until[0];\n      }\n      for (; node; node = node[siblingName]) {\n        if (nodeType && node.nodeType !== nodeType) {\n          continue;\n        }\n        if (until !== undefined) {\n          if (node === until) {\n            break;\n          }\n          if (typeof until === 'string' && DomQuery(node).is(until)) {\n            break;\n          }\n        }\n        result.push(node);\n      }\n      return result;\n    };\n    var firstSibling = function (node, siblingName, nodeType) {\n      for (node = node[siblingName]; node; node = node[siblingName]) {\n        if (node.nodeType === nodeType) {\n          return node;\n        }\n      }\n      return null;\n    };\n    each$4({\n      parent: function (node) {\n        var parent = node.parentNode;\n        return parent && parent.nodeType !== 11 ? parent : null;\n      },\n      parents: function (node) {\n        return dir(node, 'parentNode');\n      },\n      next: function (node) {\n        return firstSibling(node, 'nextSibling', 1);\n      },\n      prev: function (node) {\n        return firstSibling(node, 'previousSibling', 1);\n      },\n      children: function (node) {\n        return sibling(node.firstChild, 'nextSibling', 1);\n      },\n      contents: function (node) {\n        return Tools.toArray((node.nodeName === 'iframe' ? node.contentDocument || node.contentWindow.document : node).childNodes);\n      }\n    }, function (name, fn) {\n      DomQueryConstructor.fn[name] = function (selector) {\n        var self = this;\n        var result = [];\n        self.each(function () {\n          var nodes = fn.call(result, this, selector, result);\n          if (nodes) {\n            if (DomQuery.isArray(nodes)) {\n              result.push.apply(result, nodes);\n            } else {\n              result.push(nodes);\n            }\n          }\n        });\n        if (this.length > 1) {\n          if (!skipUniques[name]) {\n            result = DomQuery.unique(result);\n          }\n          if (name.indexOf('parents') === 0) {\n            result = result.reverse();\n          }\n        }\n        var wrappedResult = DomQuery(result);\n        if (selector) {\n          return wrappedResult.filter(selector);\n        }\n        return wrappedResult;\n      };\n    });\n    each$4({\n      parentsUntil: function (node, until) {\n        return dir(node, 'parentNode', until);\n      },\n      nextUntil: function (node, until) {\n        return sibling(node, 'nextSibling', 1, until).slice(1);\n      },\n      prevUntil: function (node, until) {\n        return sibling(node, 'previousSibling', 1, until).slice(1);\n      }\n    }, function (name, fn) {\n      DomQueryConstructor.fn[name] = function (selector, filter) {\n        var self = this;\n        var result = [];\n        self.each(function () {\n          var nodes = fn.call(result, this, selector, result);\n          if (nodes) {\n            if (DomQuery.isArray(nodes)) {\n              result.push.apply(result, nodes);\n            } else {\n              result.push(nodes);\n            }\n          }\n        });\n        if (this.length > 1) {\n          result = DomQuery.unique(result);\n          if (name.indexOf('parents') === 0 || name === 'prevUntil') {\n            result = result.reverse();\n          }\n        }\n        var wrappedResult = DomQuery(result);\n        if (filter) {\n          return wrappedResult.filter(filter);\n        }\n        return wrappedResult;\n      };\n    });\n    DomQueryConstructor.fn.is = function (selector) {\n      return !!selector && this.filter(selector).length > 0;\n    };\n    DomQueryConstructor.fn.init.prototype = DomQueryConstructor.fn;\n    DomQueryConstructor.overrideDefaults = function (callback) {\n      var defaults;\n      var sub = function (selector, context) {\n        defaults = defaults || callback();\n        if (arguments.length === 0) {\n          selector = defaults.element;\n        }\n        if (!context) {\n          context = defaults.context;\n        }\n        return new sub.fn.init(selector, context);\n      };\n      DomQuery.extend(sub, this);\n      return sub;\n    };\n    DomQueryConstructor.attrHooks = attrHooks;\n    DomQueryConstructor.cssHooks = cssHooks;\n    var DomQuery = DomQueryConstructor;\n\n    var TreeWalker = function () {\n      function TreeWalker(startNode, rootNode) {\n        this.node = startNode;\n        this.rootNode = rootNode;\n        this.current = this.current.bind(this);\n        this.next = this.next.bind(this);\n        this.prev = this.prev.bind(this);\n        this.prev2 = this.prev2.bind(this);\n      }\n      TreeWalker.prototype.current = function () {\n        return this.node;\n      };\n      TreeWalker.prototype.next = function (shallow) {\n        this.node = this.findSibling(this.node, 'firstChild', 'nextSibling', shallow);\n        return this.node;\n      };\n      TreeWalker.prototype.prev = function (shallow) {\n        this.node = this.findSibling(this.node, 'lastChild', 'previousSibling', shallow);\n        return this.node;\n      };\n      TreeWalker.prototype.prev2 = function (shallow) {\n        this.node = this.findPreviousNode(this.node, 'lastChild', 'previousSibling', shallow);\n        return this.node;\n      };\n      TreeWalker.prototype.findSibling = function (node, startName, siblingName, shallow) {\n        var sibling, parent;\n        if (node) {\n          if (!shallow && node[startName]) {\n            return node[startName];\n          }\n          if (node !== this.rootNode) {\n            sibling = node[siblingName];\n            if (sibling) {\n              return sibling;\n            }\n            for (parent = node.parentNode; parent && parent !== this.rootNode; parent = parent.parentNode) {\n              sibling = parent[siblingName];\n              if (sibling) {\n                return sibling;\n              }\n            }\n          }\n        }\n      };\n      TreeWalker.prototype.findPreviousNode = function (node, startName, siblingName, shallow) {\n        var sibling, parent, child;\n        if (node) {\n          sibling = node[siblingName];\n          if (this.rootNode && sibling === this.rootNode) {\n            return;\n          }\n          if (sibling) {\n            if (!shallow) {\n              for (child = sibling[startName]; child; child = child[startName]) {\n                if (!child[startName]) {\n                  return child;\n                }\n              }\n            }\n            return sibling;\n          }\n          parent = node.parentNode;\n          if (parent && parent !== this.rootNode) {\n            return parent;\n          }\n        }\n      };\n      return TreeWalker;\n    }();\n\n    var before = function (marker, element) {\n      var parent$1 = parent(marker);\n      parent$1.each(function (v) {\n        v.dom().insertBefore(element.dom(), marker.dom());\n      });\n    };\n    var after = function (marker, element) {\n      var sibling = nextSibling(marker);\n      sibling.fold(function () {\n        var parent$1 = parent(marker);\n        parent$1.each(function (v) {\n          append(v, element);\n        });\n      }, function (v) {\n        before(v, element);\n      });\n    };\n    var prepend = function (parent, element) {\n      var firstChild$1 = firstChild(parent);\n      firstChild$1.fold(function () {\n        append(parent, element);\n      }, function (v) {\n        parent.dom().insertBefore(element.dom(), v.dom());\n      });\n    };\n    var append = function (parent, element) {\n      parent.dom().appendChild(element.dom());\n    };\n    var wrap$1 = function (element, wrapper) {\n      before(element, wrapper);\n      append(wrapper, element);\n    };\n\n    var before$1 = function (marker, elements) {\n      each(elements, function (x) {\n        before(marker, x);\n      });\n    };\n    var append$1 = function (parent, elements) {\n      each(elements, function (x) {\n        append(parent, x);\n      });\n    };\n\n    var empty = function (element) {\n      element.dom().textContent = '';\n      each(children(element), function (rogue) {\n        remove$1(rogue);\n      });\n    };\n    var remove$1 = function (element) {\n      var dom = element.dom();\n      if (dom.parentNode !== null) {\n        dom.parentNode.removeChild(dom);\n      }\n    };\n    var unwrap = function (wrapper) {\n      var children$1 = children(wrapper);\n      if (children$1.length > 0) {\n        before$1(wrapper, children$1);\n      }\n      remove$1(wrapper);\n    };\n\n    var r = function (left, top) {\n      var translate = function (x, y) {\n        return r(left + x, top + y);\n      };\n      return {\n        left: constant(left),\n        top: constant(top),\n        translate: translate\n      };\n    };\n    var Position$1 = r;\n\n    var boxPosition = function (dom) {\n      var box = dom.getBoundingClientRect();\n      return Position$1(box.left, box.top);\n    };\n    var firstDefinedOrZero = function (a, b) {\n      return a !== undefined ? a : b !== undefined ? b : 0;\n    };\n    var absolute = function (element) {\n      var doc = element.dom().ownerDocument;\n      var body = doc.body;\n      var win = doc.defaultView;\n      var html = doc.documentElement;\n      if (body === element.dom()) {\n        return Position$1(body.offsetLeft, body.offsetTop);\n      }\n      var scrollTop = firstDefinedOrZero(win.pageYOffset, html.scrollTop);\n      var scrollLeft = firstDefinedOrZero(win.pageXOffset, html.scrollLeft);\n      var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);\n      var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);\n      return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);\n    };\n    var viewport = function (element) {\n      var dom = element.dom();\n      var doc = dom.ownerDocument;\n      var body = doc.body;\n      if (body === dom) {\n        return Position$1(body.offsetLeft, body.offsetTop);\n      }\n      if (!inBody(element)) {\n        return Position$1(0, 0);\n      }\n      return boxPosition(dom);\n    };\n\n    var isSafari = detect$3().browser.isSafari();\n    var get$3 = function (_DOC) {\n      var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document;\n      var x = doc.body.scrollLeft || doc.documentElement.scrollLeft;\n      var y = doc.body.scrollTop || doc.documentElement.scrollTop;\n      return Position$1(x, y);\n    };\n    var to = function (x, y, _DOC) {\n      var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document;\n      var win = doc.defaultView;\n      win.scrollTo(x, y);\n    };\n    var intoView = function (element, alignToTop) {\n      if (isSafari && isFunction(element.dom().scrollIntoViewIfNeeded)) {\n        element.dom().scrollIntoViewIfNeeded(false);\n      } else {\n        element.dom().scrollIntoView(alignToTop);\n      }\n    };\n\n    var bounds = function (x, y, width, height) {\n      return {\n        x: constant(x),\n        y: constant(y),\n        width: constant(width),\n        height: constant(height),\n        right: constant(x + width),\n        bottom: constant(y + height)\n      };\n    };\n    var getBounds = function (_win) {\n      var win = _win === undefined ? domGlobals.window : _win;\n      var doc = win.document;\n      var scroll = get$3(Element.fromDom(doc));\n      var visualViewport = win['visualViewport'];\n      if (visualViewport !== undefined) {\n        return bounds(Math.max(visualViewport.pageLeft, scroll.left()), Math.max(visualViewport.pageTop, scroll.top()), visualViewport.width, visualViewport.height);\n      } else {\n        var html = doc.documentElement;\n        var width = html.clientWidth;\n        var height = html.clientHeight;\n        return bounds(scroll.left(), scroll.top(), width, height);\n      }\n    };\n\n    var each$5 = Tools.each;\n    var grep$1 = Tools.grep;\n    var isIE = Env.ie;\n    var simpleSelectorRe = /^([a-z0-9],?)+$/i;\n    var whiteSpaceRegExp$2 = /^[ \\t\\r\\n]*$/;\n    var setupAttrHooks = function (styles, settings, getContext) {\n      var keepValues = settings.keep_values;\n      var keepUrlHook = {\n        set: function ($elm, value, name) {\n          if (settings.url_converter) {\n            value = settings.url_converter.call(settings.url_converter_scope || getContext(), value, name, $elm[0]);\n          }\n          $elm.attr('data-mce-' + name, value).attr(name, value);\n        },\n        get: function ($elm, name) {\n          return $elm.attr('data-mce-' + name) || $elm.attr(name);\n        }\n      };\n      var attrHooks = {\n        style: {\n          set: function ($elm, value) {\n            if (value !== null && typeof value === 'object') {\n              $elm.css(value);\n              return;\n            }\n            if (keepValues) {\n              $elm.attr('data-mce-style', value);\n            }\n            $elm.attr('style', value);\n          },\n          get: function ($elm) {\n            var value = $elm.attr('data-mce-style') || $elm.attr('style');\n            value = styles.serialize(styles.parse(value), $elm[0].nodeName);\n            return value;\n          }\n        }\n      };\n      if (keepValues) {\n        attrHooks.href = attrHooks.src = keepUrlHook;\n      }\n      return attrHooks;\n    };\n    var updateInternalStyleAttr = function (styles, $elm) {\n      var rawValue = $elm.attr('style');\n      var value = styles.serialize(styles.parse(rawValue), $elm[0].nodeName);\n      if (!value) {\n        value = null;\n      }\n      $elm.attr('data-mce-style', value);\n    };\n    var findNodeIndex = function (node, normalized) {\n      var idx = 0, lastNodeType, nodeType;\n      if (node) {\n        for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) {\n          nodeType = node.nodeType;\n          if (normalized && nodeType === 3) {\n            if (nodeType === lastNodeType || !node.nodeValue.length) {\n              continue;\n            }\n          }\n          idx++;\n          lastNodeType = nodeType;\n        }\n      }\n      return idx;\n    };\n    function DOMUtils(doc, settings) {\n      var _this = this;\n      if (settings === void 0) {\n        settings = {};\n      }\n      var attrHooks;\n      var addedStyles = {};\n      var win = domGlobals.window;\n      var files = {};\n      var counter = 0;\n      var stdMode = true;\n      var boxModel = true;\n      var styleSheetLoader = StyleSheetLoader(doc, {\n        contentCssCors: settings.contentCssCors,\n        referrerPolicy: settings.referrerPolicy\n      });\n      var boundEvents = [];\n      var schema = settings.schema ? settings.schema : Schema({});\n      var styles = Styles({\n        url_converter: settings.url_converter,\n        url_converter_scope: settings.url_converter_scope\n      }, settings.schema);\n      var events = settings.ownEvents ? new EventUtils() : EventUtils.Event;\n      var blockElementsMap = schema.getBlockElements();\n      var $ = DomQuery.overrideDefaults(function () {\n        return {\n          context: doc,\n          element: self.getRoot()\n        };\n      });\n      var isBlock = function (node) {\n        if (typeof node === 'string') {\n          return !!blockElementsMap[node];\n        } else if (node) {\n          var type = node.nodeType;\n          if (type) {\n            return !!(type === 1 && blockElementsMap[node.nodeName]);\n          }\n        }\n        return false;\n      };\n      var get = function (elm) {\n        if (elm && doc && typeof elm === 'string') {\n          var node = doc.getElementById(elm);\n          if (node && node.id !== elm) {\n            return doc.getElementsByName(elm)[1];\n          } else {\n            return node;\n          }\n        }\n        return elm;\n      };\n      var $$ = function (elm) {\n        if (typeof elm === 'string') {\n          elm = get(elm);\n        }\n        return $(elm);\n      };\n      var getAttrib = function (elm, name, defaultVal) {\n        var hook, value;\n        var $elm = $$(elm);\n        if ($elm.length) {\n          hook = attrHooks[name];\n          if (hook && hook.get) {\n            value = hook.get($elm, name);\n          } else {\n            value = $elm.attr(name);\n          }\n        }\n        if (typeof value === 'undefined') {\n          value = defaultVal || '';\n        }\n        return value;\n      };\n      var getAttribs = function (elm) {\n        var node = get(elm);\n        if (!node) {\n          return [];\n        }\n        return node.attributes;\n      };\n      var setAttrib = function (elm, name, value) {\n        var originalValue, hook;\n        if (value === '') {\n          value = null;\n        }\n        var $elm = $$(elm);\n        originalValue = $elm.attr(name);\n        if (!$elm.length) {\n          return;\n        }\n        hook = attrHooks[name];\n        if (hook && hook.set) {\n          hook.set($elm, value, name);\n        } else {\n          $elm.attr(name, value);\n        }\n        if (originalValue !== value && settings.onSetAttrib) {\n          settings.onSetAttrib({\n            attrElm: $elm,\n            attrName: name,\n            attrValue: value\n          });\n        }\n      };\n      var clone = function (node, deep) {\n        if (!isIE || node.nodeType !== 1 || deep) {\n          return node.cloneNode(deep);\n        }\n        if (!deep) {\n          var clone_1 = doc.createElement(node.nodeName);\n          each$5(getAttribs(node), function (attr) {\n            setAttrib(clone_1, attr.nodeName, getAttrib(node, attr.nodeName));\n          });\n          return clone_1;\n        }\n        return null;\n      };\n      var getRoot = function () {\n        return settings.root_element || doc.body;\n      };\n      var getViewPort = function (argWin) {\n        var vp = getBounds(argWin);\n        return {\n          x: vp.x(),\n          y: vp.y(),\n          w: vp.width(),\n          h: vp.height()\n        };\n      };\n      var getPos = function (elm, rootElm) {\n        return Position.getPos(doc.body, get(elm), rootElm);\n      };\n      var setStyle = function (elm, name, value) {\n        var $elm = isString(name) ? $$(elm).css(name, value) : $$(elm).css(name);\n        if (settings.update_styles) {\n          updateInternalStyleAttr(styles, $elm);\n        }\n      };\n      var setStyles = function (elm, stylesArg) {\n        var $elm = $$(elm).css(stylesArg);\n        if (settings.update_styles) {\n          updateInternalStyleAttr(styles, $elm);\n        }\n      };\n      var getStyle = function (elm, name, computed) {\n        var $elm = $$(elm);\n        if (computed) {\n          return $elm.css(name);\n        }\n        name = name.replace(/-(\\D)/g, function (a, b) {\n          return b.toUpperCase();\n        });\n        if (name === 'float') {\n          name = Env.browser.isIE() ? 'styleFloat' : 'cssFloat';\n        }\n        return $elm[0] && $elm[0].style ? $elm[0].style[name] : undefined;\n      };\n      var getSize = function (elm) {\n        var w, h;\n        elm = get(elm);\n        w = getStyle(elm, 'width');\n        h = getStyle(elm, 'height');\n        if (w.indexOf('px') === -1) {\n          w = 0;\n        }\n        if (h.indexOf('px') === -1) {\n          h = 0;\n        }\n        return {\n          w: parseInt(w, 10) || elm.offsetWidth || elm.clientWidth,\n          h: parseInt(h, 10) || elm.offsetHeight || elm.clientHeight\n        };\n      };\n      var getRect = function (elm) {\n        var pos, size;\n        elm = get(elm);\n        pos = getPos(elm);\n        size = getSize(elm);\n        return {\n          x: pos.x,\n          y: pos.y,\n          w: size.w,\n          h: size.h\n        };\n      };\n      var is = function (elm, selector) {\n        var i;\n        if (!elm) {\n          return false;\n        }\n        if (!Array.isArray(elm)) {\n          if (selector === '*') {\n            return elm.nodeType === 1;\n          }\n          if (simpleSelectorRe.test(selector)) {\n            var selectors = selector.toLowerCase().split(/,/);\n            var elmName = elm.nodeName.toLowerCase();\n            for (i = selectors.length - 1; i >= 0; i--) {\n              if (selectors[i] === elmName) {\n                return true;\n              }\n            }\n            return false;\n          }\n          if (elm.nodeType && elm.nodeType !== 1) {\n            return false;\n          }\n        }\n        var elms = !Array.isArray(elm) ? [elm] : elm;\n        return Sizzle(selector, elms[0].ownerDocument || elms[0], null, elms).length > 0;\n      };\n      var getParents = function (elm, selector, root, collect) {\n        var result = [];\n        var selectorVal;\n        var node = get(elm);\n        collect = collect === undefined;\n        root = root || (getRoot().nodeName !== 'BODY' ? getRoot().parentNode : null);\n        if (Tools.is(selector, 'string')) {\n          selectorVal = selector;\n          if (selector === '*') {\n            selector = function (node) {\n              return node.nodeType === 1;\n            };\n          } else {\n            selector = function (node) {\n              return is(node, selectorVal);\n            };\n          }\n        }\n        while (node) {\n          if (node === root || !node.nodeType || node.nodeType === 9) {\n            break;\n          }\n          if (!selector || typeof selector === 'function' && selector(node)) {\n            if (collect) {\n              result.push(node);\n            } else {\n              return [node];\n            }\n          }\n          node = node.parentNode;\n        }\n        return collect ? result : null;\n      };\n      var getParent = function (node, selector, root) {\n        var parents = getParents(node, selector, root, false);\n        return parents && parents.length > 0 ? parents[0] : null;\n      };\n      var _findSib = function (node, selector, name) {\n        var func = selector;\n        if (node) {\n          if (typeof selector === 'string') {\n            func = function (node) {\n              return is(node, selector);\n            };\n          }\n          for (node = node[name]; node; node = node[name]) {\n            if (typeof func === 'function' && func(node)) {\n              return node;\n            }\n          }\n        }\n        return null;\n      };\n      var getNext = function (node, selector) {\n        return _findSib(node, selector, 'nextSibling');\n      };\n      var getPrev = function (node, selector) {\n        return _findSib(node, selector, 'previousSibling');\n      };\n      var select = function (selector, scope) {\n        return Sizzle(selector, get(scope) || settings.root_element || doc, []);\n      };\n      var run = function (elm, func, scope) {\n        var result;\n        var node = typeof elm === 'string' ? get(elm) : elm;\n        if (!node) {\n          return false;\n        }\n        if (Tools.isArray(node) && (node.length || node.length === 0)) {\n          result = [];\n          each$5(node, function (elm, i) {\n            if (elm) {\n              if (typeof elm === 'string') {\n                elm = get(elm);\n              }\n              result.push(func.call(scope, elm, i));\n            }\n          });\n          return result;\n        }\n        var context = scope ? scope : _this;\n        return func.call(context, node);\n      };\n      var setAttribs = function (elm, attrs) {\n        $$(elm).each(function (i, node) {\n          each$5(attrs, function (value, name) {\n            setAttrib(node, name, value);\n          });\n        });\n      };\n      var setHTML = function (elm, html) {\n        var $elm = $$(elm);\n        if (isIE) {\n          $elm.each(function (i, target) {\n            if (target.canHaveHTML === false) {\n              return;\n            }\n            while (target.firstChild) {\n              target.removeChild(target.firstChild);\n            }\n            try {\n              target.innerHTML = '<br>' + html;\n              target.removeChild(target.firstChild);\n            } catch (ex) {\n              DomQuery('<div></div>').html('<br>' + html).contents().slice(1).appendTo(target);\n            }\n            return html;\n          });\n        } else {\n          $elm.html(html);\n        }\n      };\n      var add = function (parentElm, name, attrs, html, create) {\n        return run(parentElm, function (parentElm) {\n          var newElm = typeof name === 'string' ? doc.createElement(name) : name;\n          setAttribs(newElm, attrs);\n          if (html) {\n            if (typeof html !== 'string' && html.nodeType) {\n              newElm.appendChild(html);\n            } else if (typeof html === 'string') {\n              setHTML(newElm, html);\n            }\n          }\n          return !create ? parentElm.appendChild(newElm) : newElm;\n        });\n      };\n      var create = function (name, attrs, html) {\n        return add(doc.createElement(name), name, attrs, html, true);\n      };\n      var decode = Entities.decode;\n      var encode = Entities.encodeAllRaw;\n      var createHTML = function (name, attrs, html) {\n        var outHtml = '', key;\n        outHtml += '<' + name;\n        for (key in attrs) {\n          if (attrs.hasOwnProperty(key) && attrs[key] !== null && typeof attrs[key] !== 'undefined') {\n            outHtml += ' ' + key + '=\"' + encode(attrs[key]) + '\"';\n          }\n        }\n        if (typeof html !== 'undefined') {\n          return outHtml + '>' + html + '</' + name + '>';\n        }\n        return outHtml + ' />';\n      };\n      var createFragment = function (html) {\n        var node;\n        var container = doc.createElement('div');\n        var frag = doc.createDocumentFragment();\n        if (html) {\n          container.innerHTML = html;\n        }\n        while (node = container.firstChild) {\n          frag.appendChild(node);\n        }\n        return frag;\n      };\n      var remove = function (node, keepChildren) {\n        var $node = $$(node);\n        if (keepChildren) {\n          $node.each(function () {\n            var child;\n            while (child = this.firstChild) {\n              if (child.nodeType === 3 && child.data.length === 0) {\n                this.removeChild(child);\n              } else {\n                this.parentNode.insertBefore(child, this);\n              }\n            }\n          }).remove();\n        } else {\n          $node.remove();\n        }\n        return $node.length > 1 ? $node.toArray() : $node[0];\n      };\n      var removeAllAttribs = function (e) {\n        return run(e, function (e) {\n          var i;\n          var attrs = e.attributes;\n          for (i = attrs.length - 1; i >= 0; i--) {\n            e.removeAttributeNode(attrs.item(i));\n          }\n        });\n      };\n      var parseStyle = function (cssText) {\n        return styles.parse(cssText);\n      };\n      var serializeStyle = function (stylesArg, name) {\n        return styles.serialize(stylesArg, name);\n      };\n      var addStyle = function (cssText) {\n        var head, styleElm;\n        if (self !== DOMUtils.DOM && doc === domGlobals.document) {\n          if (addedStyles[cssText]) {\n            return;\n          }\n          addedStyles[cssText] = true;\n        }\n        styleElm = doc.getElementById('mceDefaultStyles');\n        if (!styleElm) {\n          styleElm = doc.createElement('style');\n          styleElm.id = 'mceDefaultStyles';\n          styleElm.type = 'text/css';\n          head = doc.getElementsByTagName('head')[0];\n          if (head.firstChild) {\n            head.insertBefore(styleElm, head.firstChild);\n          } else {\n            head.appendChild(styleElm);\n          }\n        }\n        if (styleElm.styleSheet) {\n          styleElm.styleSheet.cssText += cssText;\n        } else {\n          styleElm.appendChild(doc.createTextNode(cssText));\n        }\n      };\n      var loadCSS = function (url) {\n        var head;\n        if (self !== DOMUtils.DOM && doc === domGlobals.document) {\n          DOMUtils.DOM.loadCSS(url);\n          return;\n        }\n        if (!url) {\n          url = '';\n        }\n        head = doc.getElementsByTagName('head')[0];\n        each$5(url.split(','), function (url) {\n          var link;\n          url = Tools._addCacheSuffix(url);\n          if (files[url]) {\n            return;\n          }\n          files[url] = true;\n          link = create('link', __assign(__assign({\n            rel: 'stylesheet',\n            type: 'text/css',\n            href: url\n          }, settings.contentCssCors ? { crossOrigin: 'anonymous' } : {}), settings.referrerPolicy ? { referrerPolicy: settings.referrerPolicy } : {}));\n          head.appendChild(link);\n        });\n      };\n      var toggleClass = function (elm, cls, state) {\n        $$(elm).toggleClass(cls, state).each(function () {\n          if (this.className === '') {\n            DomQuery(this).attr('class', null);\n          }\n        });\n      };\n      var addClass = function (elm, cls) {\n        $$(elm).addClass(cls);\n      };\n      var removeClass = function (elm, cls) {\n        toggleClass(elm, cls, false);\n      };\n      var hasClass = function (elm, cls) {\n        return $$(elm).hasClass(cls);\n      };\n      var show = function (elm) {\n        $$(elm).show();\n      };\n      var hide = function (elm) {\n        $$(elm).hide();\n      };\n      var isHidden = function (elm) {\n        return $$(elm).css('display') === 'none';\n      };\n      var uniqueId = function (prefix) {\n        return (!prefix ? 'mce_' : prefix) + counter++;\n      };\n      var getOuterHTML = function (elm) {\n        var node = typeof elm === 'string' ? get(elm) : elm;\n        return NodeType.isElement(node) ? node.outerHTML : DomQuery('<div></div>').append(DomQuery(node).clone()).html();\n      };\n      var setOuterHTML = function (elm, html) {\n        $$(elm).each(function () {\n          try {\n            if ('outerHTML' in this) {\n              this.outerHTML = html;\n              return;\n            }\n          } catch (ex) {\n          }\n          remove(DomQuery(this).html(html), true);\n        });\n      };\n      var insertAfter = function (node, reference) {\n        var referenceNode = get(reference);\n        return run(node, function (node) {\n          var parent, nextSibling;\n          parent = referenceNode.parentNode;\n          nextSibling = referenceNode.nextSibling;\n          if (nextSibling) {\n            parent.insertBefore(node, nextSibling);\n          } else {\n            parent.appendChild(node);\n          }\n          return node;\n        });\n      };\n      var replace = function (newElm, oldElm, keepChildren) {\n        return run(oldElm, function (oldElm) {\n          if (Tools.is(oldElm, 'array')) {\n            newElm = newElm.cloneNode(true);\n          }\n          if (keepChildren) {\n            each$5(grep$1(oldElm.childNodes), function (node) {\n              newElm.appendChild(node);\n            });\n          }\n          return oldElm.parentNode.replaceChild(newElm, oldElm);\n        });\n      };\n      var rename = function (elm, name) {\n        var newElm;\n        if (elm.nodeName !== name.toUpperCase()) {\n          newElm = create(name);\n          each$5(getAttribs(elm), function (attrNode) {\n            setAttrib(newElm, attrNode.nodeName, getAttrib(elm, attrNode.nodeName));\n          });\n          replace(newElm, elm, true);\n        }\n        return newElm || elm;\n      };\n      var findCommonAncestor = function (a, b) {\n        var ps = a, pe;\n        while (ps) {\n          pe = b;\n          while (pe && ps !== pe) {\n            pe = pe.parentNode;\n          }\n          if (ps === pe) {\n            break;\n          }\n          ps = ps.parentNode;\n        }\n        if (!ps && a.ownerDocument) {\n          return a.ownerDocument.documentElement;\n        }\n        return ps;\n      };\n      var toHex = function (rgbVal) {\n        return styles.toHex(Tools.trim(rgbVal));\n      };\n      var isEmpty = function (node, elements) {\n        var i, attributes, type, name, brCount = 0;\n        node = node.firstChild;\n        if (node) {\n          var walker = new TreeWalker(node, node.parentNode);\n          var whitespace = schema ? schema.getWhiteSpaceElements() : {};\n          elements = elements || (schema ? schema.getNonEmptyElements() : null);\n          do {\n            type = node.nodeType;\n            if (NodeType.isElement(node)) {\n              var bogusVal = node.getAttribute('data-mce-bogus');\n              if (bogusVal) {\n                node = walker.next(bogusVal === 'all');\n                continue;\n              }\n              name = node.nodeName.toLowerCase();\n              if (elements && elements[name]) {\n                if (name === 'br') {\n                  brCount++;\n                  node = walker.next();\n                  continue;\n                }\n                return false;\n              }\n              attributes = getAttribs(node);\n              i = attributes.length;\n              while (i--) {\n                name = attributes[i].nodeName;\n                if (name === 'name' || name === 'data-mce-bookmark') {\n                  return false;\n                }\n              }\n            }\n            if (type === 8) {\n              return false;\n            }\n            if (type === 3 && !whiteSpaceRegExp$2.test(node.nodeValue)) {\n              return false;\n            }\n            if (type === 3 && node.parentNode && whitespace[node.parentNode.nodeName] && whiteSpaceRegExp$2.test(node.nodeValue)) {\n              return false;\n            }\n            node = walker.next();\n          } while (node);\n        }\n        return brCount <= 1;\n      };\n      var createRng = function () {\n        return doc.createRange();\n      };\n      var split = function (parentElm, splitElm, replacementElm) {\n        var r = createRng(), bef, aft, pa;\n        if (parentElm && splitElm) {\n          r.setStart(parentElm.parentNode, findNodeIndex(parentElm));\n          r.setEnd(splitElm.parentNode, findNodeIndex(splitElm));\n          bef = r.extractContents();\n          r = createRng();\n          r.setStart(splitElm.parentNode, findNodeIndex(splitElm) + 1);\n          r.setEnd(parentElm.parentNode, findNodeIndex(parentElm) + 1);\n          aft = r.extractContents();\n          pa = parentElm.parentNode;\n          pa.insertBefore(TrimNode.trimNode(self, bef), parentElm);\n          if (replacementElm) {\n            pa.insertBefore(replacementElm, parentElm);\n          } else {\n            pa.insertBefore(splitElm, parentElm);\n          }\n          pa.insertBefore(TrimNode.trimNode(self, aft), parentElm);\n          remove(parentElm);\n          return replacementElm || splitElm;\n        }\n      };\n      var bind = function (target, name, func, scope) {\n        if (Tools.isArray(target)) {\n          var i = target.length;\n          var rv = [];\n          while (i--) {\n            rv[i] = bind(target[i], name, func, scope);\n          }\n          return rv;\n        }\n        if (settings.collect && (target === doc || target === win)) {\n          boundEvents.push([\n            target,\n            name,\n            func,\n            scope\n          ]);\n        }\n        return events.bind(target, name, func, scope || self);\n      };\n      var unbind = function (target, name, func) {\n        var i;\n        if (Tools.isArray(target)) {\n          i = target.length;\n          var rv = [];\n          while (i--) {\n            rv[i] = unbind(target[i], name, func);\n          }\n          return rv;\n        }\n        if (boundEvents && (target === doc || target === win)) {\n          i = boundEvents.length;\n          while (i--) {\n            var item = boundEvents[i];\n            if (target === item[0] && (!name || name === item[1]) && (!func || func === item[2])) {\n              events.unbind(item[0], item[1], item[2]);\n            }\n          }\n        }\n        return events.unbind(target, name, func);\n      };\n      var fire = function (target, name, evt) {\n        return events.fire(target, name, evt);\n      };\n      var getContentEditable = function (node) {\n        if (node && NodeType.isElement(node)) {\n          var contentEditable = node.getAttribute('data-mce-contenteditable');\n          if (contentEditable && contentEditable !== 'inherit') {\n            return contentEditable;\n          }\n          return node.contentEditable !== 'inherit' ? node.contentEditable : null;\n        } else {\n          return null;\n        }\n      };\n      var getContentEditableParent = function (node) {\n        var root = getRoot();\n        var state = null;\n        for (; node && node !== root; node = node.parentNode) {\n          state = getContentEditable(node);\n          if (state !== null) {\n            break;\n          }\n        }\n        return state;\n      };\n      var destroy = function () {\n        if (boundEvents) {\n          var i = boundEvents.length;\n          while (i--) {\n            var item = boundEvents[i];\n            events.unbind(item[0], item[1], item[2]);\n          }\n        }\n        if (Sizzle.setDocument) {\n          Sizzle.setDocument();\n        }\n      };\n      var isChildOf = function (node, parent) {\n        while (node) {\n          if (parent === node) {\n            return true;\n          }\n          node = node.parentNode;\n        }\n        return false;\n      };\n      var dumpRng = function (r) {\n        return 'startContainer: ' + r.startContainer.nodeName + ', startOffset: ' + r.startOffset + ', endContainer: ' + r.endContainer.nodeName + ', endOffset: ' + r.endOffset;\n      };\n      var self = {\n        doc: doc,\n        settings: settings,\n        win: win,\n        files: files,\n        stdMode: stdMode,\n        boxModel: boxModel,\n        styleSheetLoader: styleSheetLoader,\n        boundEvents: boundEvents,\n        styles: styles,\n        schema: schema,\n        events: events,\n        isBlock: isBlock,\n        $: $,\n        $$: $$,\n        root: null,\n        clone: clone,\n        getRoot: getRoot,\n        getViewPort: getViewPort,\n        getRect: getRect,\n        getSize: getSize,\n        getParent: getParent,\n        getParents: getParents,\n        get: get,\n        getNext: getNext,\n        getPrev: getPrev,\n        select: select,\n        is: is,\n        add: add,\n        create: create,\n        createHTML: createHTML,\n        createFragment: createFragment,\n        remove: remove,\n        setStyle: setStyle,\n        getStyle: getStyle,\n        setStyles: setStyles,\n        removeAllAttribs: removeAllAttribs,\n        setAttrib: setAttrib,\n        setAttribs: setAttribs,\n        getAttrib: getAttrib,\n        getPos: getPos,\n        parseStyle: parseStyle,\n        serializeStyle: serializeStyle,\n        addStyle: addStyle,\n        loadCSS: loadCSS,\n        addClass: addClass,\n        removeClass: removeClass,\n        hasClass: hasClass,\n        toggleClass: toggleClass,\n        show: show,\n        hide: hide,\n        isHidden: isHidden,\n        uniqueId: uniqueId,\n        setHTML: setHTML,\n        getOuterHTML: getOuterHTML,\n        setOuterHTML: setOuterHTML,\n        decode: decode,\n        encode: encode,\n        insertAfter: insertAfter,\n        replace: replace,\n        rename: rename,\n        findCommonAncestor: findCommonAncestor,\n        toHex: toHex,\n        run: run,\n        getAttribs: getAttribs,\n        isEmpty: isEmpty,\n        createRng: createRng,\n        nodeIndex: findNodeIndex,\n        split: split,\n        bind: bind,\n        unbind: unbind,\n        fire: fire,\n        getContentEditable: getContentEditable,\n        getContentEditableParent: getContentEditableParent,\n        destroy: destroy,\n        isChildOf: isChildOf,\n        dumpRng: dumpRng\n      };\n      attrHooks = setupAttrHooks(styles, settings, function () {\n        return self;\n      });\n      return self;\n    }\n    (function (DOMUtils) {\n      DOMUtils.DOM = DOMUtils(domGlobals.document);\n      DOMUtils.nodeIndex = findNodeIndex;\n    }(DOMUtils || (DOMUtils = {})));\n    var DOMUtils$1 = DOMUtils;\n\n    var DOM = DOMUtils$1.DOM;\n    var each$6 = Tools.each, grep$2 = Tools.grep;\n    var QUEUED = 0;\n    var LOADING = 1;\n    var LOADED = 2;\n    var FAILED = 3;\n    var ScriptLoader = function () {\n      function ScriptLoader(settings) {\n        if (settings === void 0) {\n          settings = {};\n        }\n        this.states = {};\n        this.queue = [];\n        this.scriptLoadedCallbacks = {};\n        this.queueLoadedCallbacks = [];\n        this.loading = 0;\n        this.settings = settings;\n      }\n      ScriptLoader.prototype._setReferrerPolicy = function (referrerPolicy) {\n        this.settings.referrerPolicy = referrerPolicy;\n      };\n      ScriptLoader.prototype.loadScript = function (url, success, failure) {\n        var dom = DOM;\n        var elm, id;\n        var done = function () {\n          dom.remove(id);\n          if (elm) {\n            elm.onreadystatechange = elm.onload = elm = null;\n          }\n          success();\n        };\n        var error = function () {\n          if (isFunction(failure)) {\n            failure();\n          } else {\n            if (typeof domGlobals.console !== 'undefined' && domGlobals.console.log) {\n              domGlobals.console.log('Failed to load script: ' + url);\n            }\n          }\n        };\n        id = dom.uniqueId();\n        elm = domGlobals.document.createElement('script');\n        elm.id = id;\n        elm.type = 'text/javascript';\n        elm.src = Tools._addCacheSuffix(url);\n        if (this.settings.referrerPolicy) {\n          dom.setAttrib(elm, 'referrerpolicy', this.settings.referrerPolicy);\n        }\n        elm.onload = done;\n        elm.onerror = error;\n        (domGlobals.document.getElementsByTagName('head')[0] || domGlobals.document.body).appendChild(elm);\n      };\n      ScriptLoader.prototype.isDone = function (url) {\n        return this.states[url] === LOADED;\n      };\n      ScriptLoader.prototype.markDone = function (url) {\n        this.states[url] = LOADED;\n      };\n      ScriptLoader.prototype.add = function (url, success, scope, failure) {\n        var state = this.states[url];\n        if (state === undefined) {\n          this.queue.push(url);\n          this.states[url] = QUEUED;\n        }\n        if (success) {\n          if (!this.scriptLoadedCallbacks[url]) {\n            this.scriptLoadedCallbacks[url] = [];\n          }\n          this.scriptLoadedCallbacks[url].push({\n            success: success,\n            failure: failure,\n            scope: scope || this\n          });\n        }\n      };\n      ScriptLoader.prototype.load = function (url, success, scope, failure) {\n        return this.add(url, success, scope, failure);\n      };\n      ScriptLoader.prototype.remove = function (url) {\n        delete this.states[url];\n        delete this.scriptLoadedCallbacks[url];\n      };\n      ScriptLoader.prototype.loadQueue = function (success, scope, failure) {\n        this.loadScripts(this.queue, success, scope, failure);\n      };\n      ScriptLoader.prototype.loadScripts = function (scripts, success, scope, failure) {\n        var self = this;\n        var loadScripts;\n        var failures = [];\n        var execCallbacks = function (name, url) {\n          each$6(self.scriptLoadedCallbacks[url], function (callback) {\n            if (isFunction(callback[name])) {\n              callback[name].call(callback.scope);\n            }\n          });\n          self.scriptLoadedCallbacks[url] = undefined;\n        };\n        self.queueLoadedCallbacks.push({\n          success: success,\n          failure: failure,\n          scope: scope || this\n        });\n        loadScripts = function () {\n          var loadingScripts = grep$2(scripts);\n          scripts.length = 0;\n          each$6(loadingScripts, function (url) {\n            if (self.states[url] === LOADED) {\n              execCallbacks('success', url);\n              return;\n            }\n            if (self.states[url] === FAILED) {\n              execCallbacks('failure', url);\n              return;\n            }\n            if (self.states[url] !== LOADING) {\n              self.states[url] = LOADING;\n              self.loading++;\n              self.loadScript(url, function () {\n                self.states[url] = LOADED;\n                self.loading--;\n                execCallbacks('success', url);\n                loadScripts();\n              }, function () {\n                self.states[url] = FAILED;\n                self.loading--;\n                failures.push(url);\n                execCallbacks('failure', url);\n                loadScripts();\n              });\n            }\n          });\n          if (!self.loading) {\n            var notifyCallbacks = self.queueLoadedCallbacks.slice(0);\n            self.queueLoadedCallbacks.length = 0;\n            each$6(notifyCallbacks, function (callback) {\n              if (failures.length === 0) {\n                if (isFunction(callback.success)) {\n                  callback.success.call(callback.scope);\n                }\n              } else {\n                if (isFunction(callback.failure)) {\n                  callback.failure.call(callback.scope, failures);\n                }\n              }\n            });\n          }\n        };\n        loadScripts();\n      };\n      ScriptLoader.ScriptLoader = new ScriptLoader();\n      return ScriptLoader;\n    }();\n\n    var isRaw = function (str) {\n      return isObject(str) && has(str, 'raw');\n    };\n    var isTokenised = function (str) {\n      return isArray(str) && str.length > 1;\n    };\n    var data = {};\n    var currentCode = Cell('en');\n    var getData = function () {\n      return map$1(data, function (value) {\n        return __assign({}, value);\n      });\n    };\n    var setCode = function (newCode) {\n      if (newCode) {\n        currentCode.set(newCode);\n      }\n    };\n    var getCode = function () {\n      return currentCode.get();\n    };\n    var add = function (code, items) {\n      var langData = data[code];\n      if (!langData) {\n        data[code] = langData = {};\n      }\n      for (var name in items) {\n        langData[name.toLowerCase()] = items[name];\n      }\n    };\n    var translate = function (text) {\n      var langData = data[currentCode.get()] || {};\n      var toString = function (obj) {\n        if (isFunction(obj)) {\n          return Object.prototype.toString.call(obj);\n        }\n        return !isEmpty(obj) ? '' + obj : '';\n      };\n      var isEmpty = function (text) {\n        return text === '' || text === null || text === undefined;\n      };\n      var getLangData = function (text) {\n        var textstr = toString(text);\n        var lowercaseTextstr = textstr.toLowerCase();\n        return has(langData, lowercaseTextstr) ? toString(langData[lowercaseTextstr]) : textstr;\n      };\n      var removeContext = function (str) {\n        return str.replace(/{context:\\w+}$/, '');\n      };\n      var translated = function (text) {\n        return text;\n      };\n      if (isEmpty(text)) {\n        return translated('');\n      }\n      if (isRaw(text)) {\n        return translated(toString(text.raw));\n      }\n      if (isTokenised(text)) {\n        var values_1 = text.slice(1);\n        var substitued = getLangData(text[0]).replace(/\\{([0-9]+)\\}/g, function ($1, $2) {\n          return has(values_1, $2) ? toString(values_1[$2]) : $1;\n        });\n        return translated(removeContext(substitued));\n      }\n      return translated(removeContext(getLangData(text)));\n    };\n    var isRtl = function () {\n      return get(data, currentCode.get()).bind(function (items) {\n        return get(items, '_dir');\n      }).exists(function (dir) {\n        return dir === 'rtl';\n      });\n    };\n    var hasCode = function (code) {\n      return has(data, code);\n    };\n    var I18n = {\n      getData: getData,\n      setCode: setCode,\n      getCode: getCode,\n      add: add,\n      translate: translate,\n      isRtl: isRtl,\n      hasCode: hasCode\n    };\n\n    var each$7 = Tools.each;\n    function AddOnManager() {\n      var _this = this;\n      var items = [];\n      var urls = {};\n      var lookup = {};\n      var _listeners = [];\n      var get = function (name) {\n        if (lookup[name]) {\n          return lookup[name].instance;\n        }\n        return undefined;\n      };\n      var dependencies = function (name) {\n        var result;\n        if (lookup[name]) {\n          result = lookup[name].dependencies;\n        }\n        return result || [];\n      };\n      var requireLangPack = function (name, languages) {\n        var language = I18n.getCode();\n        if (language && AddOnManager.languageLoad !== false) {\n          if (languages) {\n            languages = ',' + languages + ',';\n            if (languages.indexOf(',' + language.substr(0, 2) + ',') !== -1) {\n              language = language.substr(0, 2);\n            } else if (languages.indexOf(',' + language + ',') === -1) {\n              return;\n            }\n          }\n          ScriptLoader.ScriptLoader.add(urls[name] + '/langs/' + language + '.js');\n        }\n      };\n      var add = function (id, addOn, dependencies) {\n        items.push(addOn);\n        lookup[id] = {\n          instance: addOn,\n          dependencies: dependencies\n        };\n        var result = partition(_listeners, function (listener) {\n          return listener.name === id;\n        });\n        _listeners = result.fail;\n        each$7(result.pass, function (listener) {\n          listener.callback();\n        });\n        return addOn;\n      };\n      var remove = function (name) {\n        delete urls[name];\n        delete lookup[name];\n      };\n      var createUrl = function (baseUrl, dep) {\n        if (typeof dep === 'object') {\n          return dep;\n        }\n        return typeof baseUrl === 'string' ? {\n          prefix: '',\n          resource: dep,\n          suffix: ''\n        } : {\n          prefix: baseUrl.prefix,\n          resource: dep,\n          suffix: baseUrl.suffix\n        };\n      };\n      var addComponents = function (pluginName, scripts) {\n        var pluginUrl = _this.urls[pluginName];\n        each$7(scripts, function (script) {\n          ScriptLoader.ScriptLoader.add(pluginUrl + '/' + script);\n        });\n      };\n      var loadDependencies = function (name, addOnUrl, success, scope) {\n        var deps = dependencies(name);\n        each$7(deps, function (dep) {\n          var newUrl = createUrl(addOnUrl, dep);\n          load(newUrl.resource, newUrl, undefined, undefined);\n        });\n        if (success) {\n          if (scope) {\n            success.call(scope);\n          } else {\n            success.call(ScriptLoader);\n          }\n        }\n      };\n      var load = function (name, addOnUrl, success, scope, failure) {\n        if (urls[name]) {\n          return;\n        }\n        var urlString = typeof addOnUrl === 'string' ? addOnUrl : addOnUrl.prefix + addOnUrl.resource + addOnUrl.suffix;\n        if (urlString.indexOf('/') !== 0 && urlString.indexOf('://') === -1) {\n          urlString = AddOnManager.baseURL + '/' + urlString;\n        }\n        urls[name] = urlString.substring(0, urlString.lastIndexOf('/'));\n        if (lookup[name]) {\n          loadDependencies(name, addOnUrl, success, scope);\n        } else {\n          ScriptLoader.ScriptLoader.add(urlString, function () {\n            return loadDependencies(name, addOnUrl, success, scope);\n          }, scope, failure);\n        }\n      };\n      var waitFor = function (name, callback) {\n        if (lookup.hasOwnProperty(name)) {\n          callback();\n        } else {\n          _listeners.push({\n            name: name,\n            callback: callback\n          });\n        }\n      };\n      return {\n        items: items,\n        urls: urls,\n        lookup: lookup,\n        _listeners: _listeners,\n        get: get,\n        dependencies: dependencies,\n        requireLangPack: requireLangPack,\n        add: add,\n        remove: remove,\n        createUrl: createUrl,\n        addComponents: addComponents,\n        load: load,\n        waitFor: waitFor\n      };\n    }\n    (function (AddOnManager) {\n      AddOnManager.PluginManager = AddOnManager();\n      AddOnManager.ThemeManager = AddOnManager();\n    }(AddOnManager || (AddOnManager = {})));\n    var AddOnManager$1 = AddOnManager;\n\n    var first = function (fn, rate) {\n      var timer = null;\n      var cancel = function () {\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n          timer = null;\n        }\n      };\n      var throttle = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (timer === null) {\n          timer = domGlobals.setTimeout(function () {\n            fn.apply(null, args);\n            timer = null;\n          }, rate);\n        }\n      };\n      return {\n        cancel: cancel,\n        throttle: throttle\n      };\n    };\n    var last$2 = function (fn, rate) {\n      var timer = null;\n      var cancel = function () {\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n          timer = null;\n        }\n      };\n      var throttle = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (timer !== null) {\n          domGlobals.clearTimeout(timer);\n        }\n        timer = domGlobals.setTimeout(function () {\n          fn.apply(null, args);\n          timer = null;\n        }, rate);\n      };\n      return {\n        cancel: cancel,\n        throttle: throttle\n      };\n    };\n\n    var read = function (element, attr) {\n      var value = get$1(element, attr);\n      return value === undefined || value === '' ? [] : value.split(' ');\n    };\n    var add$1 = function (element, attr, id) {\n      var old = read(element, attr);\n      var nu = old.concat([id]);\n      set(element, attr, nu.join(' '));\n      return true;\n    };\n    var remove$2 = function (element, attr, id) {\n      var nu = filter(read(element, attr), function (v) {\n        return v !== id;\n      });\n      if (nu.length > 0) {\n        set(element, attr, nu.join(' '));\n      } else {\n        remove(element, attr);\n      }\n      return false;\n    };\n\n    var supports = function (element) {\n      return element.dom().classList !== undefined;\n    };\n    var get$4 = function (element) {\n      return read(element, 'class');\n    };\n    var add$2 = function (element, clazz) {\n      return add$1(element, 'class', clazz);\n    };\n    var remove$3 = function (element, clazz) {\n      return remove$2(element, 'class', clazz);\n    };\n\n    var add$3 = function (element, clazz) {\n      if (supports(element)) {\n        element.dom().classList.add(clazz);\n      } else {\n        add$2(element, clazz);\n      }\n    };\n    var cleanClass = function (element) {\n      var classList = supports(element) ? element.dom().classList : get$4(element);\n      if (classList.length === 0) {\n        remove(element, 'class');\n      }\n    };\n    var remove$4 = function (element, clazz) {\n      if (supports(element)) {\n        var classList = element.dom().classList;\n        classList.remove(clazz);\n      } else {\n        remove$3(element, clazz);\n      }\n      cleanClass(element);\n    };\n    var has$2 = function (element, clazz) {\n      return supports(element) && element.dom().classList.contains(clazz);\n    };\n\n    var descendants = function (scope, predicate) {\n      var result = [];\n      each(children(scope), function (x) {\n        if (predicate(x)) {\n          result = result.concat([x]);\n        }\n        result = result.concat(descendants(x, predicate));\n      });\n      return result;\n    };\n\n    var descendants$1 = function (scope, selector) {\n      return all(selector, scope);\n    };\n\n    function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {\n      return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot);\n    }\n\n    var ancestor = function (scope, predicate, isRoot) {\n      var element = scope.dom();\n      var stop = isFunction(isRoot) ? isRoot : constant(false);\n      while (element.parentNode) {\n        element = element.parentNode;\n        var el = Element.fromDom(element);\n        if (predicate(el)) {\n          return Option.some(el);\n        } else if (stop(el)) {\n          break;\n        }\n      }\n      return Option.none();\n    };\n    var closest = function (scope, predicate, isRoot) {\n      var is = function (s, test) {\n        return test(s);\n      };\n      return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);\n    };\n\n    var ancestor$1 = function (scope, selector, isRoot) {\n      return ancestor(scope, function (e) {\n        return is(e, selector);\n      }, isRoot);\n    };\n    var descendant = function (scope, selector) {\n      return one(selector, scope);\n    };\n    var closest$1 = function (scope, selector, isRoot) {\n      return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot);\n    };\n\n    var annotation = constant('mce-annotation');\n    var dataAnnotation = constant('data-mce-annotation');\n    var dataAnnotationId = constant('data-mce-annotation-uid');\n\n    var identify = function (editor, annotationName) {\n      var rng = editor.selection.getRng();\n      var start = Element.fromDom(rng.startContainer);\n      var root = Element.fromDom(editor.getBody());\n      var selector = annotationName.fold(function () {\n        return '.' + annotation();\n      }, function (an) {\n        return '[' + dataAnnotation() + '=\"' + an + '\"]';\n      });\n      var newStart = child(start, rng.startOffset).getOr(start);\n      var closest = closest$1(newStart, selector, function (n) {\n        return eq(n, root);\n      });\n      var getAttr = function (c, property) {\n        if (has$1(c, property)) {\n          return Option.some(get$1(c, property));\n        } else {\n          return Option.none();\n        }\n      };\n      return closest.bind(function (c) {\n        return getAttr(c, '' + dataAnnotationId()).bind(function (uid) {\n          return getAttr(c, '' + dataAnnotation()).map(function (name) {\n            var elements = findMarkers(editor, uid);\n            return {\n              uid: uid,\n              name: name,\n              elements: elements\n            };\n          });\n        });\n      });\n    };\n    var isAnnotation = function (elem) {\n      return isElement$1(elem) && has$2(elem, annotation());\n    };\n    var findMarkers = function (editor, uid) {\n      var body = Element.fromDom(editor.getBody());\n      return descendants$1(body, '[' + dataAnnotationId() + '=\"' + uid + '\"]');\n    };\n    var findAll = function (editor, name) {\n      var body = Element.fromDom(editor.getBody());\n      var markers = descendants$1(body, '[' + dataAnnotation() + '=\"' + name + '\"]');\n      var directory = {};\n      each(markers, function (m) {\n        var uid = get$1(m, dataAnnotationId());\n        var nodesAlready = directory.hasOwnProperty(uid) ? directory[uid] : [];\n        directory[uid] = nodesAlready.concat([m]);\n      });\n      return directory;\n    };\n\n    var setup = function (editor, registry) {\n      var changeCallbacks = Cell({});\n      var initData = function () {\n        return {\n          listeners: [],\n          previous: Cell(Option.none())\n        };\n      };\n      var withCallbacks = function (name, f) {\n        updateCallbacks(name, function (data) {\n          f(data);\n          return data;\n        });\n      };\n      var updateCallbacks = function (name, f) {\n        var callbackMap = changeCallbacks.get();\n        var data = callbackMap.hasOwnProperty(name) ? callbackMap[name] : initData();\n        var outputData = f(data);\n        callbackMap[name] = outputData;\n        changeCallbacks.set(callbackMap);\n      };\n      var fireCallbacks = function (name, uid, elements) {\n        withCallbacks(name, function (data) {\n          each(data.listeners, function (f) {\n            return f(true, name, {\n              uid: uid,\n              nodes: map(elements, function (elem) {\n                return elem.dom();\n              })\n            });\n          });\n        });\n      };\n      var fireNoAnnotation = function (name) {\n        withCallbacks(name, function (data) {\n          each(data.listeners, function (f) {\n            return f(false, name);\n          });\n        });\n      };\n      var onNodeChange = last$2(function () {\n        var callbackMap = changeCallbacks.get();\n        var annotations = sort(keys(callbackMap));\n        each(annotations, function (name) {\n          updateCallbacks(name, function (data) {\n            var prev = data.previous.get();\n            identify(editor, Option.some(name)).fold(function () {\n              if (prev.isSome()) {\n                fireNoAnnotation(name);\n                data.previous.set(Option.none());\n              }\n            }, function (_a) {\n              var uid = _a.uid, name = _a.name, elements = _a.elements;\n              if (!prev.is(uid)) {\n                fireCallbacks(name, uid, elements);\n                data.previous.set(Option.some(uid));\n              }\n            });\n            return {\n              previous: data.previous,\n              listeners: data.listeners\n            };\n          });\n        });\n      }, 30);\n      editor.on('remove', function () {\n        onNodeChange.cancel();\n      });\n      editor.on('NodeChange', function () {\n        onNodeChange.throttle();\n      });\n      var addListener = function (name, f) {\n        updateCallbacks(name, function (data) {\n          return {\n            previous: data.previous,\n            listeners: data.listeners.concat([f])\n          };\n        });\n      };\n      return { addListener: addListener };\n    };\n\n    var setup$1 = function (editor, registry) {\n      var identifyParserNode = function (span) {\n        return Option.from(span.attr(dataAnnotation())).bind(registry.lookup);\n      };\n      editor.on('init', function () {\n        editor.serializer.addNodeFilter('span', function (spans) {\n          each(spans, function (span) {\n            identifyParserNode(span).each(function (settings) {\n              if (settings.persistent === false) {\n                span.unwrap();\n              }\n            });\n          });\n        });\n      });\n    };\n\n    var create$1 = function () {\n      var annotations = {};\n      var register = function (name, settings) {\n        annotations[name] = {\n          name: name,\n          settings: settings\n        };\n      };\n      var lookup = function (name) {\n        return annotations.hasOwnProperty(name) ? Option.from(annotations[name]).map(function (a) {\n          return a.settings;\n        }) : Option.none();\n      };\n      return {\n        register: register,\n        lookup: lookup\n      };\n    };\n\n    var unique = 0;\n    var generate = function (prefix) {\n      var date = new Date();\n      var time = date.getTime();\n      var random = Math.floor(Math.random() * 1000000000);\n      unique++;\n      return prefix + '_' + random + unique + String(time);\n    };\n\n    var add$4 = function (element, classes) {\n      each(classes, function (x) {\n        add$3(element, x);\n      });\n    };\n\n    var clone = function (original, isDeep) {\n      return Element.fromDom(original.dom().cloneNode(isDeep));\n    };\n    var shallow = function (original) {\n      return clone(original, false);\n    };\n    var deep = function (original) {\n      return clone(original, true);\n    };\n\n    var fromHtml$1 = function (html, scope) {\n      var doc = scope || domGlobals.document;\n      var div = doc.createElement('div');\n      div.innerHTML = html;\n      return children(Element.fromDom(div));\n    };\n\n    var get$5 = function (element) {\n      return element.dom().innerHTML;\n    };\n    var set$1 = function (element, content) {\n      var owner$1 = owner(element);\n      var docDom = owner$1.dom();\n      var fragment = Element.fromDom(docDom.createDocumentFragment());\n      var contentElements = fromHtml$1(content, docDom);\n      append$1(fragment, contentElements);\n      empty(element);\n      append(element, fragment);\n    };\n\n    var ZWSP = '\\uFEFF';\n    var isZwsp = function (chr) {\n      return chr === ZWSP;\n    };\n    var trim$3 = function (text) {\n      return text.replace(new RegExp(ZWSP, 'g'), '');\n    };\n    var Zwsp = {\n      isZwsp: isZwsp,\n      ZWSP: ZWSP,\n      trim: trim$3\n    };\n\n    var isElement$2 = NodeType.isElement;\n    var isText$2 = NodeType.isText;\n    var isCaretContainerBlock = function (node) {\n      if (isText$2(node)) {\n        node = node.parentNode;\n      }\n      return isElement$2(node) && node.hasAttribute('data-mce-caret');\n    };\n    var isCaretContainerInline = function (node) {\n      return isText$2(node) && Zwsp.isZwsp(node.data);\n    };\n    var isCaretContainer = function (node) {\n      return isCaretContainerBlock(node) || isCaretContainerInline(node);\n    };\n    var hasContent = function (node) {\n      return node.firstChild !== node.lastChild || !NodeType.isBr(node.firstChild);\n    };\n    var insertInline = function (node, before) {\n      var doc, sibling, textNode, parentNode;\n      doc = node.ownerDocument;\n      textNode = doc.createTextNode(Zwsp.ZWSP);\n      parentNode = node.parentNode;\n      if (!before) {\n        sibling = node.nextSibling;\n        if (isText$2(sibling)) {\n          if (isCaretContainer(sibling)) {\n            return sibling;\n          }\n          if (startsWithCaretContainer(sibling)) {\n            sibling.splitText(1);\n            return sibling;\n          }\n        }\n        if (node.nextSibling) {\n          parentNode.insertBefore(textNode, node.nextSibling);\n        } else {\n          parentNode.appendChild(textNode);\n        }\n      } else {\n        sibling = node.previousSibling;\n        if (isText$2(sibling)) {\n          if (isCaretContainer(sibling)) {\n            return sibling;\n          }\n          if (endsWithCaretContainer(sibling)) {\n            return sibling.splitText(sibling.data.length - 1);\n          }\n        }\n        parentNode.insertBefore(textNode, node);\n      }\n      return textNode;\n    };\n    var isBeforeInline = function (pos) {\n      var container = pos.container();\n      if (!pos || !NodeType.isText(container)) {\n        return false;\n      }\n      return container.data.charAt(pos.offset()) === Zwsp.ZWSP || pos.isAtStart() && isCaretContainerInline(container.previousSibling);\n    };\n    var isAfterInline = function (pos) {\n      var container = pos.container();\n      if (!pos || !NodeType.isText(container)) {\n        return false;\n      }\n      return container.data.charAt(pos.offset() - 1) === Zwsp.ZWSP || pos.isAtEnd() && isCaretContainerInline(container.nextSibling);\n    };\n    var createBogusBr = function () {\n      var br = domGlobals.document.createElement('br');\n      br.setAttribute('data-mce-bogus', '1');\n      return br;\n    };\n    var insertBlock = function (blockName, node, before) {\n      var doc, blockNode, parentNode;\n      doc = node.ownerDocument;\n      blockNode = doc.createElement(blockName);\n      blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after');\n      blockNode.setAttribute('data-mce-bogus', 'all');\n      blockNode.appendChild(createBogusBr());\n      parentNode = node.parentNode;\n      if (!before) {\n        if (node.nextSibling) {\n          parentNode.insertBefore(blockNode, node.nextSibling);\n        } else {\n          parentNode.appendChild(blockNode);\n        }\n      } else {\n        parentNode.insertBefore(blockNode, node);\n      }\n      return blockNode;\n    };\n    var startsWithCaretContainer = function (node) {\n      return isText$2(node) && node.data[0] === Zwsp.ZWSP;\n    };\n    var endsWithCaretContainer = function (node) {\n      return isText$2(node) && node.data[node.data.length - 1] === Zwsp.ZWSP;\n    };\n    var trimBogusBr = function (elm) {\n      var brs = elm.getElementsByTagName('br');\n      var lastBr = brs[brs.length - 1];\n      if (NodeType.isBogus(lastBr)) {\n        lastBr.parentNode.removeChild(lastBr);\n      }\n    };\n    var showCaretContainerBlock = function (caretContainer) {\n      if (caretContainer && caretContainer.hasAttribute('data-mce-caret')) {\n        trimBogusBr(caretContainer);\n        caretContainer.removeAttribute('data-mce-caret');\n        caretContainer.removeAttribute('data-mce-bogus');\n        caretContainer.removeAttribute('style');\n        caretContainer.removeAttribute('_moz_abspos');\n        return caretContainer;\n      }\n      return null;\n    };\n    var isRangeInCaretContainerBlock = function (range) {\n      return isCaretContainerBlock(range.startContainer);\n    };\n\n    var isContentEditableTrue$1 = NodeType.isContentEditableTrue;\n    var isContentEditableFalse$1 = NodeType.isContentEditableFalse;\n    var isBr$2 = NodeType.isBr;\n    var isText$3 = NodeType.isText;\n    var isInvalidTextElement = NodeType.matchNodeNames([\n      'script',\n      'style',\n      'textarea'\n    ]);\n    var isAtomicInline = NodeType.matchNodeNames([\n      'img',\n      'input',\n      'textarea',\n      'hr',\n      'iframe',\n      'video',\n      'audio',\n      'object'\n    ]);\n    var isTable$2 = NodeType.matchNodeNames(['table']);\n    var isCaretContainer$1 = isCaretContainer;\n    var isCaretCandidate = function (node) {\n      if (isCaretContainer$1(node)) {\n        return false;\n      }\n      if (isText$3(node)) {\n        if (isInvalidTextElement(node.parentNode)) {\n          return false;\n        }\n        return true;\n      }\n      return isAtomicInline(node) || isBr$2(node) || isTable$2(node) || isNonUiContentEditableFalse(node);\n    };\n    var isUnselectable = function (node) {\n      return NodeType.isElement(node) && node.getAttribute('unselectable') === 'true';\n    };\n    var isNonUiContentEditableFalse = function (node) {\n      return isUnselectable(node) === false && isContentEditableFalse$1(node);\n    };\n    var isInEditable = function (node, root) {\n      for (node = node.parentNode; node && node !== root; node = node.parentNode) {\n        if (isNonUiContentEditableFalse(node)) {\n          return false;\n        }\n        if (isContentEditableTrue$1(node)) {\n          return true;\n        }\n      }\n      return true;\n    };\n    var isAtomicContentEditableFalse = function (node) {\n      if (!isNonUiContentEditableFalse(node)) {\n        return false;\n      }\n      return foldl(from$1(node.getElementsByTagName('*')), function (result, elm) {\n        return result || isContentEditableTrue$1(elm);\n      }, false) !== true;\n    };\n    var isAtomic = function (node) {\n      return isAtomicInline(node) || isAtomicContentEditableFalse(node);\n    };\n    var isEditableCaretCandidate = function (node, root) {\n      return isCaretCandidate(node) && isInEditable(node, root);\n    };\n\n    var round = Math.round;\n    var clone$1 = function (rect) {\n      if (!rect) {\n        return {\n          left: 0,\n          top: 0,\n          bottom: 0,\n          right: 0,\n          width: 0,\n          height: 0\n        };\n      }\n      return {\n        left: round(rect.left),\n        top: round(rect.top),\n        bottom: round(rect.bottom),\n        right: round(rect.right),\n        width: round(rect.width),\n        height: round(rect.height)\n      };\n    };\n    var collapse = function (rect, toStart) {\n      rect = clone$1(rect);\n      if (toStart) {\n        rect.right = rect.left;\n      } else {\n        rect.left = rect.left + rect.width;\n        rect.right = rect.left;\n      }\n      rect.width = 0;\n      return rect;\n    };\n    var isEqual = function (rect1, rect2) {\n      return rect1.left === rect2.left && rect1.top === rect2.top && rect1.bottom === rect2.bottom && rect1.right === rect2.right;\n    };\n    var isValidOverflow = function (overflowY, rect1, rect2) {\n      return overflowY >= 0 && overflowY <= Math.min(rect1.height, rect2.height) / 2;\n    };\n    var isAbove = function (rect1, rect2) {\n      if (rect1.bottom - rect1.height / 2 < rect2.top) {\n        return true;\n      }\n      if (rect1.top > rect2.bottom) {\n        return false;\n      }\n      return isValidOverflow(rect2.top - rect1.bottom, rect1, rect2);\n    };\n    var isBelow = function (rect1, rect2) {\n      if (rect1.top > rect2.bottom) {\n        return true;\n      }\n      if (rect1.bottom < rect2.top) {\n        return false;\n      }\n      return isValidOverflow(rect2.bottom - rect1.top, rect1, rect2);\n    };\n    var containsXY = function (rect, clientX, clientY) {\n      return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;\n    };\n\n    var getSelectedNode = function (range) {\n      var startContainer = range.startContainer, startOffset = range.startOffset;\n      if (startContainer.hasChildNodes() && range.endOffset === startOffset + 1) {\n        return startContainer.childNodes[startOffset];\n      }\n      return null;\n    };\n    var getNode = function (container, offset) {\n      if (container.nodeType === 1 && container.hasChildNodes()) {\n        if (offset >= container.childNodes.length) {\n          offset = container.childNodes.length - 1;\n        }\n        container = container.childNodes[offset];\n      }\n      return container;\n    };\n\n    var extendingChars = new RegExp('[\\u0300-\\u036f\\u0483-\\u0487\\u0488-\\u0489\\u0591-\\u05bd\\u05bf\\u05c1-\\u05c2\\u05c4-\\u05c5\\u05c7\\u0610-\\u061a' + '\\u064b-\\u065f\\u0670\\u06d6-\\u06dc\\u06df-\\u06e4\\u06e7-\\u06e8\\u06ea-\\u06ed\\u0711\\u0730-\\u074a\\u07a6-\\u07b0' + '\\u07eb-\\u07f3\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0859-\\u085b\\u08e3-\\u0902\\u093a\\u093c' + '\\u0941-\\u0948\\u094d\\u0951-\\u0957\\u0962-\\u0963\\u0981\\u09bc\\u09be\\u09c1-\\u09c4\\u09cd\\u09d7\\u09e2-\\u09e3' + '\\u0a01-\\u0a02\\u0a3c\\u0a41-\\u0a42\\u0a47-\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a70-\\u0a71\\u0a75\\u0a81-\\u0a82\\u0abc' + '\\u0ac1-\\u0ac5\\u0ac7-\\u0ac8\\u0acd\\u0ae2-\\u0ae3\\u0b01\\u0b3c\\u0b3e\\u0b3f\\u0b41-\\u0b44\\u0b4d\\u0b56\\u0b57' + '\\u0b62-\\u0b63\\u0b82\\u0bbe\\u0bc0\\u0bcd\\u0bd7\\u0c00\\u0c3e-\\u0c40\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55-\\u0c56' + '\\u0c62-\\u0c63\\u0c81\\u0cbc\\u0cbf\\u0cc2\\u0cc6\\u0ccc-\\u0ccd\\u0cd5-\\u0cd6\\u0ce2-\\u0ce3\\u0d01\\u0d3e\\u0d41-\\u0d44' + '\\u0d4d\\u0d57\\u0d62-\\u0d63\\u0dca\\u0dcf\\u0dd2-\\u0dd4\\u0dd6\\u0ddf\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0eb1\\u0eb4-\\u0eb9' + '\\u0ebb-\\u0ebc\\u0ec8-\\u0ecd\\u0f18-\\u0f19\\u0f35\\u0f37\\u0f39\\u0f71-\\u0f7e\\u0f80-\\u0f84\\u0f86-\\u0f87\\u0f8d-\\u0f97' + '\\u0f99-\\u0fbc\\u0fc6\\u102d-\\u1030\\u1032-\\u1037\\u1039-\\u103a\\u103d-\\u103e\\u1058-\\u1059\\u105e-\\u1060\\u1071-\\u1074' + '\\u1082\\u1085-\\u1086\\u108d\\u109d\\u135d-\\u135f\\u1712-\\u1714\\u1732-\\u1734\\u1752-\\u1753\\u1772-\\u1773\\u17b4-\\u17b5' + '\\u17b7-\\u17bd\\u17c6\\u17c9-\\u17d3\\u17dd\\u180b-\\u180d\\u18a9\\u1920-\\u1922\\u1927-\\u1928\\u1932\\u1939-\\u193b\\u1a17-\\u1a18' + '\\u1a1b\\u1a56\\u1a58-\\u1a5e\\u1a60\\u1a62\\u1a65-\\u1a6c\\u1a73-\\u1a7c\\u1a7f\\u1ab0-\\u1abd\\u1ABE\\u1b00-\\u1b03\\u1b34' + '\\u1b36-\\u1b3a\\u1b3c\\u1b42\\u1b6b-\\u1b73\\u1b80-\\u1b81\\u1ba2-\\u1ba5\\u1ba8-\\u1ba9\\u1bab-\\u1bad\\u1be6\\u1be8-\\u1be9' + '\\u1bed\\u1bef-\\u1bf1\\u1c2c-\\u1c33\\u1c36-\\u1c37\\u1cd0-\\u1cd2\\u1cd4-\\u1ce0\\u1ce2-\\u1ce8\\u1ced\\u1cf4\\u1cf8-\\u1cf9' + '\\u1dc0-\\u1df5\\u1dfc-\\u1dff\\u200c-\\u200d\\u20d0-\\u20dc\\u20DD-\\u20E0\\u20e1\\u20E2-\\u20E4\\u20e5-\\u20f0\\u2cef-\\u2cf1' + '\\u2d7f\\u2de0-\\u2dff\\u302a-\\u302d\\u302e-\\u302f\\u3099-\\u309a\\ua66f\\uA670-\\uA672\\ua674-\\ua67d\\ua69e-\\ua69f\\ua6f0-\\ua6f1' + '\\ua802\\ua806\\ua80b\\ua825-\\ua826\\ua8c4\\ua8e0-\\ua8f1\\ua926-\\ua92d\\ua947-\\ua951\\ua980-\\ua982\\ua9b3\\ua9b6-\\ua9b9\\ua9bc' + '\\ua9e5\\uaa29-\\uaa2e\\uaa31-\\uaa32\\uaa35-\\uaa36\\uaa43\\uaa4c\\uaa7c\\uaab0\\uaab2-\\uaab4\\uaab7-\\uaab8\\uaabe-\\uaabf\\uaac1' + '\\uaaec-\\uaaed\\uaaf6\\uabe5\\uabe8\\uabed\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe2f\\uff9e-\\uff9f]');\n    var isExtendingChar = function (ch) {\n      return typeof ch === 'string' && ch.charCodeAt(0) >= 768 && extendingChars.test(ch);\n    };\n\n    var lift2 = function (oa, ob, f) {\n      return oa.isSome() && ob.isSome() ? Option.some(f(oa.getOrDie(), ob.getOrDie())) : Option.none();\n    };\n    var lift3 = function (oa, ob, oc, f) {\n      return oa.isSome() && ob.isSome() && oc.isSome() ? Option.some(f(oa.getOrDie(), ob.getOrDie(), oc.getOrDie())) : Option.none();\n    };\n    var someIf = function (b, a) {\n      return b ? Option.some(a) : Option.none();\n    };\n\n    var slice$2 = [].slice;\n    var or = function () {\n      var x = [];\n      for (var _i = 0; _i < arguments.length; _i++) {\n        x[_i] = arguments[_i];\n      }\n      var args = slice$2.call(arguments);\n      return function (x) {\n        for (var i = 0; i < args.length; i++) {\n          if (args[i](x)) {\n            return true;\n          }\n        }\n        return false;\n      };\n    };\n    var and = function () {\n      var x = [];\n      for (var _i = 0; _i < arguments.length; _i++) {\n        x[_i] = arguments[_i];\n      }\n      var args = slice$2.call(arguments);\n      return function (x) {\n        for (var i = 0; i < args.length; i++) {\n          if (!args[i](x)) {\n            return false;\n          }\n        }\n        return true;\n      };\n    };\n    var Predicate = {\n      and: and,\n      or: or\n    };\n\n    var isElement$3 = NodeType.isElement;\n    var isCaretCandidate$1 = isCaretCandidate;\n    var isBlock$1 = NodeType.matchStyleValues('display', 'block table');\n    var isFloated = NodeType.matchStyleValues('float', 'left right');\n    var isValidElementCaretCandidate = Predicate.and(isElement$3, isCaretCandidate$1, not(isFloated));\n    var isNotPre = not(NodeType.matchStyleValues('white-space', 'pre pre-line pre-wrap'));\n    var isText$4 = NodeType.isText;\n    var isBr$3 = NodeType.isBr;\n    var nodeIndex = DOMUtils$1.nodeIndex;\n    var resolveIndex = getNode;\n    var createRange = function (doc) {\n      return 'createRange' in doc ? doc.createRange() : DOMUtils$1.DOM.createRng();\n    };\n    var isWhiteSpace = function (chr) {\n      return chr && /[\\r\\n\\t ]/.test(chr);\n    };\n    var isRange = function (rng) {\n      return !!rng.setStart && !!rng.setEnd;\n    };\n    var isHiddenWhiteSpaceRange = function (range) {\n      var container = range.startContainer;\n      var offset = range.startOffset;\n      var text;\n      if (isWhiteSpace(range.toString()) && isNotPre(container.parentNode) && NodeType.isText(container)) {\n        text = container.data;\n        if (isWhiteSpace(text[offset - 1]) || isWhiteSpace(text[offset + 1])) {\n          return true;\n        }\n      }\n      return false;\n    };\n    var getBrClientRect = function (brNode) {\n      var doc = brNode.ownerDocument;\n      var rng = createRange(doc);\n      var nbsp = doc.createTextNode('\\xA0');\n      var parentNode = brNode.parentNode;\n      var clientRect;\n      parentNode.insertBefore(nbsp, brNode);\n      rng.setStart(nbsp, 0);\n      rng.setEnd(nbsp, 1);\n      clientRect = clone$1(rng.getBoundingClientRect());\n      parentNode.removeChild(nbsp);\n      return clientRect;\n    };\n    var getBoundingClientRectWebKitText = function (rng) {\n      var sc = rng.startContainer;\n      var ec = rng.endContainer;\n      var so = rng.startOffset;\n      var eo = rng.endOffset;\n      if (sc === ec && NodeType.isText(ec) && so === 0 && eo === 1) {\n        var newRng = rng.cloneRange();\n        newRng.setEndAfter(ec);\n        return getBoundingClientRect(newRng);\n      } else {\n        return null;\n      }\n    };\n    var isZeroRect = function (r) {\n      return r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0;\n    };\n    var getBoundingClientRect = function (item) {\n      var clientRect, clientRects;\n      clientRects = item.getClientRects();\n      if (clientRects.length > 0) {\n        clientRect = clone$1(clientRects[0]);\n      } else {\n        clientRect = clone$1(item.getBoundingClientRect());\n      }\n      if (!isRange(item) && isBr$3(item) && isZeroRect(clientRect)) {\n        return getBrClientRect(item);\n      }\n      if (isZeroRect(clientRect) && isRange(item)) {\n        return getBoundingClientRectWebKitText(item);\n      }\n      return clientRect;\n    };\n    var collapseAndInflateWidth = function (clientRect, toStart) {\n      var newClientRect = collapse(clientRect, toStart);\n      newClientRect.width = 1;\n      newClientRect.right = newClientRect.left + 1;\n      return newClientRect;\n    };\n    var getCaretPositionClientRects = function (caretPosition) {\n      var clientRects = [];\n      var beforeNode, node;\n      var addUniqueAndValidRect = function (clientRect) {\n        if (clientRect.height === 0) {\n          return;\n        }\n        if (clientRects.length > 0) {\n          if (isEqual(clientRect, clientRects[clientRects.length - 1])) {\n            return;\n          }\n        }\n        clientRects.push(clientRect);\n      };\n      var addCharacterOffset = function (container, offset) {\n        var range = createRange(container.ownerDocument);\n        if (offset < container.data.length) {\n          if (isExtendingChar(container.data[offset])) {\n            return clientRects;\n          }\n          if (isExtendingChar(container.data[offset - 1])) {\n            range.setStart(container, offset);\n            range.setEnd(container, offset + 1);\n            if (!isHiddenWhiteSpaceRange(range)) {\n              addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false));\n              return clientRects;\n            }\n          }\n        }\n        if (offset > 0) {\n          range.setStart(container, offset - 1);\n          range.setEnd(container, offset);\n          if (!isHiddenWhiteSpaceRange(range)) {\n            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false));\n          }\n        }\n        if (offset < container.data.length) {\n          range.setStart(container, offset);\n          range.setEnd(container, offset + 1);\n          if (!isHiddenWhiteSpaceRange(range)) {\n            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), true));\n          }\n        }\n      };\n      if (isText$4(caretPosition.container())) {\n        addCharacterOffset(caretPosition.container(), caretPosition.offset());\n        return clientRects;\n      }\n      if (isElement$3(caretPosition.container())) {\n        if (caretPosition.isAtEnd()) {\n          node = resolveIndex(caretPosition.container(), caretPosition.offset());\n          if (isText$4(node)) {\n            addCharacterOffset(node, node.data.length);\n          }\n          if (isValidElementCaretCandidate(node) && !isBr$3(node)) {\n            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false));\n          }\n        } else {\n          node = resolveIndex(caretPosition.container(), caretPosition.offset());\n          if (isText$4(node)) {\n            addCharacterOffset(node, 0);\n          }\n          if (isValidElementCaretCandidate(node) && caretPosition.isAtEnd()) {\n            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false));\n            return clientRects;\n          }\n          beforeNode = resolveIndex(caretPosition.container(), caretPosition.offset() - 1);\n          if (isValidElementCaretCandidate(beforeNode) && !isBr$3(beforeNode)) {\n            if (isBlock$1(beforeNode) || isBlock$1(node) || !isValidElementCaretCandidate(node)) {\n              addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(beforeNode), false));\n            }\n          }\n          if (isValidElementCaretCandidate(node)) {\n            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), true));\n          }\n        }\n      }\n      return clientRects;\n    };\n    function CaretPosition(container, offset, clientRects) {\n      var isAtStart = function () {\n        if (isText$4(container)) {\n          return offset === 0;\n        }\n        return offset === 0;\n      };\n      var isAtEnd = function () {\n        if (isText$4(container)) {\n          return offset >= container.data.length;\n        }\n        return offset >= container.childNodes.length;\n      };\n      var toRange = function () {\n        var range;\n        range = createRange(container.ownerDocument);\n        range.setStart(container, offset);\n        range.setEnd(container, offset);\n        return range;\n      };\n      var getClientRects = function () {\n        if (!clientRects) {\n          clientRects = getCaretPositionClientRects(CaretPosition(container, offset));\n        }\n        return clientRects;\n      };\n      var isVisible = function () {\n        return getClientRects().length > 0;\n      };\n      var isEqual = function (caretPosition) {\n        return caretPosition && container === caretPosition.container() && offset === caretPosition.offset();\n      };\n      var getNode = function (before) {\n        return resolveIndex(container, before ? offset - 1 : offset);\n      };\n      return {\n        container: constant(container),\n        offset: constant(offset),\n        toRange: toRange,\n        getClientRects: getClientRects,\n        isVisible: isVisible,\n        isAtStart: isAtStart,\n        isAtEnd: isAtEnd,\n        isEqual: isEqual,\n        getNode: getNode\n      };\n    }\n    (function (CaretPosition) {\n      CaretPosition.fromRangeStart = function (range) {\n        return CaretPosition(range.startContainer, range.startOffset);\n      };\n      CaretPosition.fromRangeEnd = function (range) {\n        return CaretPosition(range.endContainer, range.endOffset);\n      };\n      CaretPosition.after = function (node) {\n        return CaretPosition(node.parentNode, nodeIndex(node) + 1);\n      };\n      CaretPosition.before = function (node) {\n        return CaretPosition(node.parentNode, nodeIndex(node));\n      };\n      CaretPosition.isAbove = function (pos1, pos2) {\n        return lift2(head(pos2.getClientRects()), last(pos1.getClientRects()), isAbove).getOr(false);\n      };\n      CaretPosition.isBelow = function (pos1, pos2) {\n        return lift2(last(pos2.getClientRects()), head(pos1.getClientRects()), isBelow).getOr(false);\n      };\n      CaretPosition.isAtStart = function (pos) {\n        return pos ? pos.isAtStart() : false;\n      };\n      CaretPosition.isAtEnd = function (pos) {\n        return pos ? pos.isAtEnd() : false;\n      };\n      CaretPosition.isTextPosition = function (pos) {\n        return pos ? NodeType.isText(pos.container()) : false;\n      };\n      CaretPosition.isElementPosition = function (pos) {\n        return CaretPosition.isTextPosition(pos) === false;\n      };\n    }(CaretPosition || (CaretPosition = {})));\n    var CaretPosition$1 = CaretPosition;\n\n    var isText$5 = NodeType.isText;\n    var isBogus$1 = NodeType.isBogus;\n    var nodeIndex$1 = DOMUtils$1.nodeIndex;\n    var normalizedParent = function (node) {\n      var parentNode = node.parentNode;\n      if (isBogus$1(parentNode)) {\n        return normalizedParent(parentNode);\n      }\n      return parentNode;\n    };\n    var getChildNodes = function (node) {\n      if (!node) {\n        return [];\n      }\n      return ArrUtils.reduce(node.childNodes, function (result, node) {\n        if (isBogus$1(node) && node.nodeName !== 'BR') {\n          result = result.concat(getChildNodes(node));\n        } else {\n          result.push(node);\n        }\n        return result;\n      }, []);\n    };\n    var normalizedTextOffset = function (node, offset) {\n      while (node = node.previousSibling) {\n        if (!isText$5(node)) {\n          break;\n        }\n        offset += node.data.length;\n      }\n      return offset;\n    };\n    var equal = function (a) {\n      return function (b) {\n        return a === b;\n      };\n    };\n    var normalizedNodeIndex = function (node) {\n      var nodes, index, numTextFragments;\n      nodes = getChildNodes(normalizedParent(node));\n      index = ArrUtils.findIndex(nodes, equal(node), node);\n      nodes = nodes.slice(0, index + 1);\n      numTextFragments = ArrUtils.reduce(nodes, function (result, node, i) {\n        if (isText$5(node) && isText$5(nodes[i - 1])) {\n          result++;\n        }\n        return result;\n      }, 0);\n      nodes = ArrUtils.filter(nodes, NodeType.matchNodeNames([node.nodeName]));\n      index = ArrUtils.findIndex(nodes, equal(node), node);\n      return index - numTextFragments;\n    };\n    var createPathItem = function (node) {\n      var name;\n      if (isText$5(node)) {\n        name = 'text()';\n      } else {\n        name = node.nodeName.toLowerCase();\n      }\n      return name + '[' + normalizedNodeIndex(node) + ']';\n    };\n    var parentsUntil = function (root, node, predicate) {\n      var parents = [];\n      for (node = node.parentNode; node !== root; node = node.parentNode) {\n        if (predicate && predicate(node)) {\n          break;\n        }\n        parents.push(node);\n      }\n      return parents;\n    };\n    var create$2 = function (root, caretPosition) {\n      var container, offset, path = [], outputOffset, childNodes, parents;\n      container = caretPosition.container();\n      offset = caretPosition.offset();\n      if (isText$5(container)) {\n        outputOffset = normalizedTextOffset(container, offset);\n      } else {\n        childNodes = container.childNodes;\n        if (offset >= childNodes.length) {\n          outputOffset = 'after';\n          offset = childNodes.length - 1;\n        } else {\n          outputOffset = 'before';\n        }\n        container = childNodes[offset];\n      }\n      path.push(createPathItem(container));\n      parents = parentsUntil(root, container);\n      parents = ArrUtils.filter(parents, not(NodeType.isBogus));\n      path = path.concat(ArrUtils.map(parents, function (node) {\n        return createPathItem(node);\n      }));\n      return path.reverse().join('/') + ',' + outputOffset;\n    };\n    var resolvePathItem = function (node, name, index) {\n      var nodes = getChildNodes(node);\n      nodes = ArrUtils.filter(nodes, function (node, index) {\n        return !isText$5(node) || !isText$5(nodes[index - 1]);\n      });\n      nodes = ArrUtils.filter(nodes, NodeType.matchNodeNames([name]));\n      return nodes[index];\n    };\n    var findTextPosition = function (container, offset) {\n      var node = container, targetOffset = 0, dataLen;\n      while (isText$5(node)) {\n        dataLen = node.data.length;\n        if (offset >= targetOffset && offset <= targetOffset + dataLen) {\n          container = node;\n          offset = offset - targetOffset;\n          break;\n        }\n        if (!isText$5(node.nextSibling)) {\n          container = node;\n          offset = dataLen;\n          break;\n        }\n        targetOffset += dataLen;\n        node = node.nextSibling;\n      }\n      if (isText$5(container) && offset > container.data.length) {\n        offset = container.data.length;\n      }\n      return CaretPosition$1(container, offset);\n    };\n    var resolve$1 = function (root, path) {\n      var parts, container, offset;\n      if (!path) {\n        return null;\n      }\n      parts = path.split(',');\n      path = parts[0].split('/');\n      offset = parts.length > 1 ? parts[1] : 'before';\n      container = ArrUtils.reduce(path, function (result, value) {\n        value = /([\\w\\-\\(\\)]+)\\[([0-9]+)\\]/.exec(value);\n        if (!value) {\n          return null;\n        }\n        if (value[1] === 'text()') {\n          value[1] = '#text';\n        }\n        return resolvePathItem(result, value[1], parseInt(value[2], 10));\n      }, root);\n      if (!container) {\n        return null;\n      }\n      if (!isText$5(container)) {\n        if (offset === 'after') {\n          offset = nodeIndex$1(container) + 1;\n        } else {\n          offset = nodeIndex$1(container);\n        }\n        return CaretPosition$1(container.parentNode, offset);\n      }\n      return findTextPosition(container, parseInt(offset, 10));\n    };\n\n    var trimEmptyTextNode = function (dom, node) {\n      if (NodeType.isText(node) && node.data.length === 0) {\n        dom.remove(node);\n      }\n    };\n    var insertNode = function (dom, rng, node) {\n      rng.insertNode(node);\n      trimEmptyTextNode(dom, node.previousSibling);\n      trimEmptyTextNode(dom, node.nextSibling);\n    };\n    var insertFragment = function (dom, rng, frag) {\n      var firstChild = Option.from(frag.firstChild);\n      var lastChild = Option.from(frag.lastChild);\n      rng.insertNode(frag);\n      firstChild.each(function (child) {\n        return trimEmptyTextNode(dom, child.previousSibling);\n      });\n      lastChild.each(function (child) {\n        return trimEmptyTextNode(dom, child.nextSibling);\n      });\n    };\n    var rangeInsertNode = function (dom, rng, node) {\n      if (NodeType.isDocumentFragment(node)) {\n        insertFragment(dom, rng, node);\n      } else {\n        insertNode(dom, rng, node);\n      }\n    };\n\n    var isContentEditableFalse$2 = NodeType.isContentEditableFalse;\n    var getNormalizedTextOffset = function (trim, container, offset) {\n      var node, trimmedOffset;\n      trimmedOffset = trim(container.data.slice(0, offset)).length;\n      for (node = container.previousSibling; node && NodeType.isText(node); node = node.previousSibling) {\n        trimmedOffset += trim(node.data).length;\n      }\n      return trimmedOffset;\n    };\n    var getPoint = function (dom, trim, normalized, rng, start) {\n      var container = rng[start ? 'startContainer' : 'endContainer'];\n      var offset = rng[start ? 'startOffset' : 'endOffset'];\n      var point = [];\n      var childNodes, after = 0;\n      var root = dom.getRoot();\n      if (NodeType.isText(container)) {\n        point.push(normalized ? getNormalizedTextOffset(trim, container, offset) : offset);\n      } else {\n        childNodes = container.childNodes;\n        if (offset >= childNodes.length && childNodes.length) {\n          after = 1;\n          offset = Math.max(0, childNodes.length - 1);\n        }\n        point.push(dom.nodeIndex(childNodes[offset], normalized) + after);\n      }\n      for (; container && container !== root; container = container.parentNode) {\n        point.push(dom.nodeIndex(container, normalized));\n      }\n      return point;\n    };\n    var getLocation = function (trim, selection, normalized, rng) {\n      var dom = selection.dom, bookmark = {};\n      bookmark.start = getPoint(dom, trim, normalized, rng, true);\n      if (!selection.isCollapsed()) {\n        bookmark.end = getPoint(dom, trim, normalized, rng, false);\n      }\n      return bookmark;\n    };\n    var findIndex$2 = function (dom, name, element) {\n      var count = 0;\n      Tools.each(dom.select(name), function (node) {\n        if (node.getAttribute('data-mce-bogus') === 'all') {\n          return;\n        }\n        if (node === element) {\n          return false;\n        }\n        count++;\n      });\n      return count;\n    };\n    var moveEndPoint = function (rng, start) {\n      var container, offset, childNodes;\n      var prefix = start ? 'start' : 'end';\n      container = rng[prefix + 'Container'];\n      offset = rng[prefix + 'Offset'];\n      if (NodeType.isElement(container) && container.nodeName === 'TR') {\n        childNodes = container.childNodes;\n        container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];\n        if (container) {\n          offset = start ? 0 : container.childNodes.length;\n          rng['set' + (start ? 'Start' : 'End')](container, offset);\n        }\n      }\n    };\n    var normalizeTableCellSelection = function (rng) {\n      moveEndPoint(rng, true);\n      moveEndPoint(rng, false);\n      return rng;\n    };\n    var findSibling = function (node, offset) {\n      var sibling;\n      if (NodeType.isElement(node)) {\n        node = getNode(node, offset);\n        if (isContentEditableFalse$2(node)) {\n          return node;\n        }\n      }\n      if (isCaretContainer(node)) {\n        if (NodeType.isText(node) && isCaretContainerBlock(node)) {\n          node = node.parentNode;\n        }\n        sibling = node.previousSibling;\n        if (isContentEditableFalse$2(sibling)) {\n          return sibling;\n        }\n        sibling = node.nextSibling;\n        if (isContentEditableFalse$2(sibling)) {\n          return sibling;\n        }\n      }\n    };\n    var findAdjacentContentEditableFalseElm = function (rng) {\n      return findSibling(rng.startContainer, rng.startOffset) || findSibling(rng.endContainer, rng.endOffset);\n    };\n    var getOffsetBookmark = function (trim, normalized, selection) {\n      var element = selection.getNode();\n      var name = element ? element.nodeName : null;\n      var rng = selection.getRng();\n      if (isContentEditableFalse$2(element) || name === 'IMG') {\n        return {\n          name: name,\n          index: findIndex$2(selection.dom, name, element)\n        };\n      }\n      var sibling = findAdjacentContentEditableFalseElm(rng);\n      if (sibling) {\n        name = sibling.tagName;\n        return {\n          name: name,\n          index: findIndex$2(selection.dom, name, sibling)\n        };\n      }\n      return getLocation(trim, selection, normalized, rng);\n    };\n    var getCaretBookmark = function (selection) {\n      var rng = selection.getRng();\n      return {\n        start: create$2(selection.dom.getRoot(), CaretPosition$1.fromRangeStart(rng)),\n        end: create$2(selection.dom.getRoot(), CaretPosition$1.fromRangeEnd(rng))\n      };\n    };\n    var getRangeBookmark = function (selection) {\n      return { rng: selection.getRng() };\n    };\n    var createBookmarkSpan = function (dom, id, filled) {\n      var args = {\n        'data-mce-type': 'bookmark',\n        'id': id,\n        'style': 'overflow:hidden;line-height:0px'\n      };\n      return filled ? dom.create('span', args, '&#xFEFF;') : dom.create('span', args);\n    };\n    var getPersistentBookmark = function (selection, filled) {\n      var dom = selection.dom;\n      var rng = selection.getRng();\n      var id = dom.uniqueId();\n      var collapsed = selection.isCollapsed();\n      var element = selection.getNode();\n      var name = element.nodeName;\n      if (name === 'IMG') {\n        return {\n          name: name,\n          index: findIndex$2(dom, name, element)\n        };\n      }\n      var rng2 = normalizeTableCellSelection(rng.cloneRange());\n      if (!collapsed) {\n        rng2.collapse(false);\n        var endBookmarkNode = createBookmarkSpan(dom, id + '_end', filled);\n        rangeInsertNode(dom, rng2, endBookmarkNode);\n      }\n      rng = normalizeTableCellSelection(rng);\n      rng.collapse(true);\n      var startBookmarkNode = createBookmarkSpan(dom, id + '_start', filled);\n      rangeInsertNode(dom, rng, startBookmarkNode);\n      selection.moveToBookmark({\n        id: id,\n        keep: 1\n      });\n      return { id: id };\n    };\n    var getBookmark = function (selection, type, normalized) {\n      if (type === 2) {\n        return getOffsetBookmark(Zwsp.trim, normalized, selection);\n      } else if (type === 3) {\n        return getCaretBookmark(selection);\n      } else if (type) {\n        return getRangeBookmark(selection);\n      } else {\n        return getPersistentBookmark(selection, false);\n      }\n    };\n    var GetBookmark = {\n      getBookmark: getBookmark,\n      getUndoBookmark: curry(getOffsetBookmark, identity, true),\n      getPersistentBookmark: getPersistentBookmark\n    };\n\n    var CARET_ID = '_mce_caret';\n    var isCaretNode = function (node) {\n      return NodeType.isElement(node) && node.id === CARET_ID;\n    };\n    var getParentCaretContainer = function (body, node) {\n      while (node && node !== body) {\n        if (node.id === CARET_ID) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return null;\n    };\n\n    var isElement$4 = NodeType.isElement;\n    var isText$6 = NodeType.isText;\n    var removeNode = function (node) {\n      var parentNode = node.parentNode;\n      if (parentNode) {\n        parentNode.removeChild(node);\n      }\n    };\n    var getNodeValue = function (node) {\n      try {\n        return node.nodeValue;\n      } catch (ex) {\n        return '';\n      }\n    };\n    var setNodeValue = function (node, text) {\n      if (text.length === 0) {\n        removeNode(node);\n      } else {\n        node.nodeValue = text;\n      }\n    };\n    var trimCount = function (text) {\n      var trimmedText = Zwsp.trim(text);\n      return {\n        count: text.length - trimmedText.length,\n        text: trimmedText\n      };\n    };\n    var removeUnchanged = function (caretContainer, pos) {\n      remove$5(caretContainer);\n      return pos;\n    };\n    var removeTextAndReposition = function (caretContainer, pos) {\n      var before = trimCount(caretContainer.data.substr(0, pos.offset()));\n      var after = trimCount(caretContainer.data.substr(pos.offset()));\n      var text = before.text + after.text;\n      if (text.length > 0) {\n        setNodeValue(caretContainer, text);\n        return CaretPosition$1(caretContainer, pos.offset() - before.count);\n      } else {\n        return pos;\n      }\n    };\n    var removeElementAndReposition = function (caretContainer, pos) {\n      var parentNode = pos.container();\n      var newPosition = indexOf(from$1(parentNode.childNodes), caretContainer).map(function (index) {\n        return index < pos.offset() ? CaretPosition$1(parentNode, pos.offset() - 1) : pos;\n      }).getOr(pos);\n      remove$5(caretContainer);\n      return newPosition;\n    };\n    var removeTextCaretContainer = function (caretContainer, pos) {\n      return isText$6(caretContainer) && pos.container() === caretContainer ? removeTextAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);\n    };\n    var removeElementCaretContainer = function (caretContainer, pos) {\n      return pos.container() === caretContainer.parentNode ? removeElementAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);\n    };\n    var removeAndReposition = function (container, pos) {\n      return CaretPosition$1.isTextPosition(pos) ? removeTextCaretContainer(container, pos) : removeElementCaretContainer(container, pos);\n    };\n    var remove$5 = function (caretContainerNode) {\n      if (isElement$4(caretContainerNode) && isCaretContainer(caretContainerNode)) {\n        if (hasContent(caretContainerNode)) {\n          caretContainerNode.removeAttribute('data-mce-caret');\n        } else {\n          removeNode(caretContainerNode);\n        }\n      }\n      if (isText$6(caretContainerNode)) {\n        var text = Zwsp.trim(getNodeValue(caretContainerNode));\n        setNodeValue(caretContainerNode, text);\n      }\n    };\n    var CaretContainerRemove = {\n      removeAndReposition: removeAndReposition,\n      remove: remove$5\n    };\n\n    var browser$3 = detect$3().browser;\n    var isContentEditableFalse$3 = NodeType.isContentEditableFalse;\n    var isTableCell$1 = function (node) {\n      return NodeType.isElement(node) && /^(TD|TH)$/i.test(node.tagName);\n    };\n    var getAbsoluteClientRect = function (root, element, before) {\n      var clientRect = collapse(element.getBoundingClientRect(), before);\n      var docElm, scrollX, scrollY, margin, rootRect;\n      if (root.tagName === 'BODY') {\n        docElm = root.ownerDocument.documentElement;\n        scrollX = root.scrollLeft || docElm.scrollLeft;\n        scrollY = root.scrollTop || docElm.scrollTop;\n      } else {\n        rootRect = root.getBoundingClientRect();\n        scrollX = root.scrollLeft - rootRect.left;\n        scrollY = root.scrollTop - rootRect.top;\n      }\n      clientRect.left += scrollX;\n      clientRect.right += scrollX;\n      clientRect.top += scrollY;\n      clientRect.bottom += scrollY;\n      clientRect.width = 1;\n      margin = element.offsetWidth - element.clientWidth;\n      if (margin > 0) {\n        if (before) {\n          margin *= -1;\n        }\n        clientRect.left += margin;\n        clientRect.right += margin;\n      }\n      return clientRect;\n    };\n    var trimInlineCaretContainers = function (root) {\n      var contentEditableFalseNodes, node, sibling, i, data;\n      contentEditableFalseNodes = DomQuery('*[contentEditable=false]', root);\n      for (i = 0; i < contentEditableFalseNodes.length; i++) {\n        node = contentEditableFalseNodes[i];\n        sibling = node.previousSibling;\n        if (endsWithCaretContainer(sibling)) {\n          data = sibling.data;\n          if (data.length === 1) {\n            sibling.parentNode.removeChild(sibling);\n          } else {\n            sibling.deleteData(data.length - 1, 1);\n          }\n        }\n        sibling = node.nextSibling;\n        if (startsWithCaretContainer(sibling)) {\n          data = sibling.data;\n          if (data.length === 1) {\n            sibling.parentNode.removeChild(sibling);\n          } else {\n            sibling.deleteData(0, 1);\n          }\n        }\n      }\n    };\n    var FakeCaret = function (root, isBlock, hasFocus) {\n      var lastVisualCaret = Cell(Option.none());\n      var cursorInterval, caretContainerNode;\n      var show = function (before, element) {\n        var clientRect, rng;\n        hide();\n        if (isTableCell$1(element)) {\n          return null;\n        }\n        if (isBlock(element)) {\n          caretContainerNode = insertBlock('p', element, before);\n          clientRect = getAbsoluteClientRect(root, element, before);\n          DomQuery(caretContainerNode).css('top', clientRect.top);\n          var caret = DomQuery('<div class=\"mce-visual-caret\" data-mce-bogus=\"all\"></div>').css(clientRect).appendTo(root)[0];\n          lastVisualCaret.set(Option.some({\n            caret: caret,\n            element: element,\n            before: before\n          }));\n          lastVisualCaret.get().each(function (caretState) {\n            if (before) {\n              DomQuery(caretState.caret).addClass('mce-visual-caret-before');\n            }\n          });\n          startBlink();\n          rng = element.ownerDocument.createRange();\n          rng.setStart(caretContainerNode, 0);\n          rng.setEnd(caretContainerNode, 0);\n        } else {\n          caretContainerNode = insertInline(element, before);\n          rng = element.ownerDocument.createRange();\n          if (isContentEditableFalse$3(caretContainerNode.nextSibling)) {\n            rng.setStart(caretContainerNode, 0);\n            rng.setEnd(caretContainerNode, 0);\n          } else {\n            rng.setStart(caretContainerNode, 1);\n            rng.setEnd(caretContainerNode, 1);\n          }\n          return rng;\n        }\n        return rng;\n      };\n      var hide = function () {\n        trimInlineCaretContainers(root);\n        if (caretContainerNode) {\n          CaretContainerRemove.remove(caretContainerNode);\n          caretContainerNode = null;\n        }\n        lastVisualCaret.get().each(function (caretState) {\n          DomQuery(caretState.caret).remove();\n          lastVisualCaret.set(Option.none());\n        });\n        Delay.clearInterval(cursorInterval);\n      };\n      var startBlink = function () {\n        cursorInterval = Delay.setInterval(function () {\n          if (hasFocus()) {\n            DomQuery('div.mce-visual-caret', root).toggleClass('mce-visual-caret-hidden');\n          } else {\n            DomQuery('div.mce-visual-caret', root).addClass('mce-visual-caret-hidden');\n          }\n        }, 500);\n      };\n      var reposition = function () {\n        lastVisualCaret.get().each(function (caretState) {\n          var clientRect = getAbsoluteClientRect(root, caretState.element, caretState.before);\n          DomQuery(caretState.caret).css(__assign({}, clientRect));\n        });\n      };\n      var destroy = function () {\n        return Delay.clearInterval(cursorInterval);\n      };\n      var getCss = function () {\n        return '.mce-visual-caret {' + 'position: absolute;' + 'background-color: black;' + 'background-color: currentcolor;' + '}' + '.mce-visual-caret-hidden {' + 'display: none;' + '}' + '*[data-mce-caret] {' + 'position: absolute;' + 'left: -1000px;' + 'right: auto;' + 'top: 0;' + 'margin: 0;' + 'padding: 0;' + '}';\n      };\n      return {\n        show: show,\n        hide: hide,\n        getCss: getCss,\n        reposition: reposition,\n        destroy: destroy\n      };\n    };\n    var isFakeCaretTableBrowser = function () {\n      return browser$3.isIE() || browser$3.isEdge() || browser$3.isFirefox();\n    };\n    var isFakeCaretTarget = function (node) {\n      return isContentEditableFalse$3(node) || NodeType.isTable(node) && isFakeCaretTableBrowser();\n    };\n\n    var isContentEditableFalse$4 = NodeType.isContentEditableFalse;\n    var isBlockLike = NodeType.matchStyleValues('display', 'block table table-cell table-caption list-item');\n    var isCaretContainer$2 = isCaretContainer;\n    var isCaretContainerBlock$1 = isCaretContainerBlock;\n    var isElement$5 = NodeType.isElement;\n    var isCaretCandidate$2 = isCaretCandidate;\n    var isForwards = function (direction) {\n      return direction > 0;\n    };\n    var isBackwards = function (direction) {\n      return direction < 0;\n    };\n    var skipCaretContainers = function (walk, shallow) {\n      var node;\n      while (node = walk(shallow)) {\n        if (!isCaretContainerBlock$1(node)) {\n          return node;\n        }\n      }\n      return null;\n    };\n    var findNode = function (node, direction, predicateFn, rootNode, shallow) {\n      var walker = new TreeWalker(node, rootNode);\n      if (isBackwards(direction)) {\n        if (isContentEditableFalse$4(node) || isCaretContainerBlock$1(node)) {\n          node = skipCaretContainers(walker.prev, true);\n          if (predicateFn(node)) {\n            return node;\n          }\n        }\n        while (node = skipCaretContainers(walker.prev, shallow)) {\n          if (predicateFn(node)) {\n            return node;\n          }\n        }\n      }\n      if (isForwards(direction)) {\n        if (isContentEditableFalse$4(node) || isCaretContainerBlock$1(node)) {\n          node = skipCaretContainers(walker.next, true);\n          if (predicateFn(node)) {\n            return node;\n          }\n        }\n        while (node = skipCaretContainers(walker.next, shallow)) {\n          if (predicateFn(node)) {\n            return node;\n          }\n        }\n      }\n      return null;\n    };\n    var getParentBlock = function (node, rootNode) {\n      while (node && node !== rootNode) {\n        if (isBlockLike(node)) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return null;\n    };\n    var isInSameBlock = function (caretPosition1, caretPosition2, rootNode) {\n      return getParentBlock(caretPosition1.container(), rootNode) === getParentBlock(caretPosition2.container(), rootNode);\n    };\n    var getChildNodeAtRelativeOffset = function (relativeOffset, caretPosition) {\n      var container, offset;\n      if (!caretPosition) {\n        return null;\n      }\n      container = caretPosition.container();\n      offset = caretPosition.offset();\n      if (!isElement$5(container)) {\n        return null;\n      }\n      return container.childNodes[offset + relativeOffset];\n    };\n    var beforeAfter = function (before, node) {\n      var range = node.ownerDocument.createRange();\n      if (before) {\n        range.setStartBefore(node);\n        range.setEndBefore(node);\n      } else {\n        range.setStartAfter(node);\n        range.setEndAfter(node);\n      }\n      return range;\n    };\n    var isNodesInSameBlock = function (root, node1, node2) {\n      return getParentBlock(node1, root) === getParentBlock(node2, root);\n    };\n    var lean = function (left, root, node) {\n      var sibling, siblingName;\n      if (left) {\n        siblingName = 'previousSibling';\n      } else {\n        siblingName = 'nextSibling';\n      }\n      while (node && node !== root) {\n        sibling = node[siblingName];\n        if (isCaretContainer$2(sibling)) {\n          sibling = sibling[siblingName];\n        }\n        if (isContentEditableFalse$4(sibling)) {\n          if (isNodesInSameBlock(root, sibling, node)) {\n            return sibling;\n          }\n          break;\n        }\n        if (isCaretCandidate$2(sibling)) {\n          break;\n        }\n        node = node.parentNode;\n      }\n      return null;\n    };\n    var before$2 = curry(beforeAfter, true);\n    var after$1 = curry(beforeAfter, false);\n    var normalizeRange = function (direction, root, range) {\n      var node, container, offset, location;\n      var leanLeft = curry(lean, true, root);\n      var leanRight = curry(lean, false, root);\n      container = range.startContainer;\n      offset = range.startOffset;\n      if (isCaretContainerBlock(container)) {\n        if (!isElement$5(container)) {\n          container = container.parentNode;\n        }\n        location = container.getAttribute('data-mce-caret');\n        if (location === 'before') {\n          node = container.nextSibling;\n          if (isFakeCaretTarget(node)) {\n            return before$2(node);\n          }\n        }\n        if (location === 'after') {\n          node = container.previousSibling;\n          if (isFakeCaretTarget(node)) {\n            return after$1(node);\n          }\n        }\n      }\n      if (!range.collapsed) {\n        return range;\n      }\n      if (NodeType.isText(container)) {\n        if (isCaretContainer$2(container)) {\n          if (direction === 1) {\n            node = leanRight(container);\n            if (node) {\n              return before$2(node);\n            }\n            node = leanLeft(container);\n            if (node) {\n              return after$1(node);\n            }\n          }\n          if (direction === -1) {\n            node = leanLeft(container);\n            if (node) {\n              return after$1(node);\n            }\n            node = leanRight(container);\n            if (node) {\n              return before$2(node);\n            }\n          }\n          return range;\n        }\n        if (endsWithCaretContainer(container) && offset >= container.data.length - 1) {\n          if (direction === 1) {\n            node = leanRight(container);\n            if (node) {\n              return before$2(node);\n            }\n          }\n          return range;\n        }\n        if (startsWithCaretContainer(container) && offset <= 1) {\n          if (direction === -1) {\n            node = leanLeft(container);\n            if (node) {\n              return after$1(node);\n            }\n          }\n          return range;\n        }\n        if (offset === container.data.length) {\n          node = leanRight(container);\n          if (node) {\n            return before$2(node);\n          }\n          return range;\n        }\n        if (offset === 0) {\n          node = leanLeft(container);\n          if (node) {\n            return after$1(node);\n          }\n          return range;\n        }\n      }\n      return range;\n    };\n    var getRelativeCefElm = function (forward, caretPosition) {\n      return Option.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, caretPosition)).filter(isContentEditableFalse$4);\n    };\n    var getNormalizedRangeEndPoint = function (direction, root, range) {\n      var normalizedRange = normalizeRange(direction, root, range);\n      if (direction === -1) {\n        return CaretPosition.fromRangeStart(normalizedRange);\n      }\n      return CaretPosition.fromRangeEnd(normalizedRange);\n    };\n    var getElementFromPosition = function (pos) {\n      return Option.from(pos.getNode()).map(Element.fromDom);\n    };\n    var getElementFromPrevPosition = function (pos) {\n      return Option.from(pos.getNode(true)).map(Element.fromDom);\n    };\n    var getVisualCaretPosition = function (walkFn, caretPosition) {\n      while (caretPosition = walkFn(caretPosition)) {\n        if (caretPosition.isVisible()) {\n          return caretPosition;\n        }\n      }\n      return caretPosition;\n    };\n    var isMoveInsideSameBlock = function (from, to) {\n      var inSameBlock = isInSameBlock(from, to);\n      if (!inSameBlock && NodeType.isBr(from.getNode())) {\n        return true;\n      }\n      return inSameBlock;\n    };\n\n    var HDirection;\n    (function (HDirection) {\n      HDirection[HDirection['Backwards'] = -1] = 'Backwards';\n      HDirection[HDirection['Forwards'] = 1] = 'Forwards';\n    }(HDirection || (HDirection = {})));\n    var isContentEditableFalse$5 = NodeType.isContentEditableFalse;\n    var isText$7 = NodeType.isText;\n    var isElement$6 = NodeType.isElement;\n    var isBr$4 = NodeType.isBr;\n    var isCaretCandidate$3 = isCaretCandidate;\n    var isAtomic$1 = isAtomic;\n    var isEditableCaretCandidate$1 = isEditableCaretCandidate;\n    var getParents = function (node, root) {\n      var parents = [];\n      while (node && node !== root) {\n        parents.push(node);\n        node = node.parentNode;\n      }\n      return parents;\n    };\n    var nodeAtIndex = function (container, offset) {\n      if (container.hasChildNodes() && offset < container.childNodes.length) {\n        return container.childNodes[offset];\n      }\n      return null;\n    };\n    var getCaretCandidatePosition = function (direction, node) {\n      if (isForwards(direction)) {\n        if (isCaretCandidate$3(node.previousSibling) && !isText$7(node.previousSibling)) {\n          return CaretPosition$1.before(node);\n        }\n        if (isText$7(node)) {\n          return CaretPosition$1(node, 0);\n        }\n      }\n      if (isBackwards(direction)) {\n        if (isCaretCandidate$3(node.nextSibling) && !isText$7(node.nextSibling)) {\n          return CaretPosition$1.after(node);\n        }\n        if (isText$7(node)) {\n          return CaretPosition$1(node, node.data.length);\n        }\n      }\n      if (isBackwards(direction)) {\n        if (isBr$4(node)) {\n          return CaretPosition$1.before(node);\n        }\n        return CaretPosition$1.after(node);\n      }\n      return CaretPosition$1.before(node);\n    };\n    var moveForwardFromBr = function (root, nextNode) {\n      var nextSibling = nextNode.nextSibling;\n      if (nextSibling && isCaretCandidate$3(nextSibling)) {\n        if (isText$7(nextSibling)) {\n          return CaretPosition$1(nextSibling, 0);\n        } else {\n          return CaretPosition$1.before(nextSibling);\n        }\n      } else {\n        return findCaretPosition(HDirection.Forwards, CaretPosition$1.after(nextNode), root);\n      }\n    };\n    var findCaretPosition = function (direction, startPos, root) {\n      var node, nextNode, innerNode;\n      var rootContentEditableFalseElm, caretPosition;\n      if (!isElement$6(root) || !startPos) {\n        return null;\n      }\n      if (startPos.isEqual(CaretPosition$1.after(root)) && root.lastChild) {\n        caretPosition = CaretPosition$1.after(root.lastChild);\n        if (isBackwards(direction) && isCaretCandidate$3(root.lastChild) && isElement$6(root.lastChild)) {\n          return isBr$4(root.lastChild) ? CaretPosition$1.before(root.lastChild) : caretPosition;\n        }\n      } else {\n        caretPosition = startPos;\n      }\n      var container = caretPosition.container();\n      var offset = caretPosition.offset();\n      if (isText$7(container)) {\n        if (isBackwards(direction) && offset > 0) {\n          return CaretPosition$1(container, --offset);\n        }\n        if (isForwards(direction) && offset < container.length) {\n          return CaretPosition$1(container, ++offset);\n        }\n        node = container;\n      } else {\n        if (isBackwards(direction) && offset > 0) {\n          nextNode = nodeAtIndex(container, offset - 1);\n          if (isCaretCandidate$3(nextNode)) {\n            if (!isAtomic$1(nextNode)) {\n              innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode);\n              if (innerNode) {\n                if (isText$7(innerNode)) {\n                  return CaretPosition$1(innerNode, innerNode.data.length);\n                }\n                return CaretPosition$1.after(innerNode);\n              }\n            }\n            if (isText$7(nextNode)) {\n              return CaretPosition$1(nextNode, nextNode.data.length);\n            }\n            return CaretPosition$1.before(nextNode);\n          }\n        }\n        if (isForwards(direction) && offset < container.childNodes.length) {\n          nextNode = nodeAtIndex(container, offset);\n          if (isCaretCandidate$3(nextNode)) {\n            if (isBr$4(nextNode)) {\n              return moveForwardFromBr(root, nextNode);\n            }\n            if (!isAtomic$1(nextNode)) {\n              innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode);\n              if (innerNode) {\n                if (isText$7(innerNode)) {\n                  return CaretPosition$1(innerNode, 0);\n                }\n                return CaretPosition$1.before(innerNode);\n              }\n            }\n            if (isText$7(nextNode)) {\n              return CaretPosition$1(nextNode, 0);\n            }\n            return CaretPosition$1.after(nextNode);\n          }\n        }\n        node = nextNode ? nextNode : caretPosition.getNode();\n      }\n      if (isForwards(direction) && caretPosition.isAtEnd() || isBackwards(direction) && caretPosition.isAtStart()) {\n        node = findNode(node, direction, constant(true), root, true);\n        if (isEditableCaretCandidate$1(node, root)) {\n          return getCaretCandidatePosition(direction, node);\n        }\n      }\n      nextNode = findNode(node, direction, isEditableCaretCandidate$1, root);\n      rootContentEditableFalseElm = ArrUtils.last(filter(getParents(container, root), isContentEditableFalse$5));\n      if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) {\n        if (isForwards(direction)) {\n          caretPosition = CaretPosition$1.after(rootContentEditableFalseElm);\n        } else {\n          caretPosition = CaretPosition$1.before(rootContentEditableFalseElm);\n        }\n        return caretPosition;\n      }\n      if (nextNode) {\n        return getCaretCandidatePosition(direction, nextNode);\n      }\n      return null;\n    };\n    var CaretWalker = function (root) {\n      return {\n        next: function (caretPosition) {\n          return findCaretPosition(HDirection.Forwards, caretPosition, root);\n        },\n        prev: function (caretPosition) {\n          return findCaretPosition(HDirection.Backwards, caretPosition, root);\n        }\n      };\n    };\n\n    var walkToPositionIn = function (forward, root, start) {\n      var position = forward ? CaretPosition$1.before(start) : CaretPosition$1.after(start);\n      return fromPosition(forward, root, position);\n    };\n    var afterElement = function (node) {\n      return NodeType.isBr(node) ? CaretPosition$1.before(node) : CaretPosition$1.after(node);\n    };\n    var isBeforeOrStart = function (position) {\n      if (CaretPosition$1.isTextPosition(position)) {\n        return position.offset() === 0;\n      } else {\n        return isCaretCandidate(position.getNode());\n      }\n    };\n    var isAfterOrEnd = function (position) {\n      if (CaretPosition$1.isTextPosition(position)) {\n        var container = position.container();\n        return position.offset() === container.data.length;\n      } else {\n        return isCaretCandidate(position.getNode(true));\n      }\n    };\n    var isBeforeAfterSameElement = function (from, to) {\n      return !CaretPosition$1.isTextPosition(from) && !CaretPosition$1.isTextPosition(to) && from.getNode() === to.getNode(true);\n    };\n    var isAtBr = function (position) {\n      return !CaretPosition$1.isTextPosition(position) && NodeType.isBr(position.getNode());\n    };\n    var shouldSkipPosition = function (forward, from, to) {\n      if (forward) {\n        return !isBeforeAfterSameElement(from, to) && !isAtBr(from) && isAfterOrEnd(from) && isBeforeOrStart(to);\n      } else {\n        return !isBeforeAfterSameElement(to, from) && isBeforeOrStart(from) && isAfterOrEnd(to);\n      }\n    };\n    var fromPosition = function (forward, root, pos) {\n      var walker = CaretWalker(root);\n      return Option.from(forward ? walker.next(pos) : walker.prev(pos));\n    };\n    var navigate = function (forward, root, from) {\n      return fromPosition(forward, root, from).bind(function (to) {\n        if (isInSameBlock(from, to, root) && shouldSkipPosition(forward, from, to)) {\n          return fromPosition(forward, root, to);\n        } else {\n          return Option.some(to);\n        }\n      });\n    };\n    var navigateIgnore = function (forward, root, from, ignoreFilter) {\n      return navigate(forward, root, from).bind(function (pos) {\n        return ignoreFilter(pos) ? navigateIgnore(forward, root, pos, ignoreFilter) : Option.some(pos);\n      });\n    };\n    var positionIn = function (forward, element) {\n      var startNode = forward ? element.firstChild : element.lastChild;\n      if (NodeType.isText(startNode)) {\n        return Option.some(CaretPosition$1(startNode, forward ? 0 : startNode.data.length));\n      } else if (startNode) {\n        if (isCaretCandidate(startNode)) {\n          return Option.some(forward ? CaretPosition$1.before(startNode) : afterElement(startNode));\n        } else {\n          return walkToPositionIn(forward, element, startNode);\n        }\n      } else {\n        return Option.none();\n      }\n    };\n    var nextPosition = curry(fromPosition, true);\n    var prevPosition = curry(fromPosition, false);\n    var CaretFinder = {\n      fromPosition: fromPosition,\n      nextPosition: nextPosition,\n      prevPosition: prevPosition,\n      navigate: navigate,\n      navigateIgnore: navigateIgnore,\n      positionIn: positionIn,\n      firstPositionIn: curry(positionIn, true),\n      lastPositionIn: curry(positionIn, false)\n    };\n\n    var isStringPathBookmark = function (bookmark) {\n      return typeof bookmark.start === 'string';\n    };\n    var isRangeBookmark = function (bookmark) {\n      return bookmark.hasOwnProperty('rng');\n    };\n    var isIdBookmark = function (bookmark) {\n      return bookmark.hasOwnProperty('id');\n    };\n    var isIndexBookmark = function (bookmark) {\n      return bookmark.hasOwnProperty('name');\n    };\n    var isPathBookmark = function (bookmark) {\n      return Tools.isArray(bookmark.start);\n    };\n\n    var addBogus = function (dom, node) {\n      if (NodeType.isElement(node) && dom.isBlock(node) && !node.innerHTML && !Env.ie) {\n        node.innerHTML = '<br data-mce-bogus=\"1\" />';\n      }\n      return node;\n    };\n    var resolveCaretPositionBookmark = function (dom, bookmark) {\n      var rng, pos;\n      rng = dom.createRng();\n      pos = resolve$1(dom.getRoot(), bookmark.start);\n      rng.setStart(pos.container(), pos.offset());\n      pos = resolve$1(dom.getRoot(), bookmark.end);\n      rng.setEnd(pos.container(), pos.offset());\n      return rng;\n    };\n    var insertZwsp = function (node, rng) {\n      var textNode = node.ownerDocument.createTextNode(Zwsp.ZWSP);\n      node.appendChild(textNode);\n      rng.setStart(textNode, 0);\n      rng.setEnd(textNode, 0);\n    };\n    var isEmpty = function (node) {\n      return node.hasChildNodes() === false;\n    };\n    var tryFindRangePosition = function (node, rng) {\n      return CaretFinder.lastPositionIn(node).fold(function () {\n        return false;\n      }, function (pos) {\n        rng.setStart(pos.container(), pos.offset());\n        rng.setEnd(pos.container(), pos.offset());\n        return true;\n      });\n    };\n    var padEmptyCaretContainer = function (root, node, rng) {\n      if (isEmpty(node) && getParentCaretContainer(root, node)) {\n        insertZwsp(node, rng);\n        return true;\n      } else {\n        return false;\n      }\n    };\n    var setEndPoint = function (dom, start, bookmark, rng) {\n      var point = bookmark[start ? 'start' : 'end'];\n      var i, node, offset, children;\n      var root = dom.getRoot();\n      if (point) {\n        offset = point[0];\n        for (node = root, i = point.length - 1; i >= 1; i--) {\n          children = node.childNodes;\n          if (padEmptyCaretContainer(root, node, rng)) {\n            return true;\n          }\n          if (point[i] > children.length - 1) {\n            if (padEmptyCaretContainer(root, node, rng)) {\n              return true;\n            }\n            return tryFindRangePosition(node, rng);\n          }\n          node = children[point[i]];\n        }\n        if (node.nodeType === 3) {\n          offset = Math.min(point[0], node.nodeValue.length);\n        }\n        if (node.nodeType === 1) {\n          offset = Math.min(point[0], node.childNodes.length);\n        }\n        if (start) {\n          rng.setStart(node, offset);\n        } else {\n          rng.setEnd(node, offset);\n        }\n      }\n      return true;\n    };\n    var isValidTextNode = function (node) {\n      return NodeType.isText(node) && node.data.length > 0;\n    };\n    var restoreEndPoint = function (dom, suffix, bookmark) {\n      var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev;\n      var keep = bookmark.keep;\n      var container, offset;\n      if (marker) {\n        node = marker.parentNode;\n        if (suffix === 'start') {\n          if (!keep) {\n            idx = dom.nodeIndex(marker);\n          } else {\n            if (marker.hasChildNodes()) {\n              node = marker.firstChild;\n              idx = 1;\n            } else if (isValidTextNode(marker.nextSibling)) {\n              node = marker.nextSibling;\n              idx = 0;\n            } else if (isValidTextNode(marker.previousSibling)) {\n              node = marker.previousSibling;\n              idx = marker.previousSibling.data.length;\n            } else {\n              node = marker.parentNode;\n              idx = dom.nodeIndex(marker) + 1;\n            }\n          }\n          container = node;\n          offset = idx;\n        } else {\n          if (!keep) {\n            idx = dom.nodeIndex(marker);\n          } else {\n            if (marker.hasChildNodes()) {\n              node = marker.firstChild;\n              idx = 1;\n            } else if (isValidTextNode(marker.previousSibling)) {\n              node = marker.previousSibling;\n              idx = marker.previousSibling.data.length;\n            } else {\n              node = marker.parentNode;\n              idx = dom.nodeIndex(marker);\n            }\n          }\n          container = node;\n          offset = idx;\n        }\n        if (!keep) {\n          prev = marker.previousSibling;\n          next = marker.nextSibling;\n          Tools.each(Tools.grep(marker.childNodes), function (node) {\n            if (NodeType.isText(node)) {\n              node.nodeValue = node.nodeValue.replace(/\\uFEFF/g, '');\n            }\n          });\n          while (marker = dom.get(bookmark.id + '_' + suffix)) {\n            dom.remove(marker, true);\n          }\n          if (prev && next && prev.nodeType === next.nodeType && NodeType.isText(prev) && !Env.opera) {\n            idx = prev.nodeValue.length;\n            prev.appendData(next.nodeValue);\n            dom.remove(next);\n            if (suffix === 'start') {\n              container = prev;\n              offset = idx;\n            } else {\n              container = prev;\n              offset = idx;\n            }\n          }\n        }\n        return Option.some(CaretPosition$1(container, offset));\n      } else {\n        return Option.none();\n      }\n    };\n    var resolvePaths = function (dom, bookmark) {\n      var rng = dom.createRng();\n      if (setEndPoint(dom, true, bookmark, rng) && setEndPoint(dom, false, bookmark, rng)) {\n        return Option.some(rng);\n      } else {\n        return Option.none();\n      }\n    };\n    var resolveId = function (dom, bookmark) {\n      var startPos = restoreEndPoint(dom, 'start', bookmark);\n      var endPos = restoreEndPoint(dom, 'end', bookmark);\n      return lift2(startPos, endPos.or(startPos), function (spos, epos) {\n        var rng = dom.createRng();\n        rng.setStart(addBogus(dom, spos.container()), spos.offset());\n        rng.setEnd(addBogus(dom, epos.container()), epos.offset());\n        return rng;\n      });\n    };\n    var resolveIndex$1 = function (dom, bookmark) {\n      return Option.from(dom.select(bookmark.name)[bookmark.index]).map(function (elm) {\n        var rng = dom.createRng();\n        rng.selectNode(elm);\n        return rng;\n      });\n    };\n    var resolve$2 = function (selection, bookmark) {\n      var dom = selection.dom;\n      if (bookmark) {\n        if (isPathBookmark(bookmark)) {\n          return resolvePaths(dom, bookmark);\n        } else if (isStringPathBookmark(bookmark)) {\n          return Option.some(resolveCaretPositionBookmark(dom, bookmark));\n        } else if (isIdBookmark(bookmark)) {\n          return resolveId(dom, bookmark);\n        } else if (isIndexBookmark(bookmark)) {\n          return resolveIndex$1(dom, bookmark);\n        } else if (isRangeBookmark(bookmark)) {\n          return Option.some(bookmark.rng);\n        }\n      }\n      return Option.none();\n    };\n    var ResolveBookmark = { resolve: resolve$2 };\n\n    var getBookmark$1 = function (selection, type, normalized) {\n      return GetBookmark.getBookmark(selection, type, normalized);\n    };\n    var moveToBookmark = function (selection, bookmark) {\n      ResolveBookmark.resolve(selection, bookmark).each(function (rng) {\n        selection.setRng(rng);\n      });\n    };\n    var isBookmarkNode$1 = function (node) {\n      return NodeType.isElement(node) && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';\n    };\n    var Bookmarks = {\n      getBookmark: getBookmark$1,\n      moveToBookmark: moveToBookmark,\n      isBookmarkNode: isBookmarkNode$1\n    };\n\n    var isInlineBlock = function (node) {\n      return node && /^(IMG)$/.test(node.nodeName);\n    };\n    var moveStart = function (dom, selection, rng) {\n      var offset = rng.startOffset;\n      var container = rng.startContainer, walker, node, nodes;\n      if (rng.startContainer === rng.endContainer) {\n        if (isInlineBlock(rng.startContainer.childNodes[rng.startOffset])) {\n          return;\n        }\n      }\n      if (container.nodeType === 1) {\n        nodes = container.childNodes;\n        if (offset < nodes.length) {\n          container = nodes[offset];\n          walker = new TreeWalker(container, dom.getParent(container, dom.isBlock));\n        } else {\n          container = nodes[nodes.length - 1];\n          walker = new TreeWalker(container, dom.getParent(container, dom.isBlock));\n          walker.next(true);\n        }\n        for (node = walker.current(); node; node = walker.next()) {\n          if (node.nodeType === 3 && !isWhiteSpaceNode(node)) {\n            rng.setStart(node, 0);\n            selection.setRng(rng);\n            return;\n          }\n        }\n      }\n    };\n    var getNonWhiteSpaceSibling = function (node, next, inc) {\n      if (node) {\n        next = next ? 'nextSibling' : 'previousSibling';\n        for (node = inc ? node : node[next]; node; node = node[next]) {\n          if (node.nodeType === 1 || !isWhiteSpaceNode(node)) {\n            return node;\n          }\n        }\n      }\n    };\n    var isTextBlock$1 = function (editor, name) {\n      if (name.nodeType) {\n        name = name.nodeName;\n      }\n      return !!editor.schema.getTextBlockElements()[name.toLowerCase()];\n    };\n    var isValid = function (ed, parent, child) {\n      return ed.schema.isValidChild(parent, child);\n    };\n    var isWhiteSpaceNode = function (node) {\n      return node && node.nodeType === 3 && /^([\\t \\r\\n]+|)$/.test(node.nodeValue);\n    };\n    var replaceVars = function (value, vars) {\n      if (typeof value !== 'string') {\n        value = value(vars);\n      } else if (vars) {\n        value = value.replace(/%(\\w+)/g, function (str, name) {\n          return vars[name] || str;\n        });\n      }\n      return value;\n    };\n    var isEq = function (str1, str2) {\n      str1 = str1 || '';\n      str2 = str2 || '';\n      str1 = '' + (str1.nodeName || str1);\n      str2 = '' + (str2.nodeName || str2);\n      return str1.toLowerCase() === str2.toLowerCase();\n    };\n    var normalizeStyleValue = function (dom, value, name) {\n      if (name === 'color' || name === 'backgroundColor') {\n        value = dom.toHex(value);\n      }\n      if (name === 'fontWeight' && value === 700) {\n        value = 'bold';\n      }\n      if (name === 'fontFamily') {\n        value = value.replace(/[\\'\\\"]/g, '').replace(/,\\s+/g, ',');\n      }\n      return '' + value;\n    };\n    var getStyle = function (dom, node, name) {\n      return normalizeStyleValue(dom, dom.getStyle(node, name), name);\n    };\n    var getTextDecoration = function (dom, node) {\n      var decoration;\n      dom.getParent(node, function (n) {\n        decoration = dom.getStyle(n, 'text-decoration');\n        return decoration && decoration !== 'none';\n      });\n      return decoration;\n    };\n    var getParents$1 = function (dom, node, selector) {\n      return dom.getParents(node, selector, dom.getRoot());\n    };\n    var FormatUtils = {\n      isInlineBlock: isInlineBlock,\n      moveStart: moveStart,\n      getNonWhiteSpaceSibling: getNonWhiteSpaceSibling,\n      isTextBlock: isTextBlock$1,\n      isValid: isValid,\n      isWhiteSpaceNode: isWhiteSpaceNode,\n      replaceVars: replaceVars,\n      isEq: isEq,\n      normalizeStyleValue: normalizeStyleValue,\n      getStyle: getStyle,\n      getTextDecoration: getTextDecoration,\n      getParents: getParents$1\n    };\n\n    var isBookmarkNode$2 = Bookmarks.isBookmarkNode;\n    var getParents$2 = FormatUtils.getParents, isWhiteSpaceNode$1 = FormatUtils.isWhiteSpaceNode, isTextBlock$2 = FormatUtils.isTextBlock;\n    var findLeaf = function (node, offset) {\n      if (typeof offset === 'undefined') {\n        offset = node.nodeType === 3 ? node.length : node.childNodes.length;\n      }\n      while (node && node.hasChildNodes()) {\n        node = node.childNodes[offset];\n        if (node) {\n          offset = node.nodeType === 3 ? node.length : node.childNodes.length;\n        }\n      }\n      return {\n        node: node,\n        offset: offset\n      };\n    };\n    var excludeTrailingWhitespace = function (endContainer, endOffset) {\n      var leaf = findLeaf(endContainer, endOffset);\n      if (leaf.node) {\n        while (leaf.node && leaf.offset === 0 && leaf.node.previousSibling) {\n          leaf = findLeaf(leaf.node.previousSibling);\n        }\n        if (leaf.node && leaf.offset > 0 && leaf.node.nodeType === 3 && leaf.node.nodeValue.charAt(leaf.offset - 1) === ' ') {\n          if (leaf.offset > 1) {\n            endContainer = leaf.node;\n            endContainer.splitText(leaf.offset - 1);\n          }\n        }\n      }\n      return endContainer;\n    };\n    var isBogusBr = function (node) {\n      return node.nodeName === 'BR' && node.getAttribute('data-mce-bogus') && !node.nextSibling;\n    };\n    var findParentContentEditable = function (dom, node) {\n      var parent = node;\n      while (parent) {\n        if (parent.nodeType === 1 && dom.getContentEditable(parent)) {\n          return dom.getContentEditable(parent) === 'false' ? parent : node;\n        }\n        parent = parent.parentNode;\n      }\n      return node;\n    };\n    var findSpace = function (start, remove, node, offset) {\n      var pos, pos2;\n      var str = node.nodeValue;\n      if (typeof offset === 'undefined') {\n        offset = start ? str.length : 0;\n      }\n      if (start) {\n        pos = str.lastIndexOf(' ', offset);\n        pos2 = str.lastIndexOf('\\xA0', offset);\n        pos = pos > pos2 ? pos : pos2;\n        if (pos !== -1 && !remove && (pos < offset || !start) && pos <= str.length) {\n          pos++;\n        }\n      } else {\n        pos = str.indexOf(' ', offset);\n        pos2 = str.indexOf('\\xA0', offset);\n        pos = pos !== -1 && (pos2 === -1 || pos < pos2) ? pos : pos2;\n      }\n      return pos;\n    };\n    var findWordEndPoint = function (dom, body, container, offset, start, remove) {\n      var node, pos, lastTextNode;\n      if (container.nodeType === 3) {\n        pos = findSpace(start, remove, container, offset);\n        if (pos !== -1) {\n          return {\n            container: container,\n            offset: pos\n          };\n        }\n        lastTextNode = container;\n      }\n      var walker = new TreeWalker(container, dom.getParent(container, dom.isBlock) || body);\n      while (node = walker[start ? 'prev' : 'next']()) {\n        if (node.nodeType === 3 && !isBookmarkNode$2(node.parentNode)) {\n          lastTextNode = node;\n          pos = findSpace(start, remove, node);\n          if (pos !== -1) {\n            return {\n              container: node,\n              offset: pos\n            };\n          }\n        } else if (dom.isBlock(node) || FormatUtils.isEq(node, 'BR')) {\n          break;\n        }\n      }\n      if (lastTextNode) {\n        if (start) {\n          offset = 0;\n        } else {\n          offset = lastTextNode.length;\n        }\n        return {\n          container: lastTextNode,\n          offset: offset\n        };\n      }\n    };\n    var findSelectorEndPoint = function (dom, format, rng, container, siblingName) {\n      var parents, i, y, curFormat;\n      if (container.nodeType === 3 && container.nodeValue.length === 0 && container[siblingName]) {\n        container = container[siblingName];\n      }\n      parents = getParents$2(dom, container);\n      for (i = 0; i < parents.length; i++) {\n        for (y = 0; y < format.length; y++) {\n          curFormat = format[y];\n          if ('collapsed' in curFormat && curFormat.collapsed !== rng.collapsed) {\n            continue;\n          }\n          if (dom.is(parents[i], curFormat.selector)) {\n            return parents[i];\n          }\n        }\n      }\n      return container;\n    };\n    var findBlockEndPoint = function (editor, format, container, siblingName) {\n      var node;\n      var dom = editor.dom;\n      var root = dom.getRoot();\n      if (!format[0].wrapper) {\n        node = dom.getParent(container, format[0].block, root);\n      }\n      if (!node) {\n        var scopeRoot = dom.getParent(container, 'LI,TD,TH');\n        node = dom.getParent(container.nodeType === 3 ? container.parentNode : container, function (node) {\n          return node !== root && isTextBlock$2(editor, node);\n        }, scopeRoot);\n      }\n      if (node && format[0].wrapper) {\n        node = getParents$2(dom, node, 'ul,ol').reverse()[0] || node;\n      }\n      if (!node) {\n        node = container;\n        while (node[siblingName] && !dom.isBlock(node[siblingName])) {\n          node = node[siblingName];\n          if (FormatUtils.isEq(node, 'br')) {\n            break;\n          }\n        }\n      }\n      return node || container;\n    };\n    var findParentContainer = function (dom, format, startContainer, startOffset, endContainer, endOffset, start) {\n      var container, parent, sibling, siblingName, root;\n      container = parent = start ? startContainer : endContainer;\n      siblingName = start ? 'previousSibling' : 'nextSibling';\n      root = dom.getRoot();\n      if (container.nodeType === 3 && !isWhiteSpaceNode$1(container)) {\n        if (start ? startOffset > 0 : endOffset < container.nodeValue.length) {\n          return container;\n        }\n      }\n      while (true) {\n        if (!format[0].block_expand && dom.isBlock(parent)) {\n          return parent;\n        }\n        for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {\n          if (!isBookmarkNode$2(sibling) && !isWhiteSpaceNode$1(sibling) && !isBogusBr(sibling)) {\n            return parent;\n          }\n        }\n        if (parent === root || parent.parentNode === root) {\n          container = parent;\n          break;\n        }\n        parent = parent.parentNode;\n      }\n      return container;\n    };\n    var expandRng = function (editor, rng, format, remove) {\n      var endPoint, startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;\n      var dom = editor.dom;\n      if (startContainer.nodeType === 1 && startContainer.hasChildNodes()) {\n        startContainer = getNode(startContainer, startOffset);\n        if (startContainer.nodeType === 3) {\n          startOffset = 0;\n        }\n      }\n      if (endContainer.nodeType === 1 && endContainer.hasChildNodes()) {\n        endContainer = getNode(endContainer, rng.collapsed ? endOffset : endOffset - 1);\n        if (endContainer.nodeType === 3) {\n          endOffset = endContainer.nodeValue.length;\n        }\n      }\n      startContainer = findParentContentEditable(dom, startContainer);\n      endContainer = findParentContentEditable(dom, endContainer);\n      if (isBookmarkNode$2(startContainer.parentNode) || isBookmarkNode$2(startContainer)) {\n        startContainer = isBookmarkNode$2(startContainer) ? startContainer : startContainer.parentNode;\n        if (rng.collapsed) {\n          startContainer = startContainer.previousSibling || startContainer;\n        } else {\n          startContainer = startContainer.nextSibling || startContainer;\n        }\n        if (startContainer.nodeType === 3) {\n          startOffset = rng.collapsed ? startContainer.length : 0;\n        }\n      }\n      if (isBookmarkNode$2(endContainer.parentNode) || isBookmarkNode$2(endContainer)) {\n        endContainer = isBookmarkNode$2(endContainer) ? endContainer : endContainer.parentNode;\n        if (rng.collapsed) {\n          endContainer = endContainer.nextSibling || endContainer;\n        } else {\n          endContainer = endContainer.previousSibling || endContainer;\n        }\n        if (endContainer.nodeType === 3) {\n          endOffset = rng.collapsed ? 0 : endContainer.length;\n        }\n      }\n      if (rng.collapsed) {\n        endPoint = findWordEndPoint(dom, editor.getBody(), startContainer, startOffset, true, remove);\n        if (endPoint) {\n          startContainer = endPoint.container;\n          startOffset = endPoint.offset;\n        }\n        endPoint = findWordEndPoint(dom, editor.getBody(), endContainer, endOffset, false, remove);\n        if (endPoint) {\n          endContainer = endPoint.container;\n          endOffset = endPoint.offset;\n        }\n      }\n      if (format[0].inline) {\n        endContainer = remove ? endContainer : excludeTrailingWhitespace(endContainer, endOffset);\n      }\n      if (format[0].inline || format[0].block_expand) {\n        if (!format[0].inline || (startContainer.nodeType !== 3 || startOffset === 0)) {\n          startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true);\n        }\n        if (!format[0].inline || (endContainer.nodeType !== 3 || endOffset === endContainer.nodeValue.length)) {\n          endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false);\n        }\n      }\n      if (format[0].selector && format[0].expand !== false && !format[0].inline) {\n        startContainer = findSelectorEndPoint(dom, format, rng, startContainer, 'previousSibling');\n        endContainer = findSelectorEndPoint(dom, format, rng, endContainer, 'nextSibling');\n      }\n      if (format[0].block || format[0].selector) {\n        startContainer = findBlockEndPoint(editor, format, startContainer, 'previousSibling');\n        endContainer = findBlockEndPoint(editor, format, endContainer, 'nextSibling');\n        if (format[0].block) {\n          if (!dom.isBlock(startContainer)) {\n            startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true);\n          }\n          if (!dom.isBlock(endContainer)) {\n            endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false);\n          }\n        }\n      }\n      if (startContainer.nodeType === 1) {\n        startOffset = dom.nodeIndex(startContainer);\n        startContainer = startContainer.parentNode;\n      }\n      if (endContainer.nodeType === 1) {\n        endOffset = dom.nodeIndex(endContainer) + 1;\n        endContainer = endContainer.parentNode;\n      }\n      return {\n        startContainer: startContainer,\n        startOffset: startOffset,\n        endContainer: endContainer,\n        endOffset: endOffset\n      };\n    };\n    var ExpandRange = { expandRng: expandRng };\n\n    var each$8 = Tools.each;\n    var getEndChild = function (container, index) {\n      var childNodes = container.childNodes;\n      index--;\n      if (index > childNodes.length - 1) {\n        index = childNodes.length - 1;\n      } else if (index < 0) {\n        index = 0;\n      }\n      return childNodes[index] || container;\n    };\n    var walk$1 = function (dom, rng, callback) {\n      var startContainer = rng.startContainer;\n      var startOffset = rng.startOffset;\n      var endContainer = rng.endContainer;\n      var endOffset = rng.endOffset;\n      var ancestor;\n      var startPoint;\n      var endPoint;\n      var node;\n      var parent;\n      var siblings;\n      var nodes;\n      nodes = dom.select('td[data-mce-selected],th[data-mce-selected]');\n      if (nodes.length > 0) {\n        each$8(nodes, function (node) {\n          callback([node]);\n        });\n        return;\n      }\n      var exclude = function (nodes) {\n        var node;\n        node = nodes[0];\n        if (node.nodeType === 3 && node === startContainer && startOffset >= node.nodeValue.length) {\n          nodes.splice(0, 1);\n        }\n        node = nodes[nodes.length - 1];\n        if (endOffset === 0 && nodes.length > 0 && node === endContainer && node.nodeType === 3) {\n          nodes.splice(nodes.length - 1, 1);\n        }\n        return nodes;\n      };\n      var collectSiblings = function (node, name, endNode) {\n        var siblings = [];\n        for (; node && node !== endNode; node = node[name]) {\n          siblings.push(node);\n        }\n        return siblings;\n      };\n      var findEndPoint = function (node, root) {\n        do {\n          if (node.parentNode === root) {\n            return node;\n          }\n          node = node.parentNode;\n        } while (node);\n      };\n      var walkBoundary = function (startNode, endNode, next) {\n        var siblingName = next ? 'nextSibling' : 'previousSibling';\n        for (node = startNode, parent = node.parentNode; node && node !== endNode; node = parent) {\n          parent = node.parentNode;\n          siblings = collectSiblings(node === startNode ? node : node[siblingName], siblingName);\n          if (siblings.length) {\n            if (!next) {\n              siblings.reverse();\n            }\n            callback(exclude(siblings));\n          }\n        }\n      };\n      if (startContainer.nodeType === 1 && startContainer.hasChildNodes()) {\n        startContainer = startContainer.childNodes[startOffset];\n      }\n      if (endContainer.nodeType === 1 && endContainer.hasChildNodes()) {\n        endContainer = getEndChild(endContainer, endOffset);\n      }\n      if (startContainer === endContainer) {\n        return callback(exclude([startContainer]));\n      }\n      ancestor = dom.findCommonAncestor(startContainer, endContainer);\n      for (node = startContainer; node; node = node.parentNode) {\n        if (node === endContainer) {\n          return walkBoundary(startContainer, ancestor, true);\n        }\n        if (node === ancestor) {\n          break;\n        }\n      }\n      for (node = endContainer; node; node = node.parentNode) {\n        if (node === startContainer) {\n          return walkBoundary(endContainer, ancestor);\n        }\n        if (node === ancestor) {\n          break;\n        }\n      }\n      startPoint = findEndPoint(startContainer, ancestor) || startContainer;\n      endPoint = findEndPoint(endContainer, ancestor) || endContainer;\n      walkBoundary(startContainer, startPoint, true);\n      siblings = collectSiblings(startPoint === startContainer ? startPoint : startPoint.nextSibling, 'nextSibling', endPoint === endContainer ? endPoint.nextSibling : endPoint);\n      if (siblings.length) {\n        callback(exclude(siblings));\n      }\n      walkBoundary(endContainer, endPoint);\n    };\n    var RangeWalk = { walk: walk$1 };\n\n    var zeroWidth = function () {\n      return '\\uFEFF';\n    };\n\n    function NodeValue (is, name) {\n      var get = function (element) {\n        if (!is(element)) {\n          throw new Error('Can only get ' + name + ' value of a ' + name + ' node');\n        }\n        return getOption(element).getOr('');\n      };\n      var getOption = function (element) {\n        return is(element) ? Option.from(element.dom().nodeValue) : Option.none();\n      };\n      var set = function (element, value) {\n        if (!is(element)) {\n          throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');\n        }\n        element.dom().nodeValue = value;\n      };\n      return {\n        get: get,\n        getOption: getOption,\n        set: set\n      };\n    }\n\n    var api = NodeValue(isText$1, 'text');\n    var get$6 = function (element) {\n      return api.get(element);\n    };\n\n    var isZeroWidth = function (elem) {\n      return isText$1(elem) && get$6(elem) === zeroWidth();\n    };\n    var context = function (editor, elem, wrapName, nodeName) {\n      return parent(elem).fold(function () {\n        return 'skipping';\n      }, function (parent) {\n        if (nodeName === 'br' || isZeroWidth(elem)) {\n          return 'valid';\n        } else if (isAnnotation(elem)) {\n          return 'existing';\n        } else if (isCaretNode(elem)) {\n          return 'caret';\n        } else if (!FormatUtils.isValid(editor, wrapName, nodeName) || !FormatUtils.isValid(editor, name(parent), wrapName)) {\n          return 'invalid-child';\n        } else {\n          return 'valid';\n        }\n      });\n    };\n\n    var shouldApplyToTrailingSpaces = function (rng) {\n      return rng.startContainer.nodeType === 3 && rng.startContainer.nodeValue.length >= rng.startOffset && rng.startContainer.nodeValue[rng.startOffset] === '\\xA0';\n    };\n    var applyWordGrab = function (editor, rng) {\n      var r = ExpandRange.expandRng(editor, rng, [{ inline: true }], shouldApplyToTrailingSpaces(rng));\n      rng.setStart(r.startContainer, r.startOffset);\n      rng.setEnd(r.endContainer, r.endOffset);\n      editor.selection.setRng(rng);\n    };\n    var makeAnnotation = function (eDoc, _a, annotationName, decorate) {\n      var _b = _a.uid, uid = _b === void 0 ? generate('mce-annotation') : _b, data = __rest(_a, ['uid']);\n      var master = Element.fromTag('span', eDoc);\n      add$3(master, annotation());\n      set(master, '' + dataAnnotationId(), uid);\n      set(master, '' + dataAnnotation(), annotationName);\n      var _c = decorate(uid, data), _d = _c.attributes, attributes = _d === void 0 ? {} : _d, _e = _c.classes, classes = _e === void 0 ? [] : _e;\n      setAll(master, attributes);\n      add$4(master, classes);\n      return master;\n    };\n    var annotate = function (editor, rng, annotationName, decorate, data) {\n      var newWrappers = [];\n      var master = makeAnnotation(editor.getDoc(), data, annotationName, decorate);\n      var wrapper = Cell(Option.none());\n      var finishWrapper = function () {\n        wrapper.set(Option.none());\n      };\n      var getOrOpenWrapper = function () {\n        return wrapper.get().getOrThunk(function () {\n          var nu = shallow(master);\n          newWrappers.push(nu);\n          wrapper.set(Option.some(nu));\n          return nu;\n        });\n      };\n      var processElements = function (elems) {\n        each(elems, processElement);\n      };\n      var processElement = function (elem) {\n        var ctx = context(editor, elem, 'span', name(elem));\n        switch (ctx) {\n        case 'invalid-child': {\n            finishWrapper();\n            var children$1 = children(elem);\n            processElements(children$1);\n            finishWrapper();\n            break;\n          }\n        case 'valid': {\n            var w = getOrOpenWrapper();\n            wrap$1(elem, w);\n            break;\n          }\n        case 'skipping':\n        case 'existing':\n        case 'caret':\n        }\n      };\n      var processNodes = function (nodes) {\n        var elems = map(nodes, Element.fromDom);\n        processElements(elems);\n      };\n      RangeWalk.walk(editor.dom, rng, function (nodes) {\n        finishWrapper();\n        processNodes(nodes);\n      });\n      return newWrappers;\n    };\n    var annotateWithBookmark = function (editor, name, settings, data) {\n      editor.undoManager.transact(function () {\n        var initialRng = editor.selection.getRng();\n        if (initialRng.collapsed) {\n          applyWordGrab(editor, initialRng);\n        }\n        if (editor.selection.getRng().collapsed) {\n          var wrapper = makeAnnotation(editor.getDoc(), data, name, settings.decorate);\n          set$1(wrapper, '\\xA0');\n          editor.selection.getRng().insertNode(wrapper.dom());\n          editor.selection.select(wrapper.dom());\n        } else {\n          var bookmark = GetBookmark.getPersistentBookmark(editor.selection, false);\n          var rng = editor.selection.getRng();\n          annotate(editor, rng, name, settings.decorate, data);\n          editor.selection.moveToBookmark(bookmark);\n        }\n      });\n    };\n\n    var Annotator = function (editor) {\n      var registry = create$1();\n      setup$1(editor, registry);\n      var changes = setup(editor);\n      return {\n        register: function (name, settings) {\n          registry.register(name, settings);\n        },\n        annotate: function (name, data) {\n          registry.lookup(name).each(function (settings) {\n            annotateWithBookmark(editor, name, settings, data);\n          });\n        },\n        annotationChanged: function (name, callback) {\n          changes.addListener(name, callback);\n        },\n        remove: function (name) {\n          identify(editor, Option.some(name)).each(function (_a) {\n            var elements = _a.elements;\n            each(elements, unwrap);\n          });\n        },\n        getAll: function (name) {\n          var directory = findAll(editor, name);\n          return map$1(directory, function (elems) {\n            return map(elems, function (elem) {\n              return elem.dom();\n            });\n          });\n        }\n      };\n    };\n\n    var whiteSpaceRegExp$3 = /^[ \\t\\r\\n]*$/;\n    var typeLookup = {\n      '#text': 3,\n      '#comment': 8,\n      '#cdata': 4,\n      '#pi': 7,\n      '#doctype': 10,\n      '#document-fragment': 11\n    };\n    var walk$2 = function (node, root, prev) {\n      var startName = prev ? 'lastChild' : 'firstChild';\n      var siblingName = prev ? 'prev' : 'next';\n      if (node[startName]) {\n        return node[startName];\n      }\n      if (node !== root) {\n        var sibling = node[siblingName];\n        if (sibling) {\n          return sibling;\n        }\n        for (var parent = node.parent; parent && parent !== root; parent = parent.parent) {\n          sibling = parent[siblingName];\n          if (sibling) {\n            return sibling;\n          }\n        }\n      }\n    };\n    var Node$1 = function () {\n      function Node(name, type) {\n        this.name = name;\n        this.type = type;\n        if (type === 1) {\n          this.attributes = [];\n          this.attributes.map = {};\n        }\n      }\n      Node.create = function (name, attrs) {\n        var node = new Node(name, typeLookup[name] || 1);\n        if (attrs) {\n          for (var attrName in attrs) {\n            node.attr(attrName, attrs[attrName]);\n          }\n        }\n        return node;\n      };\n      Node.prototype.replace = function (node) {\n        var self = this;\n        if (node.parent) {\n          node.remove();\n        }\n        self.insert(node, self);\n        self.remove();\n        return self;\n      };\n      Node.prototype.attr = function (name, value) {\n        var self = this;\n        var attrs;\n        if (typeof name !== 'string') {\n          for (var key in name) {\n            self.attr(key, name[key]);\n          }\n          return self;\n        }\n        if (attrs = self.attributes) {\n          if (value !== undefined) {\n            if (value === null) {\n              if (name in attrs.map) {\n                delete attrs.map[name];\n                var i = attrs.length;\n                while (i--) {\n                  if (attrs[i].name === name) {\n                    attrs.splice(i, 1);\n                    return self;\n                  }\n                }\n              }\n              return self;\n            }\n            if (name in attrs.map) {\n              var i = attrs.length;\n              while (i--) {\n                if (attrs[i].name === name) {\n                  attrs[i].value = value;\n                  break;\n                }\n              }\n            } else {\n              attrs.push({\n                name: name,\n                value: value\n              });\n            }\n            attrs.map[name] = value;\n            return self;\n          }\n          return attrs.map[name];\n        }\n      };\n      Node.prototype.clone = function () {\n        var self = this;\n        var clone = new Node(self.name, self.type);\n        var selfAttrs;\n        if (selfAttrs = self.attributes) {\n          var cloneAttrs = [];\n          cloneAttrs.map = {};\n          for (var i = 0, l = selfAttrs.length; i < l; i++) {\n            var selfAttr = selfAttrs[i];\n            if (selfAttr.name !== 'id') {\n              cloneAttrs[cloneAttrs.length] = {\n                name: selfAttr.name,\n                value: selfAttr.value\n              };\n              cloneAttrs.map[selfAttr.name] = selfAttr.value;\n            }\n          }\n          clone.attributes = cloneAttrs;\n        }\n        clone.value = self.value;\n        clone.shortEnded = self.shortEnded;\n        return clone;\n      };\n      Node.prototype.wrap = function (wrapper) {\n        var self = this;\n        self.parent.insert(wrapper, self);\n        wrapper.append(self);\n        return self;\n      };\n      Node.prototype.unwrap = function () {\n        var self = this;\n        for (var node = self.firstChild; node;) {\n          var next = node.next;\n          self.insert(node, self, true);\n          node = next;\n        }\n        self.remove();\n      };\n      Node.prototype.remove = function () {\n        var self = this, parent = self.parent, next = self.next, prev = self.prev;\n        if (parent) {\n          if (parent.firstChild === self) {\n            parent.firstChild = next;\n            if (next) {\n              next.prev = null;\n            }\n          } else {\n            prev.next = next;\n          }\n          if (parent.lastChild === self) {\n            parent.lastChild = prev;\n            if (prev) {\n              prev.next = null;\n            }\n          } else {\n            next.prev = prev;\n          }\n          self.parent = self.next = self.prev = null;\n        }\n        return self;\n      };\n      Node.prototype.append = function (node) {\n        var self = this;\n        if (node.parent) {\n          node.remove();\n        }\n        var last = self.lastChild;\n        if (last) {\n          last.next = node;\n          node.prev = last;\n          self.lastChild = node;\n        } else {\n          self.lastChild = self.firstChild = node;\n        }\n        node.parent = self;\n        return node;\n      };\n      Node.prototype.insert = function (node, refNode, before) {\n        if (node.parent) {\n          node.remove();\n        }\n        var parent = refNode.parent || this;\n        if (before) {\n          if (refNode === parent.firstChild) {\n            parent.firstChild = node;\n          } else {\n            refNode.prev.next = node;\n          }\n          node.prev = refNode.prev;\n          node.next = refNode;\n          refNode.prev = node;\n        } else {\n          if (refNode === parent.lastChild) {\n            parent.lastChild = node;\n          } else {\n            refNode.next.prev = node;\n          }\n          node.next = refNode.next;\n          node.prev = refNode;\n          refNode.next = node;\n        }\n        node.parent = parent;\n        return node;\n      };\n      Node.prototype.getAll = function (name) {\n        var self = this;\n        var collection = [];\n        for (var node = self.firstChild; node; node = walk$2(node, self)) {\n          if (node.name === name) {\n            collection.push(node);\n          }\n        }\n        return collection;\n      };\n      Node.prototype.empty = function () {\n        var self = this;\n        if (self.firstChild) {\n          var nodes = [];\n          for (var node = self.firstChild; node; node = walk$2(node, self)) {\n            nodes.push(node);\n          }\n          var i = nodes.length;\n          while (i--) {\n            var node = nodes[i];\n            node.parent = node.firstChild = node.lastChild = node.next = node.prev = null;\n          }\n        }\n        self.firstChild = self.lastChild = null;\n        return self;\n      };\n      Node.prototype.isEmpty = function (elements, whitespace, predicate) {\n        if (whitespace === void 0) {\n          whitespace = {};\n        }\n        var self = this;\n        var node = self.firstChild;\n        if (node) {\n          do {\n            if (node.type === 1) {\n              if (node.attr('data-mce-bogus')) {\n                continue;\n              }\n              if (elements[node.name]) {\n                return false;\n              }\n              var i = node.attributes.length;\n              while (i--) {\n                var name = node.attributes[i].name;\n                if (name === 'name' || name.indexOf('data-mce-bookmark') === 0) {\n                  return false;\n                }\n              }\n            }\n            if (node.type === 8) {\n              return false;\n            }\n            if (node.type === 3 && !whiteSpaceRegExp$3.test(node.value)) {\n              return false;\n            }\n            if (node.type === 3 && node.parent && whitespace[node.parent.name] && whiteSpaceRegExp$3.test(node.value)) {\n              return false;\n            }\n            if (predicate && predicate(node)) {\n              return false;\n            }\n          } while (node = walk$2(node, self));\n        }\n        return true;\n      };\n      Node.prototype.walk = function (prev) {\n        return walk$2(this, null, prev);\n      };\n      return Node;\n    }();\n\n    var isValidPrefixAttrName = function (name) {\n      return name.indexOf('data-') === 0 || name.indexOf('aria-') === 0;\n    };\n    var trimComments = function (text) {\n      return text.replace(/<!--|-->/g, '');\n    };\n    var isInvalidUri = function (settings, uri) {\n      if (settings.allow_html_data_urls) {\n        return false;\n      } else if (/^data:image\\//i.test(uri)) {\n        return settings.allow_svg_data_urls === false && /^data:image\\/svg\\+xml/i.test(uri);\n      } else {\n        return /^data:/i.test(uri);\n      }\n    };\n    var findEndTagIndex = function (schema, html, startIndex) {\n      var count = 1, index, matches, tokenRegExp, shortEndedElements;\n      shortEndedElements = schema.getShortEndedElements();\n      tokenRegExp = /<([!?\\/])?([A-Za-z0-9\\-_\\:\\.]+)((?:\\s+[^\"\\'>]+(?:(?:\"[^\"]*\")|(?:\\'[^\\']*\\')|[^>]*))*|\\/|\\s+)>/g;\n      tokenRegExp.lastIndex = index = startIndex;\n      while (matches = tokenRegExp.exec(html)) {\n        index = tokenRegExp.lastIndex;\n        if (matches[1] === '/') {\n          count--;\n        } else if (!matches[1]) {\n          if (matches[2] in shortEndedElements) {\n            continue;\n          }\n          count++;\n        }\n        if (count === 0) {\n          break;\n        }\n      }\n      return index;\n    };\n    var checkBogusAttribute = function (regExp, attrString) {\n      var matches = regExp.exec(attrString);\n      if (matches) {\n        var name = matches[1];\n        var value = matches[2];\n        return typeof name === 'string' && name.toLowerCase() === 'data-mce-bogus' ? value : null;\n      } else {\n        return null;\n      }\n    };\n    function SaxParser(settings, schema) {\n      if (schema === void 0) {\n        schema = Schema();\n      }\n      var noop = function () {\n      };\n      settings = settings || {};\n      if (settings.fix_self_closing !== false) {\n        settings.fix_self_closing = true;\n      }\n      var comment = settings.comment ? settings.comment : noop;\n      var cdata = settings.cdata ? settings.cdata : noop;\n      var text = settings.text ? settings.text : noop;\n      var start = settings.start ? settings.start : noop;\n      var end = settings.end ? settings.end : noop;\n      var pi = settings.pi ? settings.pi : noop;\n      var doctype = settings.doctype ? settings.doctype : noop;\n      var parse = function (html) {\n        var matches, index = 0, value, endRegExp;\n        var stack = [];\n        var attrList, i, textData, name;\n        var isInternalElement, removeInternalElements, shortEndedElements, fillAttrsMap, isShortEnded;\n        var validate, elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns;\n        var attributesRequired, attributesDefault, attributesForced, processHtml;\n        var anyAttributesRequired, selfClosing, tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0;\n        var decode = Entities.decode;\n        var fixSelfClosing;\n        var filteredUrlAttrs = Tools.makeMap('src,href,data,background,formaction,poster,xlink:href');\n        var scriptUriRegExp = /((java|vb)script|mhtml):/i;\n        var processEndTag = function (name) {\n          var pos, i;\n          pos = stack.length;\n          while (pos--) {\n            if (stack[pos].name === name) {\n              break;\n            }\n          }\n          if (pos >= 0) {\n            for (i = stack.length - 1; i >= pos; i--) {\n              name = stack[i];\n              if (name.valid) {\n                end(name.name);\n              }\n            }\n            stack.length = pos;\n          }\n        };\n        var parseAttribute = function (match, name, value, val2, val3) {\n          var attrRule, i;\n          var trimRegExp = /[\\s\\u0000-\\u001F]+/g;\n          name = name.toLowerCase();\n          value = name in fillAttrsMap ? name : decode(value || val2 || val3 || '');\n          if (validate && !isInternalElement && isValidPrefixAttrName(name) === false) {\n            attrRule = validAttributesMap[name];\n            if (!attrRule && validAttributePatterns) {\n              i = validAttributePatterns.length;\n              while (i--) {\n                attrRule = validAttributePatterns[i];\n                if (attrRule.pattern.test(name)) {\n                  break;\n                }\n              }\n              if (i === -1) {\n                attrRule = null;\n              }\n            }\n            if (!attrRule) {\n              return;\n            }\n            if (attrRule.validValues && !(value in attrRule.validValues)) {\n              return;\n            }\n          }\n          if (filteredUrlAttrs[name] && !settings.allow_script_urls) {\n            var uri = value.replace(trimRegExp, '');\n            try {\n              uri = decodeURIComponent(uri);\n            } catch (ex) {\n              uri = unescape(uri);\n            }\n            if (scriptUriRegExp.test(uri)) {\n              return;\n            }\n            if (isInvalidUri(settings, uri)) {\n              return;\n            }\n          }\n          if (isInternalElement && (name in filteredUrlAttrs || name.indexOf('on') === 0)) {\n            return;\n          }\n          attrList.map[name] = value;\n          attrList.push({\n            name: name,\n            value: value\n          });\n        };\n        tokenRegExp = new RegExp('<(?:' + '(?:!--([\\\\w\\\\W]*?)--!?>)|' + '(?:!\\\\[CDATA\\\\[([\\\\w\\\\W]*?)\\\\]\\\\]>)|' + '(?:!DOCTYPE([\\\\w\\\\W]*?)>)|' + '(?:\\\\?([^\\\\s\\\\/<>]+) ?([\\\\w\\\\W]*?)[?/]>)|' + '(?:\\\\/([A-Za-z][A-Za-z0-9\\\\-_\\\\:\\\\.]*)>)|' + '(?:([A-Za-z][A-Za-z0-9\\\\-_\\\\:\\\\.]*)((?:\\\\s+[^\"\\'>]+(?:(?:\"[^\"]*\")|(?:\\'[^\\']*\\')|[^>]*))*|\\\\/|\\\\s+)>)' + ')', 'g');\n        attrRegExp = /([\\w:\\-]+)(?:\\s*=\\s*(?:(?:\\\"((?:[^\\\"])*)\\\")|(?:\\'((?:[^\\'])*)\\')|([^>\\s]+)))?/g;\n        shortEndedElements = schema.getShortEndedElements();\n        selfClosing = settings.self_closing_elements || schema.getSelfClosingElements();\n        fillAttrsMap = schema.getBoolAttrs();\n        validate = settings.validate;\n        removeInternalElements = settings.remove_internals;\n        fixSelfClosing = settings.fix_self_closing;\n        specialElements = schema.getSpecialElements();\n        processHtml = html + '>';\n        while (matches = tokenRegExp.exec(processHtml)) {\n          if (index < matches.index) {\n            text(decode(html.substr(index, matches.index - index)));\n          }\n          if (value = matches[6]) {\n            value = value.toLowerCase();\n            if (value.charAt(0) === ':') {\n              value = value.substr(1);\n            }\n            processEndTag(value);\n          } else if (value = matches[7]) {\n            if (matches.index + matches[0].length > html.length) {\n              text(decode(html.substr(matches.index)));\n              index = matches.index + matches[0].length;\n              continue;\n            }\n            value = value.toLowerCase();\n            if (value.charAt(0) === ':') {\n              value = value.substr(1);\n            }\n            isShortEnded = value in shortEndedElements;\n            if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) {\n              processEndTag(value);\n            }\n            var bogusValue = checkBogusAttribute(attrRegExp, matches[8]);\n            if (bogusValue !== null) {\n              if (bogusValue === 'all') {\n                index = findEndTagIndex(schema, html, tokenRegExp.lastIndex);\n                tokenRegExp.lastIndex = index;\n                continue;\n              }\n              isValidElement = false;\n            }\n            if (!validate || (elementRule = schema.getElementRule(value))) {\n              isValidElement = true;\n              if (validate) {\n                validAttributesMap = elementRule.attributes;\n                validAttributePatterns = elementRule.attributePatterns;\n              }\n              if (attribsValue = matches[8]) {\n                isInternalElement = attribsValue.indexOf('data-mce-type') !== -1;\n                if (isInternalElement && removeInternalElements) {\n                  isValidElement = false;\n                }\n                attrList = [];\n                attrList.map = {};\n                attribsValue.replace(attrRegExp, parseAttribute);\n              } else {\n                attrList = [];\n                attrList.map = {};\n              }\n              if (validate && !isInternalElement) {\n                attributesRequired = elementRule.attributesRequired;\n                attributesDefault = elementRule.attributesDefault;\n                attributesForced = elementRule.attributesForced;\n                anyAttributesRequired = elementRule.removeEmptyAttrs;\n                if (anyAttributesRequired && !attrList.length) {\n                  isValidElement = false;\n                }\n                if (attributesForced) {\n                  i = attributesForced.length;\n                  while (i--) {\n                    attr = attributesForced[i];\n                    name = attr.name;\n                    attrValue = attr.value;\n                    if (attrValue === '{$uid}') {\n                      attrValue = 'mce_' + idCount++;\n                    }\n                    attrList.map[name] = attrValue;\n                    attrList.push({\n                      name: name,\n                      value: attrValue\n                    });\n                  }\n                }\n                if (attributesDefault) {\n                  i = attributesDefault.length;\n                  while (i--) {\n                    attr = attributesDefault[i];\n                    name = attr.name;\n                    if (!(name in attrList.map)) {\n                      attrValue = attr.value;\n                      if (attrValue === '{$uid}') {\n                        attrValue = 'mce_' + idCount++;\n                      }\n                      attrList.map[name] = attrValue;\n                      attrList.push({\n                        name: name,\n                        value: attrValue\n                      });\n                    }\n                  }\n                }\n                if (attributesRequired) {\n                  i = attributesRequired.length;\n                  while (i--) {\n                    if (attributesRequired[i] in attrList.map) {\n                      break;\n                    }\n                  }\n                  if (i === -1) {\n                    isValidElement = false;\n                  }\n                }\n                if (attr = attrList.map['data-mce-bogus']) {\n                  if (attr === 'all') {\n                    index = findEndTagIndex(schema, html, tokenRegExp.lastIndex);\n                    tokenRegExp.lastIndex = index;\n                    continue;\n                  }\n                  isValidElement = false;\n                }\n              }\n              if (isValidElement) {\n                start(value, attrList, isShortEnded);\n              }\n            } else {\n              isValidElement = false;\n            }\n            if (endRegExp = specialElements[value]) {\n              endRegExp.lastIndex = index = matches.index + matches[0].length;\n              if (matches = endRegExp.exec(html)) {\n                if (isValidElement) {\n                  textData = html.substr(index, matches.index - index);\n                }\n                index = matches.index + matches[0].length;\n              } else {\n                textData = html.substr(index);\n                index = html.length;\n              }\n              if (isValidElement) {\n                if (textData.length > 0) {\n                  text(textData, true);\n                }\n                end(value);\n              }\n              tokenRegExp.lastIndex = index;\n              continue;\n            }\n            if (!isShortEnded) {\n              if (!attribsValue || attribsValue.indexOf('/') !== attribsValue.length - 1) {\n                stack.push({\n                  name: value,\n                  valid: isValidElement\n                });\n              } else if (isValidElement) {\n                end(value);\n              }\n            }\n          } else if (value = matches[1]) {\n            if (value.charAt(0) === '>') {\n              value = ' ' + value;\n            }\n            if (!settings.allow_conditional_comments && value.substr(0, 3).toLowerCase() === '[if') {\n              value = ' ' + value;\n            }\n            comment(value);\n          } else if (value = matches[2]) {\n            cdata(trimComments(value));\n          } else if (value = matches[3]) {\n            doctype(value);\n          } else if (value = matches[4]) {\n            pi(value, matches[5]);\n          }\n          index = matches.index + matches[0].length;\n        }\n        if (index < html.length) {\n          text(decode(html.substr(index)));\n        }\n        for (i = stack.length - 1; i >= 0; i--) {\n          value = stack[i];\n          if (value.valid) {\n            end(value.name);\n          }\n        }\n      };\n      return { parse: parse };\n    }\n    (function (SaxParser) {\n      SaxParser.findEndTag = findEndTagIndex;\n    }(SaxParser || (SaxParser = {})));\n    var SaxParser$1 = SaxParser;\n\n    var trimHtml = function (tempAttrs, html) {\n      var trimContentRegExp = new RegExp(['\\\\s?(' + tempAttrs.join('|') + ')=\"[^\"]+\"'].join('|'), 'gi');\n      return html.replace(trimContentRegExp, '');\n    };\n    var trimInternal = function (serializer, html) {\n      var content = html;\n      var bogusAllRegExp = /<(\\w+) [^>]*data-mce-bogus=\"all\"[^>]*>/g;\n      var endTagIndex, index, matchLength, matches, shortEndedElements;\n      var schema = serializer.schema;\n      content = trimHtml(serializer.getTempAttrs(), content);\n      shortEndedElements = schema.getShortEndedElements();\n      while (matches = bogusAllRegExp.exec(content)) {\n        index = bogusAllRegExp.lastIndex;\n        matchLength = matches[0].length;\n        if (shortEndedElements[matches[1]]) {\n          endTagIndex = index;\n        } else {\n          endTagIndex = SaxParser$1.findEndTag(schema, content, index);\n        }\n        content = content.substring(0, index - matchLength) + content.substring(endTagIndex);\n        bogusAllRegExp.lastIndex = index - matchLength;\n      }\n      return Zwsp.trim(content);\n    };\n    var trimExternal = trimInternal;\n    var TrimHtml = {\n      trimExternal: trimExternal,\n      trimInternal: trimInternal\n    };\n\n    var getBodySetting = function (editor, name, defaultValue) {\n      var value = editor.getParam(name, defaultValue);\n      if (value.indexOf('=') !== -1) {\n        var bodyObj = editor.getParam(name, '', 'hash');\n        return bodyObj.hasOwnProperty(editor.id) ? bodyObj[editor.id] : defaultValue;\n      } else {\n        return value;\n      }\n    };\n    var getIframeAttrs = function (editor) {\n      return editor.getParam('iframe_attrs', {});\n    };\n    var getDocType = function (editor) {\n      return editor.getParam('doctype', '<!DOCTYPE html>');\n    };\n    var getDocumentBaseUrl = function (editor) {\n      return editor.getParam('document_base_url', '');\n    };\n    var getBodyId = function (editor) {\n      return getBodySetting(editor, 'body_id', 'tinymce');\n    };\n    var getBodyClass = function (editor) {\n      return getBodySetting(editor, 'body_class', '');\n    };\n    var getContentSecurityPolicy = function (editor) {\n      return editor.getParam('content_security_policy', '');\n    };\n    var shouldPutBrInPre = function (editor) {\n      return editor.getParam('br_in_pre', true);\n    };\n    var getForcedRootBlock = function (editor) {\n      if (editor.getParam('force_p_newlines', false)) {\n        return 'p';\n      }\n      var block = editor.getParam('forced_root_block', 'p');\n      if (block === false) {\n        return '';\n      } else if (block === true) {\n        return 'p';\n      } else {\n        return block;\n      }\n    };\n    var getForcedRootBlockAttrs = function (editor) {\n      return editor.getParam('forced_root_block_attrs', {});\n    };\n    var getBrNewLineSelector = function (editor) {\n      return editor.getParam('br_newline_selector', '.mce-toc h2,figcaption,caption');\n    };\n    var getNoNewLineSelector = function (editor) {\n      return editor.getParam('no_newline_selector', '');\n    };\n    var shouldKeepStyles = function (editor) {\n      return editor.getParam('keep_styles', true);\n    };\n    var shouldEndContainerOnEmptyBlock = function (editor) {\n      return editor.getParam('end_container_on_empty_block', false);\n    };\n    var getFontStyleValues = function (editor) {\n      return Tools.explode(editor.getParam('font_size_style_values', 'xx-small,x-small,small,medium,large,x-large,xx-large'));\n    };\n    var getFontSizeClasses = function (editor) {\n      return Tools.explode(editor.getParam('font_size_classes', ''));\n    };\n    var getImagesDataImgFilter = function (editor) {\n      return editor.getParam('images_dataimg_filter', constant(true), 'function');\n    };\n    var isAutomaticUploadsEnabled = function (editor) {\n      return editor.getParam('automatic_uploads', true, 'boolean');\n    };\n    var shouldReuseFileName = function (editor) {\n      return editor.getParam('images_reuse_filename', false, 'boolean');\n    };\n    var shouldReplaceBlobUris = function (editor) {\n      return editor.getParam('images_replace_blob_uris', true, 'boolean');\n    };\n    var getIconPackName = function (editor) {\n      return editor.getParam('icons', '', 'string');\n    };\n    var getIconsUrl = function (editor) {\n      return editor.getParam('icons_url', '', 'string');\n    };\n    var getImageUploadUrl = function (editor) {\n      return editor.getParam('images_upload_url', '', 'string');\n    };\n    var getImageUploadBasePath = function (editor) {\n      return editor.getParam('images_upload_base_path', '', 'string');\n    };\n    var getImagesUploadCredentials = function (editor) {\n      return editor.getParam('images_upload_credentials', false, 'boolean');\n    };\n    var getImagesUploadHandler = function (editor) {\n      return editor.getParam('images_upload_handler', null, 'function');\n    };\n    var shouldUseContentCssCors = function (editor) {\n      return editor.getParam('content_css_cors', false, 'boolean');\n    };\n    var getReferrerPolicy = function (editor) {\n      return editor.getParam('referrer_policy', '', 'string');\n    };\n    var getLanguageCode = function (editor) {\n      return editor.getParam('language', 'en', 'string');\n    };\n    var getLanguageUrl = function (editor) {\n      return editor.getParam('language_url', '', 'string');\n    };\n    var shouldIndentUseMargin = function (editor) {\n      return editor.getParam('indent_use_margin', false);\n    };\n    var getIndentation = function (editor) {\n      return editor.getParam('indentation', '40px', 'string');\n    };\n    var getContentCss = function (editor) {\n      var contentCss = editor.settings.content_css;\n      if (isString(contentCss)) {\n        return map(contentCss.split(','), trim);\n      } else if (isArray(contentCss)) {\n        return contentCss;\n      } else if (contentCss === false || editor.inline) {\n        return [];\n      } else {\n        return ['default'];\n      }\n    };\n    var getDirectionality = function (editor) {\n      return editor.getParam('directionality', I18n.isRtl() ? 'rtl' : undefined);\n    };\n    var getInlineBoundarySelector = function (editor) {\n      return editor.getParam('inline_boundaries_selector', 'a[href],code,.mce-annotation', 'string');\n    };\n    var Settings = {\n      getIframeAttrs: getIframeAttrs,\n      getDocType: getDocType,\n      getDocumentBaseUrl: getDocumentBaseUrl,\n      getBodyId: getBodyId,\n      getBodyClass: getBodyClass,\n      getContentSecurityPolicy: getContentSecurityPolicy,\n      shouldPutBrInPre: shouldPutBrInPre,\n      getForcedRootBlock: getForcedRootBlock,\n      getForcedRootBlockAttrs: getForcedRootBlockAttrs,\n      getBrNewLineSelector: getBrNewLineSelector,\n      getNoNewLineSelector: getNoNewLineSelector,\n      shouldKeepStyles: shouldKeepStyles,\n      shouldEndContainerOnEmptyBlock: shouldEndContainerOnEmptyBlock,\n      getFontStyleValues: getFontStyleValues,\n      getFontSizeClasses: getFontSizeClasses,\n      getIconPackName: getIconPackName,\n      getIconsUrl: getIconsUrl,\n      getImagesDataImgFilter: getImagesDataImgFilter,\n      isAutomaticUploadsEnabled: isAutomaticUploadsEnabled,\n      shouldReuseFileName: shouldReuseFileName,\n      shouldReplaceBlobUris: shouldReplaceBlobUris,\n      getImageUploadUrl: getImageUploadUrl,\n      getImageUploadBasePath: getImageUploadBasePath,\n      getImagesUploadCredentials: getImagesUploadCredentials,\n      getImagesUploadHandler: getImagesUploadHandler,\n      shouldUseContentCssCors: shouldUseContentCssCors,\n      getReferrerPolicy: getReferrerPolicy,\n      getLanguageCode: getLanguageCode,\n      getLanguageUrl: getLanguageUrl,\n      shouldIndentUseMargin: shouldIndentUseMargin,\n      getIndentation: getIndentation,\n      getContentCss: getContentCss,\n      getDirectionality: getDirectionality,\n      getInlineBoundarySelector: getInlineBoundarySelector\n    };\n\n    var defaultFormat = 'html';\n    var trimEmptyContents = function (editor, html) {\n      var blockName = Settings.getForcedRootBlock(editor);\n      var emptyRegExp = new RegExp('^(<' + blockName + '[^>]*>(&nbsp;|&#160;|\\\\s|\\xA0|<br \\\\/>|)<\\\\/' + blockName + '>[\\r\\n]*|<br \\\\/>[\\r\\n]*)$');\n      return html.replace(emptyRegExp, '');\n    };\n    var getContentFromBody = function (editor, args, body) {\n      var content;\n      args.format = args.format ? args.format : defaultFormat;\n      args.get = true;\n      args.getInner = true;\n      if (!args.no_events) {\n        editor.fire('BeforeGetContent', args);\n      }\n      if (args.format === 'raw') {\n        content = Tools.trim(TrimHtml.trimExternal(editor.serializer, body.innerHTML));\n      } else if (args.format === 'text') {\n        content = Zwsp.trim(body.innerText || body.textContent);\n      } else if (args.format === 'tree') {\n        return editor.serializer.serialize(body, args);\n      } else {\n        content = trimEmptyContents(editor, editor.serializer.serialize(body, args));\n      }\n      if (args.format !== 'text' && !isWsPreserveElement(Element.fromDom(body))) {\n        args.content = Tools.trim(content);\n      } else {\n        args.content = content;\n      }\n      if (!args.no_events) {\n        editor.fire('GetContent', args);\n      }\n      return args.content;\n    };\n    var getContent = function (editor, args) {\n      if (args === void 0) {\n        args = {};\n      }\n      return Option.from(editor.getBody()).fold(constant(args.format === 'tree' ? new Node$1('body', 11) : ''), function (body) {\n        return getContentFromBody(editor, args, body);\n      });\n    };\n\n    var makeMap$3 = Tools.makeMap;\n    var Writer = function (settings) {\n      var html = [];\n      var indent, indentBefore, indentAfter, encode, htmlOutput;\n      settings = settings || {};\n      indent = settings.indent;\n      indentBefore = makeMap$3(settings.indent_before || '');\n      indentAfter = makeMap$3(settings.indent_after || '');\n      encode = Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities);\n      htmlOutput = settings.element_format === 'html';\n      return {\n        start: function (name, attrs, empty) {\n          var i, l, attr, value;\n          if (indent && indentBefore[name] && html.length > 0) {\n            value = html[html.length - 1];\n            if (value.length > 0 && value !== '\\n') {\n              html.push('\\n');\n            }\n          }\n          html.push('<', name);\n          if (attrs) {\n            for (i = 0, l = attrs.length; i < l; i++) {\n              attr = attrs[i];\n              html.push(' ', attr.name, '=\"', encode(attr.value, true), '\"');\n            }\n          }\n          if (!empty || htmlOutput) {\n            html[html.length] = '>';\n          } else {\n            html[html.length] = ' />';\n          }\n          if (empty && indent && indentAfter[name] && html.length > 0) {\n            value = html[html.length - 1];\n            if (value.length > 0 && value !== '\\n') {\n              html.push('\\n');\n            }\n          }\n        },\n        end: function (name) {\n          var value;\n          html.push('</', name, '>');\n          if (indent && indentAfter[name] && html.length > 0) {\n            value = html[html.length - 1];\n            if (value.length > 0 && value !== '\\n') {\n              html.push('\\n');\n            }\n          }\n        },\n        text: function (text, raw) {\n          if (text.length > 0) {\n            html[html.length] = raw ? text : encode(text);\n          }\n        },\n        cdata: function (text) {\n          html.push('<![CDATA[', text, ']]>');\n        },\n        comment: function (text) {\n          html.push('<!--', text, '-->');\n        },\n        pi: function (name, text) {\n          if (text) {\n            html.push('<?', name, ' ', encode(text), '?>');\n          } else {\n            html.push('<?', name, '?>');\n          }\n          if (indent) {\n            html.push('\\n');\n          }\n        },\n        doctype: function (text) {\n          html.push('<!DOCTYPE', text, '>', indent ? '\\n' : '');\n        },\n        reset: function () {\n          html.length = 0;\n        },\n        getContent: function () {\n          return html.join('').replace(/\\n$/, '');\n        }\n      };\n    };\n\n    var Serializer = function (settings, schema) {\n      if (schema === void 0) {\n        schema = Schema();\n      }\n      var writer = Writer(settings);\n      settings = settings || {};\n      settings.validate = 'validate' in settings ? settings.validate : true;\n      var serialize = function (node) {\n        var handlers, validate;\n        validate = settings.validate;\n        handlers = {\n          3: function (node) {\n            writer.text(node.value, node.raw);\n          },\n          8: function (node) {\n            writer.comment(node.value);\n          },\n          7: function (node) {\n            writer.pi(node.name, node.value);\n          },\n          10: function (node) {\n            writer.doctype(node.value);\n          },\n          4: function (node) {\n            writer.cdata(node.value);\n          },\n          11: function (node) {\n            if (node = node.firstChild) {\n              do {\n                walk(node);\n              } while (node = node.next);\n            }\n          }\n        };\n        writer.reset();\n        var walk = function (node) {\n          var handler = handlers[node.type];\n          var name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule;\n          if (!handler) {\n            name = node.name;\n            isEmpty = node.shortEnded;\n            attrs = node.attributes;\n            if (validate && attrs && attrs.length > 1) {\n              sortedAttrs = [];\n              sortedAttrs.map = {};\n              elementRule = schema.getElementRule(node.name);\n              if (elementRule) {\n                for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) {\n                  attrName = elementRule.attributesOrder[i];\n                  if (attrName in attrs.map) {\n                    attrValue = attrs.map[attrName];\n                    sortedAttrs.map[attrName] = attrValue;\n                    sortedAttrs.push({\n                      name: attrName,\n                      value: attrValue\n                    });\n                  }\n                }\n                for (i = 0, l = attrs.length; i < l; i++) {\n                  attrName = attrs[i].name;\n                  if (!(attrName in sortedAttrs.map)) {\n                    attrValue = attrs.map[attrName];\n                    sortedAttrs.map[attrName] = attrValue;\n                    sortedAttrs.push({\n                      name: attrName,\n                      value: attrValue\n                    });\n                  }\n                }\n                attrs = sortedAttrs;\n              }\n            }\n            writer.start(node.name, attrs, isEmpty);\n            if (!isEmpty) {\n              if (node = node.firstChild) {\n                do {\n                  walk(node);\n                } while (node = node.next);\n              }\n              writer.end(name);\n            }\n          } else {\n            handler(node);\n          }\n        };\n        if (node.type === 1 && !settings.inner) {\n          walk(node);\n        } else {\n          handlers[11](node);\n        }\n        return writer.getContent();\n      };\n      return { serialize: serialize };\n    };\n\n    var traverse = function (node, fn) {\n      fn(node);\n      if (node.firstChild) {\n        traverse(node.firstChild, fn);\n      }\n      if (node.next) {\n        traverse(node.next, fn);\n      }\n    };\n    var findMatchingNodes = function (nodeFilters, attributeFilters, node) {\n      var nodeMatches = {};\n      var attrMatches = {};\n      var matches = [];\n      if (node.firstChild) {\n        traverse(node.firstChild, function (node) {\n          each(nodeFilters, function (filter) {\n            if (filter.name === node.name) {\n              if (nodeMatches[filter.name]) {\n                nodeMatches[filter.name].nodes.push(node);\n              } else {\n                nodeMatches[filter.name] = {\n                  filter: filter,\n                  nodes: [node]\n                };\n              }\n            }\n          });\n          each(attributeFilters, function (filter) {\n            if (typeof node.attr(filter.name) === 'string') {\n              if (attrMatches[filter.name]) {\n                attrMatches[filter.name].nodes.push(node);\n              } else {\n                attrMatches[filter.name] = {\n                  filter: filter,\n                  nodes: [node]\n                };\n              }\n            }\n          });\n        });\n      }\n      for (var name in nodeMatches) {\n        if (nodeMatches.hasOwnProperty(name)) {\n          matches.push(nodeMatches[name]);\n        }\n      }\n      for (var name in attrMatches) {\n        if (attrMatches.hasOwnProperty(name)) {\n          matches.push(attrMatches[name]);\n        }\n      }\n      return matches;\n    };\n    var filter$2 = function (nodeFilters, attributeFilters, node) {\n      var matches = findMatchingNodes(nodeFilters, attributeFilters, node);\n      each(matches, function (match) {\n        each(match.filter.callbacks, function (callback) {\n          callback(match.nodes, match.filter.name, {});\n        });\n      });\n    };\n\n    var hasFocus = function (element) {\n      var doc = owner(element).dom();\n      return element.dom() === doc.activeElement;\n    };\n    var active = function (_doc) {\n      var doc = _doc !== undefined ? _doc.dom() : domGlobals.document;\n      return Option.from(doc.activeElement).map(Element.fromDom);\n    };\n    var search = function (element) {\n      return active(owner(element)).filter(function (e) {\n        return element.dom().contains(e.dom());\n      });\n    };\n\n    var generate$1 = function (cases) {\n      if (!isArray(cases)) {\n        throw new Error('cases must be an array');\n      }\n      if (cases.length === 0) {\n        throw new Error('there must be at least one case');\n      }\n      var constructors = [];\n      var adt = {};\n      each(cases, function (acase, count) {\n        var keys$1 = keys(acase);\n        if (keys$1.length !== 1) {\n          throw new Error('one and only one name per case');\n        }\n        var key = keys$1[0];\n        var value = acase[key];\n        if (adt[key] !== undefined) {\n          throw new Error('duplicate key detected:' + key);\n        } else if (key === 'cata') {\n          throw new Error('cannot have a case named cata (sorry)');\n        } else if (!isArray(value)) {\n          throw new Error('case arguments must be an array');\n        }\n        constructors.push(key);\n        adt[key] = function () {\n          var argLength = arguments.length;\n          if (argLength !== value.length) {\n            throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);\n          }\n          var args = new Array(argLength);\n          for (var i = 0; i < args.length; i++) {\n            args[i] = arguments[i];\n          }\n          var match = function (branches) {\n            var branchKeys = keys(branches);\n            if (constructors.length !== branchKeys.length) {\n              throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\\nActual: ' + branchKeys.join(','));\n            }\n            var allReqd = forall(constructors, function (reqKey) {\n              return contains(branchKeys, reqKey);\n            });\n            if (!allReqd) {\n              throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\\nRequired: ' + constructors.join(', '));\n            }\n            return branches[key].apply(null, args);\n          };\n          return {\n            fold: function () {\n              if (arguments.length !== cases.length) {\n                throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length);\n              }\n              var target = arguments[count];\n              return target.apply(null, args);\n            },\n            match: match,\n            log: function (label) {\n              domGlobals.console.log(label, {\n                constructors: constructors,\n                constructor: key,\n                params: args\n              });\n            }\n          };\n        };\n      });\n      return adt;\n    };\n    var Adt = { generate: generate$1 };\n\n    var create$3 = Immutable('start', 'soffset', 'finish', 'foffset');\n    var SimRange = { create: create$3 };\n\n    var adt = Adt.generate([\n      { before: ['element'] },\n      {\n        on: [\n          'element',\n          'offset'\n        ]\n      },\n      { after: ['element'] }\n    ]);\n    var cata = function (subject, onBefore, onOn, onAfter) {\n      return subject.fold(onBefore, onOn, onAfter);\n    };\n    var getStart = function (situ) {\n      return situ.fold(identity, identity, identity);\n    };\n    var before$3 = adt.before;\n    var on = adt.on;\n    var after$2 = adt.after;\n    var Situ = {\n      before: before$3,\n      on: on,\n      after: after$2,\n      cata: cata,\n      getStart: getStart\n    };\n\n    var adt$1 = Adt.generate([\n      { domRange: ['rng'] },\n      {\n        relative: [\n          'startSitu',\n          'finishSitu'\n        ]\n      },\n      {\n        exact: [\n          'start',\n          'soffset',\n          'finish',\n          'foffset'\n        ]\n      }\n    ]);\n    var exactFromRange = function (simRange) {\n      return adt$1.exact(simRange.start(), simRange.soffset(), simRange.finish(), simRange.foffset());\n    };\n    var getStart$1 = function (selection) {\n      return selection.match({\n        domRange: function (rng) {\n          return Element.fromDom(rng.startContainer);\n        },\n        relative: function (startSitu, finishSitu) {\n          return Situ.getStart(startSitu);\n        },\n        exact: function (start, soffset, finish, foffset) {\n          return start;\n        }\n      });\n    };\n    var domRange = adt$1.domRange;\n    var relative = adt$1.relative;\n    var exact = adt$1.exact;\n    var getWin = function (selection) {\n      var start = getStart$1(selection);\n      return defaultView(start);\n    };\n    var range = SimRange.create;\n    var Selection = {\n      domRange: domRange,\n      relative: relative,\n      exact: exact,\n      exactFromRange: exactFromRange,\n      getWin: getWin,\n      range: range\n    };\n\n    var browser$4 = detect$3().browser;\n    var clamp = function (offset, element) {\n      var max = isText$1(element) ? get$6(element).length : children(element).length + 1;\n      if (offset > max) {\n        return max;\n      } else if (offset < 0) {\n        return 0;\n      }\n      return offset;\n    };\n    var normalizeRng = function (rng) {\n      return Selection.range(rng.start(), clamp(rng.soffset(), rng.start()), rng.finish(), clamp(rng.foffset(), rng.finish()));\n    };\n    var isOrContains = function (root, elm) {\n      return !NodeType.isRestrictedNode(elm.dom()) && (contains$2(root, elm) || eq(root, elm));\n    };\n    var isRngInRoot = function (root) {\n      return function (rng) {\n        return isOrContains(root, rng.start()) && isOrContains(root, rng.finish());\n      };\n    };\n    var shouldStore = function (editor) {\n      return editor.inline === true || browser$4.isIE();\n    };\n    var nativeRangeToSelectionRange = function (r) {\n      return Selection.range(Element.fromDom(r.startContainer), r.startOffset, Element.fromDom(r.endContainer), r.endOffset);\n    };\n    var readRange = function (win) {\n      var selection = win.getSelection();\n      var rng = !selection || selection.rangeCount === 0 ? Option.none() : Option.from(selection.getRangeAt(0));\n      return rng.map(nativeRangeToSelectionRange);\n    };\n    var getBookmark$2 = function (root) {\n      var win = defaultView(root);\n      return readRange(win.dom()).filter(isRngInRoot(root));\n    };\n    var validate = function (root, bookmark) {\n      return Option.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng);\n    };\n    var bookmarkToNativeRng = function (bookmark) {\n      var rng = domGlobals.document.createRange();\n      try {\n        rng.setStart(bookmark.start().dom(), bookmark.soffset());\n        rng.setEnd(bookmark.finish().dom(), bookmark.foffset());\n        return Option.some(rng);\n      } catch (_) {\n        return Option.none();\n      }\n    };\n    var store = function (editor) {\n      var newBookmark = shouldStore(editor) ? getBookmark$2(Element.fromDom(editor.getBody())) : Option.none();\n      editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;\n    };\n    var storeNative = function (editor, rng) {\n      var root = Element.fromDom(editor.getBody());\n      var range = shouldStore(editor) ? Option.from(rng) : Option.none();\n      var newBookmark = range.map(nativeRangeToSelectionRange).filter(isRngInRoot(root));\n      editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;\n    };\n    var getRng = function (editor) {\n      var bookmark = editor.bookmark ? editor.bookmark : Option.none();\n      return bookmark.bind(function (x) {\n        return validate(Element.fromDom(editor.getBody()), x);\n      }).bind(bookmarkToNativeRng);\n    };\n    var restore = function (editor) {\n      getRng(editor).each(function (rng) {\n        editor.selection.setRng(rng);\n      });\n    };\n    var SelectionBookmark = {\n      store: store,\n      storeNative: storeNative,\n      readRange: readRange,\n      restore: restore,\n      getRng: getRng,\n      getBookmark: getBookmark$2,\n      validate: validate\n    };\n\n    var isEditorUIElement = function (elm) {\n      var className = elm.className.toString();\n      return className.indexOf('tox-') !== -1 || className.indexOf('mce-') !== -1;\n    };\n    var FocusManager = { isEditorUIElement: isEditorUIElement };\n\n    var isManualNodeChange = function (e) {\n      return e.type === 'nodechange' && e.selectionChange;\n    };\n    var registerPageMouseUp = function (editor, throttledStore) {\n      var mouseUpPage = function () {\n        throttledStore.throttle();\n      };\n      DOMUtils$1.DOM.bind(domGlobals.document, 'mouseup', mouseUpPage);\n      editor.on('remove', function () {\n        DOMUtils$1.DOM.unbind(domGlobals.document, 'mouseup', mouseUpPage);\n      });\n    };\n    var registerFocusOut = function (editor) {\n      editor.on('focusout', function () {\n        SelectionBookmark.store(editor);\n      });\n    };\n    var registerMouseUp = function (editor, throttledStore) {\n      editor.on('mouseup touchend', function (e) {\n        throttledStore.throttle();\n      });\n    };\n    var registerEditorEvents = function (editor, throttledStore) {\n      var browser = detect$3().browser;\n      if (browser.isIE()) {\n        registerFocusOut(editor);\n      } else {\n        registerMouseUp(editor, throttledStore);\n      }\n      editor.on('keyup NodeChange', function (e) {\n        if (!isManualNodeChange(e)) {\n          SelectionBookmark.store(editor);\n        }\n      });\n    };\n    var register = function (editor) {\n      var throttledStore = first(function () {\n        SelectionBookmark.store(editor);\n      }, 0);\n      editor.on('init', function () {\n        if (editor.inline) {\n          registerPageMouseUp(editor, throttledStore);\n        }\n        registerEditorEvents(editor, throttledStore);\n      });\n      editor.on('remove', function () {\n        throttledStore.cancel();\n      });\n    };\n    var SelectionRestore = { register: register };\n\n    var documentFocusInHandler;\n    var DOM$1 = DOMUtils$1.DOM;\n    var isEditorUIElement$1 = function (elm) {\n      return FocusManager.isEditorUIElement(elm);\n    };\n    var isEditorContentAreaElement = function (elm) {\n      var classList = elm.classList;\n      if (classList !== undefined) {\n        return classList.contains('tox-edit-area') || classList.contains('tox-edit-area__iframe') || classList.contains('mce-content-body');\n      } else {\n        return false;\n      }\n    };\n    var isUIElement = function (editor, elm) {\n      var customSelector = editor ? editor.settings.custom_ui_selector : '';\n      var parent = DOM$1.getParent(elm, function (elm) {\n        return isEditorUIElement$1(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false);\n      });\n      return parent !== null;\n    };\n    var getActiveElement = function () {\n      try {\n        return domGlobals.document.activeElement;\n      } catch (ex) {\n        return domGlobals.document.body;\n      }\n    };\n    var registerEvents = function (editorManager, e) {\n      var editor = e.editor;\n      SelectionRestore.register(editor);\n      editor.on('focusin', function () {\n        var self = this;\n        var focusedEditor = editorManager.focusedEditor;\n        if (focusedEditor !== self) {\n          if (focusedEditor) {\n            focusedEditor.fire('blur', { focusedEditor: self });\n          }\n          editorManager.setActive(self);\n          editorManager.focusedEditor = self;\n          self.fire('focus', { blurredEditor: focusedEditor });\n          self.focus(true);\n        }\n      });\n      editor.on('focusout', function () {\n        var self = this;\n        Delay.setEditorTimeout(self, function () {\n          var focusedEditor = editorManager.focusedEditor;\n          if (!isUIElement(self, getActiveElement()) && focusedEditor === self) {\n            self.fire('blur', { focusedEditor: null });\n            editorManager.focusedEditor = null;\n          }\n        });\n      });\n      if (!documentFocusInHandler) {\n        documentFocusInHandler = function (e) {\n          var activeEditor = editorManager.activeEditor;\n          var target;\n          target = e.target;\n          if (activeEditor && target.ownerDocument === domGlobals.document) {\n            if (target !== domGlobals.document.body && !isUIElement(activeEditor, target) && editorManager.focusedEditor === activeEditor) {\n              activeEditor.fire('blur', { focusedEditor: null });\n              editorManager.focusedEditor = null;\n            }\n          }\n        };\n        DOM$1.bind(domGlobals.document, 'focusin', documentFocusInHandler);\n      }\n    };\n    var unregisterDocumentEvents = function (editorManager, e) {\n      if (editorManager.focusedEditor === e.editor) {\n        editorManager.focusedEditor = null;\n      }\n      if (!editorManager.activeEditor) {\n        DOM$1.unbind(domGlobals.document, 'focusin', documentFocusInHandler);\n        documentFocusInHandler = null;\n      }\n    };\n    var setup$2 = function (editorManager) {\n      editorManager.on('AddEditor', curry(registerEvents, editorManager));\n      editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager));\n    };\n    var FocusController = {\n      setup: setup$2,\n      isEditorUIElement: isEditorUIElement$1,\n      isEditorContentAreaElement: isEditorContentAreaElement,\n      isUIElement: isUIElement\n    };\n\n    var getContentEditableHost = function (editor, node) {\n      return editor.dom.getParent(node, function (node) {\n        return editor.dom.getContentEditable(node) === 'true';\n      });\n    };\n    var getCollapsedNode = function (rng) {\n      return rng.collapsed ? Option.from(getNode(rng.startContainer, rng.startOffset)).map(Element.fromDom) : Option.none();\n    };\n    var getFocusInElement = function (root, rng) {\n      return getCollapsedNode(rng).bind(function (node) {\n        if (isTableSection(node)) {\n          return Option.some(node);\n        } else if (contains$2(root, node) === false) {\n          return Option.some(root);\n        } else {\n          return Option.none();\n        }\n      });\n    };\n    var normalizeSelection = function (editor, rng) {\n      getFocusInElement(Element.fromDom(editor.getBody()), rng).bind(function (elm) {\n        return CaretFinder.firstPositionIn(elm.dom());\n      }).fold(function () {\n        editor.selection.normalize();\n        return;\n      }, function (caretPos) {\n        return editor.selection.setRng(caretPos.toRange());\n      });\n    };\n    var focusBody = function (body) {\n      if (body.setActive) {\n        try {\n          body.setActive();\n        } catch (ex) {\n          body.focus();\n        }\n      } else {\n        body.focus();\n      }\n    };\n    var hasElementFocus = function (elm) {\n      return hasFocus(elm) || search(elm).isSome();\n    };\n    var hasIframeFocus = function (editor) {\n      return editor.iframeElement && hasFocus(Element.fromDom(editor.iframeElement));\n    };\n    var hasInlineFocus = function (editor) {\n      var rawBody = editor.getBody();\n      return rawBody && hasElementFocus(Element.fromDom(rawBody));\n    };\n    var hasUiFocus = function (editor) {\n      return active().filter(function (elem) {\n        return !FocusController.isEditorContentAreaElement(elem.dom()) && FocusController.isUIElement(editor, elem.dom());\n      }).isSome();\n    };\n    var hasFocus$1 = function (editor) {\n      return editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor);\n    };\n    var hasEditorOrUiFocus = function (editor) {\n      return hasFocus$1(editor) || hasUiFocus(editor);\n    };\n    var focusEditor = function (editor) {\n      var selection = editor.selection;\n      var body = editor.getBody();\n      var rng = selection.getRng();\n      editor.quirks.refreshContentEditable();\n      if (editor.bookmark !== undefined && hasFocus$1(editor) === false) {\n        SelectionBookmark.getRng(editor).each(function (bookmarkRng) {\n          editor.selection.setRng(bookmarkRng);\n          rng = bookmarkRng;\n        });\n      }\n      var contentEditableHost = getContentEditableHost(editor, selection.getNode());\n      if (editor.$.contains(body, contentEditableHost)) {\n        focusBody(contentEditableHost);\n        normalizeSelection(editor, rng);\n        activateEditor(editor);\n        return;\n      }\n      if (!editor.inline) {\n        if (!Env.opera) {\n          focusBody(body);\n        }\n        editor.getWin().focus();\n      }\n      if (Env.gecko || editor.inline) {\n        focusBody(body);\n        normalizeSelection(editor, rng);\n      }\n      activateEditor(editor);\n    };\n    var activateEditor = function (editor) {\n      return editor.editorManager.setActive(editor);\n    };\n    var focus = function (editor, skipFocus) {\n      if (editor.removed) {\n        return;\n      }\n      skipFocus ? activateEditor(editor) : focusEditor(editor);\n    };\n    var EditorFocus = {\n      focus: focus,\n      hasFocus: hasFocus$1,\n      hasEditorOrUiFocus: hasEditorOrUiFocus\n    };\n\n    var defaultFormat$1 = 'html';\n    var isTreeNode = function (content) {\n      return content instanceof Node$1;\n    };\n    var moveSelection = function (editor) {\n      if (EditorFocus.hasFocus(editor)) {\n        CaretFinder.firstPositionIn(editor.getBody()).each(function (pos) {\n          var node = pos.getNode();\n          var caretPos = NodeType.isTable(node) ? CaretFinder.firstPositionIn(node).getOr(pos) : pos;\n          editor.selection.setRng(caretPos.toRange());\n        });\n      }\n    };\n    var setEditorHtml = function (editor, html) {\n      editor.dom.setHTML(editor.getBody(), html);\n      moveSelection(editor);\n    };\n    var setContentString = function (editor, body, content, args) {\n      var forcedRootBlockName, padd;\n      if (content.length === 0 || /^\\s+$/.test(content)) {\n        padd = '<br data-mce-bogus=\"1\">';\n        if (body.nodeName === 'TABLE') {\n          content = '<tr><td>' + padd + '</td></tr>';\n        } else if (/^(UL|OL)$/.test(body.nodeName)) {\n          content = '<li>' + padd + '</li>';\n        }\n        forcedRootBlockName = Settings.getForcedRootBlock(editor);\n        if (forcedRootBlockName && editor.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {\n          content = padd;\n          content = editor.dom.createHTML(forcedRootBlockName, editor.settings.forced_root_block_attrs, content);\n        } else if (!content) {\n          content = '<br data-mce-bogus=\"1\">';\n        }\n        setEditorHtml(editor, content);\n        editor.fire('SetContent', args);\n      } else {\n        if (args.format !== 'raw') {\n          content = Serializer({ validate: editor.validate }, editor.schema).serialize(editor.parser.parse(content, {\n            isRootContent: true,\n            insert: true\n          }));\n        }\n        args.content = isWsPreserveElement(Element.fromDom(body)) ? content : Tools.trim(content);\n        setEditorHtml(editor, args.content);\n        if (!args.no_events) {\n          editor.fire('SetContent', args);\n        }\n      }\n      return args.content;\n    };\n    var setContentTree = function (editor, body, content, args) {\n      filter$2(editor.parser.getNodeFilters(), editor.parser.getAttributeFilters(), content);\n      var html = Serializer({ validate: editor.validate }, editor.schema).serialize(content);\n      args.content = isWsPreserveElement(Element.fromDom(body)) ? html : Tools.trim(html);\n      setEditorHtml(editor, args.content);\n      if (!args.no_events) {\n        editor.fire('SetContent', args);\n      }\n      return content;\n    };\n    var setContent = function (editor, content, args) {\n      if (args === void 0) {\n        args = {};\n      }\n      args.format = args.format ? args.format : defaultFormat$1;\n      args.set = true;\n      args.content = isTreeNode(content) ? '' : content;\n      if (!isTreeNode(content) && !args.no_events) {\n        editor.fire('BeforeSetContent', args);\n        content = args.content;\n      }\n      return Option.from(editor.getBody()).fold(constant(content), function (body) {\n        return isTreeNode(content) ? setContentTree(editor, body, content, args) : setContentString(editor, body, content, args);\n      });\n    };\n\n    var firePreProcess = function (editor, args) {\n      return editor.fire('PreProcess', args);\n    };\n    var firePostProcess = function (editor, args) {\n      return editor.fire('PostProcess', args);\n    };\n    var fireRemove = function (editor) {\n      return editor.fire('remove');\n    };\n    var fireDetach = function (editor) {\n      return editor.fire('detach');\n    };\n    var fireSwitchMode = function (editor, mode) {\n      return editor.fire('SwitchMode', { mode: mode });\n    };\n    var fireObjectResizeStart = function (editor, target, width, height) {\n      editor.fire('ObjectResizeStart', {\n        target: target,\n        width: width,\n        height: height\n      });\n    };\n    var fireObjectResized = function (editor, target, width, height) {\n      editor.fire('ObjectResized', {\n        target: target,\n        width: width,\n        height: height\n      });\n    };\n    var Events = {\n      firePreProcess: firePreProcess,\n      firePostProcess: firePostProcess,\n      fireRemove: fireRemove,\n      fireDetach: fireDetach,\n      fireSwitchMode: fireSwitchMode,\n      fireObjectResizeStart: fireObjectResizeStart,\n      fireObjectResized: fireObjectResized\n    };\n\n    var DOM$2 = DOMUtils$1.DOM;\n    var restoreOriginalStyles = function (editor) {\n      DOM$2.setStyle(editor.id, 'display', editor.orgDisplay);\n    };\n    var safeDestroy = function (x) {\n      return Option.from(x).each(function (x) {\n        return x.destroy();\n      });\n    };\n    var clearDomReferences = function (editor) {\n      editor.contentAreaContainer = editor.formElement = editor.container = editor.editorContainer = null;\n      editor.bodyElement = editor.contentDocument = editor.contentWindow = null;\n      editor.iframeElement = editor.targetElm = null;\n      if (editor.selection) {\n        editor.selection = editor.selection.win = editor.selection.dom = editor.selection.dom.doc = null;\n      }\n    };\n    var restoreForm = function (editor) {\n      var form = editor.formElement;\n      if (form) {\n        if (form._mceOldSubmit) {\n          form.submit = form._mceOldSubmit;\n          form._mceOldSubmit = null;\n        }\n        DOM$2.unbind(form, 'submit reset', editor.formEventDelegate);\n      }\n    };\n    var remove$6 = function (editor) {\n      if (!editor.removed) {\n        var _selectionOverrides = editor._selectionOverrides, editorUpload = editor.editorUpload;\n        var body = editor.getBody();\n        var element = editor.getElement();\n        if (body) {\n          editor.save({ is_removing: true });\n        }\n        editor.removed = true;\n        editor.unbindAllNativeEvents();\n        if (editor.hasHiddenInput && element) {\n          DOM$2.remove(element.nextSibling);\n        }\n        Events.fireRemove(editor);\n        editor.editorManager.remove(editor);\n        if (!editor.inline && body) {\n          restoreOriginalStyles(editor);\n        }\n        Events.fireDetach(editor);\n        DOM$2.remove(editor.getContainer());\n        safeDestroy(_selectionOverrides);\n        safeDestroy(editorUpload);\n        editor.destroy();\n      }\n    };\n    var destroy = function (editor, automatic) {\n      var selection = editor.selection, dom = editor.dom;\n      if (editor.destroyed) {\n        return;\n      }\n      if (!automatic && !editor.removed) {\n        editor.remove();\n        return;\n      }\n      if (!automatic) {\n        editor.editorManager.off('beforeunload', editor._beforeUnload);\n        if (editor.theme && editor.theme.destroy) {\n          editor.theme.destroy();\n        }\n        safeDestroy(selection);\n        safeDestroy(dom);\n      }\n      restoreForm(editor);\n      clearDomReferences(editor);\n      editor.destroyed = true;\n    };\n\n    var hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n    var shallow$1 = function (old, nu) {\n      return nu;\n    };\n    var deep$1 = function (old, nu) {\n      var bothObjects = isObject(old) && isObject(nu);\n      return bothObjects ? deepMerge(old, nu) : nu;\n    };\n    var baseMerge = function (merger) {\n      return function () {\n        var objects = new Array(arguments.length);\n        for (var i = 0; i < objects.length; i++) {\n          objects[i] = arguments[i];\n        }\n        if (objects.length === 0) {\n          throw new Error('Can\\'t merge zero objects');\n        }\n        var ret = {};\n        for (var j = 0; j < objects.length; j++) {\n          var curObject = objects[j];\n          for (var key in curObject) {\n            if (hasOwnProperty$2.call(curObject, key)) {\n              ret[key] = merger(ret[key], curObject[key]);\n            }\n          }\n        }\n        return ret;\n      };\n    };\n    var deepMerge = baseMerge(deep$1);\n    var merge = baseMerge(shallow$1);\n\n    var sectionResult = Immutable('sections', 'settings');\n    var deviceDetection = detect$3().deviceType;\n    var isTouch = deviceDetection.isTouch();\n    var isPhone = deviceDetection.isPhone();\n    var isTablet = deviceDetection.isTablet();\n    var legacyMobilePlugins = [\n      'lists',\n      'autolink',\n      'autosave'\n    ];\n    var defaultTouchSettings = {\n      table_grid: false,\n      object_resizing: false,\n      resize: false\n    };\n    var normalizePlugins = function (plugins) {\n      var pluginNames = isArray(plugins) ? plugins.join(' ') : plugins;\n      var trimmedPlugins = map(isString(pluginNames) ? pluginNames.split(' ') : [], trim);\n      return filter(trimmedPlugins, function (item) {\n        return item.length > 0;\n      });\n    };\n    var filterLegacyMobilePlugins = function (plugins) {\n      return filter(plugins, curry(contains, legacyMobilePlugins));\n    };\n    var extractSections = function (keys, settings) {\n      var result = bifilter(settings, function (value, key) {\n        return contains(keys, key);\n      });\n      return sectionResult(result.t, result.f);\n    };\n    var getSection = function (sectionResult, name, defaults) {\n      if (defaults === void 0) {\n        defaults = {};\n      }\n      var sections = sectionResult.sections();\n      var sectionSettings = sections.hasOwnProperty(name) ? sections[name] : {};\n      return Tools.extend({}, defaults, sectionSettings);\n    };\n    var hasSection = function (sectionResult, name) {\n      return sectionResult.sections().hasOwnProperty(name);\n    };\n    var isSectionTheme = function (sectionResult, name, theme) {\n      var section = sectionResult.sections();\n      return hasSection(sectionResult, name) && section[name].theme === theme;\n    };\n    var getSectionConfig = function (sectionResult, name) {\n      return hasSection(sectionResult, name) ? sectionResult.sections()[name] : {};\n    };\n    var getDefaultSettings = function (id, documentBaseUrl, isTouch, editor) {\n      var baseDefaults = {\n        id: id,\n        theme: 'silver',\n        toolbar_drawer: 'floating',\n        plugins: '',\n        document_base_url: documentBaseUrl,\n        add_form_submit_trigger: true,\n        submit_patch: true,\n        add_unload_trigger: true,\n        convert_urls: true,\n        relative_urls: true,\n        remove_script_host: true,\n        object_resizing: true,\n        doctype: '<!DOCTYPE html>',\n        visual: true,\n        font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',\n        forced_root_block: 'p',\n        hidden_input: true,\n        inline_styles: true,\n        convert_fonts_to_spans: true,\n        indent: true,\n        indent_before: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',\n        indent_after: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',\n        entity_encoding: 'named',\n        url_converter: editor.convertURL,\n        url_converter_scope: editor\n      };\n      return __assign(__assign({}, baseDefaults), isTouch ? defaultTouchSettings : {});\n    };\n    var getDefaultMobileSettings = function (isPhone) {\n      var defaultMobileSettings = {\n        resize: false,\n        toolbar_drawer: 'scrolling',\n        toolbar_sticky: false\n      };\n      var defaultPhoneSettings = { menubar: false };\n      return __assign(__assign(__assign({}, defaultTouchSettings), defaultMobileSettings), isPhone ? defaultPhoneSettings : {});\n    };\n    var getExternalPlugins = function (overrideSettings, settings) {\n      var userDefinedExternalPlugins = settings.external_plugins ? settings.external_plugins : {};\n      if (overrideSettings && overrideSettings.external_plugins) {\n        return Tools.extend({}, overrideSettings.external_plugins, userDefinedExternalPlugins);\n      } else {\n        return userDefinedExternalPlugins;\n      }\n    };\n    var combinePlugins = function (forcedPlugins, plugins) {\n      return [].concat(normalizePlugins(forcedPlugins)).concat(normalizePlugins(plugins));\n    };\n    var processPlugins = function (isMobileDevice, sectionResult, defaultOverrideSettings, settings) {\n      var forcedPlugins = normalizePlugins(defaultOverrideSettings.forced_plugins);\n      var desktopPlugins = normalizePlugins(settings.plugins);\n      var mobileConfig = getSectionConfig(sectionResult, 'mobile');\n      var mobilePlugins = mobileConfig.plugins ? normalizePlugins(mobileConfig.plugins) : desktopPlugins;\n      var platformPlugins = isMobileDevice && isSectionTheme(sectionResult, 'mobile', 'mobile') ? filterLegacyMobilePlugins(mobilePlugins) : isMobileDevice && hasSection(sectionResult, 'mobile') ? mobilePlugins : desktopPlugins;\n      var combinedPlugins = combinePlugins(forcedPlugins, platformPlugins);\n      return Tools.extend(settings, { plugins: combinedPlugins.join(' ') });\n    };\n    var isOnMobile = function (isMobileDevice, sectionResult) {\n      return isMobileDevice && hasSection(sectionResult, 'mobile');\n    };\n    var combineSettings = function (isMobileDevice, isPhone, defaultSettings, defaultOverrideSettings, settings) {\n      var defaultDeviceSettings = isMobileDevice ? { mobile: getDefaultMobileSettings(isPhone) } : {};\n      var sectionResult = extractSections(['mobile'], deepMerge(defaultDeviceSettings, settings));\n      var extendedSettings = Tools.extend(defaultSettings, defaultOverrideSettings, sectionResult.settings(), isOnMobile(isMobileDevice, sectionResult) ? getSection(sectionResult, 'mobile') : {}, {\n        validate: true,\n        external_plugins: getExternalPlugins(defaultOverrideSettings, sectionResult.settings())\n      });\n      return processPlugins(isMobileDevice, sectionResult, defaultOverrideSettings, extendedSettings);\n    };\n    var getEditorSettings = function (editor, id, documentBaseUrl, defaultOverrideSettings, settings) {\n      var defaultSettings = getDefaultSettings(id, documentBaseUrl, isTouch, editor);\n      return combineSettings(isPhone || isTablet, isPhone, defaultSettings, defaultOverrideSettings, settings);\n    };\n    var getFiltered = function (predicate, editor, name) {\n      return Option.from(editor.settings[name]).filter(predicate);\n    };\n    var getParamObject = function (value) {\n      var output = {};\n      if (typeof value === 'string') {\n        each(value.indexOf('=') > 0 ? value.split(/[;,](?![^=;,]*(?:[;,]|$))/) : value.split(','), function (val) {\n          var arr = val.split('=');\n          if (arr.length > 1) {\n            output[Tools.trim(arr[0])] = Tools.trim(arr[1]);\n          } else {\n            output[Tools.trim(arr[0])] = Tools.trim(arr[0]);\n          }\n        });\n      } else {\n        output = value;\n      }\n      return output;\n    };\n    var isArrayOf = function (p) {\n      return function (a) {\n        return isArray(a) && forall(a, p);\n      };\n    };\n    var getParam = function (editor, name, defaultVal, type) {\n      var value = name in editor.settings ? editor.settings[name] : defaultVal;\n      if (type === 'hash') {\n        return getParamObject(value);\n      } else if (type === 'string') {\n        return getFiltered(isString, editor, name).getOr(defaultVal);\n      } else if (type === 'number') {\n        return getFiltered(isNumber, editor, name).getOr(defaultVal);\n      } else if (type === 'boolean') {\n        return getFiltered(isBoolean, editor, name).getOr(defaultVal);\n      } else if (type === 'object') {\n        return getFiltered(isObject, editor, name).getOr(defaultVal);\n      } else if (type === 'array') {\n        return getFiltered(isArray, editor, name).getOr(defaultVal);\n      } else if (type === 'string[]') {\n        return getFiltered(isArrayOf(isString), editor, name).getOr(defaultVal);\n      } else if (type === 'function') {\n        return getFiltered(isFunction, editor, name).getOr(defaultVal);\n      } else {\n        return value;\n      }\n    };\n\n    var getProp = function (propName, elm) {\n      var rawElm = elm.dom();\n      return rawElm[propName];\n    };\n    var getComputedSizeProp = function (propName, elm) {\n      return parseInt(get$2(elm, propName), 10);\n    };\n    var getClientWidth = curry(getProp, 'clientWidth');\n    var getClientHeight = curry(getProp, 'clientHeight');\n    var getMarginTop = curry(getComputedSizeProp, 'margin-top');\n    var getMarginLeft = curry(getComputedSizeProp, 'margin-left');\n    var getBoundingClientRect$1 = function (elm) {\n      return elm.dom().getBoundingClientRect();\n    };\n    var isInsideElementContentArea = function (bodyElm, clientX, clientY) {\n      var clientWidth = getClientWidth(bodyElm);\n      var clientHeight = getClientHeight(bodyElm);\n      return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;\n    };\n    var transpose = function (inline, elm, clientX, clientY) {\n      var clientRect = getBoundingClientRect$1(elm);\n      var deltaX = inline ? clientRect.left + elm.dom().clientLeft + getMarginLeft(elm) : 0;\n      var deltaY = inline ? clientRect.top + elm.dom().clientTop + getMarginTop(elm) : 0;\n      var x = clientX - deltaX;\n      var y = clientY - deltaY;\n      return {\n        x: x,\n        y: y\n      };\n    };\n    var isXYInContentArea = function (editor, clientX, clientY) {\n      var bodyElm = Element.fromDom(editor.getBody());\n      var targetElm = editor.inline ? bodyElm : documentElement(bodyElm);\n      var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);\n      return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);\n    };\n    var fromDomSafe = function (node) {\n      return Option.from(node).map(Element.fromDom);\n    };\n    var isEditorAttachedToDom = function (editor) {\n      var rawContainer = editor.inline ? editor.getBody() : editor.getContentAreaContainer();\n      return fromDomSafe(rawContainer).map(function (container) {\n        return contains$2(owner(container), container);\n      }).getOr(false);\n    };\n    var EditorView = {\n      isXYInContentArea: isXYInContentArea,\n      isEditorAttachedToDom: isEditorAttachedToDom\n    };\n\n    function NotificationManagerImpl() {\n      var unimplemented = function () {\n        throw new Error('Theme did not provide a NotificationManager implementation.');\n      };\n      return {\n        open: unimplemented,\n        close: unimplemented,\n        reposition: unimplemented,\n        getArgs: unimplemented\n      };\n    }\n\n    function NotificationManager(editor) {\n      var notifications = [];\n      var getImplementation = function () {\n        var theme = editor.theme;\n        return theme && theme.getNotificationManagerImpl ? theme.getNotificationManagerImpl() : NotificationManagerImpl();\n      };\n      var getTopNotification = function () {\n        return Option.from(notifications[0]);\n      };\n      var isEqual = function (a, b) {\n        return a.type === b.type && a.text === b.text && !a.progressBar && !a.timeout && !b.progressBar && !b.timeout;\n      };\n      var reposition = function () {\n        if (notifications.length > 0) {\n          getImplementation().reposition(notifications);\n        }\n      };\n      var addNotification = function (notification) {\n        notifications.push(notification);\n      };\n      var closeNotification = function (notification) {\n        findIndex(notifications, function (otherNotification) {\n          return otherNotification === notification;\n        }).each(function (index) {\n          notifications.splice(index, 1);\n        });\n      };\n      var open = function (spec) {\n        if (editor.removed || !EditorView.isEditorAttachedToDom(editor)) {\n          return;\n        }\n        return find(notifications, function (notification) {\n          return isEqual(getImplementation().getArgs(notification), spec);\n        }).getOrThunk(function () {\n          editor.editorManager.setActive(editor);\n          var notification = getImplementation().open(spec, function () {\n            closeNotification(notification);\n            reposition();\n          });\n          addNotification(notification);\n          reposition();\n          return notification;\n        });\n      };\n      var close = function () {\n        getTopNotification().each(function (notification) {\n          getImplementation().close(notification);\n          closeNotification(notification);\n          reposition();\n        });\n      };\n      var getNotifications = function () {\n        return notifications;\n      };\n      var registerEvents = function (editor) {\n        editor.on('SkinLoaded', function () {\n          var serviceMessage = editor.settings.service_message;\n          if (serviceMessage) {\n            open({\n              text: serviceMessage,\n              type: 'warning',\n              timeout: 0\n            });\n          }\n        });\n        editor.on('ResizeEditor ResizeWindow NodeChange', function () {\n          Delay.requestAnimationFrame(reposition);\n        });\n        editor.on('remove', function () {\n          each(notifications.slice(), function (notification) {\n            getImplementation().close(notification);\n          });\n        });\n      };\n      registerEvents(editor);\n      return {\n        open: open,\n        close: close,\n        getNotifications: getNotifications\n      };\n    }\n\n    function WindowManagerImpl () {\n      var unimplemented = function () {\n        throw new Error('Theme did not provide a WindowManager implementation.');\n      };\n      return {\n        open: unimplemented,\n        openUrl: unimplemented,\n        alert: unimplemented,\n        confirm: unimplemented,\n        close: unimplemented,\n        getParams: unimplemented,\n        setParams: unimplemented\n      };\n    }\n\n    var WindowManager = function (editor) {\n      var dialogs = [];\n      var getImplementation = function () {\n        var theme = editor.theme;\n        return theme && theme.getWindowManagerImpl ? theme.getWindowManagerImpl() : WindowManagerImpl();\n      };\n      var funcBind = function (scope, f) {\n        return function () {\n          return f ? f.apply(scope, arguments) : undefined;\n        };\n      };\n      var fireOpenEvent = function (dialog) {\n        editor.fire('OpenWindow', { dialog: dialog });\n      };\n      var fireCloseEvent = function (dialog) {\n        editor.fire('CloseWindow', { dialog: dialog });\n      };\n      var addDialog = function (dialog) {\n        dialogs.push(dialog);\n        fireOpenEvent(dialog);\n      };\n      var closeDialog = function (dialog) {\n        fireCloseEvent(dialog);\n        dialogs = filter(dialogs, function (otherDialog) {\n          return otherDialog !== dialog;\n        });\n        if (dialogs.length === 0) {\n          editor.focus();\n        }\n      };\n      var getTopDialog = function () {\n        return Option.from(dialogs[dialogs.length - 1]);\n      };\n      var storeSelectionAndOpenDialog = function (openDialog) {\n        editor.editorManager.setActive(editor);\n        SelectionBookmark.store(editor);\n        var dialog = openDialog();\n        addDialog(dialog);\n        return dialog;\n      };\n      var open = function (args, params) {\n        return storeSelectionAndOpenDialog(function () {\n          return getImplementation().open(args, params, closeDialog);\n        });\n      };\n      var openUrl = function (args) {\n        return storeSelectionAndOpenDialog(function () {\n          return getImplementation().openUrl(args, closeDialog);\n        });\n      };\n      var alert = function (message, callback, scope) {\n        getImplementation().alert(message, funcBind(scope ? scope : this, callback));\n      };\n      var confirm = function (message, callback, scope) {\n        getImplementation().confirm(message, funcBind(scope ? scope : this, callback));\n      };\n      var close = function () {\n        getTopDialog().each(function (dialog) {\n          getImplementation().close(dialog);\n          closeDialog(dialog);\n        });\n      };\n      editor.on('remove', function () {\n        each(dialogs, function (dialog) {\n          getImplementation().close(dialog);\n        });\n      });\n      return {\n        open: open,\n        openUrl: openUrl,\n        alert: alert,\n        confirm: confirm,\n        close: close\n      };\n    };\n\n    var displayNotification = function (editor, message) {\n      editor.notificationManager.open({\n        type: 'error',\n        text: message\n      });\n    };\n    var displayError = function (editor, message) {\n      if (editor._skinLoaded) {\n        displayNotification(editor, message);\n      } else {\n        editor.on('SkinLoaded', function () {\n          displayNotification(editor, message);\n        });\n      }\n    };\n    var uploadError = function (editor, message) {\n      displayError(editor, I18n.translate([\n        'Failed to upload image: {0}',\n        message\n      ]));\n    };\n    var logError = function (msg) {\n      domGlobals.console.error(msg);\n    };\n    var createLoadError = function (type, url, name) {\n      return name ? 'Failed to load ' + type + ': ' + name + ' from url ' + url : 'Failed to load ' + type + ' url: ' + url;\n    };\n    var pluginLoadError = function (url, name) {\n      logError(createLoadError('plugin', url, name));\n    };\n    var iconsLoadError = function (url, name) {\n      logError(createLoadError('icons', url, name));\n    };\n    var languageLoadError = function (url, name) {\n      logError(createLoadError('language', url, name));\n    };\n    var pluginInitError = function (editor, name, err) {\n      var message = I18n.translate([\n        'Failed to initialize plugin: {0}',\n        name\n      ]);\n      initError(message, err);\n      displayError(editor, message);\n    };\n    var initError = function (message) {\n      var x = [];\n      for (var _i = 1; _i < arguments.length; _i++) {\n        x[_i - 1] = arguments[_i];\n      }\n      var console = domGlobals.window.console;\n      if (console) {\n        if (console.error) {\n          console.error.apply(console, arguments);\n        } else {\n          console.log.apply(console, arguments);\n        }\n      }\n    };\n    var ErrorReporter = {\n      pluginLoadError: pluginLoadError,\n      iconsLoadError: iconsLoadError,\n      languageLoadError: languageLoadError,\n      pluginInitError: pluginInitError,\n      uploadError: uploadError,\n      displayError: displayError,\n      initError: initError\n    };\n\n    var getAll = function () {\n      return {\n        'accessibility-check': '<svg width=\"24\" height=\"24\"><path d=\"M12 2a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2c0-1.1.9-2 2-2zm8 7h-5v12c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-5c0-.6-.4-1-1-1a1 1 0 0 0-1 1v5c0 .6-.4 1-1 1a1 1 0 0 1-1-1V9H4a1 1 0 1 1 0-2h16c.6 0 1 .4 1 1s-.4 1-1 1z\" fill-rule=\"nonzero\"/></svg>',\n        'action-next': '<svg width=\"24\" height=\"24\"><path fill-rule=\"nonzero\" d=\"M5.7 7.3a1 1 0 0 0-1.4 1.4l7.7 7.7 7.7-7.7a1 1 0 1 0-1.4-1.4L12 13.6 5.7 7.3z\"/></svg>',\n        'action-prev': '<svg width=\"24\" height=\"24\"><path fill-rule=\"nonzero\" d=\"M18.3 15.7a1 1 0 0 0 1.4-1.4L12 6.6l-7.7 7.7a1 1 0 0 0 1.4 1.4L12 9.4l6.3 6.3z\"/></svg>',\n        'align-center': '<svg width=\"24\" height=\"24\"><path d=\"M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm3 4h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 1 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm-3-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z\" fill-rule=\"evenodd\"/></svg>',\n        'align-justify': '<svg width=\"24\" height=\"24\"><path d=\"M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z\" fill-rule=\"evenodd\"/></svg>',\n        'align-left': '<svg width=\"24\" height=\"24\"><path d=\"M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z\" fill-rule=\"evenodd\"/></svg>',\n        'align-none': '<svg width=\"24\" height=\"24\"><path d=\"M14.2 5L13 7H5a1 1 0 1 1 0-2h9.2zm4 0h.8a1 1 0 0 1 0 2h-2l1.2-2zm-6.4 4l-1.2 2H5a1 1 0 0 1 0-2h6.8zm4 0H19a1 1 0 0 1 0 2h-4.4l1.2-2zm-6.4 4l-1.2 2H5a1 1 0 0 1 0-2h4.4zm4 0H19a1 1 0 0 1 0 2h-6.8l1.2-2zM7 17l-1.2 2H5a1 1 0 0 1 0-2h2zm4 0h8a1 1 0 0 1 0 2H9.8l1.2-2zm5.2-13.5l1.3.7-9.7 16.3-1.3-.7 9.7-16.3z\" fill-rule=\"evenodd\"/></svg>',\n        'align-right': '<svg width=\"24\" height=\"24\"><path d=\"M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm6 4h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm-6-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z\" fill-rule=\"evenodd\"/></svg>',\n        'arrow-left': '<svg width=\"24\" height=\"24\"><path d=\"M5.6 13l12 6a1 1 0 0 0 1.4-1V6a1 1 0 0 0-1.4-.9l-12 6a1 1 0 0 0 0 1.8z\" fill-rule=\"evenodd\"/></svg>',\n        'arrow-right': '<svg width=\"24\" height=\"24\"><path d=\"M18.5 13l-12 6A1 1 0 0 1 5 18V6a1 1 0 0 1 1.4-.9l12 6a1 1 0 0 1 0 1.8z\" fill-rule=\"evenodd\"/></svg>',\n        'bold': '<svg width=\"24\" height=\"24\"><path d=\"M7.8 19c-.3 0-.5 0-.6-.2l-.2-.5V5.7c0-.2 0-.4.2-.5l.6-.2h5c1.5 0 2.7.3 3.5 1 .7.6 1.1 1.4 1.1 2.5a3 3 0 0 1-.6 1.9c-.4.6-1 1-1.6 1.2.4.1.9.3 1.3.6s.8.7 1 1.2c.4.4.5 1 .5 1.6 0 1.3-.4 2.3-1.3 3-.8.7-2.1 1-3.8 1H7.8zm5-8.3c.6 0 1.2-.1 1.6-.5.4-.3.6-.7.6-1.3 0-1.1-.8-1.7-2.3-1.7H9.3v3.5h3.4zm.5 6c.7 0 1.3-.1 1.7-.4.4-.4.6-.9.6-1.5s-.2-1-.7-1.4c-.4-.3-1-.4-2-.4H9.4v3.8h4z\" fill-rule=\"evenodd\"/></svg>',\n        'bookmark': '<svg width=\"24\" height=\"24\"><path d=\"M6 4v17l6-4 6 4V4c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1z\" fill-rule=\"nonzero\"/></svg>',\n        'border-width': '<svg width=\"24\" height=\"24\"><path d=\"M5 14.8h14a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2zm-.5 3.7h15c.3 0 .5.2.5.5s-.2.5-.5.5h-15a.5.5 0 1 1 0-1zm.5-8.3h14c.6 0 1 .4 1 1v1c0 .5-.4 1-1 1H5a1 1 0 0 1-1-1v-1c0-.6.4-1 1-1zm0-5.7h14c.6 0 1 .4 1 1v2c0 .6-.4 1-1 1H5a1 1 0 0 1-1-1v-2c0-.6.4-1 1-1z\" fill-rule=\"evenodd\"/></svg>',\n        'brightness': '<svg width=\"24\" height=\"24\"><path d=\"M12 17c.3 0 .5.1.7.3.2.2.3.4.3.7v1c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7v-1c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3zm0-10a1 1 0 0 1-.7-.3A1 1 0 0 1 11 6V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3.3 0 .5.1.7.3.2.2.3.4.3.7v1c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3zm7 4c.3 0 .5.1.7.3.2.2.3.4.3.7 0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-1a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h1zM7 12c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3H5a1 1 0 0 1-.7-.3A1 1 0 0 1 4 12c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h1c.3 0 .5.1.7.3.2.2.3.4.3.7zm10 3.5l.7.8c.2.1.3.4.3.6 0 .3-.1.6-.3.8a1 1 0 0 1-.8.3 1 1 0 0 1-.6-.3l-.8-.7a1 1 0 0 1-.3-.8c0-.2.1-.5.3-.7a1 1 0 0 1 1.4 0zm-10-7l-.7-.8a1 1 0 0 1-.3-.6c0-.3.1-.6.3-.8.2-.2.5-.3.8-.3.2 0 .5.1.7.3l.7.7c.2.2.3.5.3.8 0 .2-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.8-.3zm10 0a1 1 0 0 1-.8.3 1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.6.3-.8l.8-.7c.1-.2.4-.3.6-.3.3 0 .6.1.8.3.2.2.3.5.3.8 0 .2-.1.5-.3.7l-.7.7zm-10 7c.2-.2.5-.3.8-.3.2 0 .5.1.7.3a1 1 0 0 1 0 1.4l-.8.8a1 1 0 0 1-.6.3 1 1 0 0 1-.8-.3 1 1 0 0 1-.3-.8c0-.2.1-.5.3-.6l.7-.8zM12 8a4 4 0 0 1 3.7 2.4 4 4 0 0 1 0 3.2A4 4 0 0 1 12 16a4 4 0 0 1-3.7-2.4 4 4 0 0 1 0-3.2A4 4 0 0 1 12 8zm0 6.5c.7 0 1.3-.2 1.8-.7.5-.5.7-1.1.7-1.8s-.2-1.3-.7-1.8c-.5-.5-1.1-.7-1.8-.7s-1.3.2-1.8.7c-.5.5-.7 1.1-.7 1.8s.2 1.3.7 1.8c.5.5 1.1.7 1.8.7z\" fill-rule=\"evenodd\"/></svg>',\n        'browse': '<svg width=\"24\" height=\"24\"><path d=\"M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4v-2h4V8H5v10h4v2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm-8 9.4l-2.3 2.3a1 1 0 1 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 0 1-1.4 1.4L13 13.4V20a1 1 0 0 1-2 0v-6.6z\" fill-rule=\"nonzero\"/></svg>',\n        'cancel': '<svg width=\"24\" height=\"24\"><path d=\"M12 4.6a7.4 7.4 0 1 1 0 14.8 7.4 7.4 0 0 1 0-14.8zM12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18zm0 8L14.8 8l1 1.1-2.7 2.8 2.7 2.7-1.1 1.1-2.7-2.7-2.7 2.7-1-1.1 2.6-2.7-2.7-2.7 1-1.1 2.8 2.7z\" fill-rule=\"nonzero\"/></svg>',\n        'change-case': '<svg width=\"24\" height=\"24\"><path d=\"M18.4 18.2v-.6c-.5.8-1.3 1.2-2.4 1.2-2.2 0-3.3-1.6-3.3-4.8 0-3.1 1-4.7 3.3-4.7 1.1 0 1.8.3 2.4 1.1v-.6c0-.5.4-.8.8-.8s.8.3.8.8v8.4c0 .5-.4.8-.8.8a.8.8 0 0 1-.8-.8zm-2-7.4c-1.3 0-1.8.9-1.8 3.2 0 2.4.5 3.3 1.7 3.3 1.3 0 1.8-.9 1.8-3.2 0-2.4-.5-3.3-1.7-3.3zM10 15.7H5.5l-.8 2.6a1 1 0 0 1-1 .7h-.2a.7.7 0 0 1-.7-1l4-12a1 1 0 1 1 2 0l4 12a.7.7 0 0 1-.8 1h-.2a1 1 0 0 1-1-.7l-.8-2.6zm-.3-1.5l-2-6.5-1.9 6.5h3.9z\" fill-rule=\"evenodd\"/></svg>',\n        'character-count': '<svg width=\"24\" height=\"24\"><path d=\"M4 11.5h16v1H4v-1zm4.8-6.8V10H7.7V5.8h-1v-1h2zM11 8.3V9h2v1h-3V7.7l2-1v-.9h-2v-1h3v2.4l-2 1zm6.3-3.4V10h-3.1V9h2.1V8h-2.1V6.8h2.1v-1h-2.1v-1h3.1zM5.8 16.4c0-.5.2-.8.5-1 .2-.2.6-.3 1.2-.3l.8.1c.2 0 .4.2.5.3l.4.4v2.8l.2.3H8.2v-.1-.2l-.6.3H7c-.4 0-.7 0-1-.2a1 1 0 0 1-.3-.9c0-.3 0-.6.3-.8.3-.2.7-.4 1.2-.4l.6-.2h.3v-.2l-.1-.2a.8.8 0 0 0-.5-.1 1 1 0 0 0-.4 0l-.3.4h-1zm2.3.8h-.2l-.2.1-.4.1a1 1 0 0 0-.4.2l-.2.2.1.3.5.1h.4l.4-.4v-.6zm2-3.4h1.2v1.7l.5-.3h.5c.5 0 .9.1 1.2.5.3.4.5.8.5 1.4 0 .6-.2 1.1-.5 1.5-.3.4-.7.6-1.3.6l-.6-.1-.4-.4v.4h-1.1v-5.4zm1.1 3.3c0 .3 0 .6.2.8a.7.7 0 0 0 1.2 0l.2-.8c0-.4 0-.6-.2-.8a.7.7 0 0 0-.6-.3l-.6.3-.2.8zm6.1-.5c0-.2 0-.3-.2-.4a.8.8 0 0 0-.5-.2c-.3 0-.5.1-.6.3l-.2.9c0 .3 0 .6.2.8.1.2.3.3.6.3.2 0 .4 0 .5-.2l.2-.4h1.1c0 .5-.3.8-.6 1.1a2 2 0 0 1-1.3.4c-.5 0-1-.2-1.3-.6a2 2 0 0 1-.5-1.4c0-.6.1-1.1.5-1.5.3-.4.8-.5 1.4-.5.5 0 1 0 1.2.3.4.3.5.7.5 1.2h-1v-.1z\" fill-rule=\"evenodd\"/></svg>',\n        'checklist-rtl': '<svg width=\"24\" height=\"24\"><path d=\"M5 17h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm14.2 11c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 20c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 14c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 8c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8z\" fill-rule=\"evenodd\"/></svg>',\n        'checklist': '<svg width=\"24\" height=\"24\"><path d=\"M11 17h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2h-8a1 1 0 0 1 0-2zM7.2 16c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 20c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 14c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 8c-.2.3-.7.4-1 0L3.8 6.9a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8z\" fill-rule=\"evenodd\"/></svg>',\n        'checkmark': '<svg width=\"24\" height=\"24\"><path d=\"M18.2 5.4a1 1 0 0 1 1.6 1.2l-8 12a1 1 0 0 1-1.5.1l-5-5a1 1 0 1 1 1.4-1.4l4.1 4.1 7.4-11z\" fill-rule=\"nonzero\"/></svg>',\n        'chevron-down': '<svg width=\"10\" height=\"10\"><path d=\"M8.7 2.2c.3-.3.8-.3 1 0 .4.4.4.9 0 1.2L5.7 7.8c-.3.3-.9.3-1.2 0L.2 3.4a.8.8 0 0 1 0-1.2c.3-.3.8-.3 1.1 0L5 6l3.7-3.8z\" fill-rule=\"nonzero\"/></svg>',\n        'chevron-left': '<svg width=\"10\" height=\"10\"><path d=\"M7.8 1.3L4 5l3.8 3.7c.3.3.3.8 0 1-.4.4-.9.4-1.2 0L2.2 5.7a.8.8 0 0 1 0-1.2L6.6.2C7 0 7.4 0 7.8.2c.3.3.3.8 0 1.1z\" fill-rule=\"nonzero\"/></svg>',\n        'chevron-right': '<svg width=\"10\" height=\"10\"><path d=\"M2.2 1.3a.8.8 0 0 1 0-1c.4-.4.9-.4 1.2 0l4.4 4.1c.3.4.3.9 0 1.2L3.4 9.8c-.3.3-.8.3-1.2 0a.8.8 0 0 1 0-1.1L6 5 2.2 1.3z\" fill-rule=\"nonzero\"/></svg>',\n        'chevron-up': '<svg width=\"10\" height=\"10\"><path d=\"M8.7 7.8L5 4 1.3 7.8c-.3.3-.8.3-1 0a.8.8 0 0 1 0-1.2l4.1-4.4c.3-.3.9-.3 1.2 0l4.2 4.4c.3.3.3.9 0 1.2-.3.3-.8.3-1.1 0z\" fill-rule=\"nonzero\"/></svg>',\n        'close': '<svg width=\"24\" height=\"24\"><path d=\"M17.3 8.2L13.4 12l3.9 3.8a1 1 0 0 1-1.5 1.5L12 13.4l-3.8 3.9a1 1 0 0 1-1.5-1.5l3.9-3.8-3.9-3.8a1 1 0 0 1 1.5-1.5l3.8 3.9 3.8-3.9a1 1 0 0 1 1.5 1.5z\" fill-rule=\"evenodd\"/></svg>',\n        'code-sample': '<svg width=\"24\" height=\"26\"><path d=\"M7.1 11a2.8 2.8 0 0 1-.8 2 2.8 2.8 0 0 1 .8 2v1.7c0 .3.1.6.4.8.2.3.5.4.8.4.3 0 .4.2.4.4v.8c0 .2-.1.4-.4.4-.7 0-1.4-.3-2-.8-.5-.6-.8-1.3-.8-2V15c0-.3-.1-.6-.4-.8-.2-.3-.5-.4-.8-.4a.4.4 0 0 1-.4-.4v-.8c0-.2.2-.4.4-.4.3 0 .6-.1.8-.4.3-.2.4-.5.4-.8V9.3c0-.7.3-1.4.8-2 .6-.5 1.3-.8 2-.8.3 0 .4.2.4.4v.8c0 .2-.1.4-.4.4-.3 0-.6.1-.8.4-.3.2-.4.5-.4.8V11zm9.8 0V9.3c0-.3-.1-.6-.4-.8-.2-.3-.5-.4-.8-.4a.4.4 0 0 1-.4-.4V7c0-.2.1-.4.4-.4.7 0 1.4.3 2 .8.5.6.8 1.3.8 2V11c0 .3.1.6.4.8.2.3.5.4.8.4.2 0 .4.2.4.4v.8c0 .2-.2.4-.4.4-.3 0-.6.1-.8.4-.3.2-.4.5-.4.8v1.7c0 .7-.3 1.4-.8 2-.6.5-1.3.8-2 .8a.4.4 0 0 1-.4-.4v-.8c0-.2.1-.4.4-.4.3 0 .6-.1.8-.4.3-.2.4-.5.4-.8V15a2.8 2.8 0 0 1 .8-2 2.8 2.8 0 0 1-.8-2zm-3.3-.4c0 .4-.1.8-.5 1.1-.3.3-.7.5-1.1.5-.4 0-.8-.2-1.1-.5-.4-.3-.5-.7-.5-1.1 0-.5.1-.9.5-1.2.3-.3.7-.4 1.1-.4.4 0 .8.1 1.1.4.4.3.5.7.5 1.2zM12 13c.4 0 .8.1 1.1.5.4.3.5.7.5 1.1 0 1-.1 1.6-.5 2a3 3 0 0 1-1.1 1c-.4.3-.8.4-1.1.4a.5.5 0 0 1-.5-.5V17a3 3 0 0 0 1-.2l.6-.6c-.6 0-1-.2-1.3-.5-.2-.3-.3-.7-.3-1 0-.5.1-1 .5-1.2.3-.4.7-.5 1.1-.5z\" fill-rule=\"evenodd\"/></svg>',\n        'color-levels': '<svg width=\"24\" height=\"24\"><path d=\"M17.5 11.4A9 9 0 0 1 18 14c0 .5 0 1-.2 1.4 0 .4-.3.9-.5 1.3a6.2 6.2 0 0 1-3.7 3 5.7 5.7 0 0 1-3.2 0A5.9 5.9 0 0 1 7.6 18a6.2 6.2 0 0 1-1.4-2.6 6.7 6.7 0 0 1 0-2.8c0-.4.1-.9.3-1.3a13.6 13.6 0 0 1 2.3-4A20 20 0 0 1 12 4a26.4 26.4 0 0 1 3.2 3.4 18.2 18.2 0 0 1 2.3 4zm-2 4.5c.4-.7.5-1.4.5-2a7.3 7.3 0 0 0-1-3.2c.2.6.2 1.2.2 1.9a4.5 4.5 0 0 1-1.3 3 5.3 5.3 0 0 1-2.3 1.5 4.9 4.9 0 0 1-2 .1 4.3 4.3 0 0 0 2.4.8 4 4 0 0 0 2-.6 4 4 0 0 0 1.5-1.5z\" fill-rule=\"evenodd\"/></svg>',\n        'color-picker': '<svg width=\"24\" height=\"24\"><path d=\"M12 3a9 9 0 0 0 0 18 1.5 1.5 0 0 0 1.1-2.5c-.2-.3-.4-.6-.4-1 0-.8.7-1.5 1.5-1.5H16a5 5 0 0 0 5-5c0-4.4-4-8-9-8zm-5.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm3-4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm3 4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z\" fill-rule=\"nonzero\"/></svg>',\n        'color-swatch-remove-color': '<svg width=\"24\" height=\"24\"><path stroke=\"#000\" stroke-width=\"2\" d=\"M21 3L3 21\" fill-rule=\"evenodd\"/></svg>',\n        'color-swatch': '<svg width=\"24\" height=\"24\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\" fill-rule=\"evenodd\"/></svg>',\n        'comment-add': '<svg width=\"24\" height=\"24\"><g fill-rule=\"nonzero\"><path d=\"M9 19l3-2h7c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H5a1 1 0 0 0-1 1v10c0 .6.4 1 1 1h4v2zm-2 4v-4H5a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-6.4L7 23z\"/><path d=\"M13 10h2a1 1 0 0 1 0 2h-2v2a1 1 0 0 1-2 0v-2H9a1 1 0 0 1 0-2h2V8a1 1 0 0 1 2 0v2z\"/></g></svg>',\n        'comment': '<svg width=\"24\" height=\"24\"><path fill-rule=\"nonzero\" d=\"M9 19l3-2h7c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H5a1 1 0 0 0-1 1v10c0 .6.4 1 1 1h4v2zm-2 4v-4H5a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-6.4L7 23z\"/></svg>',\n        'contrast': '<svg width=\"24\" height=\"24\"><path d=\"M12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4zm-6 8a6 6 0 0 0 6 6V6a6 6 0 0 0-6 6z\" fill-rule=\"evenodd\"/></svg>',\n        'copy': '<svg width=\"24\" height=\"24\"><path d=\"M16 3H6a2 2 0 0 0-2 2v11h2V5h10V3zm1 4a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V9c0-1.2.9-2 2-2h7zm0 12V9h-7v10h7z\" fill-rule=\"nonzero\"/></svg>',\n        'crop': '<svg width=\"24\" height=\"24\"><path d=\"M17 8v7h2c.6 0 1 .4 1 1s-.4 1-1 1h-2v2c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-2H7V9H5a1 1 0 1 1 0-2h2V5c0-.6.4-1 1-1s1 .4 1 1v2h7l3-3 1 1-3 3zM9 9v5l5-5H9zm1 6h5v-5l-5 5z\" fill-rule=\"evenodd\"/></svg>',\n        'cut': '<svg width=\"24\" height=\"24\"><path d=\"M18 15c.6.7 1 1.4 1 2.3 0 .8-.2 1.5-.7 2l-.8.5-1 .2c-.4 0-.8 0-1.2-.3a3.9 3.9 0 0 1-2.1-2.2c-.2-.5-.3-1-.2-1.5l-1-1-1 1c0 .5 0 1-.2 1.5-.1.5-.4 1-.9 1.4-.3.4-.7.6-1.2.8l-1.2.3c-.4 0-.7 0-1-.2-.3 0-.6-.3-.8-.5-.5-.5-.8-1.2-.7-2 0-.9.4-1.6 1-2.2A3.7 3.7 0 0 1 8.6 14H9l1-1-4-4-.5-1a3.3 3.3 0 0 1 0-2c0-.4.3-.7.5-1l6 6 6-6 .5 1a3.3 3.3 0 0 1 0 2c0 .4-.3.7-.5 1l-4 4 1 1h.5c.4 0 .8 0 1.2.3.5.2.9.4 1.2.8zm-8.5 2.2l.1-.4v-.3-.4a1 1 0 0 0-.2-.5 1 1 0 0 0-.4-.2 1.6 1.6 0 0 0-.8 0 2.6 2.6 0 0 0-.8.3 2.5 2.5 0 0 0-.9 1.1l-.1.4v.7l.2.5.5.2h.7a2.5 2.5 0 0 0 .8-.3 2.8 2.8 0 0 0 1-1zm2.5-2.8c.4 0 .7-.1 1-.4.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.3-.6-.4-1-.4s-.7.1-1 .4c-.3.3-.4.6-.4 1s.1.7.4 1c.3.3.6.4 1 .4zm5.4 4l.2-.5v-.4-.3a2.6 2.6 0 0 0-.3-.8 2.4 2.4 0 0 0-.7-.7 2.5 2.5 0 0 0-.8-.3 1.5 1.5 0 0 0-.8 0 1 1 0 0 0-.4.2 1 1 0 0 0-.2.5 1.5 1.5 0 0 0 0 .7v.4l.3.4.3.4a2.8 2.8 0 0 0 .8.5l.4.1h.7l.5-.2z\" fill-rule=\"evenodd\"/></svg>',\n        'document-properties': '<svg width=\"24\" height=\"24\"><path d=\"M14.4 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V7.6L14.4 3zM17 19H7V5h6v4h4v10z\" fill-rule=\"nonzero\"/></svg>',\n        'drag': '<svg width=\"24\" height=\"24\"><path d=\"M13 5h2v2h-2V5zm0 4h2v2h-2V9zM9 9h2v2H9V9zm4 4h2v2h-2v-2zm-4 0h2v2H9v-2zm0 4h2v2H9v-2zm4 0h2v2h-2v-2zM9 5h2v2H9V5z\" fill-rule=\"evenodd\"/></svg>',\n        'duplicate': '<svg width=\"24\" height=\"24\"><g fill-rule=\"nonzero\"><path d=\"M16 3v2H6v11H4V5c0-1.1.9-2 2-2h10zm3 8h-2V9h-7v10h9a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V9c0-1.2.9-2 2-2h7a2 2 0 0 1 2 2v2z\"/><path d=\"M17 14h1a1 1 0 0 1 0 2h-1v1a1 1 0 0 1-2 0v-1h-1a1 1 0 0 1 0-2h1v-1a1 1 0 0 1 2 0v1z\"/></g></svg>',\n        'edit-block': '<svg width=\"24\" height=\"24\"><path fill-rule=\"nonzero\" d=\"M19.8 8.8l-9.4 9.4c-.2.2-.5.4-.9.4l-5.4 1.2 1.2-5.4.5-.8 9.4-9.4c.7-.7 1.8-.7 2.5 0l2.1 2.1c.7.7.7 1.8 0 2.5zm-2-.2l1-.9v-.3l-2.2-2.2a.3.3 0 0 0-.3 0l-1 1L18 8.5zm-1 1l-2.5-2.4-6 6 2.5 2.5 6-6zm-7 7.1l-2.6-2.4-.3.3-.1.2-.7 3 3.1-.6h.1l.4-.5z\"/></svg>',\n        'edit-image': '<svg width=\"24\" height=\"24\"><path d=\"M18 16h2V7a2 2 0 0 0-2-2H7v2h11v9zM6 17h15a1 1 0 0 1 0 2h-1v1a1 1 0 0 1-2 0v-1H6a2 2 0 0 1-2-2V7H3a1 1 0 1 1 0-2h1V4a1 1 0 1 1 2 0v13zm3-5.3l1.3 2 3-4.7 3.7 6H7l2-3.3z\" fill-rule=\"nonzero\"/></svg>',\n        'embed-page': '<svg width=\"24\" height=\"24\"><path d=\"M19 6V5H5v14h2A13 13 0 0 1 19 6zm0 1.4c-.8.8-1.6 2.4-2.2 4.6H19V7.4zm0 5.6h-2.4c-.4 1.8-.6 3.8-.6 6h3v-6zm-4 6c0-2.2.2-4.2.6-6H13c-.7 1.8-1.1 3.8-1.1 6h3zm-4 0c0-2.2.4-4.2 1-6H9.6A12 12 0 0 0 8 19h3zM4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm11.8 9c.4-1.9 1-3.4 1.8-4.5a9.2 9.2 0 0 0-4 4.5h2.2zm-3.4 0a12 12 0 0 1 2.8-4 12 12 0 0 0-5 4h2.2z\" fill-rule=\"nonzero\"/></svg>',\n        'embed': '<svg width=\"24\" height=\"24\"><path d=\"M4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm1 2v14h14V5H5zm4.8 2.6l5.6 4a.5.5 0 0 1 0 .8l-5.6 4A.5.5 0 0 1 9 16V8a.5.5 0 0 1 .8-.4z\" fill-rule=\"nonzero\"/></svg>',\n        'emoji': '<svg width=\"24\" height=\"24\"><path d=\"M9 11c.6 0 1-.4 1-1s-.4-1-1-1a1 1 0 0 0-1 1c0 .6.4 1 1 1zm6 0c.6 0 1-.4 1-1s-.4-1-1-1a1 1 0 0 0-1 1c0 .6.4 1 1 1zm-3 5.5c2.1 0 4-1.5 4.4-3.5H7.6c.5 2 2.3 3.5 4.4 3.5zM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm0 14.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13z\" fill-rule=\"nonzero\"/></svg>',\n        'fill': '<svg width=\"24\" height=\"26\"><path d=\"M16.6 12l-9-9-1.4 1.4 2.4 2.4-5.2 5.1c-.5.6-.5 1.6 0 2.2L9 19.6a1.5 1.5 0 0 0 2.2 0l5.5-5.5c.5-.6.5-1.6 0-2.2zM5.2 13L10 8.2l4.8 4.8H5.2zM19 14.5s-2 2.2-2 3.5c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.3-2-3.5-2-3.5z\" fill-rule=\"nonzero\"/></svg>',\n        'flip-horizontally': '<svg width=\"24\" height=\"24\"><path d=\"M14 19h2v-2h-2v2zm4-8h2V9h-2v2zM4 7v10c0 1.1.9 2 2 2h3v-2H6V7h3V5H6a2 2 0 0 0-2 2zm14-2v2h2a2 2 0 0 0-2-2zm-7 16h2V3h-2v18zm7-6h2v-2h-2v2zm-4-8h2V5h-2v2zm4 12a2 2 0 0 0 2-2h-2v2z\" fill-rule=\"nonzero\"/></svg>',\n        'flip-vertically': '<svg width=\"24\" height=\"24\"><path d=\"M5 14v2h2v-2H5zm8 4v2h2v-2h-2zm4-14H7a2 2 0 0 0-2 2v3h2V6h10v3h2V6a2 2 0 0 0-2-2zm2 14h-2v2a2 2 0 0 0 2-2zM3 11v2h18v-2H3zm6 7v2h2v-2H9zm8-4v2h2v-2h-2zM5 18c0 1.1.9 2 2 2v-2H5z\" fill-rule=\"nonzero\"/></svg>',\n        'format-painter': '<svg width=\"24\" height=\"24\"><path d=\"M18 5V4c0-.5-.4-1-1-1H5a1 1 0 0 0-1 1v4c0 .6.5 1 1 1h12c.6 0 1-.4 1-1V7h1v4H9v9c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-7h8V5h-3z\" fill-rule=\"nonzero\"/></svg>',\n        'fullscreen': '<svg width=\"24\" height=\"24\"><path d=\"M15.3 10l-1.2-1.3 2.9-3h-2.3a.9.9 0 1 1 0-1.7H19c.5 0 .9.4.9.9v4.4a.9.9 0 1 1-1.8 0V7l-2.9 3zm0 4l3 3v-2.3a.9.9 0 1 1 1.7 0V19c0 .5-.4.9-.9.9h-4.4a.9.9 0 1 1 0-1.8H17l-3-2.9 1.3-1.2zM10 15.4l-2.9 3h2.3a.9.9 0 1 1 0 1.7H5a.9.9 0 0 1-.9-.9v-4.4a.9.9 0 1 1 1.8 0V17l2.9-3 1.2 1.3zM8.7 10L5.7 7v2.3a.9.9 0 0 1-1.7 0V5c0-.5.4-.9.9-.9h4.4a.9.9 0 0 1 0 1.8H7l3 2.9-1.3 1.2z\" fill-rule=\"nonzero\"/></svg>',\n        'gallery': '<svg width=\"24\" height=\"24\"><path fill-rule=\"nonzero\" d=\"M5 15.7l2.3-2.2c.3-.3.7-.3 1 0L11 16l5.1-5c.3-.4.8-.4 1 0l2 1.9V8H5v7.7zM5 18V19h3l1.8-1.9-2-2L5 17.9zm14-3l-2.5-2.4-6.4 6.5H19v-4zM4 6h16c.6 0 1 .4 1 1v13c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V7c0-.6.4-1 1-1zm6 7a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM4.5 4h15a.5.5 0 1 1 0 1h-15a.5.5 0 0 1 0-1zm2-2h11a.5.5 0 1 1 0 1h-11a.5.5 0 0 1 0-1z\"/></svg>',\n        'gamma': '<svg width=\"24\" height=\"24\"><path d=\"M4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm1 2v14h14V5H5zm6.5 11.8V14L9.2 8.7a5.1 5.1 0 0 0-.4-.8l-.1-.2H8 8v-1l.3-.1.3-.1h.7a1 1 0 0 1 .6.5l.1.3a8.5 8.5 0 0 1 .3.6l1.9 4.6 2-5.2a1 1 0 0 1 1-.6.5.5 0 0 1 .5.6L13 14v2.8a.7.7 0 0 1-1.4 0z\" fill-rule=\"nonzero\"/></svg>',\n        'help': '<svg width=\"24\" height=\"24\"><g fill-rule=\"evenodd\"><path d=\"M12 5.5a6.5 6.5 0 0 0-6 9 6.3 6.3 0 0 0 1.4 2l1 1a6.3 6.3 0 0 0 3.6 1 6.5 6.5 0 0 0 6-9 6.3 6.3 0 0 0-1.4-2l-1-1a6.3 6.3 0 0 0-3.6-1zM12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4z\"/><path d=\"M9.6 9.7a.7.7 0 0 1-.7-.8c0-1.1 1.5-1.8 3.2-1.8 1.8 0 3.2.8 3.2 2.4 0 1.4-.4 2.1-1.5 2.8-.2 0-.3.1-.3.2a2 2 0 0 0-.8.8.8.8 0 0 1-1.4-.6c.3-.7.8-1 1.3-1.5l.4-.2c.7-.4.8-.6.8-1.5 0-.5-.6-.9-1.7-.9-.5 0-1 .1-1.4.3-.2 0-.3.1-.3.2v-.2c0 .4-.4.8-.8.8z\" fill-rule=\"nonzero\"/><circle cx=\"12\" cy=\"16\" r=\"1\"/></g></svg>',\n        'highlight-bg-color': '<svg width=\"24\" height=\"24\"><g fill-rule=\"evenodd\"><path id=\"tox-icon-highlight-bg-color__color\" d=\"M3 18h18v3H3z\"/><path fill-rule=\"nonzero\" d=\"M7.7 16.7H3l3.3-3.3-.7-.8L10.2 8l4 4.1-4 4.2c-.2.2-.6.2-.8 0l-.6-.7-1.1 1.1zm5-7.5L11 7.4l3-2.9a2 2 0 0 1 2.6 0L18 6c.7.7.7 2 0 2.7l-2.9 2.9-1.8-1.8-.5-.6\"/></g></svg>',\n        'home': '<svg width=\"24\" height=\"24\"><path fill-rule=\"nonzero\" d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\"/></svg>',\n        'horizontal-rule': '<svg width=\"24\" height=\"24\"><path d=\"M4 11h16v2H4z\" fill-rule=\"evenodd\"/></svg>',\n        'image-options': '<svg width=\"24\" height=\"24\"><path d=\"M6 10a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm12 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm-6 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2z\" fill-rule=\"nonzero\"/></svg>',\n        'image': '<svg width=\"24\" height=\"24\"><path d=\"M5 15.7l3.3-3.2c.3-.3.7-.3 1 0L12 15l4.1-4c.3-.4.8-.4 1 0l2 1.9V5H5v10.7zM5 18V19h3l2.8-2.9-2-2L5 17.9zm14-3l-2.5-2.4-6.4 6.5H19v-4zM4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm6 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4z\" fill-rule=\"nonzero\"/></svg>',\n        'indent': '<svg width=\"24\" height=\"24\"><path d=\"M7 5h12c.6 0 1 .4 1 1s-.4 1-1 1H7a1 1 0 1 1 0-2zm5 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm0 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm-5 4h12a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm-2.6-3.8L6.2 12l-1.8-1.2a1 1 0 0 1 1.2-1.6l3 2a1 1 0 0 1 0 1.6l-3 2a1 1 0 1 1-1.2-1.6z\" fill-rule=\"evenodd\"/></svg>',\n        'info': '<svg width=\"24\" height=\"24\"><path d=\"M12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4zm-1 3v2h2V7h-2zm3 10v-1h-1v-5h-3v1h1v4h-1v1h4z\" fill-rule=\"evenodd\"/></svg>',\n        'insert-character': '<svg width=\"24\" height=\"24\"><path d=\"M15 18h4l1-2v4h-6v-3.3l1.4-1a6 6 0 0 0 1.8-2.9 6.3 6.3 0 0 0-.1-4.1 5.8 5.8 0 0 0-3-3.2c-.6-.3-1.3-.5-2.1-.5a5.1 5.1 0 0 0-3.9 1.8 6.3 6.3 0 0 0-1.3 6 6.2 6.2 0 0 0 1.8 3l1.4.9V20H4v-4l1 2h4v-.5l-2-1L5.4 15A6.5 6.5 0 0 1 4 11c0-1 .2-1.9.6-2.7A7 7 0 0 1 6.3 6C7.1 5.4 8 5 9 4.5c1-.3 2-.5 3.1-.5a8.8 8.8 0 0 1 5.7 2 7 7 0 0 1 1.7 2.3 6 6 0 0 1 .2 4.8c-.2.7-.6 1.3-1 1.9a7.6 7.6 0 0 1-3.6 2.5v.5z\" fill-rule=\"evenodd\"/></svg>',\n        'insert-time': '<svg width=\"24\" height=\"24\"><g fill-rule=\"nonzero\"><path d=\"M12 19a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm0 2a9 9 0 1 1 0-18 9 9 0 0 1 0 18z\"/><path d=\"M16 12h-3V7c0-.6-.4-1-1-1a1 1 0 0 0-1 1v7h5c.6 0 1-.4 1-1s-.4-1-1-1z\"/></g></svg>',\n        'invert': '<svg width=\"24\" height=\"24\"><path d=\"M18 19.3L16.5 18a5.8 5.8 0 0 1-3.1 1.9 6.1 6.1 0 0 1-5.5-1.6A5.8 5.8 0 0 1 6 14v-.3l.1-1.2A13.9 13.9 0 0 1 7.7 9l-3-3 .7-.8 2.8 2.9 9 8.9 1.5 1.6-.7.6zm0-5.5v.3l-.1 1.1-.4 1-1.2-1.2a4.3 4.3 0 0 0 .2-1v-.2c0-.4 0-.8-.2-1.3l-.5-1.4a14.8 14.8 0 0 0-3-4.2L12 6a26.1 26.1 0 0 0-2.2 2.5l-1-1a20.9 20.9 0 0 1 2.9-3.3L12 4l1 .8a22.2 22.2 0 0 1 4 5.4c.6 1.2 1 2.4 1 3.6z\" fill-rule=\"evenodd\"/></svg>',\n        'italic': '<svg width=\"24\" height=\"24\"><path d=\"M16.7 4.7l-.1.9h-.3c-.6 0-1 0-1.4.3-.3.3-.4.6-.5 1.1l-2.1 9.8v.6c0 .5.4.8 1.4.8h.2l-.2.8H8l.2-.8h.2c1.1 0 1.8-.5 2-1.5l2-9.8.1-.5c0-.6-.4-.8-1.4-.8h-.3l.2-.9h5.8z\" fill-rule=\"evenodd\"/></svg>',\n        'line': '<svg width=\"24\" height=\"24\"><path d=\"M15 9l-8 8H4v-3l8-8 3 3zm1-1l-3-3 1-1h1c-.2 0 0 0 0 0l2 2s0 .2 0 0v1l-1 1zM4 18h16v2H4v-2z\" fill-rule=\"evenodd\"/></svg>',\n        'link': '<svg width=\"24\" height=\"24\"><path d=\"M6.2 12.3a1 1 0 0 1 1.4 1.4l-2.1 2a2 2 0 1 0 2.7 2.8l4.8-4.8a1 1 0 0 0 0-1.4 1 1 0 1 1 1.4-1.3 2.9 2.9 0 0 1 0 4L9.6 20a3.9 3.9 0 0 1-5.5-5.5l2-2zm11.6-.6a1 1 0 0 1-1.4-1.4l2-2a2 2 0 1 0-2.6-2.8L11 10.3a1 1 0 0 0 0 1.4A1 1 0 1 1 9.6 13a2.9 2.9 0 0 1 0-4L14.4 4a3.9 3.9 0 0 1 5.5 5.5l-2 2z\" fill-rule=\"nonzero\"/></svg>',\n        'list-bull-circle': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path d=\"M11 16a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zM11 26a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zM11 36a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6z\" fill-rule=\"nonzero\"/><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/></g></svg>',\n        'list-bull-default': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><circle cx=\"11\" cy=\"14\" r=\"3\"/><circle cx=\"11\" cy=\"24\" r=\"3\"/><circle cx=\"11\" cy=\"34\" r=\"3\"/><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/></g></svg>',\n        'list-bull-square': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path d=\"M8 11h6v6H8zM8 21h6v6H8zM8 31h6v6H8z\"/><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/></g></svg>',\n        'list-num-default-rtl': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z\"/><path d=\"M37.4 17v-4.8l-1.6 1v-1.1l1.6-1h1.2V17zM33.3 17.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm1.7 5.7c0-1.2 1-2 2.2-2 1.3 0 2.1.8 2.1 1.8 0 .7-.3 1.2-1.3 2.2l-1.2 1v.2h2.6v1h-4.3v-.9l2-1.9c.8-.8 1-1.1 1-1.5 0-.5-.4-.8-1-.8-.5 0-.9.3-.9.9H35zm-1.7 4.3c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm3.2 7.3v-1h.7c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7s-1 .3-1 .8H35c0-1.1 1-1.8 2.2-1.8 1.2 0 2.1.6 2.1 1.6 0 .7-.4 1.2-1 1.3v.1c.7.1 1.3.7 1.3 1.4 0 1-1 1.9-2.4 1.9-1.3 0-2.2-.8-2.3-2h1.2c0 .6.5 1 1.1 1 .6 0 1-.4 1-1 0-.5-.3-.8-1-.8h-.7zm-3.3 2.7c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7z\"/></g></svg>',\n        'list-num-default': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/><path d=\"M10 17v-4.8l-1.5 1v-1.1l1.6-1h1.2V17h-1.2zm3.6.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm-5 5.7c0-1.2.8-2 2.1-2s2.1.8 2.1 1.8c0 .7-.3 1.2-1.4 2.2l-1.1 1v.2h2.6v1H8.6v-.9l2-1.9c.8-.8 1-1.1 1-1.5 0-.5-.4-.8-1-.8-.5 0-.9.3-.9.9H8.5zm6.3 4.3c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM10 34.4v-1h.7c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7s-1 .3-1 .8H8.6c0-1.1 1-1.8 2.2-1.8 1.3 0 2.1.6 2.1 1.6 0 .7-.4 1.2-1 1.3v.1c.8.1 1.3.7 1.3 1.4 0 1-1 1.9-2.4 1.9-1.3 0-2.2-.8-2.3-2h1.2c0 .6.5 1 1.1 1 .7 0 1-.4 1-1 0-.5-.3-.8-1-.8h-.7zm4.7 2.7c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7z\"/></g></svg>',\n        'list-num-lower-alpha-rtl': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z\"/><path d=\"M36.5 16c-.9 0-1.5-.5-1.5-1.3s.6-1.3 1.8-1.4h1v-.4c0-.4-.2-.6-.7-.6-.4 0-.7.1-.8.4h-1.1c0-.8.8-1.4 2-1.4S39 12 39 13V16h-1.2v-.6c-.3.4-.8.7-1.4.7zm.4-.8c.6 0 1-.4 1-.9V14h-1c-.5.1-.7.3-.7.6 0 .4.3.6.7.6zM33.1 16.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zM37.7 26c-.7 0-1.2-.2-1.5-.7v.7H35v-6.3h1.2v2.5c.3-.5.8-.9 1.5-.9 1.1 0 1.8 1 1.8 2.4 0 1.5-.7 2.4-1.8 2.4zm-.5-3.6c-.6 0-1 .5-1 1.3s.4 1.4 1 1.4c.7 0 1-.6 1-1.4 0-.8-.3-1.3-1-1.3zM33.2 26.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zm6 7h-1c-.1-.5-.4-.8-1-.8s-1 .5-1 1.4c0 1 .4 1.4 1 1.4.5 0 .9-.2 1-.7h1c0 1-.8 1.7-2 1.7-1.4 0-2.2-.9-2.2-2.4s.8-2.4 2.2-2.4c1.2 0 2 .7 2 1.7zm-6.1 3c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z\"/></g></svg>',\n        'list-num-lower-alpha': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/><path d=\"M10.3 15.2c.5 0 1-.4 1-.9V14h-1c-.5.1-.8.3-.8.6 0 .4.3.6.8.6zm-.4.9c-1 0-1.5-.6-1.5-1.4 0-.8.6-1.3 1.7-1.4h1.1v-.4c0-.4-.2-.6-.7-.6-.5 0-.8.1-.9.4h-1c0-.8.8-1.4 2-1.4 1.1 0 1.8.6 1.8 1.6V16h-1.1v-.6h-.1c-.2.4-.7.7-1.3.7zm4.6 0c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-3.2 10c-.6 0-1.2-.3-1.4-.8v.7H8.5v-6.3H10v2.5c.3-.5.8-.9 1.4-.9 1.2 0 1.9 1 1.9 2.4 0 1.5-.7 2.4-1.9 2.4zm-.4-3.7c-.7 0-1 .5-1 1.3s.3 1.4 1 1.4c.6 0 1-.6 1-1.4 0-.8-.4-1.3-1-1.3zm4 3.7c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-2.2 7h-1.2c0-.5-.4-.8-.9-.8-.6 0-1 .5-1 1.4 0 1 .4 1.4 1 1.4.5 0 .8-.2 1-.7h1c0 1-.8 1.7-2 1.7-1.4 0-2.2-.9-2.2-2.4s.8-2.4 2.2-2.4c1.2 0 2 .7 2 1.7zm1.8 3c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z\"/></g></svg>',\n        'list-num-lower-greek-rtl': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z\"/><path d=\"M37.4 16c-1.2 0-2-.8-2-2.3 0-1.5.8-2.4 2-2.4.6 0 1 .4 1.3 1v-.9H40v3.2c0 .4.1.5.4.5h.2v.9h-.6c-.6 0-1-.2-1-.7h-.2c-.2.4-.7.8-1.3.8zm.3-1c.6 0 1-.5 1-1.3s-.4-1.3-1-1.3-1 .5-1 1.3.4 1.4 1 1.4zM33.3 16.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM36 21.9c0-1.5.8-2.3 2.1-2.3 1.2 0 2 .6 2 1.6 0 .6-.3 1-.9 1.3.9.3 1.3.8 1.3 1.7 0 1.2-.7 1.9-1.8 1.9-.6 0-1.1-.3-1.4-.8v2.2H36V22zm1.8 1.2v-1h.3c.5 0 .9-.2.9-.7 0-.5-.3-.8-.9-.8-.5 0-.8.3-.8 1v2.2c0 .8.4 1.3 1 1.3s1-.4 1-1-.4-1-1.2-1h-.3zM33.3 26.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM37.1 34.6L34.8 30h1.4l1.7 3.5 1.7-3.5h1.1l-2.2 4.6v.1c.5.8.7 1.4.7 1.8 0 .4-.2.8-.4 1-.2.2-.6.3-1 .3-.9 0-1.3-.4-1.3-1.2 0-.5.2-1 .5-1.7l.1-.2zm.7 1a2 2 0 0 0-.4.9c0 .3.1.4.4.4.3 0 .4-.1.4-.4 0-.2-.1-.6-.4-1zM33.3 36.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z\"/></g></svg>',\n        'list-num-lower-greek': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/><path d=\"M10.5 15c.7 0 1-.5 1-1.3s-.3-1.3-1-1.3c-.5 0-.9.5-.9 1.3s.4 1.4 1 1.4zm-.3 1c-1.1 0-1.8-.8-1.8-2.3 0-1.5.7-2.4 1.8-2.4.7 0 1.1.4 1.3 1h.1v-.9h1.2v3.2c0 .4.1.5.4.5h.2v.9h-.6c-.6 0-1-.2-1.1-.7h-.1c-.2.4-.7.8-1.4.8zm5 .1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zm-4.9 7v-1h.3c.6 0 1-.2 1-.7 0-.5-.4-.8-1-.8-.5 0-.8.3-.8 1v2.2c0 .8.4 1.3 1.1 1.3.6 0 1-.4 1-1s-.5-1-1.3-1h-.3zM8.6 22c0-1.5.7-2.3 2-2.3 1.2 0 2 .6 2 1.6 0 .6-.3 1-.8 1.3.8.3 1.3.8 1.3 1.7 0 1.2-.8 1.9-1.9 1.9-.6 0-1.1-.3-1.3-.8v2.2H8.5V22zm6.2 4.2c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm-4.5 8.5L8 30h1.4l1.7 3.5 1.7-3.5h1.1l-2.2 4.6v.1c.5.8.7 1.4.7 1.8 0 .4-.1.8-.4 1-.2.2-.6.3-1 .3-.9 0-1.3-.4-1.3-1.2 0-.5.2-1 .5-1.7l.1-.2zm.7 1a2 2 0 0 0-.4.9c0 .3.1.4.4.4.3 0 .4-.1.4-.4 0-.2-.1-.6-.4-1zm4.5.5c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z\"/></g></svg>',\n        'list-num-lower-roman-rtl': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z\"/><path d=\"M32.9 16v-1.2h-1.3V16H33zm0 10v-1.2h-1.3V26H33zm0 10v-1.2h-1.3V36H33z\"/><path fill-rule=\"nonzero\" d=\"M36 21h-1.5v5H36zM36 31h-1.5v5H36zM39 21h-1.5v5H39zM39 31h-1.5v5H39zM42 31h-1.5v5H42zM36 11h-1.5v5H36zM36 19h-1.5v1H36zM36 29h-1.5v1H36zM39 19h-1.5v1H39zM39 29h-1.5v1H39zM42 29h-1.5v1H42zM36 9h-1.5v1H36z\"/></g></svg>',\n        'list-num-lower-roman': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/><path d=\"M15.1 16v-1.2h1.3V16H15zm0 10v-1.2h1.3V26H15zm0 10v-1.2h1.3V36H15z\"/><path fill-rule=\"nonzero\" d=\"M12 21h1.5v5H12zM12 31h1.5v5H12zM9 21h1.5v5H9zM9 31h1.5v5H9zM6 31h1.5v5H6zM12 11h1.5v5H12zM12 19h1.5v1H12zM12 29h1.5v1H12zM9 19h1.5v1H9zM9 29h1.5v1H9zM6 29h1.5v1H6zM12 9h1.5v1H12z\"/></g></svg>',\n        'list-num-upper-alpha-rtl': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z\"/><path d=\"M39.3 17l-.5-1.4h-2l-.5 1.4H35l2-6h1.6l2 6h-1.3zm-1.6-4.7l-.7 2.3h1.6l-.8-2.3zM33.4 17c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm4.7 9.9h-2.7v-6H38c1.2 0 1.9.6 1.9 1.5 0 .6-.5 1.2-1 1.3.7.1 1.3.7 1.3 1.5 0 1-.8 1.7-2 1.7zm-1.4-5v1.5h1c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7h-1zm0 4h1.1c.7 0 1.1-.3 1.1-.8 0-.6-.4-.9-1.1-.9h-1.1V26zM33 27.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm4.9 10c-1.8 0-2.8-1.1-2.8-3.1s1-3.1 2.8-3.1c1.4 0 2.5.9 2.6 2.2h-1.3c0-.7-.6-1.1-1.3-1.1-1 0-1.6.7-1.6 2s.6 2 1.6 2c.7 0 1.2-.4 1.4-1h1.2c-.1 1.3-1.2 2.2-2.6 2.2zm-4.5 0c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z\"/></g></svg>',\n        'list-num-upper-alpha': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/><path d=\"M12.6 17l-.5-1.4h-2L9.5 17H8.3l2-6H12l2 6h-1.3zM11 12.3l-.7 2.3h1.6l-.8-2.3zm4.7 4.8c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zM11.4 27H8.7v-6h2.6c1.2 0 1.9.6 1.9 1.5 0 .6-.5 1.2-1 1.3.7.1 1.3.7 1.3 1.5 0 1-.8 1.7-2 1.7zM10 22v1.5h1c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7h-1zm0 4H11c.7 0 1.1-.3 1.1-.8 0-.6-.4-.9-1.1-.9H10V26zm5.4 1.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-4.1 10c-1.8 0-2.8-1.1-2.8-3.1s1-3.1 2.8-3.1c1.4 0 2.5.9 2.6 2.2h-1.3c0-.7-.6-1.1-1.3-1.1-1 0-1.6.7-1.6 2s.6 2 1.6 2c.7 0 1.2-.4 1.4-1h1.2c-.1 1.3-1.2 2.2-2.6 2.2zm4.5 0c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z\"/></g></svg>',\n        'list-num-upper-roman-rtl': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z\"/><path d=\"M31.6 17v-1.2H33V17h-1.3zm0 10v-1.2H33V27h-1.3zm0 10v-1.2H33V37h-1.3z\"/><path fill-rule=\"nonzero\" d=\"M34.5 20H36v7h-1.5zM34.5 30H36v7h-1.5zM37.5 20H39v7h-1.5zM37.5 30H39v7h-1.5zM40.5 30H42v7h-1.5zM34.5 10H36v7h-1.5z\"/></g></svg>',\n        'list-num-upper-roman': '<svg width=\"48\" height=\"48\"><g fill-rule=\"evenodd\"><path opacity=\".2\" d=\"M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z\"/><path d=\"M15.1 17v-1.2h1.3V17H15zm0 10v-1.2h1.3V27H15zm0 10v-1.2h1.3V37H15z\"/><path fill-rule=\"nonzero\" d=\"M12 20h1.5v7H12zM12 30h1.5v7H12zM9 20h1.5v7H9zM9 30h1.5v7H9zM6 30h1.5v7H6zM12 10h1.5v7H12z\"/></g></svg>',\n        'lock': '<svg width=\"24\" height=\"24\"><path d=\"M16.3 11c.2 0 .3 0 .5.2l.2.6v7.4c0 .3 0 .4-.2.6l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6v-7.4c0-.3 0-.4.2-.6l.5-.2H8V8c0-.8.3-1.5.9-2.1.6-.6 1.3-.9 2.1-.9h2c.8 0 1.5.3 2.1.9.6.6.9 1.3.9 2.1v3h.3zM10 8v3h4V8a1 1 0 0 0-.3-.7A1 1 0 0 0 13 7h-2a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7z\" fill-rule=\"evenodd\"/></svg>',\n        'ltr': '<svg width=\"24\" height=\"24\"><path d=\"M11 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 7.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L11 5zM4.4 16.2L6.2 15l-1.8-1.2a1 1 0 0 1 1.2-1.6l3 2a1 1 0 0 1 0 1.6l-3 2a1 1 0 1 1-1.2-1.6z\" fill-rule=\"evenodd\"/></svg>',\n        'more-drawer': '<svg width=\"24\" height=\"24\"><path d=\"M6 10a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm12 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm-6 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2z\" fill-rule=\"nonzero\"/></svg>',\n        'new-document': '<svg width=\"24\" height=\"24\"><path d=\"M14.4 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V7.6L14.4 3zM17 19H7V5h6v4h4v10z\" fill-rule=\"nonzero\"/></svg>',\n        'new-tab': '<svg width=\"24\" height=\"24\"><path d=\"M15 13l2-2v8H5V7h8l-2 2H7v8h8v-4zm4-8v5.5l-2-2-5.6 5.5H10v-1.4L15.5 7l-2-2H19z\" fill-rule=\"evenodd\"/></svg>',\n        'non-breaking': '<svg width=\"24\" height=\"24\"><path d=\"M11 11H8a1 1 0 1 1 0-2h3V6c0-.6.4-1 1-1s1 .4 1 1v3h3c.6 0 1 .4 1 1s-.4 1-1 1h-3v3c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-3zm10 4v5H3v-5c0-.6.4-1 1-1s1 .4 1 1v3h14v-3c0-.6.4-1 1-1s1 .4 1 1z\" fill-rule=\"evenodd\"/></svg>',\n        'notice': '<svg width=\"24\" height=\"24\"><path d=\"M17.8 9.8L15.4 4 20 8.5v7L15.5 20h-7L4 15.5v-7L8.5 4h7l2.3 5.8zm0 0l2.2 5.7-2.3-5.8zM13 17v-2h-2v2h2zm0-4V7h-2v6h2z\" fill-rule=\"evenodd\"/></svg>',\n        'ordered-list-rtl': '<svg width=\"24\" height=\"24\"><path d=\"M6 17h8a1 1 0 0 1 0 2H6a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2H6a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2H6a1 1 0 1 1 0-2zm13-1v3.5a.5.5 0 1 1-1 0V5h-.5a.5.5 0 1 1 0-1H19zm-1 8.8l.2.2h1.3a.5.5 0 1 1 0 1h-1.6a1 1 0 0 1-.9-1V13c0-.4.3-.8.6-1l1.2-.4.2-.3a.2.2 0 0 0-.2-.2h-1.3a.5.5 0 0 1-.5-.5c0-.3.2-.5.5-.5h1.6c.5 0 .9.4.9 1v.1c0 .4-.3.8-.6 1l-1.2.4-.2.3zm2 4.2v2c0 .6-.4 1-1 1h-1.5a.5.5 0 0 1 0-1h1.2a.3.3 0 1 0 0-.6h-1.3a.4.4 0 1 1 0-.8h1.3a.3.3 0 0 0 0-.6h-1.2a.5.5 0 1 1 0-1H19c.6 0 1 .4 1 1z\" fill-rule=\"evenodd\"/></svg>',\n        'ordered-list': '<svg width=\"24\" height=\"24\"><path d=\"M10 17h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 1 1 0-2zM6 4v3.5c0 .3-.2.5-.5.5a.5.5 0 0 1-.5-.5V5h-.5a.5.5 0 0 1 0-1H6zm-1 8.8l.2.2h1.3c.3 0 .5.2.5.5s-.2.5-.5.5H4.9a1 1 0 0 1-.9-1V13c0-.4.3-.8.6-1l1.2-.4.2-.3a.2.2 0 0 0-.2-.2H4.5a.5.5 0 0 1-.5-.5c0-.3.2-.5.5-.5h1.6c.5 0 .9.4.9 1v.1c0 .4-.3.8-.6 1l-1.2.4-.2.3zM7 17v2c0 .6-.4 1-1 1H4.5a.5.5 0 0 1 0-1h1.2c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3H4.4a.4.4 0 1 1 0-.8h1.3c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3H4.5a.5.5 0 1 1 0-1H6c.6 0 1 .4 1 1z\" fill-rule=\"evenodd\"/></svg>',\n        'orientation': '<svg width=\"24\" height=\"24\"><path d=\"M7.3 6.4L1 13l6.4 6.5 6.5-6.5-6.5-6.5zM3.7 13l3.6-3.7L11 13l-3.7 3.7-3.6-3.7zM12 6l2.8 2.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0L9.2 5.7a.8.8 0 0 1 0-1.2L13.6.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L12 4h1a9 9 0 1 1-4.3 16.9l1.5-1.5A7 7 0 1 0 13 6h-1z\" fill-rule=\"nonzero\"/></svg>',\n        'outdent': '<svg width=\"24\" height=\"24\"><path d=\"M7 5h12c.6 0 1 .4 1 1s-.4 1-1 1H7a1 1 0 1 1 0-2zm5 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm0 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm-5 4h12a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm1.6-3.8a1 1 0 0 1-1.2 1.6l-3-2a1 1 0 0 1 0-1.6l3-2a1 1 0 0 1 1.2 1.6L6.8 12l1.8 1.2z\" fill-rule=\"evenodd\"/></svg>',\n        'page-break': '<svg width=\"24\" height=\"24\"><g fill-rule=\"evenodd\"><path d=\"M5 11c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h1c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm4 0c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h1c.6 0 1 .4 1 1s-.4 1-1 1h-1a1 1 0 0 1 0-2zm4 0c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zM7 3v5h10V3c0-.6.4-1 1-1s1 .4 1 1v7H5V3c0-.6.4-1 1-1s1 .4 1 1zM6 22a1 1 0 0 1-1-1v-7h14v7c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-5H7v5c0 .6-.4 1-1 1z\"/></g></svg>',\n        'paste-text': '<svg width=\"24\" height=\"24\"><path d=\"M18 9V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h3V9h9zM9 20H6a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h3.2A3 3 0 0 1 12 1a3 3 0 0 1 2.8 2H18a2 2 0 0 1 2 2v4h1v12H9v-1zm1.5-9.5v9h9v-9h-9zM12 3a1 1 0 0 0-1 1c0 .5.4 1 1 1s1-.5 1-1-.4-1-1-1zm0 9h6v2h-.5l-.5-1h-1v4h.8v1h-3.6v-1h.8v-4h-1l-.5 1H12v-2z\" fill-rule=\"nonzero\"/></svg>',\n        'paste': '<svg width=\"24\" height=\"24\"><path d=\"M18 9V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h3V9h9zM9 20H6a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h3.2A3 3 0 0 1 12 1a3 3 0 0 1 2.8 2H18a2 2 0 0 1 2 2v4h1v12H9v-1zm1.5-9.5v9h9v-9h-9zM12 3a1 1 0 0 0-1 1c0 .5.4 1 1 1s1-.5 1-1-.4-1-1-1z\" fill-rule=\"nonzero\"/></svg>',\n        'permanent-pen': '<svg width=\"24\" height=\"24\"><path d=\"M10.5 17.5L8 20H3v-3l3.5-3.5a2 2 0 0 1 0-3L14 3l1 1-7.3 7.3a1 1 0 0 0 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0L20 9l1 1-7.6 7.6a2 2 0 0 1-2.8 0l-.1-.1z\" fill-rule=\"nonzero\"/></svg>',\n        'plus': '<svg width=\"24\" height=\"24\"><g fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#000\" stroke-width=\"2\"><path d=\"M12 5v14M5 12h14\"/></g></svg>',\n        'preferences': '<svg width=\"24\" height=\"24\"><path d=\"M20.1 13.5l-1.9.2a5.8 5.8 0 0 1-.6 1.5l1.2 1.5c.4.4.3 1 0 1.4l-.7.7a1 1 0 0 1-1.4 0l-1.5-1.2a6.2 6.2 0 0 1-1.5.6l-.2 1.9c0 .5-.5.9-1 .9h-1a1 1 0 0 1-1-.9l-.2-1.9a5.8 5.8 0 0 1-1.5-.6l-1.5 1.2a1 1 0 0 1-1.4 0l-.7-.7a1 1 0 0 1 0-1.4l1.2-1.5a6.2 6.2 0 0 1-.6-1.5l-1.9-.2a1 1 0 0 1-.9-1v-1c0-.5.4-1 .9-1l1.9-.2a5.8 5.8 0 0 1 .6-1.5L5.2 7.3a1 1 0 0 1 0-1.4l.7-.7a1 1 0 0 1 1.4 0l1.5 1.2a6.2 6.2 0 0 1 1.5-.6l.2-1.9c0-.5.5-.9 1-.9h1c.5 0 1 .4 1 .9l.2 1.9a5.8 5.8 0 0 1 1.5.6l1.5-1.2a1 1 0 0 1 1.4 0l.7.7c.3.4.4 1 0 1.4l-1.2 1.5a6.2 6.2 0 0 1 .6 1.5l1.9.2c.5 0 .9.5.9 1v1c0 .5-.4 1-.9 1zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z\" fill-rule=\"evenodd\"/></svg>',\n        'preview': '<svg width=\"24\" height=\"24\"><path d=\"M3.5 12.5c.5.8 1.1 1.6 1.8 2.3 2 2 4.2 3.2 6.7 3.2s4.7-1.2 6.7-3.2a16.2 16.2 0 0 0 2.1-2.8 15.7 15.7 0 0 0-2.1-2.8c-2-2-4.2-3.2-6.7-3.2a9.3 9.3 0 0 0-6.7 3.2A16.2 16.2 0 0 0 3.2 12c0 .2.2.3.3.5zm-2.4-1l.7-1.2L4 7.8C6.2 5.4 8.9 4 12 4c3 0 5.8 1.4 8.1 3.8a18.2 18.2 0 0 1 2.8 3.7v1l-.7 1.2-2.1 2.5c-2.3 2.4-5 3.8-8.1 3.8-3 0-5.8-1.4-8.1-3.8a18.2 18.2 0 0 1-2.8-3.7 1 1 0 0 1 0-1zm12-3.3a2 2 0 1 0 2.7 2.6 4 4 0 1 1-2.6-2.6z\" fill-rule=\"nonzero\"/></svg>',\n        'print': '<svg width=\"24\" height=\"24\"><path d=\"M18 8H6a3 3 0 0 0-3 3v6h2v3h14v-3h2v-6a3 3 0 0 0-3-3zm-1 10H7v-4h10v4zm.5-5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm.5-8H6v2h12V5z\" fill-rule=\"nonzero\"/></svg>',\n        'quote': '<svg width=\"24\" height=\"24\"><path d=\"M7.5 17h.9c.4 0 .7-.2.9-.6L11 13V8c0-.6-.4-1-1-1H6a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h2l-1.3 2.7a1 1 0 0 0 .8 1.3zm8 0h.9c.4 0 .7-.2.9-.6L19 13V8c0-.6-.4-1-1-1h-4a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h2l-1.3 2.7a1 1 0 0 0 .8 1.3z\" fill-rule=\"nonzero\"/></svg>',\n        'redo': '<svg width=\"24\" height=\"24\"><path d=\"M17.6 10H12c-2.8 0-4.4 1.4-4.9 3.5-.4 2 .3 4 1.4 4.6a1 1 0 1 1-1 1.8c-2-1.2-2.9-4.1-2.3-6.8.6-3 3-5.1 6.8-5.1h5.6l-3.3-3.3a1 1 0 1 1 1.4-1.4l5 5a1 1 0 0 1 0 1.4l-5 5a1 1 0 0 1-1.4-1.4l3.3-3.3z\" fill-rule=\"nonzero\"/></svg>',\n        'reload': '<svg width=\"24\" height=\"24\"><g fill-rule=\"nonzero\"><path d=\"M5 22.1l-1.2-4.7v-.2a1 1 0 0 1 1-1l5 .4a1 1 0 1 1-.2 2l-2.2-.2a7.8 7.8 0 0 0 8.4.2 7.5 7.5 0 0 0 3.5-6.4 1 1 0 1 1 2 0 9.5 9.5 0 0 1-4.5 8 9.9 9.9 0 0 1-10.2 0l.4 1.4a1 1 0 1 1-2 .5zM13.6 7.4c0-.5.5-1 1-.9l2.8.2a8 8 0 0 0-9.5-1 7.5 7.5 0 0 0-3.6 7 1 1 0 0 1-2 0 9.5 9.5 0 0 1 4.5-8.6 10 10 0 0 1 10.9.3l-.3-1a1 1 0 0 1 2-.5l1.1 4.8a1 1 0 0 1-1 1.2l-5-.4a1 1 0 0 1-.9-1z\"/></g></svg>',\n        'remove-formatting': '<svg width=\"24\" height=\"24\"><path d=\"M13.2 6a1 1 0 0 1 0 .2l-2.6 10a1 1 0 0 1-1 .8h-.2a.8.8 0 0 1-.8-1l2.6-10H8a1 1 0 1 1 0-2h9a1 1 0 0 1 0 2h-3.8zM5 18h7a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2zm13 1.5L16.5 18 15 19.5a.7.7 0 0 1-1-1l1.5-1.5-1.5-1.5a.7.7 0 0 1 1-1l1.5 1.5 1.5-1.5a.7.7 0 0 1 1 1L17.5 17l1.5 1.5a.7.7 0 0 1-1 1z\" fill-rule=\"evenodd\"/></svg>',\n        'remove': '<svg width=\"24\" height=\"24\"><path d=\"M16 7h3a1 1 0 0 1 0 2h-1v9a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V9H5a1 1 0 1 1 0-2h3V6a3 3 0 0 1 3-3h2a3 3 0 0 1 3 3v1zm-2 0V6c0-.6-.4-1-1-1h-2a1 1 0 0 0-1 1v1h4zm2 2H8v9c0 .6.4 1 1 1h6c.6 0 1-.4 1-1V9zm-7 3a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0v-4zm4 0a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0v-4z\" fill-rule=\"nonzero\"/></svg>',\n        'resize-handle': '<svg width=\"10\" height=\"10\"><g fill-rule=\"nonzero\"><path d=\"M8.1 1.1A.5.5 0 1 1 9 2l-7 7A.5.5 0 1 1 1 8l7-7zM8.1 5.1A.5.5 0 1 1 9 6l-3 3A.5.5 0 1 1 5 8l3-3z\"/></g></svg>',\n        'resize': '<svg width=\"24\" height=\"24\"><path d=\"M4 5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h6c.3 0 .5.1.7.3.2.2.3.4.3.7 0 .3-.1.5-.3.7a1 1 0 0 1-.7.3H7.4L18 16.6V13c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3.3 0 .5.1.7.3.2.2.3.4.3.7v6c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-6a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h3.6L6 7.4V11c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.7-.3A1 1 0 0 1 4 11V5z\" fill-rule=\"evenodd\"/></svg>',\n        'restore-draft': '<svg width=\"24\" height=\"24\"><g fill-rule=\"evenodd\"><path d=\"M17 13c0 .6-.4 1-1 1h-4V8c0-.6.4-1 1-1s1 .4 1 1v4h2c.6 0 1 .4 1 1z\"/><path d=\"M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10z\" fill-rule=\"nonzero\"/></g></svg>',\n        'rotate-left': '<svg width=\"24\" height=\"24\"><path d=\"M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10z\" fill-rule=\"nonzero\"/></svg>',\n        'rotate-right': '<svg width=\"24\" height=\"24\"><path d=\"M20 8V5a1 1 0 0 1 2 0v6c0 .6-.4 1-1 1h-6a1 1 0 0 1 0-2h4.3L16 7A7.2 7.2 0 0 0 7.7 6a7 7 0 0 0 3 13.1c1.9.1 3.7-.5 5-1.7a1 1 0 0 1 1.4 1.5A9.2 9.2 0 0 1 2.2 14c-.9-3.9 1-8 4.5-9.9 3.5-1.9 8-1.3 10.8 1.5L20 8z\" fill-rule=\"nonzero\"/></svg>',\n        'rtl': '<svg width=\"24\" height=\"24\"><path d=\"M8 5h8v2h-2v12h-2V7h-2v12H8v-7c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 4.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L8 5zm12 11.2a1 1 0 1 1-1 1.6l-3-2a1 1 0 0 1 0-1.6l3-2a1 1 0 1 1 1 1.6L18.4 15l1.8 1.2z\" fill-rule=\"evenodd\"/></svg>',\n        'save': '<svg width=\"24\" height=\"24\"><path d=\"M5 16h14a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2c0-1.1.9-2 2-2zm0 2v2h14v-2H5zm10 0h2v2h-2v-2zm-4-6.4L8.7 9.3a1 1 0 1 0-1.4 1.4l4 4c.4.4 1 .4 1.4 0l4-4a1 1 0 1 0-1.4-1.4L13 11.6V4a1 1 0 0 0-2 0v7.6z\" fill-rule=\"nonzero\"/></svg>',\n        'search': '<svg width=\"24\" height=\"24\"><path d=\"M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12z\" fill-rule=\"nonzero\"/></svg>',\n        'select-all': '<svg width=\"24\" height=\"24\"><path d=\"M3 5h2V3a2 2 0 0 0-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2a2 2 0 0 0-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8a2 2 0 0 0 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z\" fill-rule=\"nonzero\"/></svg>',\n        'selected': '<svg width=\"24\" height=\"24\"><path fill-rule=\"nonzero\" d=\"M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2zm3.6 10.9L7 12.3a.7.7 0 0 0-1 1L9.6 17 18 8.6a.7.7 0 0 0 0-1 .7.7 0 0 0-1 0l-7.4 7.3z\"/></svg>',\n        'settings': '<svg width=\"24\" height=\"24\"><path d=\"M11 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8v.3c0 .2 0 .3-.2.5l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V8H5a1 1 0 1 1 0-2h2v-.3c0-.2 0-.3.2-.5l.5-.2h2.5c.3 0 .4 0 .6.2l.2.5V6zM8 8h2V6H8v2zm9 2.8v.2h2c.6 0 1 .4 1 1s-.4 1-1 1h-2v.3c0 .2 0 .3-.2.5l-.6.2h-2.4c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V13H5a1 1 0 0 1 0-2h8v-.3c0-.2 0-.3.2-.5l.6-.2h2.4c.3 0 .4 0 .6.2l.2.6zM14 13h2v-2h-2v2zm-3 2.8v.2h8c.6 0 1 .4 1 1s-.4 1-1 1h-8v.3c0 .2 0 .3-.2.5l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V18H5a1 1 0 0 1 0-2h2v-.3c0-.2 0-.3.2-.5l.5-.2h2.5c.3 0 .4 0 .6.2l.2.6zM8 18h2v-2H8v2z\" fill-rule=\"evenodd\"/></svg>',\n        'sharpen': '<svg width=\"24\" height=\"24\"><path d=\"M16 6l4 4-8 9-8-9 4-4h8zm-4 10.2l5.5-6.2-.1-.1H12v-.3h5.1l-.2-.2H12V9h4.6l-.2-.2H12v-.3h4.1l-.2-.2H12V8h3.6l-.2-.2H8.7L6.5 10l.1.1H12v.3H6.9l.2.2H12v.3H7.3l.2.2H12v.3H7.7l.3.2h4v.3H8.2l.2.2H12v.3H8.6l.3.2H12v.3H9l.3.2H12v.3H9.5l.2.2H12v.3h-2l.2.2H12v.3h-1.6l.2.2H12v.3h-1.1l.2.2h.9v.3h-.7l.2.2h.5v.3h-.3l.3.2z\" fill-rule=\"evenodd\"/></svg>',\n        'sourcecode': '<svg width=\"24\" height=\"24\"><g fill-rule=\"nonzero\"><path d=\"M9.8 15.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0l-4.4-4.1a.8.8 0 0 1 0-1.2l4.4-4.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L6 12l3.8 3.7zM14.2 15.7c-.3.3-.3.8 0 1 .4.4.9.4 1.2 0l4.4-4.1c.3-.3.3-.9 0-1.2l-4.4-4.2a.8.8 0 0 0-1.2 0c-.3.3-.3.8 0 1.1L18 12l-3.8 3.7z\"/></g></svg>',\n        'spell-check': '<svg width=\"24\" height=\"24\"><path d=\"M6 8v3H5V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h2c.3 0 .5.1.7.3.2.2.3.4.3.7v6H8V8H6zm0-3v2h2V5H6zm13 0h-3v5h3v1h-3a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h3v1zm-5 1.5l-.1.7c-.1.2-.3.3-.6.3.3 0 .5.1.6.3l.1.7V10c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-3V4h3c.3 0 .5.1.7.3.2.2.3.4.3.7v1.5zM13 10V8h-2v2h2zm0-3V5h-2v2h2zm3 5l1 1-6.5 7L7 15.5l1.3-1 2.2 2.2L16 12z\" fill-rule=\"evenodd\"/></svg>',\n        'strike-through': '<svg width=\"24\" height=\"24\"><g fill-rule=\"evenodd\"><path d=\"M15.6 8.5c-.5-.7-1-1.1-1.3-1.3-.6-.4-1.3-.6-2-.6-2.7 0-2.8 1.7-2.8 2.1 0 1.6 1.8 2 3.2 2.3 4.4.9 4.6 2.8 4.6 3.9 0 1.4-.7 4.1-5 4.1A6.2 6.2 0 0 1 7 16.4l1.5-1.1c.4.6 1.6 2 3.7 2 1.6 0 2.5-.4 3-1.2.4-.8.3-2-.8-2.6-.7-.4-1.6-.7-2.9-1-1-.2-3.9-.8-3.9-3.6C7.6 6 10.3 5 12.4 5c2.9 0 4.2 1.6 4.7 2.4l-1.5 1.1z\"/><path d=\"M5 11h14a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2z\" fill-rule=\"nonzero\"/></g></svg>',\n        'subscript': '<svg width=\"24\" height=\"24\"><path d=\"M10.4 10l4.6 4.6-1.4 1.4L9 11.4 4.4 16 3 14.6 7.6 10 3 5.4 4.4 4 9 8.6 13.6 4 15 5.4 10.4 10zM21 19h-5v-1l1-.8 1.7-1.6c.3-.4.5-.8.5-1.2 0-.3 0-.6-.2-.7-.2-.2-.5-.3-.9-.3a2 2 0 0 0-.8.2l-.7.3-.4-1.1 1-.6 1.2-.2c.8 0 1.4.3 1.8.7.4.4.6.9.6 1.5s-.2 1.1-.5 1.6a8 8 0 0 1-1.3 1.3l-.6.6h2.6V19z\" fill-rule=\"nonzero\"/></svg>',\n        'superscript': '<svg width=\"24\" height=\"24\"><path d=\"M15 9.4L10.4 14l4.6 4.6-1.4 1.4L9 15.4 4.4 20 3 18.6 7.6 14 3 9.4 4.4 8 9 12.6 13.6 8 15 9.4zm5.9 1.6h-5v-1l1-.8 1.7-1.6c.3-.5.5-.9.5-1.3 0-.3 0-.5-.2-.7-.2-.2-.5-.3-.9-.3l-.8.2-.7.4-.4-1.2c.2-.2.5-.4 1-.5.3-.2.8-.2 1.2-.2.8 0 1.4.2 1.8.6.4.4.6 1 .6 1.6 0 .5-.2 1-.5 1.5l-1.3 1.4-.6.5h2.6V11z\" fill-rule=\"nonzero\"/></svg>',\n        'table-cell-properties': '<svg width=\"24\" height=\"24\"><path d=\"M4 5h16v14H4V5zm10 10h-4v3h4v-3zm0-8h-4v3h4V7zM9 7H5v3h4V7zm-4 4v3h4v-3H5zm10 0v3h4v-3h-4zm0-1h4V7h-4v3zM5 15v3h4v-3H5zm10 3h4v-3h-4v3z\" fill-rule=\"evenodd\"/></svg>',\n        'table-cell-select-all': '<svg width=\"24\" height=\"24\"><path d=\"M12.5 5.5v6h6v-6h-6zm-1 0h-6v6h6v-6zm1 13h6v-6h-6v6zm-1 0v-6h-6v6h6zm-7-14h15v15h-15v-15z\" fill-rule=\"nonzero\"/></svg>',\n        'table-cell-select-inner': '<svg width=\"24\" height=\"24\"><g fill-rule=\"nonzero\"><path d=\"M5.5 5.5v13h13v-13h-13zm-1-1h15v15h-15v-15z\" opacity=\".2\"/><path d=\"M11.5 11.5v-7h1v7h7v1h-7v7h-1v-7h-7v-1h7z\"/></g></svg>',\n        'table-delete-column': '<svg width=\"24\" height=\"24\"><path d=\"M9 11.2l1 1v.2l-1 1v-2.2zm5 1l1-1v2.2l-1-1v-.2zM20 5v14H4V5h16zm-1 2h-4v.8l-.2-.2-.8.8V7h-4v1.4l-.8-.8-.2.2V7H5v11h4v-1.8l.5.5.5-.4V18h4v-1.8l.8.8.2-.3V18h4V7zm-3.9 3.4l-1.8 1.9 1.8 1.9c.4.3.4.9 0 1.2-.3.3-.8.3-1.2 0L12 13.5l-1.8 1.9a.8.8 0 0 1-1.2 0 .9.9 0 0 1 0-1.2l1.8-1.9-1.9-2a.9.9 0 0 1 1.2-1.2l2 2 1.8-1.8c.3-.4.9-.4 1.2 0a.8.8 0 0 1 0 1.1z\" fill-rule=\"evenodd\"/></svg>',\n        'table-delete-row': '<svg width=\"24\" height=\"24\"><path d=\"M16.7 8.8l1.1 1.2-2.4 2.5L18 15l-1.2 1.2-2.5-2.5-2.4 2.5-1.3-1.2 2.5-2.5-2.5-2.5 1.2-1.3 2.6 2.6 2.4-2.5zM4 5h16v14H4V5zm15 5V7H5v3h4.8l1 1H5v3h5.8l-1 1H5v3h14v-3h-.4l-1-1H19v-3h-1.3l1-1h.3z\" fill-rule=\"evenodd\"/></svg>',\n        'table-delete-table': '<svg width=\"24\" height=\"26\"><path d=\"M4 6h16v14H4V6zm1 2v11h14V8H5zm11.7 8.7l-1.5 1.5L12 15l-3.3 3.2-1.4-1.5 3.2-3.2-3.3-3.2 1.5-1.5L12 12l3.2-3.2 1.5 1.5-3.2 3.2 3.2 3.2z\" fill-rule=\"evenodd\"/></svg>',\n        'table-insert-column-after': '<svg width=\"24\" height=\"24\"><path d=\"M14.3 9c.4 0 .7.3.7.6v2.2h2.1c.4 0 .7.3.7.7 0 .4-.3.7-.7.7H15v2.2c0 .3-.3.6-.7.6a.7.7 0 0 1-.6-.6v-2.2h-2.2a.7.7 0 0 1 0-1.4h2.2V9.6c0-.3.3-.6.6-.6zM4 5h16v14H4V5zm5 13v-3H5v3h4zm0-4v-3H5v3h4zm0-4V7H5v3h4zm10 8V7h-9v11h9z\" fill-rule=\"evenodd\"/></svg>',\n        'table-insert-column-before': '<svg width=\"24\" height=\"24\"><path d=\"M9.7 16a.7.7 0 0 1-.7-.6v-2.2H6.9a.7.7 0 0 1 0-1.4H9V9.6c0-.3.3-.6.7-.6.3 0 .6.3.6.6v2.2h2.2c.4 0 .8.3.8.7 0 .4-.4.7-.8.7h-2.2v2.2c0 .3-.3.6-.6.6zM4 5h16v14H4V5zm10 13V7H5v11h9zm5 0v-3h-4v3h4zm0-4v-3h-4v3h4zm0-4V7h-4v3h4z\" fill-rule=\"evenodd\"/></svg>',\n        'table-insert-row-above': '<svg width=\"24\" height=\"24\"><path d=\"M14.8 10.5c0 .3-.2.5-.5.5h-1.8v1.8c0 .3-.2.5-.5.5a.5.5 0 0 1-.5-.6V11H9.7a.5.5 0 0 1 0-1h1.8V8.3c0-.3.2-.6.5-.6s.5.3.5.6V10h1.8c.3 0 .5.2.5.5zM4 5h16v14H4V5zm5 13v-3H5v3h4zm5 0v-3h-4v3h4zm5 0v-3h-4v3h4zm0-4V7H5v7h14z\" fill-rule=\"evenodd\"/></svg>',\n        'table-insert-row-after': '<svg width=\"24\" height=\"24\"><path d=\"M9.2 14.5c0-.3.2-.5.5-.5h1.8v-1.8c0-.3.2-.5.5-.5s.5.2.5.6V14h1.8c.3 0 .5.2.5.5s-.2.5-.5.5h-1.8v1.7c0 .3-.2.6-.5.6a.5.5 0 0 1-.5-.6V15H9.7a.5.5 0 0 1-.5-.5zM4 5h16v14H4V5zm6 2v3h4V7h-4zM5 7v3h4V7H5zm14 11v-7H5v7h14zm0-8V7h-4v3h4z\" fill-rule=\"evenodd\"/></svg>',\n        'table-left-header': '<svg width=\"24\" height=\"24\"><path d=\"M4 5h16v13H4V5zm10 12v-3h-4v3h4zm0-4v-3h-4v3h4zm0-4V6h-4v3h4zm5 8v-3h-4v3h4zm0-4v-3h-4v3h4zm0-4V6h-4v3h4z\" fill-rule=\"evenodd\"/></svg>',\n        'table-merge-cells': '<svg width=\"24\" height=\"24\"><path d=\"M4 5h16v14H4V5zm6 13h9v-7h-9v7zm4-11h-4v3h4V7zM9 7H5v3h4V7zm-4 4v3h4v-3H5zm10-1h4V7h-4v3zM5 15v3h4v-3H5z\" fill-rule=\"evenodd\"/></svg>',\n        'table-row-properties': '<svg width=\"24\" height=\"24\"><path d=\"M4 5h16v14H4V5zm10 10h-4v3h4v-3zm0-8h-4v3h4V7zM9 7H5v3h4V7zm6 3h4V7h-4v3zM5 15v3h4v-3H5zm10 3h4v-3h-4v3z\" fill-rule=\"evenodd\"/></svg>',\n        'table-split-cells': '<svg width=\"24\" height=\"24\"><path d=\"M4 5h16v14H4V5zm6 2v3h4V7h-4zM9 18v-3H5v3h4zm0-4v-3H5v3h4zm0-4V7H5v3h4zm10 8v-7h-9v7h9zm0-8V7h-4v3h4zm-3.5 4.5l1.5 1.6c.3.2.3.7 0 1-.2.2-.7.2-1 0l-1.5-1.6-1.6 1.5c-.2.3-.7.3-1 0a.7.7 0 0 1 0-1l1.6-1.5-1.5-1.6a.7.7 0 0 1 1-1l1.5 1.6 1.6-1.5c.2-.3.7-.3 1 0 .2.2.2.7 0 1l-1.6 1.5z\" fill-rule=\"evenodd\"/></svg>',\n        'table-top-header': '<svg width=\"24\" height=\"24\"><path d=\"M4 5h16v13H4V5zm5 12v-3H5v3h4zm0-4v-3H5v3h4zm5 4v-3h-4v3h4zm0-4v-3h-4v3h4zm5 4v-3h-4v3h4zm0-4v-3h-4v3h4z\" fill-rule=\"evenodd\"/></svg>',\n        'table': '<svg width=\"24\" height=\"24\"><path d=\"M4 5h16v14H4V5zm6 9h4v-3h-4v3zm4 1h-4v3h4v-3zm0-8h-4v3h4V7zM9 7H5v3h4V7zm-4 4v3h4v-3H5zm10 0v3h4v-3h-4zm0-1h4V7h-4v3zM5 15v3h4v-3H5zm10 3h4v-3h-4v3z\" fill-rule=\"evenodd\"/></svg>',\n        'template': '<svg width=\"24\" height=\"24\"><path d=\"M19 19v-1H5v1h14zM9 16v-4a5 5 0 1 1 6 0v4h4a2 2 0 0 1 2 2v3H3v-3c0-1.1.9-2 2-2h4zm4 0v-5l.8-.6a3 3 0 1 0-3.6 0l.8.6v5h2z\" fill-rule=\"nonzero\"/></svg>',\n        'temporary-placeholder': '<svg width=\"24\" height=\"24\"><g fill-rule=\"evenodd\"><path d=\"M9 7.6V6h2.5V4.5a.5.5 0 1 1 1 0V6H15v1.6a8 8 0 1 1-6 0zm-2.6 5.3a.5.5 0 0 0 .3.6c.3 0 .6 0 .6-.3l.1-.2a5 5 0 0 1 3.3-2.8c.3-.1.4-.4.4-.6-.1-.3-.4-.5-.6-.4a6 6 0 0 0-4.1 3.7z\"/><circle cx=\"14\" cy=\"4\" r=\"1\"/><circle cx=\"12\" cy=\"2\" r=\"1\"/><circle cx=\"10\" cy=\"4\" r=\"1\"/></g></svg>',\n        'text-color': '<svg width=\"24\" height=\"24\"><g fill-rule=\"evenodd\"><path id=\"tox-icon-text-color__color\" d=\"M3 18h18v3H3z\"/><path d=\"M8.7 16h-.8a.5.5 0 0 1-.5-.6l2.7-9c.1-.3.3-.4.5-.4h2.8c.2 0 .4.1.5.4l2.7 9a.5.5 0 0 1-.5.6h-.8a.5.5 0 0 1-.4-.4l-.7-2.2c0-.3-.3-.4-.5-.4h-3.4c-.2 0-.4.1-.5.4l-.7 2.2c0 .3-.2.4-.4.4zm2.6-7.6l-.6 2a.5.5 0 0 0 .5.6h1.6a.5.5 0 0 0 .5-.6l-.6-2c0-.3-.3-.4-.5-.4h-.4c-.2 0-.4.1-.5.4z\"/></g></svg>',\n        'toc': '<svg width=\"24\" height=\"24\"><path d=\"M5 5c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 1 1 0-2zm3 0h11c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 1 1 0-2zm-3 8c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h11c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm0-4c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 1 1 0-2zm3 0h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm-3 8c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2z\" fill-rule=\"evenodd\"/></svg>',\n        'translate': '<svg width=\"24\" height=\"24\"><path d=\"M12.7 14.3l-.3.7-.4.7-2.2-2.2-3.1 3c-.3.4-.8.4-1 0a.7.7 0 0 1 0-1l3.1-3A12.4 12.4 0 0 1 6.7 9H8a10.1 10.1 0 0 0 1.7 2.4c.5-.5 1-1.1 1.4-1.8l.9-2H4.7a.7.7 0 1 1 0-1.5h4.4v-.7c0-.4.3-.8.7-.8.4 0 .7.4.7.8v.7H15c.4 0 .8.3.8.7 0 .4-.4.8-.8.8h-1.4a12.3 12.3 0 0 1-1 2.4 13.5 13.5 0 0 1-1.7 2.3l1.9 1.8zm4.3-3l2.7 7.3a.5.5 0 0 1-.4.7 1 1 0 0 1-1-.7l-.6-1.5h-3.4l-.6 1.5a1 1 0 0 1-1 .7.5.5 0 0 1-.4-.7l2.7-7.4a1 1 0 1 1 2 0zm-2.2 4.4h2.4L16 12.5l-1.2 3.2z\" fill-rule=\"evenodd\"/></svg>',\n        'underline': '<svg width=\"24\" height=\"24\"><path d=\"M16 5c.6 0 1 .4 1 1v5.5a4 4 0 0 1-.4 1.8l-1 1.4a5.3 5.3 0 0 1-5.5 1 5 5 0 0 1-1.6-1c-.5-.4-.8-.9-1.1-1.4a4 4 0 0 1-.4-1.8V6c0-.6.4-1 1-1s1 .4 1 1v5.5c0 .3 0 .6.2 1l.6.7a3.3 3.3 0 0 0 2.2.8 3.4 3.4 0 0 0 2.2-.8c.3-.2.4-.5.6-.8l.2-.9V6c0-.6.4-1 1-1zM8 17h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2z\" fill-rule=\"evenodd\"/></svg>',\n        'undo': '<svg width=\"24\" height=\"24\"><path d=\"M6.4 8H12c3.7 0 6.2 2 6.8 5.1.6 2.7-.4 5.6-2.3 6.8a1 1 0 0 1-1-1.8c1.1-.6 1.8-2.7 1.4-4.6-.5-2.1-2.1-3.5-4.9-3.5H6.4l3.3 3.3a1 1 0 1 1-1.4 1.4l-5-5a1 1 0 0 1 0-1.4l5-5a1 1 0 0 1 1.4 1.4L6.4 8z\" fill-rule=\"nonzero\"/></svg>',\n        'unlink': '<svg width=\"24\" height=\"24\"><path d=\"M6.2 12.3a1 1 0 0 1 1.4 1.4l-2 2a2 2 0 1 0 2.6 2.8l4.8-4.8a1 1 0 0 0 0-1.4 1 1 0 1 1 1.4-1.3 2.9 2.9 0 0 1 0 4L9.6 20a3.9 3.9 0 0 1-5.5-5.5l2-2zm11.6-.6a1 1 0 0 1-1.4-1.4l2.1-2a2 2 0 1 0-2.7-2.8L11 10.3a1 1 0 0 0 0 1.4A1 1 0 1 1 9.6 13a2.9 2.9 0 0 1 0-4L14.4 4a3.9 3.9 0 0 1 5.5 5.5l-2 2zM7.6 6.3a.8.8 0 0 1-1 1.1L3.3 4.2a.7.7 0 1 1 1-1l3.2 3.1zM5.1 8.6a.8.8 0 0 1 0 1.5H3a.8.8 0 0 1 0-1.5H5zm5-3.5a.8.8 0 0 1-1.5 0V3a.8.8 0 0 1 1.5 0V5zm6 11.8a.8.8 0 0 1 1-1l3.2 3.2a.8.8 0 0 1-1 1L16 17zm-2.2 2a.8.8 0 0 1 1.5 0V21a.8.8 0 0 1-1.5 0V19zm5-3.5a.7.7 0 1 1 0-1.5H21a.8.8 0 0 1 0 1.5H19z\" fill-rule=\"nonzero\"/></svg>',\n        'unlock': '<svg width=\"24\" height=\"24\"><path d=\"M16 5c.8 0 1.5.3 2.1.9.6.6.9 1.3.9 2.1v3h-2V8a1 1 0 0 0-.3-.7A1 1 0 0 0 16 7h-2a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7v3h.3c.2 0 .3 0 .5.2l.2.6v7.4c0 .3 0 .4-.2.6l-.6.2H4.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6v-7.4c0-.3 0-.4.2-.6l.5-.2H11V8c0-.8.3-1.5.9-2.1.6-.6 1.3-.9 2.1-.9h2z\" fill-rule=\"evenodd\"/></svg>',\n        'unordered-list': '<svg width=\"24\" height=\"24\"><path d=\"M11 5h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zM4.5 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1zm0 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1zm0 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1z\" fill-rule=\"evenodd\"/></svg>',\n        'unselected': '<svg width=\"24\" height=\"24\"><path fill-rule=\"nonzero\" d=\"M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2zm0 1a1 1 0 0 0-1 1v12c0 .6.4 1 1 1h12c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H6z\"/></svg>',\n        'upload': '<svg width=\"24\" height=\"24\"><path d=\"M18 19v-2a1 1 0 0 1 2 0v3c0 .6-.4 1-1 1H5a1 1 0 0 1-1-1v-3a1 1 0 0 1 2 0v2h12zM11 6.4L8.7 8.7a1 1 0 0 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.4L13 6.4V16a1 1 0 0 1-2 0V6.4z\" fill-rule=\"nonzero\"/></svg>',\n        'user': '<svg width=\"24\" height=\"24\"><path d=\"M12 24a12 12 0 1 1 0-24 12 12 0 0 1 0 24zm-8.7-5.3a11 11 0 0 0 17.4 0C19.4 16.3 14.6 15 12 15c-2.6 0-7.4 1.3-8.7 3.7zM12 13c2.2 0 4-2 4-4.5S14.2 4 12 4 8 6 8 8.5 9.8 13 12 13z\" fill-rule=\"nonzero\"/></svg>',\n        'visualblocks': '<svg width=\"24\" height=\"24\"><path d=\"M9 19v2H7v-2h2zm-4 0v2a2 2 0 0 1-2-2h2zm8 0v2h-2v-2h2zm8 0a2 2 0 0 1-2 2v-2h2zm-4 0v2h-2v-2h2zM15 7a1 1 0 0 1 0 2v7a1 1 0 0 1-2 0V9h-1v7a1 1 0 0 1-2 0v-4a2.5 2.5 0 0 1-.2-5H15zM5 15v2H3v-2h2zm16 0v2h-2v-2h2zM5 11v2H3v-2h2zm16 0v2h-2v-2h2zM5 7v2H3V7h2zm16 0v2h-2V7h2zM5 3v2H3c0-1.1.9-2 2-2zm8 0v2h-2V3h2zm6 0a2 2 0 0 1 2 2h-2V3zM9 3v2H7V3h2zm8 0v2h-2V3h2z\" fill-rule=\"evenodd\"/></svg>',\n        'visualchars': '<svg width=\"24\" height=\"24\"><path d=\"M10 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 6.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L10 5z\" fill-rule=\"evenodd\"/></svg>',\n        'warning': '<svg width=\"24\" height=\"24\"><path d=\"M19.8 18.3c.2.5.3.9 0 1.2-.1.3-.5.5-1 .5H5.2c-.5 0-.9-.2-1-.5-.3-.3-.2-.7 0-1.2L11 4.7l.5-.5.5-.2c.2 0 .3 0 .5.2.2 0 .3.3.5.5l6.8 13.6zM12 18c.3 0 .5-.1.7-.3.2-.2.3-.4.3-.7a1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3zm.7-3l.3-4a1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7l.3 4h1.4z\" fill-rule=\"evenodd\"/></svg>',\n        'zoom-in': '<svg width=\"24\" height=\"24\"><path d=\"M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12zm-1-9a1 1 0 0 1 2 0v6a1 1 0 0 1-2 0V8zm-2 4a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2H8z\" fill-rule=\"nonzero\"/></svg>',\n        'zoom-out': '<svg width=\"24\" height=\"24\"><path d=\"M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12zm-3-5a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2H8z\" fill-rule=\"nonzero\"/></svg>'\n      };\n    };\n\n    var CreateIconManager = function () {\n      var lookup = {};\n      var add = function (id, iconPack) {\n        lookup[id] = iconPack;\n      };\n      var get = function (id) {\n        if (lookup[id]) {\n          return lookup[id];\n        }\n        return { icons: {} };\n      };\n      var has$1 = function (id) {\n        return has(lookup, id);\n      };\n      return {\n        add: add,\n        get: get,\n        has: has$1\n      };\n    };\n    var IconManager = CreateIconManager();\n\n    var PluginManager = AddOnManager$1.PluginManager;\n\n    var ThemeManager = AddOnManager$1.ThemeManager;\n\n    function Uploader(uploadStatus, settings) {\n      var pendingPromises = {};\n      var pathJoin = function (path1, path2) {\n        if (path1) {\n          return path1.replace(/\\/$/, '') + '/' + path2.replace(/^\\//, '');\n        }\n        return path2;\n      };\n      var defaultHandler = function (blobInfo, success, failure, progress) {\n        var xhr, formData;\n        xhr = new domGlobals.XMLHttpRequest();\n        xhr.open('POST', settings.url);\n        xhr.withCredentials = settings.credentials;\n        xhr.upload.onprogress = function (e) {\n          progress(e.loaded / e.total * 100);\n        };\n        xhr.onerror = function () {\n          failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);\n        };\n        xhr.onload = function () {\n          var json;\n          if (xhr.status < 200 || xhr.status >= 300) {\n            failure('HTTP Error: ' + xhr.status);\n            return;\n          }\n          json = JSON.parse(xhr.responseText);\n          if (!json || typeof json.location !== 'string') {\n            failure('Invalid JSON: ' + xhr.responseText);\n            return;\n          }\n          success(pathJoin(settings.basePath, json.location));\n        };\n        formData = new domGlobals.FormData();\n        formData.append('file', blobInfo.blob(), blobInfo.filename());\n        xhr.send(formData);\n      };\n      var noUpload = function () {\n        return new promiseObj(function (resolve) {\n          resolve([]);\n        });\n      };\n      var handlerSuccess = function (blobInfo, url) {\n        return {\n          url: url,\n          blobInfo: blobInfo,\n          status: true\n        };\n      };\n      var handlerFailure = function (blobInfo, error) {\n        return {\n          url: '',\n          blobInfo: blobInfo,\n          status: false,\n          error: error\n        };\n      };\n      var resolvePending = function (blobUri, result) {\n        Tools.each(pendingPromises[blobUri], function (resolve) {\n          resolve(result);\n        });\n        delete pendingPromises[blobUri];\n      };\n      var uploadBlobInfo = function (blobInfo, handler, openNotification) {\n        uploadStatus.markPending(blobInfo.blobUri());\n        return new promiseObj(function (resolve) {\n          var notification, progress;\n          var noop = function () {\n          };\n          try {\n            var closeNotification_1 = function () {\n              if (notification) {\n                notification.close();\n                progress = noop;\n              }\n            };\n            var success = function (url) {\n              closeNotification_1();\n              uploadStatus.markUploaded(blobInfo.blobUri(), url);\n              resolvePending(blobInfo.blobUri(), handlerSuccess(blobInfo, url));\n              resolve(handlerSuccess(blobInfo, url));\n            };\n            var failure = function (error) {\n              closeNotification_1();\n              uploadStatus.removeFailed(blobInfo.blobUri());\n              resolvePending(blobInfo.blobUri(), handlerFailure(blobInfo, error));\n              resolve(handlerFailure(blobInfo, error));\n            };\n            progress = function (percent) {\n              if (percent < 0 || percent > 100) {\n                return;\n              }\n              if (!notification) {\n                notification = openNotification();\n              }\n              notification.progressBar.value(percent);\n            };\n            handler(blobInfo, success, failure, progress);\n          } catch (ex) {\n            resolve(handlerFailure(blobInfo, ex.message));\n          }\n        });\n      };\n      var isDefaultHandler = function (handler) {\n        return handler === defaultHandler;\n      };\n      var pendingUploadBlobInfo = function (blobInfo) {\n        var blobUri = blobInfo.blobUri();\n        return new promiseObj(function (resolve) {\n          pendingPromises[blobUri] = pendingPromises[blobUri] || [];\n          pendingPromises[blobUri].push(resolve);\n        });\n      };\n      var uploadBlobs = function (blobInfos, openNotification) {\n        blobInfos = Tools.grep(blobInfos, function (blobInfo) {\n          return !uploadStatus.isUploaded(blobInfo.blobUri());\n        });\n        return promiseObj.all(Tools.map(blobInfos, function (blobInfo) {\n          return uploadStatus.isPending(blobInfo.blobUri()) ? pendingUploadBlobInfo(blobInfo) : uploadBlobInfo(blobInfo, settings.handler, openNotification);\n        }));\n      };\n      var upload = function (blobInfos, openNotification) {\n        return !settings.url && isDefaultHandler(settings.handler) ? noUpload() : uploadBlobs(blobInfos, openNotification);\n      };\n      if (isFunction(settings.handler) === false) {\n        settings.handler = defaultHandler;\n      }\n      return { upload: upload };\n    }\n\n    var blobUriToBlob = function (url) {\n      return new promiseObj(function (resolve, reject) {\n        var rejectWithError = function () {\n          reject('Cannot convert ' + url + ' to Blob. Resource might not exist or is inaccessible.');\n        };\n        try {\n          var xhr = new domGlobals.XMLHttpRequest();\n          xhr.open('GET', url, true);\n          xhr.responseType = 'blob';\n          xhr.onload = function () {\n            if (this.status === 200) {\n              resolve(this.response);\n            } else {\n              rejectWithError();\n            }\n          };\n          xhr.onerror = rejectWithError;\n          xhr.send();\n        } catch (ex) {\n          rejectWithError();\n        }\n      });\n    };\n    var parseDataUri = function (uri) {\n      var type, matches;\n      var uriParts = decodeURIComponent(uri).split(',');\n      matches = /data:([^;]+)/.exec(uriParts[0]);\n      if (matches) {\n        type = matches[1];\n      }\n      return {\n        type: type,\n        data: uriParts[1]\n      };\n    };\n    var dataUriToBlob = function (uri) {\n      return new promiseObj(function (resolve) {\n        var str, arr, i;\n        var uriParts = parseDataUri(uri);\n        try {\n          str = domGlobals.atob(uriParts.data);\n        } catch (e) {\n          resolve(new domGlobals.Blob([]));\n          return;\n        }\n        arr = new Uint8Array(str.length);\n        for (i = 0; i < arr.length; i++) {\n          arr[i] = str.charCodeAt(i);\n        }\n        resolve(new domGlobals.Blob([arr], { type: uriParts.type }));\n      });\n    };\n    var uriToBlob = function (url) {\n      if (url.indexOf('blob:') === 0) {\n        return blobUriToBlob(url);\n      }\n      if (url.indexOf('data:') === 0) {\n        return dataUriToBlob(url);\n      }\n      return null;\n    };\n    var blobToDataUri = function (blob) {\n      return new promiseObj(function (resolve) {\n        var reader = new domGlobals.FileReader();\n        reader.onloadend = function () {\n          resolve(reader.result);\n        };\n        reader.readAsDataURL(blob);\n      });\n    };\n    var Conversions = {\n      uriToBlob: uriToBlob,\n      blobToDataUri: blobToDataUri,\n      parseDataUri: parseDataUri\n    };\n\n    var count = 0;\n    var uniqueId = function (prefix) {\n      return (prefix || 'blobid') + count++;\n    };\n    var imageToBlobInfo = function (blobCache, img, resolve, reject) {\n      var base64, blobInfo;\n      if (img.src.indexOf('blob:') === 0) {\n        blobInfo = blobCache.getByUri(img.src);\n        if (blobInfo) {\n          resolve({\n            image: img,\n            blobInfo: blobInfo\n          });\n        } else {\n          Conversions.uriToBlob(img.src).then(function (blob) {\n            Conversions.blobToDataUri(blob).then(function (dataUri) {\n              base64 = Conversions.parseDataUri(dataUri).data;\n              blobInfo = blobCache.create(uniqueId(), blob, base64);\n              blobCache.add(blobInfo);\n              resolve({\n                image: img,\n                blobInfo: blobInfo\n              });\n            });\n          }, function (err) {\n            reject(err);\n          });\n        }\n        return;\n      }\n      base64 = Conversions.parseDataUri(img.src).data;\n      blobInfo = blobCache.findFirst(function (cachedBlobInfo) {\n        return cachedBlobInfo.base64() === base64;\n      });\n      if (blobInfo) {\n        resolve({\n          image: img,\n          blobInfo: blobInfo\n        });\n      } else {\n        Conversions.uriToBlob(img.src).then(function (blob) {\n          blobInfo = blobCache.create(uniqueId(), blob, base64);\n          blobCache.add(blobInfo);\n          resolve({\n            image: img,\n            blobInfo: blobInfo\n          });\n        }, function (err) {\n          reject(err);\n        });\n      }\n    };\n    var getAllImages = function (elm) {\n      return elm ? from$1(elm.getElementsByTagName('img')) : [];\n    };\n    function ImageScanner(uploadStatus, blobCache) {\n      var cachedPromises = {};\n      var findAll = function (elm, predicate) {\n        var images;\n        if (!predicate) {\n          predicate = constant(true);\n        }\n        images = filter(getAllImages(elm), function (img) {\n          var src = img.src;\n          if (!Env.fileApi) {\n            return false;\n          }\n          if (img.hasAttribute('data-mce-bogus')) {\n            return false;\n          }\n          if (img.hasAttribute('data-mce-placeholder')) {\n            return false;\n          }\n          if (!src || src === Env.transparentSrc) {\n            return false;\n          }\n          if (src.indexOf('blob:') === 0) {\n            return !uploadStatus.isUploaded(src) && predicate(img);\n          }\n          if (src.indexOf('data:') === 0) {\n            return predicate(img);\n          }\n          return false;\n        });\n        var promises = map(images, function (img) {\n          if (cachedPromises[img.src]) {\n            return new promiseObj(function (resolve) {\n              cachedPromises[img.src].then(function (imageInfo) {\n                if (typeof imageInfo === 'string') {\n                  return imageInfo;\n                }\n                resolve({\n                  image: img,\n                  blobInfo: imageInfo.blobInfo\n                });\n              });\n            });\n          }\n          var newPromise = new promiseObj(function (resolve, reject) {\n            imageToBlobInfo(blobCache, img, resolve, reject);\n          }).then(function (result) {\n            delete cachedPromises[result.image.src];\n            return result;\n          }).catch(function (error) {\n            delete cachedPromises[img.src];\n            return error;\n          });\n          cachedPromises[img.src] = newPromise;\n          return newPromise;\n        });\n        return promiseObj.all(promises);\n      };\n      return { findAll: findAll };\n    }\n\n    var count$1 = 0;\n    var seed = function () {\n      var rnd = function () {\n        return Math.round(Math.random() * 4294967295).toString(36);\n      };\n      var now = new Date().getTime();\n      return 's' + now.toString(36) + rnd() + rnd() + rnd();\n    };\n    var uuid = function (prefix) {\n      return prefix + count$1++ + seed();\n    };\n    var Uuid = { uuid: uuid };\n\n    var BlobCache = function () {\n      var cache = [];\n      var mimeToExt = function (mime) {\n        var mimes = {\n          'image/jpeg': 'jpg',\n          'image/jpg': 'jpg',\n          'image/gif': 'gif',\n          'image/png': 'png'\n        };\n        return mimes[mime.toLowerCase()] || 'dat';\n      };\n      var create = function (o, blob, base64, filename) {\n        if (isString(o)) {\n          var id = o;\n          return toBlobInfo({\n            id: id,\n            name: filename,\n            blob: blob,\n            base64: base64\n          });\n        } else if (isObject(o)) {\n          return toBlobInfo(o);\n        } else {\n          throw new Error('Unknown input type');\n        }\n      };\n      var toBlobInfo = function (o) {\n        var id, name;\n        if (!o.blob || !o.base64) {\n          throw new Error('blob and base64 representations of the image are required for BlobInfo to be created');\n        }\n        id = o.id || Uuid.uuid('blobid');\n        name = o.name || id;\n        return {\n          id: constant(id),\n          name: constant(name),\n          filename: constant(name + '.' + mimeToExt(o.blob.type)),\n          blob: constant(o.blob),\n          base64: constant(o.base64),\n          blobUri: constant(o.blobUri || domGlobals.URL.createObjectURL(o.blob)),\n          uri: constant(o.uri)\n        };\n      };\n      var add = function (blobInfo) {\n        if (!get(blobInfo.id())) {\n          cache.push(blobInfo);\n        }\n      };\n      var get = function (id) {\n        return findFirst(function (cachedBlobInfo) {\n          return cachedBlobInfo.id() === id;\n        });\n      };\n      var findFirst = function (predicate) {\n        return filter(cache, predicate)[0];\n      };\n      var getByUri = function (blobUri) {\n        return findFirst(function (blobInfo) {\n          return blobInfo.blobUri() === blobUri;\n        });\n      };\n      var removeByUri = function (blobUri) {\n        cache = filter(cache, function (blobInfo) {\n          if (blobInfo.blobUri() === blobUri) {\n            domGlobals.URL.revokeObjectURL(blobInfo.blobUri());\n            return false;\n          }\n          return true;\n        });\n      };\n      var destroy = function () {\n        each(cache, function (cachedBlobInfo) {\n          domGlobals.URL.revokeObjectURL(cachedBlobInfo.blobUri());\n        });\n        cache = [];\n      };\n      return {\n        create: create,\n        add: add,\n        get: get,\n        getByUri: getByUri,\n        findFirst: findFirst,\n        removeByUri: removeByUri,\n        destroy: destroy\n      };\n    };\n\n    function UploadStatus () {\n      var PENDING = 1, UPLOADED = 2;\n      var blobUriStatuses = {};\n      var createStatus = function (status, resultUri) {\n        return {\n          status: status,\n          resultUri: resultUri\n        };\n      };\n      var hasBlobUri = function (blobUri) {\n        return blobUri in blobUriStatuses;\n      };\n      var getResultUri = function (blobUri) {\n        var result = blobUriStatuses[blobUri];\n        return result ? result.resultUri : null;\n      };\n      var isPending = function (blobUri) {\n        return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === PENDING : false;\n      };\n      var isUploaded = function (blobUri) {\n        return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === UPLOADED : false;\n      };\n      var markPending = function (blobUri) {\n        blobUriStatuses[blobUri] = createStatus(PENDING, null);\n      };\n      var markUploaded = function (blobUri, resultUri) {\n        blobUriStatuses[blobUri] = createStatus(UPLOADED, resultUri);\n      };\n      var removeFailed = function (blobUri) {\n        delete blobUriStatuses[blobUri];\n      };\n      var destroy = function () {\n        blobUriStatuses = {};\n      };\n      return {\n        hasBlobUri: hasBlobUri,\n        getResultUri: getResultUri,\n        isPending: isPending,\n        isUploaded: isUploaded,\n        markPending: markPending,\n        markUploaded: markUploaded,\n        removeFailed: removeFailed,\n        destroy: destroy\n      };\n    }\n\n    var EditorUpload = function (editor) {\n      var blobCache = BlobCache();\n      var uploader, imageScanner;\n      var uploadStatus = UploadStatus();\n      var urlFilters = [];\n      var aliveGuard = function (callback) {\n        return function (result) {\n          if (editor.selection) {\n            return callback(result);\n          }\n          return [];\n        };\n      };\n      var cacheInvalidator = function () {\n        return '?' + new Date().getTime();\n      };\n      var replaceString = function (content, search, replace) {\n        var index = 0;\n        do {\n          index = content.indexOf(search, index);\n          if (index !== -1) {\n            content = content.substring(0, index) + replace + content.substr(index + search.length);\n            index += replace.length - search.length + 1;\n          }\n        } while (index !== -1);\n        return content;\n      };\n      var replaceImageUrl = function (content, targetUrl, replacementUrl) {\n        content = replaceString(content, 'src=\"' + targetUrl + '\"', 'src=\"' + replacementUrl + '\"');\n        content = replaceString(content, 'data-mce-src=\"' + targetUrl + '\"', 'data-mce-src=\"' + replacementUrl + '\"');\n        return content;\n      };\n      var replaceUrlInUndoStack = function (targetUrl, replacementUrl) {\n        each(editor.undoManager.data, function (level) {\n          if (level.type === 'fragmented') {\n            level.fragments = map(level.fragments, function (fragment) {\n              return replaceImageUrl(fragment, targetUrl, replacementUrl);\n            });\n          } else {\n            level.content = replaceImageUrl(level.content, targetUrl, replacementUrl);\n          }\n        });\n      };\n      var openNotification = function () {\n        return editor.notificationManager.open({\n          text: editor.translate('Image uploading...'),\n          type: 'info',\n          timeout: -1,\n          progressBar: true\n        });\n      };\n      var replaceImageUri = function (image, resultUri) {\n        blobCache.removeByUri(image.src);\n        replaceUrlInUndoStack(image.src, resultUri);\n        editor.$(image).attr({\n          'src': Settings.shouldReuseFileName(editor) ? resultUri + cacheInvalidator() : resultUri,\n          'data-mce-src': editor.convertURL(resultUri, 'src')\n        });\n      };\n      var uploadImages = function (callback) {\n        if (!uploader) {\n          uploader = Uploader(uploadStatus, {\n            url: Settings.getImageUploadUrl(editor),\n            basePath: Settings.getImageUploadBasePath(editor),\n            credentials: Settings.getImagesUploadCredentials(editor),\n            handler: Settings.getImagesUploadHandler(editor)\n          });\n        }\n        return scanForImages().then(aliveGuard(function (imageInfos) {\n          var blobInfos;\n          blobInfos = map(imageInfos, function (imageInfo) {\n            return imageInfo.blobInfo;\n          });\n          return uploader.upload(blobInfos, openNotification).then(aliveGuard(function (result) {\n            var filteredResult = map(result, function (uploadInfo, index) {\n              var image = imageInfos[index].image;\n              if (uploadInfo.status && Settings.shouldReplaceBlobUris(editor)) {\n                replaceImageUri(image, uploadInfo.url);\n              } else if (uploadInfo.error) {\n                ErrorReporter.uploadError(editor, uploadInfo.error);\n              }\n              return {\n                element: image,\n                status: uploadInfo.status\n              };\n            });\n            if (callback) {\n              callback(filteredResult);\n            }\n            return filteredResult;\n          }));\n        }));\n      };\n      var uploadImagesAuto = function (callback) {\n        if (Settings.isAutomaticUploadsEnabled(editor)) {\n          return uploadImages(callback);\n        }\n      };\n      var isValidDataUriImage = function (imgElm) {\n        if (forall(urlFilters, function (filter) {\n            return filter(imgElm);\n          }) === false) {\n          return false;\n        }\n        if (imgElm.getAttribute('src').indexOf('data:') === 0) {\n          var dataImgFilter = Settings.getImagesDataImgFilter(editor);\n          return dataImgFilter(imgElm);\n        }\n        return true;\n      };\n      var addFilter = function (filter) {\n        urlFilters.push(filter);\n      };\n      var scanForImages = function () {\n        if (!imageScanner) {\n          imageScanner = ImageScanner(uploadStatus, blobCache);\n        }\n        return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function (result) {\n          result = filter(result, function (resultItem) {\n            if (typeof resultItem === 'string') {\n              ErrorReporter.displayError(editor, resultItem);\n              return false;\n            }\n            return true;\n          });\n          each(result, function (resultItem) {\n            replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri());\n            resultItem.image.src = resultItem.blobInfo.blobUri();\n            resultItem.image.removeAttribute('data-mce-src');\n          });\n          return result;\n        }));\n      };\n      var destroy = function () {\n        blobCache.destroy();\n        uploadStatus.destroy();\n        imageScanner = uploader = null;\n      };\n      var replaceBlobUris = function (content) {\n        return content.replace(/src=\"(blob:[^\"]+)\"/g, function (match, blobUri) {\n          var resultUri = uploadStatus.getResultUri(blobUri);\n          if (resultUri) {\n            return 'src=\"' + resultUri + '\"';\n          }\n          var blobInfo = blobCache.getByUri(blobUri);\n          if (!blobInfo) {\n            blobInfo = foldl(editor.editorManager.get(), function (result, editor) {\n              return result || editor.editorUpload && editor.editorUpload.blobCache.getByUri(blobUri);\n            }, null);\n          }\n          if (blobInfo) {\n            var blob = blobInfo.blob();\n            return 'src=\"data:' + blob.type + ';base64,' + blobInfo.base64() + '\"';\n          }\n          return match;\n        });\n      };\n      editor.on('SetContent', function () {\n        if (Settings.isAutomaticUploadsEnabled(editor)) {\n          uploadImagesAuto();\n        } else {\n          scanForImages();\n        }\n      });\n      editor.on('RawSaveContent', function (e) {\n        e.content = replaceBlobUris(e.content);\n      });\n      editor.on('GetContent', function (e) {\n        if (e.source_view || e.format === 'raw') {\n          return;\n        }\n        e.content = replaceBlobUris(e.content);\n      });\n      editor.on('PostRender', function () {\n        editor.parser.addNodeFilter('img', function (images) {\n          each(images, function (img) {\n            var src = img.attr('src');\n            if (blobCache.getByUri(src)) {\n              return;\n            }\n            var resultUri = uploadStatus.getResultUri(src);\n            if (resultUri) {\n              img.attr('src', resultUri);\n            }\n          });\n        });\n      });\n      return {\n        blobCache: blobCache,\n        addFilter: addFilter,\n        uploadImages: uploadImages,\n        uploadImagesAuto: uploadImagesAuto,\n        scanForImages: scanForImages,\n        destroy: destroy\n      };\n    };\n\n    var dropLast = function (xs) {\n      return xs.slice(0, -1);\n    };\n    var parentsUntil$1 = function (start, root, predicate) {\n      if (contains$2(root, start)) {\n        return dropLast(parents(start, function (elm) {\n          return predicate(elm) || eq(elm, root);\n        }));\n      } else {\n        return [];\n      }\n    };\n    var parents$1 = function (start, root) {\n      return parentsUntil$1(start, root, constant(false));\n    };\n    var parentsAndSelf = function (start, root) {\n      return [start].concat(parents$1(start, root));\n    };\n    var Parents = {\n      parentsUntil: parentsUntil$1,\n      parents: parents$1,\n      parentsAndSelf: parentsAndSelf\n    };\n\n    var isBlockElement = function (blockElements, node) {\n      return blockElements.hasOwnProperty(node.nodeName);\n    };\n    var isValidTarget = function (blockElements, node) {\n      if (NodeType.isText(node)) {\n        return true;\n      } else if (NodeType.isElement(node)) {\n        return !isBlockElement(blockElements, node) && !Bookmarks.isBookmarkNode(node);\n      } else {\n        return false;\n      }\n    };\n    var hasBlockParent = function (blockElements, root, node) {\n      return exists(Parents.parents(Element.fromDom(node), Element.fromDom(root)), function (elm) {\n        return isBlockElement(blockElements, elm.dom());\n      });\n    };\n    var shouldRemoveTextNode = function (blockElements, node) {\n      if (NodeType.isText(node)) {\n        if (node.nodeValue.length === 0) {\n          return true;\n        } else if (/^\\s+$/.test(node.nodeValue) && (!node.nextSibling || isBlockElement(blockElements, node.nextSibling))) {\n          return true;\n        }\n      }\n      return false;\n    };\n    var addRootBlocks = function (editor) {\n      var dom = editor.dom, selection = editor.selection;\n      var schema = editor.schema, blockElements = schema.getBlockElements();\n      var node = selection.getStart();\n      var rootNode = editor.getBody();\n      var rng;\n      var startContainer, startOffset, endContainer, endOffset, rootBlockNode;\n      var tempNode, wrapped, restoreSelection;\n      var rootNodeName;\n      var forcedRootBlock = Settings.getForcedRootBlock(editor);\n      if (!node || !NodeType.isElement(node) || !forcedRootBlock) {\n        return;\n      }\n      rootNodeName = rootNode.nodeName.toLowerCase();\n      if (!schema.isValidChild(rootNodeName, forcedRootBlock.toLowerCase()) || hasBlockParent(blockElements, rootNode, node)) {\n        return;\n      }\n      rng = selection.getRng();\n      startContainer = rng.startContainer;\n      startOffset = rng.startOffset;\n      endContainer = rng.endContainer;\n      endOffset = rng.endOffset;\n      restoreSelection = EditorFocus.hasFocus(editor);\n      node = rootNode.firstChild;\n      while (node) {\n        if (isValidTarget(blockElements, node)) {\n          if (shouldRemoveTextNode(blockElements, node)) {\n            tempNode = node;\n            node = node.nextSibling;\n            dom.remove(tempNode);\n            continue;\n          }\n          if (!rootBlockNode) {\n            rootBlockNode = dom.create(forcedRootBlock, Settings.getForcedRootBlockAttrs(editor));\n            node.parentNode.insertBefore(rootBlockNode, node);\n            wrapped = true;\n          }\n          tempNode = node;\n          node = node.nextSibling;\n          rootBlockNode.appendChild(tempNode);\n        } else {\n          rootBlockNode = null;\n          node = node.nextSibling;\n        }\n      }\n      if (wrapped && restoreSelection) {\n        rng.setStart(startContainer, startOffset);\n        rng.setEnd(endContainer, endOffset);\n        selection.setRng(rng);\n        editor.nodeChanged();\n      }\n    };\n    var setup$3 = function (editor) {\n      if (Settings.getForcedRootBlock(editor)) {\n        editor.on('NodeChange', curry(addRootBlocks, editor));\n      }\n    };\n    var ForceBlocks = { setup: setup$3 };\n\n    var isEq$1 = function (rng1, rng2) {\n      return rng1 && rng2 && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset);\n    };\n    var RangeCompare = { isEq: isEq$1 };\n\n    var getStartNode = function (rng) {\n      var sc = rng.startContainer, so = rng.startOffset;\n      if (NodeType.isText(sc)) {\n        return so === 0 ? Option.some(Element.fromDom(sc)) : Option.none();\n      } else {\n        return Option.from(sc.childNodes[so]).map(Element.fromDom);\n      }\n    };\n    var getEndNode = function (rng) {\n      var ec = rng.endContainer, eo = rng.endOffset;\n      if (NodeType.isText(ec)) {\n        return eo === ec.data.length ? Option.some(Element.fromDom(ec)) : Option.none();\n      } else {\n        return Option.from(ec.childNodes[eo - 1]).map(Element.fromDom);\n      }\n    };\n    var getFirstChildren = function (node) {\n      return firstChild(node).fold(constant([node]), function (child) {\n        return [node].concat(getFirstChildren(child));\n      });\n    };\n    var getLastChildren = function (node) {\n      return lastChild(node).fold(constant([node]), function (child) {\n        if (name(child) === 'br') {\n          return prevSibling(child).map(function (sibling) {\n            return [node].concat(getLastChildren(sibling));\n          }).getOr([]);\n        } else {\n          return [node].concat(getLastChildren(child));\n        }\n      });\n    };\n    var hasAllContentsSelected = function (elm, rng) {\n      return lift2(getStartNode(rng), getEndNode(rng), function (startNode, endNode) {\n        var start = find(getFirstChildren(elm), curry(eq, startNode));\n        var end = find(getLastChildren(elm), curry(eq, endNode));\n        return start.isSome() && end.isSome();\n      }).getOr(false);\n    };\n    var moveEndPoint$1 = function (dom, rng, node, start) {\n      var root = node, walker = new TreeWalker(node, root);\n      var nonEmptyElementsMap = dom.schema.getNonEmptyElements();\n      do {\n        if (node.nodeType === 3 && Tools.trim(node.nodeValue).length !== 0) {\n          if (start) {\n            rng.setStart(node, 0);\n          } else {\n            rng.setEnd(node, node.nodeValue.length);\n          }\n          return;\n        }\n        if (nonEmptyElementsMap[node.nodeName] && !/^(TD|TH)$/.test(node.nodeName)) {\n          if (start) {\n            rng.setStartBefore(node);\n          } else {\n            if (node.nodeName === 'BR') {\n              rng.setEndBefore(node);\n            } else {\n              rng.setEndAfter(node);\n            }\n          }\n          return;\n        }\n      } while (node = start ? walker.next() : walker.prev());\n      if (root.nodeName === 'BODY') {\n        if (start) {\n          rng.setStart(root, 0);\n        } else {\n          rng.setEnd(root, root.childNodes.length);\n        }\n      }\n    };\n    var hasAnyRanges = function (editor) {\n      var sel = editor.selection.getSel();\n      return sel && sel.rangeCount > 0;\n    };\n\n    var NodeChange = function () {\n      function NodeChange(editor) {\n        this.lastPath = [];\n        this.editor = editor;\n        var lastRng;\n        var self = this;\n        if (!('onselectionchange' in editor.getDoc())) {\n          editor.on('NodeChange click mouseup keyup focus', function (e) {\n            var nativeRng, fakeRng;\n            nativeRng = editor.selection.getRng();\n            fakeRng = {\n              startContainer: nativeRng.startContainer,\n              startOffset: nativeRng.startOffset,\n              endContainer: nativeRng.endContainer,\n              endOffset: nativeRng.endOffset\n            };\n            if (e.type === 'nodechange' || !RangeCompare.isEq(fakeRng, lastRng)) {\n              editor.fire('SelectionChange');\n            }\n            lastRng = fakeRng;\n          });\n        }\n        editor.on('contextmenu', function () {\n          editor.fire('SelectionChange');\n        });\n        editor.on('SelectionChange', function () {\n          var startElm = editor.selection.getStart(true);\n          if (!startElm || !Env.range && editor.selection.isCollapsed()) {\n            return;\n          }\n          if (hasAnyRanges(editor) && !self.isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {\n            editor.nodeChanged({ selectionChange: true });\n          }\n        });\n        editor.on('mouseup', function (e) {\n          if (!e.isDefaultPrevented() && hasAnyRanges(editor)) {\n            if (editor.selection.getNode().nodeName === 'IMG') {\n              Delay.setEditorTimeout(editor, function () {\n                editor.nodeChanged();\n              });\n            } else {\n              editor.nodeChanged();\n            }\n          }\n        });\n      }\n      NodeChange.prototype.nodeChanged = function (args) {\n        var selection = this.editor.selection;\n        var node, parents, root;\n        if (this.editor.initialized && selection && !this.editor.settings.disable_nodechange && !this.editor.readonly) {\n          root = this.editor.getBody();\n          node = selection.getStart(true) || root;\n          if (node.ownerDocument !== this.editor.getDoc() || !this.editor.dom.isChildOf(node, root)) {\n            node = root;\n          }\n          parents = [];\n          this.editor.dom.getParent(node, function (node) {\n            if (node === root) {\n              return true;\n            }\n            parents.push(node);\n          });\n          args = args || {};\n          args.element = node;\n          args.parents = parents;\n          this.editor.fire('NodeChange', args);\n        }\n      };\n      NodeChange.prototype.isSameElementPath = function (startElm) {\n        var i, currentPath;\n        currentPath = this.editor.$(startElm).parentsUntil(this.editor.getBody()).add(startElm);\n        if (currentPath.length === this.lastPath.length) {\n          for (i = currentPath.length; i >= 0; i--) {\n            if (currentPath[i] !== this.lastPath[i]) {\n              break;\n            }\n          }\n          if (i === -1) {\n            this.lastPath = currentPath;\n            return true;\n          }\n        }\n        this.lastPath = currentPath;\n        return false;\n      };\n      return NodeChange;\n    }();\n\n    var VK = {\n      BACKSPACE: 8,\n      DELETE: 46,\n      DOWN: 40,\n      ENTER: 13,\n      LEFT: 37,\n      RIGHT: 39,\n      SPACEBAR: 32,\n      TAB: 9,\n      UP: 38,\n      END: 35,\n      HOME: 36,\n      modifierPressed: function (e) {\n        return e.shiftKey || e.ctrlKey || e.altKey || this.metaKeyPressed(e);\n      },\n      metaKeyPressed: function (e) {\n        return Env.mac ? e.metaKey : e.ctrlKey && !e.altKey;\n      }\n    };\n\n    var is$2 = function (expected) {\n      return function (actual) {\n        return expected === actual;\n      };\n    };\n    var isNbsp = is$2('\\xA0');\n    var isWhiteSpace$1 = function (chr) {\n      return /^[\\r\\n\\t ]$/.test(chr);\n    };\n    var isContent = function (chr) {\n      return !isWhiteSpace$1(chr) && !isNbsp(chr);\n    };\n\n    var isChar = function (forward, predicate, pos) {\n      return Option.from(pos.container()).filter(NodeType.isText).exists(function (text) {\n        var delta = forward ? 0 : -1;\n        return predicate(text.data.charAt(pos.offset() + delta));\n      });\n    };\n    var isBeforeSpace = curry(isChar, true, isWhiteSpace$1);\n    var isAfterSpace = curry(isChar, false, isWhiteSpace$1);\n    var isEmptyText = function (pos) {\n      var container = pos.container();\n      return NodeType.isText(container) && container.data.length === 0;\n    };\n    var matchesElementPosition = function (before, predicate) {\n      return function (pos) {\n        return Option.from(getChildNodeAtRelativeOffset(before ? 0 : -1, pos)).filter(predicate).isSome();\n      };\n    };\n    var isImageBlock = function (node) {\n      return node.nodeName === 'IMG' && get$2(Element.fromDom(node), 'display') === 'block';\n    };\n    var isCefNode = function (node) {\n      return NodeType.isContentEditableFalse(node) && !NodeType.isBogusAll(node);\n    };\n    var isBeforeImageBlock = matchesElementPosition(true, isImageBlock);\n    var isAfterImageBlock = matchesElementPosition(false, isImageBlock);\n    var isBeforeTable = matchesElementPosition(true, NodeType.isTable);\n    var isAfterTable = matchesElementPosition(false, NodeType.isTable);\n    var isBeforeContentEditableFalse = matchesElementPosition(true, isCefNode);\n    var isAfterContentEditableFalse = matchesElementPosition(false, isCefNode);\n\n    var getNodeClientRects = function (node) {\n      var toArrayWithNode = function (clientRects) {\n        return map(clientRects, function (clientRect) {\n          clientRect = clone$1(clientRect);\n          clientRect.node = node;\n          return clientRect;\n        });\n      };\n      if (NodeType.isElement(node)) {\n        return toArrayWithNode(node.getClientRects());\n      }\n      if (NodeType.isText(node)) {\n        var rng = node.ownerDocument.createRange();\n        rng.setStart(node, 0);\n        rng.setEnd(node, node.data.length);\n        return toArrayWithNode(rng.getClientRects());\n      }\n    };\n    var getClientRects = function (node) {\n      return foldl(node, function (result, node) {\n        return result.concat(getNodeClientRects(node));\n      }, []);\n    };\n\n    var VDirection;\n    (function (VDirection) {\n      VDirection[VDirection['Up'] = -1] = 'Up';\n      VDirection[VDirection['Down'] = 1] = 'Down';\n    }(VDirection || (VDirection = {})));\n    var findUntil = function (direction, root, predicateFn, node) {\n      while (node = findNode(node, direction, isEditableCaretCandidate, root)) {\n        if (predicateFn(node)) {\n          return;\n        }\n      }\n    };\n    var walkUntil = function (direction, isAboveFn, isBeflowFn, root, predicateFn, caretPosition) {\n      var line = 0, node;\n      var result = [];\n      var targetClientRect;\n      var add = function (node) {\n        var i, clientRect, clientRects;\n        clientRects = getClientRects([node]);\n        if (direction === -1) {\n          clientRects = clientRects.reverse();\n        }\n        for (i = 0; i < clientRects.length; i++) {\n          clientRect = clientRects[i];\n          if (isBeflowFn(clientRect, targetClientRect)) {\n            continue;\n          }\n          if (result.length > 0 && isAboveFn(clientRect, ArrUtils.last(result))) {\n            line++;\n          }\n          clientRect.line = line;\n          if (predicateFn(clientRect)) {\n            return true;\n          }\n          result.push(clientRect);\n        }\n      };\n      targetClientRect = ArrUtils.last(caretPosition.getClientRects());\n      if (!targetClientRect) {\n        return result;\n      }\n      node = caretPosition.getNode();\n      add(node);\n      findUntil(direction, root, add, node);\n      return result;\n    };\n    var aboveLineNumber = function (lineNumber, clientRect) {\n      return clientRect.line > lineNumber;\n    };\n    var isLineNumber = function (lineNumber, clientRect) {\n      return clientRect.line === lineNumber;\n    };\n    var upUntil = curry(walkUntil, VDirection.Up, isAbove, isBelow);\n    var downUntil = curry(walkUntil, VDirection.Down, isBelow, isAbove);\n    var positionsUntil = function (direction, root, predicateFn, node) {\n      var caretWalker = CaretWalker(root);\n      var walkFn, isBelowFn, isAboveFn, caretPosition;\n      var result = [];\n      var line = 0, clientRect, targetClientRect;\n      var getClientRect = function (caretPosition) {\n        if (direction === 1) {\n          return ArrUtils.last(caretPosition.getClientRects());\n        }\n        return ArrUtils.last(caretPosition.getClientRects());\n      };\n      if (direction === 1) {\n        walkFn = caretWalker.next;\n        isBelowFn = isBelow;\n        isAboveFn = isAbove;\n        caretPosition = CaretPosition$1.after(node);\n      } else {\n        walkFn = caretWalker.prev;\n        isBelowFn = isAbove;\n        isAboveFn = isBelow;\n        caretPosition = CaretPosition$1.before(node);\n      }\n      targetClientRect = getClientRect(caretPosition);\n      do {\n        if (!caretPosition.isVisible()) {\n          continue;\n        }\n        clientRect = getClientRect(caretPosition);\n        if (isAboveFn(clientRect, targetClientRect)) {\n          continue;\n        }\n        if (result.length > 0 && isBelowFn(clientRect, ArrUtils.last(result))) {\n          line++;\n        }\n        clientRect = clone$1(clientRect);\n        clientRect.position = caretPosition;\n        clientRect.line = line;\n        if (predicateFn(clientRect)) {\n          return result;\n        }\n        result.push(clientRect);\n      } while (caretPosition = walkFn(caretPosition));\n      return result;\n    };\n    var isAboveLine = function (lineNumber) {\n      return function (clientRect) {\n        return aboveLineNumber(lineNumber, clientRect);\n      };\n    };\n    var isLine = function (lineNumber) {\n      return function (clientRect) {\n        return isLineNumber(lineNumber, clientRect);\n      };\n    };\n\n    var isContentEditableFalse$6 = NodeType.isContentEditableFalse;\n    var findNode$1 = findNode;\n    var distanceToRectLeft = function (clientRect, clientX) {\n      return Math.abs(clientRect.left - clientX);\n    };\n    var distanceToRectRight = function (clientRect, clientX) {\n      return Math.abs(clientRect.right - clientX);\n    };\n    var isInside = function (clientX, clientRect) {\n      return clientX >= clientRect.left && clientX <= clientRect.right;\n    };\n    var findClosestClientRect = function (clientRects, clientX) {\n      return ArrUtils.reduce(clientRects, function (oldClientRect, clientRect) {\n        var oldDistance, newDistance;\n        oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX));\n        newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX));\n        if (isInside(clientX, clientRect)) {\n          return clientRect;\n        }\n        if (isInside(clientX, oldClientRect)) {\n          return oldClientRect;\n        }\n        if (newDistance === oldDistance && isContentEditableFalse$6(clientRect.node)) {\n          return clientRect;\n        }\n        if (newDistance < oldDistance) {\n          return clientRect;\n        }\n        return oldClientRect;\n      });\n    };\n    var walkUntil$1 = function (direction, root, predicateFn, node) {\n      while (node = findNode$1(node, direction, isEditableCaretCandidate, root)) {\n        if (predicateFn(node)) {\n          return;\n        }\n      }\n    };\n    var findLineNodeRects = function (root, targetNodeRect) {\n      var clientRects = [];\n      var collect = function (checkPosFn, node) {\n        var lineRects;\n        lineRects = filter(getClientRects([node]), function (clientRect) {\n          return !checkPosFn(clientRect, targetNodeRect);\n        });\n        clientRects = clientRects.concat(lineRects);\n        return lineRects.length === 0;\n      };\n      clientRects.push(targetNodeRect);\n      walkUntil$1(VDirection.Up, root, curry(collect, isAbove), targetNodeRect.node);\n      walkUntil$1(VDirection.Down, root, curry(collect, isBelow), targetNodeRect.node);\n      return clientRects;\n    };\n    var getFakeCaretTargets = function (root) {\n      return filter(from$1(root.getElementsByTagName('*')), isFakeCaretTarget);\n    };\n    var caretInfo = function (clientRect, clientX) {\n      return {\n        node: clientRect.node,\n        before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX)\n      };\n    };\n    var closestCaret = function (root, clientX, clientY) {\n      var closestNodeRect;\n      var contentEditableFalseNodeRects = getClientRects(getFakeCaretTargets(root));\n      var targetNodeRects = filter(contentEditableFalseNodeRects, function (rect) {\n        return clientY >= rect.top && clientY <= rect.bottom;\n      });\n      closestNodeRect = findClosestClientRect(targetNodeRects, clientX);\n      if (closestNodeRect) {\n        closestNodeRect = findClosestClientRect(findLineNodeRects(root, closestNodeRect), clientX);\n        if (closestNodeRect && isFakeCaretTarget(closestNodeRect.node)) {\n          return caretInfo(closestNodeRect, clientX);\n        }\n      }\n      return null;\n    };\n\n    var isXYWithinRange = function (clientX, clientY, range) {\n      if (range.collapsed) {\n        return false;\n      }\n      if (Env.browser.isIE() && range.startOffset === range.endOffset - 1 && range.startContainer === range.endContainer) {\n        var elm = range.startContainer.childNodes[range.startOffset];\n        if (NodeType.isElement(elm)) {\n          return exists(elm.getClientRects(), function (rect) {\n            return containsXY(rect, clientX, clientY);\n          });\n        }\n      }\n      return exists(range.getClientRects(), function (rect) {\n        return containsXY(rect, clientX, clientY);\n      });\n    };\n    var RangePoint = { isXYWithinRange: isXYWithinRange };\n\n    var getAbsolutePosition = function (elm) {\n      var doc, docElem, win, clientRect;\n      clientRect = elm.getBoundingClientRect();\n      doc = elm.ownerDocument;\n      docElem = doc.documentElement;\n      win = doc.defaultView;\n      return {\n        top: clientRect.top + win.pageYOffset - docElem.clientTop,\n        left: clientRect.left + win.pageXOffset - docElem.clientLeft\n      };\n    };\n    var getBodyPosition = function (editor) {\n      return editor.inline ? getAbsolutePosition(editor.getBody()) : {\n        left: 0,\n        top: 0\n      };\n    };\n    var getScrollPosition = function (editor) {\n      var body = editor.getBody();\n      return editor.inline ? {\n        left: body.scrollLeft,\n        top: body.scrollTop\n      } : {\n        left: 0,\n        top: 0\n      };\n    };\n    var getBodyScroll = function (editor) {\n      var body = editor.getBody(), docElm = editor.getDoc().documentElement;\n      var inlineScroll = {\n        left: body.scrollLeft,\n        top: body.scrollTop\n      };\n      var iframeScroll = {\n        left: body.scrollLeft || docElm.scrollLeft,\n        top: body.scrollTop || docElm.scrollTop\n      };\n      return editor.inline ? inlineScroll : iframeScroll;\n    };\n    var getMousePosition = function (editor, event) {\n      if (event.target.ownerDocument !== editor.getDoc()) {\n        var iframePosition = getAbsolutePosition(editor.getContentAreaContainer());\n        var scrollPosition = getBodyScroll(editor);\n        return {\n          left: event.pageX - iframePosition.left + scrollPosition.left,\n          top: event.pageY - iframePosition.top + scrollPosition.top\n        };\n      }\n      return {\n        left: event.pageX,\n        top: event.pageY\n      };\n    };\n    var calculatePosition = function (bodyPosition, scrollPosition, mousePosition) {\n      return {\n        pageX: mousePosition.left - bodyPosition.left + scrollPosition.left,\n        pageY: mousePosition.top - bodyPosition.top + scrollPosition.top\n      };\n    };\n    var calc = function (editor, event) {\n      return calculatePosition(getBodyPosition(editor), getScrollPosition(editor), getMousePosition(editor, event));\n    };\n    var MousePosition = { calc: calc };\n\n    var isContentEditableFalse$7 = NodeType.isContentEditableFalse, isContentEditableTrue$2 = NodeType.isContentEditableTrue;\n    var isDraggable = function (rootElm, elm) {\n      return isContentEditableFalse$7(elm) && elm !== rootElm;\n    };\n    var isValidDropTarget = function (editor, targetElement, dragElement) {\n      if (targetElement === dragElement || editor.dom.isChildOf(targetElement, dragElement)) {\n        return false;\n      }\n      return !isContentEditableFalse$7(targetElement);\n    };\n    var cloneElement = function (elm) {\n      var cloneElm = elm.cloneNode(true);\n      cloneElm.removeAttribute('data-mce-selected');\n      return cloneElm;\n    };\n    var createGhost = function (editor, elm, width, height) {\n      var clonedElm = elm.cloneNode(true);\n      editor.dom.setStyles(clonedElm, {\n        width: width,\n        height: height\n      });\n      editor.dom.setAttrib(clonedElm, 'data-mce-selected', null);\n      var ghostElm = editor.dom.create('div', {\n        'class': 'mce-drag-container',\n        'data-mce-bogus': 'all',\n        'unselectable': 'on',\n        'contenteditable': 'false'\n      });\n      editor.dom.setStyles(ghostElm, {\n        position: 'absolute',\n        opacity: 0.5,\n        overflow: 'hidden',\n        border: 0,\n        padding: 0,\n        margin: 0,\n        width: width,\n        height: height\n      });\n      editor.dom.setStyles(clonedElm, {\n        margin: 0,\n        boxSizing: 'border-box'\n      });\n      ghostElm.appendChild(clonedElm);\n      return ghostElm;\n    };\n    var appendGhostToBody = function (ghostElm, bodyElm) {\n      if (ghostElm.parentNode !== bodyElm) {\n        bodyElm.appendChild(ghostElm);\n      }\n    };\n    var moveGhost = function (ghostElm, position, width, height, maxX, maxY) {\n      var overflowX = 0, overflowY = 0;\n      ghostElm.style.left = position.pageX + 'px';\n      ghostElm.style.top = position.pageY + 'px';\n      if (position.pageX + width > maxX) {\n        overflowX = position.pageX + width - maxX;\n      }\n      if (position.pageY + height > maxY) {\n        overflowY = position.pageY + height - maxY;\n      }\n      ghostElm.style.width = width - overflowX + 'px';\n      ghostElm.style.height = height - overflowY + 'px';\n    };\n    var removeElement = function (elm) {\n      if (elm && elm.parentNode) {\n        elm.parentNode.removeChild(elm);\n      }\n    };\n    var isLeftMouseButtonPressed = function (e) {\n      return e.button === 0;\n    };\n    var hasDraggableElement = function (state) {\n      return state.element;\n    };\n    var applyRelPos = function (state, position) {\n      return {\n        pageX: position.pageX - state.relX,\n        pageY: position.pageY + 5\n      };\n    };\n    var start = function (state, editor) {\n      return function (e) {\n        if (isLeftMouseButtonPressed(e)) {\n          var ceElm = find(editor.dom.getParents(e.target), Predicate.or(isContentEditableFalse$7, isContentEditableTrue$2)).getOr(null);\n          if (isDraggable(editor.getBody(), ceElm)) {\n            var elmPos = editor.dom.getPos(ceElm);\n            var bodyElm = editor.getBody();\n            var docElm = editor.getDoc().documentElement;\n            state.element = ceElm;\n            state.screenX = e.screenX;\n            state.screenY = e.screenY;\n            state.maxX = (editor.inline ? bodyElm.scrollWidth : docElm.offsetWidth) - 2;\n            state.maxY = (editor.inline ? bodyElm.scrollHeight : docElm.offsetHeight) - 2;\n            state.relX = e.pageX - elmPos.x;\n            state.relY = e.pageY - elmPos.y;\n            state.width = ceElm.offsetWidth;\n            state.height = ceElm.offsetHeight;\n            state.ghost = createGhost(editor, ceElm, state.width, state.height);\n          }\n        }\n      };\n    };\n    var move = function (state, editor) {\n      var throttledPlaceCaretAt = Delay.throttle(function (clientX, clientY) {\n        editor._selectionOverrides.hideFakeCaret();\n        editor.selection.placeCaretAt(clientX, clientY);\n      }, 0);\n      return function (e) {\n        var movement = Math.max(Math.abs(e.screenX - state.screenX), Math.abs(e.screenY - state.screenY));\n        if (hasDraggableElement(state) && !state.dragging && movement > 10) {\n          var args = editor.fire('dragstart', { target: state.element });\n          if (args.isDefaultPrevented()) {\n            return;\n          }\n          state.dragging = true;\n          editor.focus();\n        }\n        if (state.dragging) {\n          var targetPos = applyRelPos(state, MousePosition.calc(editor, e));\n          appendGhostToBody(state.ghost, editor.getBody());\n          moveGhost(state.ghost, targetPos, state.width, state.height, state.maxX, state.maxY);\n          throttledPlaceCaretAt(e.clientX, e.clientY);\n        }\n      };\n    };\n    var getRawTarget = function (selection) {\n      var rng = selection.getSel().getRangeAt(0);\n      var startContainer = rng.startContainer;\n      return startContainer.nodeType === 3 ? startContainer.parentNode : startContainer;\n    };\n    var drop = function (state, editor) {\n      return function (e) {\n        if (state.dragging) {\n          if (isValidDropTarget(editor, getRawTarget(editor.selection), state.element)) {\n            var targetClone_1 = cloneElement(state.element);\n            var args = editor.fire('drop', {\n              targetClone: targetClone_1,\n              clientX: e.clientX,\n              clientY: e.clientY\n            });\n            if (!args.isDefaultPrevented()) {\n              targetClone_1 = args.targetClone;\n              editor.undoManager.transact(function () {\n                removeElement(state.element);\n                editor.insertContent(editor.dom.getOuterHTML(targetClone_1));\n                editor._selectionOverrides.hideFakeCaret();\n              });\n            }\n          }\n        }\n        removeDragState(state);\n      };\n    };\n    var stop = function (state, editor) {\n      return function () {\n        if (state.dragging) {\n          editor.fire('dragend');\n        }\n        removeDragState(state);\n      };\n    };\n    var removeDragState = function (state) {\n      state.dragging = false;\n      state.element = null;\n      removeElement(state.ghost);\n    };\n    var bindFakeDragEvents = function (editor) {\n      var state = {};\n      var pageDom, dragStartHandler, dragHandler, dropHandler, dragEndHandler, rootDocument;\n      pageDom = DOMUtils$1.DOM;\n      rootDocument = domGlobals.document;\n      dragStartHandler = start(state, editor);\n      dragHandler = move(state, editor);\n      dropHandler = drop(state, editor);\n      dragEndHandler = stop(state, editor);\n      editor.on('mousedown', dragStartHandler);\n      editor.on('mousemove', dragHandler);\n      editor.on('mouseup', dropHandler);\n      pageDom.bind(rootDocument, 'mousemove', dragHandler);\n      pageDom.bind(rootDocument, 'mouseup', dragEndHandler);\n      editor.on('remove', function () {\n        pageDom.unbind(rootDocument, 'mousemove', dragHandler);\n        pageDom.unbind(rootDocument, 'mouseup', dragEndHandler);\n      });\n    };\n    var blockIeDrop = function (editor) {\n      editor.on('drop', function (e) {\n        var realTarget = typeof e.clientX !== 'undefined' ? editor.getDoc().elementFromPoint(e.clientX, e.clientY) : null;\n        if (isContentEditableFalse$7(realTarget) || isContentEditableFalse$7(editor.dom.getContentEditableParent(realTarget))) {\n          e.preventDefault();\n        }\n      });\n    };\n    var init = function (editor) {\n      bindFakeDragEvents(editor);\n      blockIeDrop(editor);\n    };\n    var DragDropOverrides = { init: init };\n\n    var isContentEditableTrue$3 = NodeType.isContentEditableTrue;\n    var isContentEditableFalse$8 = NodeType.isContentEditableFalse;\n    var showCaret = function (direction, editor, node, before, scrollIntoView) {\n      return editor._selectionOverrides.showCaret(direction, node, before, scrollIntoView);\n    };\n    var getNodeRange = function (node) {\n      var rng = node.ownerDocument.createRange();\n      rng.selectNode(node);\n      return rng;\n    };\n    var selectNode = function (editor, node) {\n      var e = editor.fire('BeforeObjectSelected', { target: node });\n      if (e.isDefaultPrevented()) {\n        return null;\n      }\n      return getNodeRange(node);\n    };\n    var renderCaretAtRange = function (editor, range, scrollIntoView) {\n      var normalizedRange = normalizeRange(1, editor.getBody(), range);\n      var caretPosition = CaretPosition$1.fromRangeStart(normalizedRange);\n      var caretPositionNode = caretPosition.getNode();\n      if (isContentEditableFalse$8(caretPositionNode)) {\n        return showCaret(1, editor, caretPositionNode, !caretPosition.isAtEnd(), false);\n      }\n      var caretPositionBeforeNode = caretPosition.getNode(true);\n      if (isContentEditableFalse$8(caretPositionBeforeNode)) {\n        return showCaret(1, editor, caretPositionBeforeNode, false, false);\n      }\n      var ceRoot = editor.dom.getParent(caretPosition.getNode(), function (node) {\n        return isContentEditableFalse$8(node) || isContentEditableTrue$3(node);\n      });\n      if (isContentEditableFalse$8(ceRoot)) {\n        return showCaret(1, editor, ceRoot, false, scrollIntoView);\n      }\n      return null;\n    };\n    var renderRangeCaret = function (editor, range, scrollIntoView) {\n      if (!range || !range.collapsed) {\n        return range;\n      }\n      var caretRange = renderCaretAtRange(editor, range, scrollIntoView);\n      if (caretRange) {\n        return caretRange;\n      }\n      return range;\n    };\n\n    var setup$4 = function (editor) {\n      var renderFocusCaret = first(function () {\n        if (!editor.removed && editor.getBody().contains(domGlobals.document.activeElement)) {\n          var rng = editor.selection.getRng();\n          if (rng.collapsed) {\n            var caretRange = renderRangeCaret(editor, editor.selection.getRng(), false);\n            editor.selection.setRng(caretRange);\n          }\n        }\n      }, 0);\n      editor.on('focus', function () {\n        renderFocusCaret.throttle();\n      });\n      editor.on('blur', function () {\n        renderFocusCaret.cancel();\n      });\n    };\n    var CefFocus = { setup: setup$4 };\n\n    var isContentEditableTrue$4 = NodeType.isContentEditableTrue;\n    var isContentEditableFalse$9 = NodeType.isContentEditableFalse;\n    var getContentEditableRoot = function (editor, node) {\n      var root = editor.getBody();\n      while (node && node !== root) {\n        if (isContentEditableTrue$4(node) || isContentEditableFalse$9(node)) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return null;\n    };\n    var SelectionOverrides = function (editor) {\n      var isBlock = function (node) {\n        return editor.dom.isBlock(node);\n      };\n      var rootNode = editor.getBody();\n      var fakeCaret = FakeCaret(editor.getBody(), isBlock, function () {\n        return EditorFocus.hasFocus(editor);\n      });\n      var realSelectionId = 'sel-' + editor.dom.uniqueId();\n      var selectedContentEditableNode;\n      var isFakeSelectionElement = function (elm) {\n        return editor.dom.hasClass(elm, 'mce-offscreen-selection');\n      };\n      var getRealSelectionElement = function () {\n        var container = editor.dom.get(realSelectionId);\n        return container ? container.getElementsByTagName('*')[0] : container;\n      };\n      var setRange = function (range) {\n        if (range) {\n          editor.selection.setRng(range);\n        }\n      };\n      var getRange = function () {\n        return editor.selection.getRng();\n      };\n      var showCaret = function (direction, node, before, scrollIntoView) {\n        if (scrollIntoView === void 0) {\n          scrollIntoView = true;\n        }\n        var e;\n        e = editor.fire('ShowCaret', {\n          target: node,\n          direction: direction,\n          before: before\n        });\n        if (e.isDefaultPrevented()) {\n          return null;\n        }\n        if (scrollIntoView) {\n          editor.selection.scrollIntoView(node, direction === -1);\n        }\n        return fakeCaret.show(before, node);\n      };\n      var showBlockCaretContainer = function (blockCaretContainer) {\n        if (blockCaretContainer.hasAttribute('data-mce-caret')) {\n          showCaretContainerBlock(blockCaretContainer);\n          setRange(getRange());\n          editor.selection.scrollIntoView(blockCaretContainer);\n        }\n      };\n      var registerEvents = function () {\n        editor.on('mouseup', function (e) {\n          var range = getRange();\n          if (range.collapsed && EditorView.isXYInContentArea(editor, e.clientX, e.clientY)) {\n            setRange(renderCaretAtRange(editor, range, false));\n          }\n        });\n        editor.on('click', function (e) {\n          var contentEditableRoot;\n          contentEditableRoot = getContentEditableRoot(editor, e.target);\n          if (contentEditableRoot) {\n            if (isContentEditableFalse$9(contentEditableRoot)) {\n              e.preventDefault();\n              editor.focus();\n            }\n            if (isContentEditableTrue$4(contentEditableRoot)) {\n              if (editor.dom.isChildOf(contentEditableRoot, editor.selection.getNode())) {\n                removeContentEditableSelection();\n              }\n            }\n          }\n        });\n        editor.on('blur NewBlock', function () {\n          removeContentEditableSelection();\n        });\n        editor.on('ResizeWindow FullscreenStateChanged', function () {\n          return fakeCaret.reposition();\n        });\n        var handleTouchSelect = function (editor) {\n          var moved = false;\n          editor.on('touchstart', function () {\n            moved = false;\n          });\n          editor.on('touchmove', function () {\n            moved = true;\n          });\n          editor.on('touchend', function (e) {\n            if (!moved) {\n              var contentEditableRoot = getContentEditableRoot(editor, e.target);\n              if (isContentEditableFalse$9(contentEditableRoot)) {\n                e.preventDefault();\n                setContentEditableSelection(selectNode(editor, contentEditableRoot));\n              }\n            }\n          }, true);\n        };\n        var hasNormalCaretPosition = function (elm) {\n          var caretWalker = CaretWalker(elm);\n          if (!elm.firstChild) {\n            return false;\n          }\n          var startPos = CaretPosition$1.before(elm.firstChild);\n          var newPos = caretWalker.next(startPos);\n          return newPos && !isBeforeContentEditableFalse(newPos) && !isAfterContentEditableFalse(newPos);\n        };\n        var isInSameBlock = function (node1, node2) {\n          var block1 = editor.dom.getParent(node1, editor.dom.isBlock);\n          var block2 = editor.dom.getParent(node2, editor.dom.isBlock);\n          return block1 === block2;\n        };\n        var hasBetterMouseTarget = function (targetNode, caretNode) {\n          var targetBlock = editor.dom.getParent(targetNode, editor.dom.isBlock);\n          var caretBlock = editor.dom.getParent(caretNode, editor.dom.isBlock);\n          if (targetBlock && editor.dom.isChildOf(targetBlock, caretBlock) && isContentEditableFalse$9(getContentEditableRoot(editor, targetBlock)) === false) {\n            return true;\n          }\n          return targetBlock && !isInSameBlock(targetBlock, caretBlock) && hasNormalCaretPosition(targetBlock);\n        };\n        handleTouchSelect(editor);\n        editor.on('mousedown', function (e) {\n          var contentEditableRoot;\n          var targetElm = e.target;\n          if (targetElm !== rootNode && targetElm.nodeName !== 'HTML' && !editor.dom.isChildOf(targetElm, rootNode)) {\n            return;\n          }\n          if (EditorView.isXYInContentArea(editor, e.clientX, e.clientY) === false) {\n            return;\n          }\n          contentEditableRoot = getContentEditableRoot(editor, targetElm);\n          if (contentEditableRoot) {\n            if (isContentEditableFalse$9(contentEditableRoot)) {\n              e.preventDefault();\n              setContentEditableSelection(selectNode(editor, contentEditableRoot));\n            } else {\n              removeContentEditableSelection();\n              if (!(isContentEditableTrue$4(contentEditableRoot) && e.shiftKey) && !RangePoint.isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) {\n                hideFakeCaret();\n                editor.selection.placeCaretAt(e.clientX, e.clientY);\n              }\n            }\n          } else if (isFakeCaretTarget(targetElm) === false) {\n            removeContentEditableSelection();\n            hideFakeCaret();\n            var caretInfo = closestCaret(rootNode, e.clientX, e.clientY);\n            if (caretInfo) {\n              if (!hasBetterMouseTarget(e.target, caretInfo.node)) {\n                e.preventDefault();\n                var range = showCaret(1, caretInfo.node, caretInfo.before, false);\n                editor.getBody().focus();\n                setRange(range);\n              }\n            }\n          }\n        });\n        editor.on('keypress', function (e) {\n          if (VK.modifierPressed(e)) {\n            return;\n          }\n          switch (e.keyCode) {\n          default:\n            if (isContentEditableFalse$9(editor.selection.getNode())) {\n              e.preventDefault();\n            }\n            break;\n          }\n        });\n        editor.on('GetSelectionRange', function (e) {\n          var rng = e.range;\n          if (selectedContentEditableNode) {\n            if (!selectedContentEditableNode.parentNode) {\n              selectedContentEditableNode = null;\n              return;\n            }\n            rng = rng.cloneRange();\n            rng.selectNode(selectedContentEditableNode);\n            e.range = rng;\n          }\n        });\n        editor.on('SetSelectionRange', function (e) {\n          e.range = normalizeShortEndedElementSelection(e.range);\n          var rng = setContentEditableSelection(e.range, e.forward);\n          if (rng) {\n            e.range = rng;\n          }\n        });\n        var isPasteBin = function (node) {\n          return node.id === 'mcepastebin';\n        };\n        editor.on('AfterSetSelectionRange', function (e) {\n          var rng = e.range;\n          if (!isRangeInCaretContainer(rng) && !isPasteBin(rng.startContainer.parentNode)) {\n            hideFakeCaret();\n          }\n          if (!isFakeSelectionElement(rng.startContainer.parentNode)) {\n            removeContentEditableSelection();\n          }\n        });\n        editor.on('copy', function (e) {\n          var clipboardData = e.clipboardData;\n          if (!e.isDefaultPrevented() && e.clipboardData && !Env.ie) {\n            var realSelectionElement = getRealSelectionElement();\n            if (realSelectionElement) {\n              e.preventDefault();\n              clipboardData.clearData();\n              clipboardData.setData('text/html', realSelectionElement.outerHTML);\n              clipboardData.setData('text/plain', realSelectionElement.outerText);\n            }\n          }\n        });\n        DragDropOverrides.init(editor);\n        CefFocus.setup(editor);\n      };\n      var isWithinCaretContainer = function (node) {\n        return isCaretContainer(node) || startsWithCaretContainer(node) || endsWithCaretContainer(node);\n      };\n      var isRangeInCaretContainer = function (rng) {\n        return isWithinCaretContainer(rng.startContainer) || isWithinCaretContainer(rng.endContainer);\n      };\n      var normalizeShortEndedElementSelection = function (rng) {\n        var shortEndedElements = editor.schema.getShortEndedElements();\n        var newRng = editor.dom.createRng();\n        var startContainer = rng.startContainer;\n        var startOffset = rng.startOffset;\n        var endContainer = rng.endContainer;\n        var endOffset = rng.endOffset;\n        if (has(shortEndedElements, startContainer.nodeName.toLowerCase())) {\n          if (startOffset === 0) {\n            newRng.setStartBefore(startContainer);\n          } else {\n            newRng.setStartAfter(startContainer);\n          }\n        } else {\n          newRng.setStart(startContainer, startOffset);\n        }\n        if (has(shortEndedElements, endContainer.nodeName.toLowerCase())) {\n          if (endOffset === 0) {\n            newRng.setEndBefore(endContainer);\n          } else {\n            newRng.setEndAfter(endContainer);\n          }\n        } else {\n          newRng.setEnd(endContainer, endOffset);\n        }\n        return newRng;\n      };\n      var setContentEditableSelection = function (range, forward) {\n        var node;\n        var $ = editor.$;\n        var dom = editor.dom;\n        var $realSelectionContainer, sel, startContainer, startOffset, endOffset, e, caretPosition, targetClone, origTargetClone;\n        if (!range) {\n          return null;\n        }\n        if (range.collapsed) {\n          if (!isRangeInCaretContainer(range)) {\n            if (forward === false) {\n              caretPosition = getNormalizedRangeEndPoint(-1, rootNode, range);\n              if (isFakeCaretTarget(caretPosition.getNode(true))) {\n                return showCaret(-1, caretPosition.getNode(true), false, false);\n              }\n              if (isFakeCaretTarget(caretPosition.getNode())) {\n                return showCaret(-1, caretPosition.getNode(), !caretPosition.isAtEnd(), false);\n              }\n            } else {\n              caretPosition = getNormalizedRangeEndPoint(1, rootNode, range);\n              if (isFakeCaretTarget(caretPosition.getNode())) {\n                return showCaret(1, caretPosition.getNode(), !caretPosition.isAtEnd(), false);\n              }\n              if (isFakeCaretTarget(caretPosition.getNode(true))) {\n                return showCaret(1, caretPosition.getNode(true), false, false);\n              }\n            }\n          }\n          return null;\n        }\n        startContainer = range.startContainer;\n        startOffset = range.startOffset;\n        endOffset = range.endOffset;\n        if (startContainer.nodeType === 3 && startOffset === 0 && isContentEditableFalse$9(startContainer.parentNode)) {\n          startContainer = startContainer.parentNode;\n          startOffset = dom.nodeIndex(startContainer);\n          startContainer = startContainer.parentNode;\n        }\n        if (startContainer.nodeType !== 1) {\n          return null;\n        }\n        if (endOffset === startOffset + 1 && startContainer === range.endContainer) {\n          node = startContainer.childNodes[startOffset];\n        }\n        if (!isContentEditableFalse$9(node)) {\n          return null;\n        }\n        targetClone = origTargetClone = node.cloneNode(true);\n        e = editor.fire('ObjectSelected', {\n          target: node,\n          targetClone: targetClone\n        });\n        if (e.isDefaultPrevented()) {\n          return null;\n        }\n        $realSelectionContainer = descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).fold(function () {\n          return $([]);\n        }, function (elm) {\n          return $([elm.dom()]);\n        });\n        targetClone = e.targetClone;\n        if ($realSelectionContainer.length === 0) {\n          $realSelectionContainer = $('<div data-mce-bogus=\"all\" class=\"mce-offscreen-selection\"></div>').attr('id', realSelectionId);\n          $realSelectionContainer.appendTo(editor.getBody());\n        }\n        range = editor.dom.createRng();\n        if (targetClone === origTargetClone && Env.ie) {\n          $realSelectionContainer.empty().append('<p style=\"font-size: 0\" data-mce-bogus=\"all\">\\xA0</p>').append(targetClone);\n          range.setStartAfter($realSelectionContainer[0].firstChild.firstChild);\n          range.setEndAfter(targetClone);\n        } else {\n          $realSelectionContainer.empty().append('\\xA0').append(targetClone).append('\\xA0');\n          range.setStart($realSelectionContainer[0].firstChild, 1);\n          range.setEnd($realSelectionContainer[0].lastChild, 0);\n        }\n        $realSelectionContainer.css({ top: dom.getPos(node, editor.getBody()).y });\n        $realSelectionContainer[0].focus();\n        sel = editor.selection.getSel();\n        sel.removeAllRanges();\n        sel.addRange(range);\n        var nodeElm = Element.fromDom(node);\n        each(descendants$1(Element.fromDom(editor.getBody()), '*[data-mce-selected]'), function (elm) {\n          if (!eq(nodeElm, elm)) {\n            remove(elm, 'data-mce-selected');\n          }\n        });\n        if (!editor.dom.getAttrib(node, 'data-mce-selected')) {\n          node.setAttribute('data-mce-selected', '1');\n        }\n        selectedContentEditableNode = node;\n        hideFakeCaret();\n        return range;\n      };\n      var removeContentEditableSelection = function () {\n        if (selectedContentEditableNode) {\n          selectedContentEditableNode.removeAttribute('data-mce-selected');\n          descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).each(remove$1);\n          selectedContentEditableNode = null;\n        }\n        descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).each(remove$1);\n        selectedContentEditableNode = null;\n      };\n      var destroy = function () {\n        fakeCaret.destroy();\n        selectedContentEditableNode = null;\n      };\n      var hideFakeCaret = function () {\n        fakeCaret.hide();\n      };\n      if (Env.ceFalse) {\n        registerEvents();\n      }\n      return {\n        showCaret: showCaret,\n        showBlockCaretContainer: showBlockCaretContainer,\n        hideFakeCaret: hideFakeCaret,\n        destroy: destroy\n      };\n    };\n\n    var KEEP = 0, INSERT = 1, DELETE = 2;\n    var diff = function (left, right) {\n      var size = left.length + right.length + 2;\n      var vDown = new Array(size);\n      var vUp = new Array(size);\n      var snake = function (start, end, diag) {\n        return {\n          start: start,\n          end: end,\n          diag: diag\n        };\n      };\n      var buildScript = function (start1, end1, start2, end2, script) {\n        var middle = getMiddleSnake(start1, end1, start2, end2);\n        if (middle === null || middle.start === end1 && middle.diag === end1 - end2 || middle.end === start1 && middle.diag === start1 - start2) {\n          var i = start1;\n          var j = start2;\n          while (i < end1 || j < end2) {\n            if (i < end1 && j < end2 && left[i] === right[j]) {\n              script.push([\n                KEEP,\n                left[i]\n              ]);\n              ++i;\n              ++j;\n            } else {\n              if (end1 - start1 > end2 - start2) {\n                script.push([\n                  DELETE,\n                  left[i]\n                ]);\n                ++i;\n              } else {\n                script.push([\n                  INSERT,\n                  right[j]\n                ]);\n                ++j;\n              }\n            }\n          }\n        } else {\n          buildScript(start1, middle.start, start2, middle.start - middle.diag, script);\n          for (var i2 = middle.start; i2 < middle.end; ++i2) {\n            script.push([\n              KEEP,\n              left[i2]\n            ]);\n          }\n          buildScript(middle.end, end1, middle.end - middle.diag, end2, script);\n        }\n      };\n      var buildSnake = function (start, diag, end1, end2) {\n        var end = start;\n        while (end - diag < end2 && end < end1 && left[end] === right[end - diag]) {\n          ++end;\n        }\n        return snake(start, end, diag);\n      };\n      var getMiddleSnake = function (start1, end1, start2, end2) {\n        var m = end1 - start1;\n        var n = end2 - start2;\n        if (m === 0 || n === 0) {\n          return null;\n        }\n        var delta = m - n;\n        var sum = n + m;\n        var offset = (sum % 2 === 0 ? sum : sum + 1) / 2;\n        vDown[1 + offset] = start1;\n        vUp[1 + offset] = end1 + 1;\n        var d, k, i, x, y;\n        for (d = 0; d <= offset; ++d) {\n          for (k = -d; k <= d; k += 2) {\n            i = k + offset;\n            if (k === -d || k !== d && vDown[i - 1] < vDown[i + 1]) {\n              vDown[i] = vDown[i + 1];\n            } else {\n              vDown[i] = vDown[i - 1] + 1;\n            }\n            x = vDown[i];\n            y = x - start1 + start2 - k;\n            while (x < end1 && y < end2 && left[x] === right[y]) {\n              vDown[i] = ++x;\n              ++y;\n            }\n            if (delta % 2 !== 0 && delta - d <= k && k <= delta + d) {\n              if (vUp[i - delta] <= vDown[i]) {\n                return buildSnake(vUp[i - delta], k + start1 - start2, end1, end2);\n              }\n            }\n          }\n          for (k = delta - d; k <= delta + d; k += 2) {\n            i = k + offset - delta;\n            if (k === delta - d || k !== delta + d && vUp[i + 1] <= vUp[i - 1]) {\n              vUp[i] = vUp[i + 1] - 1;\n            } else {\n              vUp[i] = vUp[i - 1];\n            }\n            x = vUp[i] - 1;\n            y = x - start1 + start2 - k;\n            while (x >= start1 && y >= start2 && left[x] === right[y]) {\n              vUp[i] = x--;\n              y--;\n            }\n            if (delta % 2 === 0 && -d <= k && k <= d) {\n              if (vUp[i] <= vDown[i + delta]) {\n                return buildSnake(vUp[i], k + start1 - start2, end1, end2);\n              }\n            }\n          }\n        }\n      };\n      var script = [];\n      buildScript(0, left.length, 0, right.length, script);\n      return script;\n    };\n    var Diff = {\n      KEEP: KEEP,\n      DELETE: DELETE,\n      INSERT: INSERT,\n      diff: diff\n    };\n\n    var getOuterHtml = function (elm) {\n      if (NodeType.isElement(elm)) {\n        return elm.outerHTML;\n      } else if (NodeType.isText(elm)) {\n        return Entities.encodeRaw(elm.data, false);\n      } else if (NodeType.isComment(elm)) {\n        return '<!--' + elm.data + '-->';\n      }\n      return '';\n    };\n    var createFragment$1 = function (html) {\n      var frag, node, container;\n      container = domGlobals.document.createElement('div');\n      frag = domGlobals.document.createDocumentFragment();\n      if (html) {\n        container.innerHTML = html;\n      }\n      while (node = container.firstChild) {\n        frag.appendChild(node);\n      }\n      return frag;\n    };\n    var insertAt = function (elm, html, index) {\n      var fragment = createFragment$1(html);\n      if (elm.hasChildNodes() && index < elm.childNodes.length) {\n        var target = elm.childNodes[index];\n        target.parentNode.insertBefore(fragment, target);\n      } else {\n        elm.appendChild(fragment);\n      }\n    };\n    var removeAt = function (elm, index) {\n      if (elm.hasChildNodes() && index < elm.childNodes.length) {\n        var target = elm.childNodes[index];\n        target.parentNode.removeChild(target);\n      }\n    };\n    var applyDiff = function (diff, elm) {\n      var index = 0;\n      each(diff, function (action) {\n        if (action[0] === Diff.KEEP) {\n          index++;\n        } else if (action[0] === Diff.INSERT) {\n          insertAt(elm, action[1], index);\n          index++;\n        } else if (action[0] === Diff.DELETE) {\n          removeAt(elm, index);\n        }\n      });\n    };\n    var read$1 = function (elm) {\n      return filter(map(from$1(elm.childNodes), getOuterHtml), function (item) {\n        return item.length > 0;\n      });\n    };\n    var write = function (fragments, elm) {\n      var currentFragments = map(from$1(elm.childNodes), getOuterHtml);\n      applyDiff(Diff.diff(currentFragments, fragments), elm);\n      return elm;\n    };\n    var Fragments = {\n      read: read$1,\n      write: write\n    };\n\n    var undoLevelDocument = Cell(Option.none());\n    var lazyTempDocument = function () {\n      return undoLevelDocument.get().getOrThunk(function () {\n        var doc = domGlobals.document.implementation.createHTMLDocument('undo');\n        undoLevelDocument.set(Option.some(doc));\n        return doc;\n      });\n    };\n    var hasIframes = function (html) {\n      return html.indexOf('</iframe>') !== -1;\n    };\n    var createFragmentedLevel = function (fragments) {\n      return {\n        type: 'fragmented',\n        fragments: fragments,\n        content: '',\n        bookmark: null,\n        beforeBookmark: null\n      };\n    };\n    var createCompleteLevel = function (content) {\n      return {\n        type: 'complete',\n        fragments: null,\n        content: content,\n        bookmark: null,\n        beforeBookmark: null\n      };\n    };\n    var createFromEditor = function (editor) {\n      var fragments, content, trimmedFragments;\n      fragments = Fragments.read(editor.getBody());\n      trimmedFragments = bind(fragments, function (html) {\n        var trimmed = TrimHtml.trimInternal(editor.serializer, html);\n        return trimmed.length > 0 ? [trimmed] : [];\n      });\n      content = trimmedFragments.join('');\n      return hasIframes(content) ? createFragmentedLevel(trimmedFragments) : createCompleteLevel(content);\n    };\n    var applyToEditor = function (editor, level, before) {\n      if (level.type === 'fragmented') {\n        Fragments.write(level.fragments, editor.getBody());\n      } else {\n        editor.setContent(level.content, { format: 'raw' });\n      }\n      editor.selection.moveToBookmark(before ? level.beforeBookmark : level.bookmark);\n    };\n    var getLevelContent = function (level) {\n      return level.type === 'fragmented' ? level.fragments.join('') : level.content;\n    };\n    var getCleanLevelContent = function (level) {\n      var elm = Element.fromTag('body', lazyTempDocument());\n      set$1(elm, getLevelContent(level));\n      each(descendants$1(elm, '*[data-mce-bogus]'), unwrap);\n      return get$5(elm);\n    };\n    var hasEqualContent = function (level1, level2) {\n      return getLevelContent(level1) === getLevelContent(level2);\n    };\n    var hasEqualCleanedContent = function (level1, level2) {\n      return getCleanLevelContent(level1) === getCleanLevelContent(level2);\n    };\n    var isEq$2 = function (level1, level2) {\n      if (!level1 || !level2) {\n        return false;\n      } else if (hasEqualContent(level1, level2)) {\n        return true;\n      } else {\n        return hasEqualCleanedContent(level1, level2);\n      }\n    };\n    var Levels = {\n      createFragmentedLevel: createFragmentedLevel,\n      createCompleteLevel: createCompleteLevel,\n      createFromEditor: createFromEditor,\n      applyToEditor: applyToEditor,\n      isEq: isEq$2\n    };\n\n    var isUnlocked = function (locks) {\n      return locks.get() === 0;\n    };\n\n    var setTyping = function (undoManager, typing, locks) {\n      if (isUnlocked(locks)) {\n        undoManager.typing = typing;\n      }\n    };\n    var endTyping = function (undoManager, locks) {\n      if (undoManager.typing) {\n        setTyping(undoManager, false, locks);\n        undoManager.add();\n      }\n    };\n    var endTypingLevelIgnoreLocks = function (undoManager) {\n      if (undoManager.typing) {\n        undoManager.typing = false;\n        undoManager.add();\n      }\n    };\n\n    var beforeChange = function (editor, locks, beforeBookmark) {\n      if (isUnlocked(locks)) {\n        beforeBookmark.set(Option.some(GetBookmark.getUndoBookmark(editor.selection)));\n      }\n    };\n    var addUndoLevel = function (editor, undoManager, index, locks, beforeBookmark, level, event) {\n      var settings = editor.settings;\n      var currentLevel = Levels.createFromEditor(editor);\n      level = level || {};\n      level = Tools.extend(level, currentLevel);\n      if (isUnlocked(locks) === false || editor.removed) {\n        return null;\n      }\n      var lastLevel = undoManager.data[index.get()];\n      if (editor.fire('BeforeAddUndo', {\n          level: level,\n          lastLevel: lastLevel,\n          originalEvent: event\n        }).isDefaultPrevented()) {\n        return null;\n      }\n      if (lastLevel && Levels.isEq(lastLevel, level)) {\n        return null;\n      }\n      if (undoManager.data[index.get()]) {\n        beforeBookmark.get().each(function (bm) {\n          undoManager.data[index.get()].beforeBookmark = bm;\n        });\n      }\n      if (settings.custom_undo_redo_levels) {\n        if (undoManager.data.length > settings.custom_undo_redo_levels) {\n          for (var i = 0; i < undoManager.data.length - 1; i++) {\n            undoManager.data[i] = undoManager.data[i + 1];\n          }\n          undoManager.data.length--;\n          index.set(undoManager.data.length);\n        }\n      }\n      level.bookmark = GetBookmark.getUndoBookmark(editor.selection);\n      if (index.get() < undoManager.data.length - 1) {\n        undoManager.data.length = index.get() + 1;\n      }\n      undoManager.data.push(level);\n      index.set(undoManager.data.length - 1);\n      var args = {\n        level: level,\n        lastLevel: lastLevel,\n        originalEvent: event\n      };\n      editor.fire('AddUndo', args);\n      if (index.get() > 0) {\n        editor.setDirty(true);\n        editor.fire('change', args);\n      }\n      return level;\n    };\n    var clear = function (editor, undoManager, index) {\n      undoManager.data = [];\n      index.set(0);\n      undoManager.typing = false;\n      editor.fire('ClearUndos');\n    };\n    var extra = function (editor, undoManager, index, callback1, callback2) {\n      if (undoManager.transact(callback1)) {\n        var bookmark = undoManager.data[index.get()].bookmark;\n        var lastLevel = undoManager.data[index.get() - 1];\n        Levels.applyToEditor(editor, lastLevel, true);\n        if (undoManager.transact(callback2)) {\n          undoManager.data[index.get() - 1].beforeBookmark = bookmark;\n        }\n      }\n    };\n    var redo = function (editor, index, data) {\n      var level;\n      if (index.get() < data.length - 1) {\n        index.set(index.get() + 1);\n        level = data[index.get()];\n        Levels.applyToEditor(editor, level, false);\n        editor.setDirty(true);\n        editor.fire('Redo', { level: level });\n      }\n      return level;\n    };\n    var undo = function (editor, undoManager, locks, index) {\n      var level;\n      if (undoManager.typing) {\n        undoManager.add();\n        undoManager.typing = false;\n        setTyping(undoManager, false, locks);\n      }\n      if (index.get() > 0) {\n        index.set(index.get() - 1);\n        level = undoManager.data[index.get()];\n        Levels.applyToEditor(editor, level, true);\n        editor.setDirty(true);\n        editor.fire('Undo', { level: level });\n      }\n      return level;\n    };\n    var reset = function (undoManager) {\n      undoManager.clear();\n      undoManager.add();\n    };\n    var hasUndo = function (editor, undoManager, index) {\n      return index.get() > 0 || undoManager.typing && undoManager.data[0] && !Levels.isEq(Levels.createFromEditor(editor), undoManager.data[0]);\n    };\n    var hasRedo = function (undoManager, index) {\n      return index.get() < undoManager.data.length - 1 && !undoManager.typing;\n    };\n    var transact = function (undoManager, locks, callback) {\n      endTyping(undoManager, locks);\n      undoManager.beforeChange();\n      undoManager.ignore(callback);\n      return undoManager.add();\n    };\n    var ignore = function (locks, callback) {\n      try {\n        locks.set(locks.get() + 1);\n        callback();\n      } finally {\n        locks.set(locks.get() - 1);\n      }\n    };\n\n    var registerEvents$1 = function (editor, undoManager, locks) {\n      var isFirstTypedCharacter = Cell(false);\n      var addNonTypingUndoLevel = function (e) {\n        setTyping(undoManager, false, locks);\n        undoManager.add({}, e);\n      };\n      editor.on('init', function () {\n        undoManager.add();\n      });\n      editor.on('BeforeExecCommand', function (e) {\n        var cmd = e.command;\n        if (cmd !== 'Undo' && cmd !== 'Redo' && cmd !== 'mceRepaint') {\n          endTyping(undoManager, locks);\n          undoManager.beforeChange();\n        }\n      });\n      editor.on('ExecCommand', function (e) {\n        var cmd = e.command;\n        if (cmd !== 'Undo' && cmd !== 'Redo' && cmd !== 'mceRepaint') {\n          addNonTypingUndoLevel(e);\n        }\n      });\n      editor.on('ObjectResizeStart cut', function () {\n        undoManager.beforeChange();\n      });\n      editor.on('SaveContent ObjectResized blur', addNonTypingUndoLevel);\n      editor.on('dragend', addNonTypingUndoLevel);\n      editor.on('keyup', function (e) {\n        var keyCode = e.keyCode;\n        if (e.isDefaultPrevented()) {\n          return;\n        }\n        if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45 || e.ctrlKey) {\n          addNonTypingUndoLevel();\n          editor.nodeChanged();\n        }\n        if (keyCode === 46 || keyCode === 8) {\n          editor.nodeChanged();\n        }\n        if (isFirstTypedCharacter.get() && undoManager.typing && Levels.isEq(Levels.createFromEditor(editor), undoManager.data[0]) === false) {\n          if (editor.isDirty() === false) {\n            editor.setDirty(true);\n            editor.fire('change', {\n              level: undoManager.data[0],\n              lastLevel: null\n            });\n          }\n          editor.fire('TypingUndo');\n          isFirstTypedCharacter.set(false);\n          editor.nodeChanged();\n        }\n      });\n      editor.on('keydown', function (e) {\n        var keyCode = e.keyCode;\n        if (e.isDefaultPrevented()) {\n          return;\n        }\n        if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45) {\n          if (undoManager.typing) {\n            addNonTypingUndoLevel(e);\n          }\n          return;\n        }\n        var modKey = e.ctrlKey && !e.altKey || e.metaKey;\n        if ((keyCode < 16 || keyCode > 20) && keyCode !== 224 && keyCode !== 91 && !undoManager.typing && !modKey) {\n          undoManager.beforeChange();\n          setTyping(undoManager, true, locks);\n          undoManager.add({}, e);\n          isFirstTypedCharacter.set(true);\n        }\n      });\n      editor.on('mousedown', function (e) {\n        if (undoManager.typing) {\n          addNonTypingUndoLevel(e);\n        }\n      });\n      var isInsertReplacementText = function (event) {\n        return event.inputType === 'insertReplacementText';\n      };\n      var isInsertTextDataNull = function (event) {\n        return event.inputType === 'insertText' && event.data === null;\n      };\n      editor.on('input', function (e) {\n        if (e.inputType && (isInsertReplacementText(e) || isInsertTextDataNull(e))) {\n          addNonTypingUndoLevel(e);\n        }\n      });\n      editor.on('AddUndo Undo Redo ClearUndos', function (e) {\n        if (!e.isDefaultPrevented()) {\n          editor.nodeChanged();\n        }\n      });\n    };\n    var addKeyboardShortcuts = function (editor) {\n      editor.addShortcut('meta+z', '', 'Undo');\n      editor.addShortcut('meta+y,meta+shift+z', '', 'Redo');\n    };\n\n    var UndoManager = function (editor) {\n      var beforeBookmark = Cell(Option.none());\n      var locks = Cell(0);\n      var index = Cell(0);\n      var undoManager = {\n        data: [],\n        typing: false,\n        beforeChange: function () {\n          beforeChange(editor, locks, beforeBookmark);\n        },\n        add: function (level, event) {\n          return addUndoLevel(editor, undoManager, index, locks, beforeBookmark, level, event);\n        },\n        undo: function () {\n          return undo(editor, undoManager, locks, index);\n        },\n        redo: function () {\n          return redo(editor, index, undoManager.data);\n        },\n        clear: function () {\n          clear(editor, undoManager, index);\n        },\n        reset: function () {\n          reset(undoManager);\n        },\n        hasUndo: function () {\n          return hasUndo(editor, undoManager, index);\n        },\n        hasRedo: function () {\n          return hasRedo(undoManager, index);\n        },\n        transact: function (callback) {\n          return transact(undoManager, locks, callback);\n        },\n        ignore: function (callback) {\n          ignore(locks, callback);\n        },\n        extra: function (callback1, callback2) {\n          extra(editor, undoManager, index, callback1, callback2);\n        }\n      };\n      registerEvents$1(editor, undoManager, locks);\n      addKeyboardShortcuts(editor);\n      return undoManager;\n    };\n\n    var getLastChildren$1 = function (elm) {\n      var children = [];\n      var rawNode = elm.dom();\n      while (rawNode) {\n        children.push(Element.fromDom(rawNode));\n        rawNode = rawNode.lastChild;\n      }\n      return children;\n    };\n    var removeTrailingBr = function (elm) {\n      var allBrs = descendants$1(elm, 'br');\n      var brs = filter(getLastChildren$1(elm).slice(-1), isBr$1);\n      if (allBrs.length === brs.length) {\n        each(brs, remove$1);\n      }\n    };\n    var fillWithPaddingBr = function (elm) {\n      empty(elm);\n      append(elm, Element.fromHtml('<br data-mce-bogus=\"1\">'));\n    };\n    var isPaddingContents = function (elm) {\n      return isText$1(elm) ? get$6(elm) === '\\xA0' : isBr$1(elm);\n    };\n    var isPaddedElement = function (elm) {\n      return filter(children(elm), isPaddingContents).length === 1;\n    };\n    var trimBlockTrailingBr = function (elm) {\n      lastChild(elm).each(function (lastChild) {\n        prevSibling(lastChild).each(function (lastChildPrevSibling) {\n          if (isBlock(elm) && isBr$1(lastChild) && isBlock(lastChildPrevSibling)) {\n            remove$1(lastChild);\n          }\n        });\n      });\n    };\n    var PaddingBr = {\n      removeTrailingBr: removeTrailingBr,\n      fillWithPaddingBr: fillWithPaddingBr,\n      isPaddedElement: isPaddedElement,\n      trimBlockTrailingBr: trimBlockTrailingBr\n    };\n\n    var isEq$3 = FormatUtils.isEq;\n    var matchesUnInheritedFormatSelector = function (ed, node, name) {\n      var formatList = ed.formatter.get(name);\n      if (formatList) {\n        for (var i = 0; i < formatList.length; i++) {\n          if (formatList[i].inherit === false && ed.dom.is(node, formatList[i].selector)) {\n            return true;\n          }\n        }\n      }\n      return false;\n    };\n    var matchParents = function (editor, node, name, vars) {\n      var root = editor.dom.getRoot();\n      if (node === root) {\n        return false;\n      }\n      node = editor.dom.getParent(node, function (node) {\n        if (matchesUnInheritedFormatSelector(editor, node, name)) {\n          return true;\n        }\n        return node.parentNode === root || !!matchNode(editor, node, name, vars, true);\n      });\n      return matchNode(editor, node, name, vars);\n    };\n    var matchName = function (dom, node, format) {\n      if (isEq$3(node, format.inline)) {\n        return true;\n      }\n      if (isEq$3(node, format.block)) {\n        return true;\n      }\n      if (format.selector) {\n        return node.nodeType === 1 && dom.is(node, format.selector);\n      }\n    };\n    var matchItems = function (dom, node, format, itemName, similar, vars) {\n      var key, value;\n      var items = format[itemName];\n      var i;\n      if (format.onmatch) {\n        return format.onmatch(node, format, itemName);\n      }\n      if (items) {\n        if (typeof items.length === 'undefined') {\n          for (key in items) {\n            if (items.hasOwnProperty(key)) {\n              if (itemName === 'attributes') {\n                value = dom.getAttrib(node, key);\n              } else {\n                value = FormatUtils.getStyle(dom, node, key);\n              }\n              if (similar && !value && !format.exact) {\n                return;\n              }\n              if ((!similar || format.exact) && !isEq$3(value, FormatUtils.normalizeStyleValue(dom, FormatUtils.replaceVars(items[key], vars), key))) {\n                return;\n              }\n            }\n          }\n        } else {\n          for (i = 0; i < items.length; i++) {\n            if (itemName === 'attributes' ? dom.getAttrib(node, items[i]) : FormatUtils.getStyle(dom, node, items[i])) {\n              return format;\n            }\n          }\n        }\n      }\n      return format;\n    };\n    var matchNode = function (ed, node, name, vars, similar) {\n      var formatList = ed.formatter.get(name);\n      var format, i, x, classes;\n      var dom = ed.dom;\n      if (formatList && node) {\n        for (i = 0; i < formatList.length; i++) {\n          format = formatList[i];\n          if (matchName(ed.dom, node, format) && matchItems(dom, node, format, 'attributes', similar, vars) && matchItems(dom, node, format, 'styles', similar, vars)) {\n            if (classes = format.classes) {\n              for (x = 0; x < classes.length; x++) {\n                if (!ed.dom.hasClass(node, classes[x])) {\n                  return;\n                }\n              }\n            }\n            return format;\n          }\n        }\n      }\n    };\n    var match = function (editor, name, vars, node) {\n      var startNode;\n      if (node) {\n        return matchParents(editor, node, name, vars);\n      }\n      node = editor.selection.getNode();\n      if (matchParents(editor, node, name, vars)) {\n        return true;\n      }\n      startNode = editor.selection.getStart();\n      if (startNode !== node) {\n        if (matchParents(editor, startNode, name, vars)) {\n          return true;\n        }\n      }\n      return false;\n    };\n    var matchAll = function (editor, names, vars) {\n      var startElement;\n      var matchedFormatNames = [];\n      var checkedMap = {};\n      startElement = editor.selection.getStart();\n      editor.dom.getParent(startElement, function (node) {\n        var i, name;\n        for (i = 0; i < names.length; i++) {\n          name = names[i];\n          if (!checkedMap[name] && matchNode(editor, node, name, vars)) {\n            checkedMap[name] = true;\n            matchedFormatNames.push(name);\n          }\n        }\n      }, editor.dom.getRoot());\n      return matchedFormatNames;\n    };\n    var canApply = function (editor, name) {\n      var formatList = editor.formatter.get(name);\n      var startNode, parents, i, x, selector;\n      var dom = editor.dom;\n      if (formatList) {\n        startNode = editor.selection.getStart();\n        parents = FormatUtils.getParents(dom, startNode);\n        for (x = formatList.length - 1; x >= 0; x--) {\n          selector = formatList[x].selector;\n          if (!selector || formatList[x].defaultBlock) {\n            return true;\n          }\n          for (i = parents.length - 1; i >= 0; i--) {\n            if (dom.is(parents[i], selector)) {\n              return true;\n            }\n          }\n        }\n      }\n      return false;\n    };\n    var MatchFormat = {\n      matchNode: matchNode,\n      matchName: matchName,\n      match: match,\n      matchAll: matchAll,\n      canApply: canApply,\n      matchesUnInheritedFormatSelector: matchesUnInheritedFormatSelector\n    };\n\n    var splitText = function (node, offset) {\n      return node.splitText(offset);\n    };\n    var split$1 = function (rng) {\n      var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;\n      if (startContainer === endContainer && NodeType.isText(startContainer)) {\n        if (startOffset > 0 && startOffset < startContainer.nodeValue.length) {\n          endContainer = splitText(startContainer, startOffset);\n          startContainer = endContainer.previousSibling;\n          if (endOffset > startOffset) {\n            endOffset = endOffset - startOffset;\n            startContainer = endContainer = splitText(endContainer, endOffset).previousSibling;\n            endOffset = endContainer.nodeValue.length;\n            startOffset = 0;\n          } else {\n            endOffset = 0;\n          }\n        }\n      } else {\n        if (NodeType.isText(startContainer) && startOffset > 0 && startOffset < startContainer.nodeValue.length) {\n          startContainer = splitText(startContainer, startOffset);\n          startOffset = 0;\n        }\n        if (NodeType.isText(endContainer) && endOffset > 0 && endOffset < endContainer.nodeValue.length) {\n          endContainer = splitText(endContainer, endOffset).previousSibling;\n          endOffset = endContainer.nodeValue.length;\n        }\n      }\n      return {\n        startContainer: startContainer,\n        startOffset: startOffset,\n        endContainer: endContainer,\n        endOffset: endOffset\n      };\n    };\n\n    var isCollapsibleWhitespace = function (c) {\n      return ' \\f\\n\\r\\t\\x0B'.indexOf(c) !== -1;\n    };\n    var normalizeContent = function (content, isStartOfContent, isEndOfContent) {\n      var result = foldl(content, function (acc, c) {\n        if (isCollapsibleWhitespace(c) || c === '\\xA0') {\n          if (acc.previousCharIsSpace || acc.str === '' && isStartOfContent || acc.str.length === content.length - 1 && isEndOfContent) {\n            return {\n              previousCharIsSpace: false,\n              str: acc.str + '\\xA0'\n            };\n          } else {\n            return {\n              previousCharIsSpace: true,\n              str: acc.str + ' '\n            };\n          }\n        } else {\n          return {\n            previousCharIsSpace: false,\n            str: acc.str + c\n          };\n        }\n      }, {\n        previousCharIsSpace: false,\n        str: ''\n      });\n      return result.str;\n    };\n    var normalize = function (node, offset, count) {\n      if (count === 0) {\n        return;\n      }\n      var whitespace = node.data.slice(offset, offset + count);\n      var isEndOfContent = offset + count >= node.data.length;\n      var isStartOfContent = offset === 0;\n      node.replaceData(offset, count, normalizeContent(whitespace, isStartOfContent, isEndOfContent));\n    };\n    var normalizeWhitespaceAfter = function (node, offset) {\n      var content = node.data.slice(offset);\n      var whitespaceCount = content.length - lTrim(content).length;\n      return normalize(node, offset, whitespaceCount);\n    };\n    var normalizeWhitespaceBefore = function (node, offset) {\n      var content = node.data.slice(0, offset);\n      var whitespaceCount = content.length - rTrim(content).length;\n      return normalize(node, offset - whitespaceCount, whitespaceCount);\n    };\n    var mergeTextNodes = function (prevNode, nextNode, normalizeWhitespace) {\n      var whitespaceOffset = rTrim(prevNode.data).length;\n      prevNode.appendData(nextNode.data);\n      remove$1(Element.fromDom(nextNode));\n      if (normalizeWhitespace) {\n        normalizeWhitespaceAfter(prevNode, whitespaceOffset);\n      }\n      return prevNode;\n    };\n\n    var ancestor$2 = function (scope, selector, isRoot) {\n      return ancestor$1(scope, selector, isRoot).isSome();\n    };\n\n    var hasWhitespacePreserveParent = function (rootNode, node) {\n      var rootElement = Element.fromDom(rootNode);\n      var startNode = Element.fromDom(node);\n      return ancestor$2(startNode, 'pre,code', curry(eq, rootElement));\n    };\n    var isWhitespace = function (rootNode, node) {\n      return NodeType.isText(node) && /^[ \\t\\r\\n]*$/.test(node.data) && hasWhitespacePreserveParent(rootNode, node) === false;\n    };\n    var isNamedAnchor = function (node) {\n      return NodeType.isElement(node) && node.nodeName === 'A' && node.hasAttribute('name');\n    };\n    var isContent$1 = function (rootNode, node) {\n      return isCaretCandidate(node) && isWhitespace(rootNode, node) === false || isNamedAnchor(node) || isBookmark(node);\n    };\n    var isBookmark = NodeType.hasAttribute('data-mce-bookmark');\n    var isBogus$2 = NodeType.hasAttribute('data-mce-bogus');\n    var isBogusAll$1 = NodeType.hasAttributeValue('data-mce-bogus', 'all');\n    var isEmptyNode = function (targetNode) {\n      var node, brCount = 0;\n      if (isContent$1(targetNode, targetNode)) {\n        return false;\n      } else {\n        node = targetNode.firstChild;\n        if (!node) {\n          return true;\n        }\n        var walker = new TreeWalker(node, targetNode);\n        do {\n          if (isBogusAll$1(node)) {\n            node = walker.next(true);\n            continue;\n          }\n          if (isBogus$2(node)) {\n            node = walker.next();\n            continue;\n          }\n          if (NodeType.isBr(node)) {\n            brCount++;\n            node = walker.next();\n            continue;\n          }\n          if (isContent$1(targetNode, node)) {\n            return false;\n          }\n          node = walker.next();\n        } while (node);\n        return brCount <= 1;\n      }\n    };\n    var isEmpty$1 = function (elm) {\n      return isEmptyNode(elm.dom());\n    };\n    var Empty = { isEmpty: isEmpty$1 };\n\n    var needsReposition = function (pos, elm) {\n      var container = pos.container();\n      var offset = pos.offset();\n      return CaretPosition$1.isTextPosition(pos) === false && container === elm.parentNode && offset > CaretPosition$1.before(elm).offset();\n    };\n    var reposition = function (elm, pos) {\n      return needsReposition(pos, elm) ? CaretPosition$1(pos.container(), pos.offset() - 1) : pos;\n    };\n    var beforeOrStartOf = function (node) {\n      return NodeType.isText(node) ? CaretPosition$1(node, 0) : CaretPosition$1.before(node);\n    };\n    var afterOrEndOf = function (node) {\n      return NodeType.isText(node) ? CaretPosition$1(node, node.data.length) : CaretPosition$1.after(node);\n    };\n    var getPreviousSiblingCaretPosition = function (elm) {\n      if (isCaretCandidate(elm.previousSibling)) {\n        return Option.some(afterOrEndOf(elm.previousSibling));\n      } else {\n        return elm.previousSibling ? CaretFinder.lastPositionIn(elm.previousSibling) : Option.none();\n      }\n    };\n    var getNextSiblingCaretPosition = function (elm) {\n      if (isCaretCandidate(elm.nextSibling)) {\n        return Option.some(beforeOrStartOf(elm.nextSibling));\n      } else {\n        return elm.nextSibling ? CaretFinder.firstPositionIn(elm.nextSibling) : Option.none();\n      }\n    };\n    var findCaretPositionBackwardsFromElm = function (rootElement, elm) {\n      var startPosition = CaretPosition$1.before(elm.previousSibling ? elm.previousSibling : elm.parentNode);\n      return CaretFinder.prevPosition(rootElement, startPosition).fold(function () {\n        return CaretFinder.nextPosition(rootElement, CaretPosition$1.after(elm));\n      }, Option.some);\n    };\n    var findCaretPositionForwardsFromElm = function (rootElement, elm) {\n      return CaretFinder.nextPosition(rootElement, CaretPosition$1.after(elm)).fold(function () {\n        return CaretFinder.prevPosition(rootElement, CaretPosition$1.before(elm));\n      }, Option.some);\n    };\n    var findCaretPositionBackwards = function (rootElement, elm) {\n      return getPreviousSiblingCaretPosition(elm).orThunk(function () {\n        return getNextSiblingCaretPosition(elm);\n      }).orThunk(function () {\n        return findCaretPositionBackwardsFromElm(rootElement, elm);\n      });\n    };\n    var findCaretPositionForward = function (rootElement, elm) {\n      return getNextSiblingCaretPosition(elm).orThunk(function () {\n        return getPreviousSiblingCaretPosition(elm);\n      }).orThunk(function () {\n        return findCaretPositionForwardsFromElm(rootElement, elm);\n      });\n    };\n    var findCaretPosition$1 = function (forward, rootElement, elm) {\n      return forward ? findCaretPositionForward(rootElement, elm) : findCaretPositionBackwards(rootElement, elm);\n    };\n    var findCaretPosOutsideElmAfterDelete = function (forward, rootElement, elm) {\n      return findCaretPosition$1(forward, rootElement, elm).map(curry(reposition, elm));\n    };\n    var setSelection = function (editor, forward, pos) {\n      pos.fold(function () {\n        editor.focus();\n      }, function (pos) {\n        editor.selection.setRng(pos.toRange(), forward);\n      });\n    };\n    var eqRawNode = function (rawNode) {\n      return function (elm) {\n        return elm.dom() === rawNode;\n      };\n    };\n    var isBlock$2 = function (editor, elm) {\n      return elm && editor.schema.getBlockElements().hasOwnProperty(name(elm));\n    };\n    var paddEmptyBlock = function (elm) {\n      if (Empty.isEmpty(elm)) {\n        var br = Element.fromHtml('<br data-mce-bogus=\"1\">');\n        empty(elm);\n        append(elm, br);\n        return Option.some(CaretPosition$1.before(br.dom()));\n      } else {\n        return Option.none();\n      }\n    };\n    var deleteNormalized = function (elm, afterDeletePosOpt, normalizeWhitespace) {\n      var prevTextOpt = prevSibling(elm).filter(isText$1);\n      var nextTextOpt = nextSibling(elm).filter(isText$1);\n      remove$1(elm);\n      return lift3(prevTextOpt, nextTextOpt, afterDeletePosOpt, function (prev, next, pos) {\n        var prevNode = prev.dom(), nextNode = next.dom();\n        var offset = prevNode.data.length;\n        mergeTextNodes(prevNode, nextNode, normalizeWhitespace);\n        return pos.container() === nextNode ? CaretPosition$1(prevNode, offset) : pos;\n      }).orThunk(function () {\n        if (normalizeWhitespace) {\n          prevTextOpt.each(function (elm) {\n            return normalizeWhitespaceBefore(elm.dom(), elm.dom().length);\n          });\n          nextTextOpt.each(function (elm) {\n            return normalizeWhitespaceAfter(elm.dom(), 0);\n          });\n        }\n        return afterDeletePosOpt;\n      });\n    };\n    var isInlineElement = function (editor, element) {\n      return has(editor.schema.getTextInlineElements(), name(element));\n    };\n    var deleteElement = function (editor, forward, elm, moveCaret) {\n      if (moveCaret === void 0) {\n        moveCaret = true;\n      }\n      var afterDeletePos = findCaretPosOutsideElmAfterDelete(forward, editor.getBody(), elm.dom());\n      var parentBlock = ancestor(elm, curry(isBlock$2, editor), eqRawNode(editor.getBody()));\n      var normalizedAfterDeletePos = deleteNormalized(elm, afterDeletePos, isInlineElement(editor, elm));\n      if (editor.dom.isEmpty(editor.getBody())) {\n        editor.setContent('');\n        editor.selection.setCursorLocation();\n      } else {\n        parentBlock.bind(paddEmptyBlock).fold(function () {\n          if (moveCaret) {\n            setSelection(editor, forward, normalizedAfterDeletePos);\n          }\n        }, function (paddPos) {\n          if (moveCaret) {\n            setSelection(editor, forward, Option.some(paddPos));\n          }\n        });\n      }\n    };\n    var DeleteElement = { deleteElement: deleteElement };\n\n    var ZWSP$1 = Zwsp.ZWSP, CARET_ID$1 = '_mce_caret';\n    var importNode = function (ownerDocument, node) {\n      return ownerDocument.importNode(node, true);\n    };\n    var getEmptyCaretContainers = function (node) {\n      var nodes = [];\n      while (node) {\n        if (node.nodeType === 3 && node.nodeValue !== ZWSP$1 || node.childNodes.length > 1) {\n          return [];\n        }\n        if (node.nodeType === 1) {\n          nodes.push(node);\n        }\n        node = node.firstChild;\n      }\n      return nodes;\n    };\n    var isCaretContainerEmpty = function (node) {\n      return getEmptyCaretContainers(node).length > 0;\n    };\n    var findFirstTextNode = function (node) {\n      if (node) {\n        var walker = new TreeWalker(node, node);\n        for (node = walker.current(); node; node = walker.next()) {\n          if (node.nodeType === 3) {\n            return node;\n          }\n        }\n      }\n      return null;\n    };\n    var createCaretContainer = function (fill) {\n      var caretContainer = Element.fromTag('span');\n      setAll(caretContainer, {\n        'id': CARET_ID$1,\n        'data-mce-bogus': '1',\n        'data-mce-type': 'format-caret'\n      });\n      if (fill) {\n        append(caretContainer, Element.fromText(ZWSP$1));\n      }\n      return caretContainer;\n    };\n    var trimZwspFromCaretContainer = function (caretContainerNode) {\n      var textNode = findFirstTextNode(caretContainerNode);\n      if (textNode && textNode.nodeValue.charAt(0) === ZWSP$1) {\n        textNode.deleteData(0, 1);\n      }\n      return textNode;\n    };\n    var removeCaretContainerNode = function (editor, node, moveCaret) {\n      if (moveCaret === void 0) {\n        moveCaret = true;\n      }\n      var dom = editor.dom, selection = editor.selection;\n      if (isCaretContainerEmpty(node)) {\n        DeleteElement.deleteElement(editor, false, Element.fromDom(node), moveCaret);\n      } else {\n        var rng = selection.getRng();\n        var block = dom.getParent(node, dom.isBlock);\n        var textNode = trimZwspFromCaretContainer(node);\n        if (rng.startContainer === textNode && rng.startOffset > 0) {\n          rng.setStart(textNode, rng.startOffset - 1);\n        }\n        if (rng.endContainer === textNode && rng.endOffset > 0) {\n          rng.setEnd(textNode, rng.endOffset - 1);\n        }\n        dom.remove(node, true);\n        if (block && dom.isEmpty(block)) {\n          PaddingBr.fillWithPaddingBr(Element.fromDom(block));\n        }\n        selection.setRng(rng);\n      }\n    };\n    var removeCaretContainer = function (editor, node, moveCaret) {\n      if (moveCaret === void 0) {\n        moveCaret = true;\n      }\n      var dom = editor.dom, selection = editor.selection;\n      if (!node) {\n        node = getParentCaretContainer(editor.getBody(), selection.getStart());\n        if (!node) {\n          while (node = dom.get(CARET_ID$1)) {\n            removeCaretContainerNode(editor, node, false);\n          }\n        }\n      } else {\n        removeCaretContainerNode(editor, node, moveCaret);\n      }\n    };\n    var insertCaretContainerNode = function (editor, caretContainer, formatNode) {\n      var dom = editor.dom, block = dom.getParent(formatNode, curry(FormatUtils.isTextBlock, editor));\n      if (block && dom.isEmpty(block)) {\n        formatNode.parentNode.replaceChild(caretContainer, formatNode);\n      } else {\n        PaddingBr.removeTrailingBr(Element.fromDom(formatNode));\n        if (dom.isEmpty(formatNode)) {\n          formatNode.parentNode.replaceChild(caretContainer, formatNode);\n        } else {\n          dom.insertAfter(caretContainer, formatNode);\n        }\n      }\n    };\n    var appendNode = function (parentNode, node) {\n      parentNode.appendChild(node);\n      return node;\n    };\n    var insertFormatNodesIntoCaretContainer = function (formatNodes, caretContainer) {\n      var innerMostFormatNode = foldr(formatNodes, function (parentNode, formatNode) {\n        return appendNode(parentNode, formatNode.cloneNode(false));\n      }, caretContainer);\n      return appendNode(innerMostFormatNode, innerMostFormatNode.ownerDocument.createTextNode(ZWSP$1));\n    };\n    var applyCaretFormat = function (editor, name, vars) {\n      var rng, caretContainer, textNode, offset, bookmark, container, text;\n      var selection = editor.selection;\n      rng = selection.getRng();\n      offset = rng.startOffset;\n      container = rng.startContainer;\n      text = container.nodeValue;\n      caretContainer = getParentCaretContainer(editor.getBody(), selection.getStart());\n      if (caretContainer) {\n        textNode = findFirstTextNode(caretContainer);\n      }\n      var wordcharRegex = /[^\\s\\u00a0\\u00ad\\u200b\\ufeff]/;\n      if (text && offset > 0 && offset < text.length && wordcharRegex.test(text.charAt(offset)) && wordcharRegex.test(text.charAt(offset - 1))) {\n        bookmark = selection.getBookmark();\n        rng.collapse(true);\n        rng = ExpandRange.expandRng(editor, rng, editor.formatter.get(name));\n        rng = split$1(rng);\n        editor.formatter.apply(name, vars, rng);\n        selection.moveToBookmark(bookmark);\n      } else {\n        if (!caretContainer || textNode.nodeValue !== ZWSP$1) {\n          caretContainer = importNode(editor.getDoc(), createCaretContainer(true).dom());\n          textNode = caretContainer.firstChild;\n          rng.insertNode(caretContainer);\n          offset = 1;\n          editor.formatter.apply(name, vars, caretContainer);\n        } else {\n          editor.formatter.apply(name, vars, caretContainer);\n        }\n        selection.setCursorLocation(textNode, offset);\n      }\n    };\n    var removeCaretFormat = function (editor, name, vars, similar) {\n      var dom = editor.dom, selection = editor.selection;\n      var container, offset, bookmark;\n      var hasContentAfter, node, formatNode;\n      var parents = [], rng = selection.getRng();\n      var caretContainer;\n      container = rng.startContainer;\n      offset = rng.startOffset;\n      node = container;\n      if (container.nodeType === 3) {\n        if (offset !== container.nodeValue.length) {\n          hasContentAfter = true;\n        }\n        node = node.parentNode;\n      }\n      while (node) {\n        if (MatchFormat.matchNode(editor, node, name, vars, similar)) {\n          formatNode = node;\n          break;\n        }\n        if (node.nextSibling) {\n          hasContentAfter = true;\n        }\n        parents.push(node);\n        node = node.parentNode;\n      }\n      if (!formatNode) {\n        return;\n      }\n      if (hasContentAfter) {\n        bookmark = selection.getBookmark();\n        rng.collapse(true);\n        var expandedRng = ExpandRange.expandRng(editor, rng, editor.formatter.get(name), true);\n        expandedRng = split$1(expandedRng);\n        editor.formatter.remove(name, vars, expandedRng);\n        selection.moveToBookmark(bookmark);\n      } else {\n        caretContainer = getParentCaretContainer(editor.getBody(), formatNode);\n        var newCaretContainer = createCaretContainer(false).dom();\n        var caretNode = insertFormatNodesIntoCaretContainer(parents, newCaretContainer);\n        if (caretContainer) {\n          insertCaretContainerNode(editor, newCaretContainer, caretContainer);\n        } else {\n          insertCaretContainerNode(editor, newCaretContainer, formatNode);\n        }\n        removeCaretContainerNode(editor, caretContainer, false);\n        selection.setCursorLocation(caretNode, 1);\n        if (dom.isEmpty(formatNode)) {\n          dom.remove(formatNode);\n        }\n      }\n    };\n    var disableCaretContainer = function (editor, keyCode) {\n      var selection = editor.selection, body = editor.getBody();\n      removeCaretContainer(editor, null, false);\n      if ((keyCode === 8 || keyCode === 46) && selection.isCollapsed() && selection.getStart().innerHTML === ZWSP$1) {\n        removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));\n      }\n      if (keyCode === 37 || keyCode === 39) {\n        removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));\n      }\n    };\n    var setup$5 = function (editor) {\n      editor.on('mouseup keydown', function (e) {\n        disableCaretContainer(editor, e.keyCode);\n      });\n    };\n    var replaceWithCaretFormat = function (targetNode, formatNodes) {\n      var caretContainer = createCaretContainer(false);\n      var innerMost = insertFormatNodesIntoCaretContainer(formatNodes, caretContainer.dom());\n      before(Element.fromDom(targetNode), caretContainer);\n      remove$1(Element.fromDom(targetNode));\n      return CaretPosition$1(innerMost, 0);\n    };\n    var isFormatElement = function (editor, element) {\n      var inlineElements = editor.schema.getTextInlineElements();\n      return inlineElements.hasOwnProperty(name(element)) && !isCaretNode(element.dom()) && !NodeType.isBogus(element.dom());\n    };\n    var isEmptyCaretFormatElement = function (element) {\n      return isCaretNode(element.dom()) && isCaretContainerEmpty(element.dom());\n    };\n\n    var postProcessHooks = {}, filter$3 = ArrUtils.filter, each$9 = ArrUtils.each;\n    var addPostProcessHook = function (name, hook) {\n      var hooks = postProcessHooks[name];\n      if (!hooks) {\n        postProcessHooks[name] = hooks = [];\n      }\n      postProcessHooks[name].push(hook);\n    };\n    var postProcess = function (name, editor) {\n      each$9(postProcessHooks[name], function (hook) {\n        hook(editor);\n      });\n    };\n    addPostProcessHook('pre', function (editor) {\n      var rng = editor.selection.getRng();\n      var isPre, blocks;\n      var hasPreSibling = function (pre) {\n        return isPre(pre.previousSibling) && ArrUtils.indexOf(blocks, pre.previousSibling) !== -1;\n      };\n      var joinPre = function (pre1, pre2) {\n        DomQuery(pre2).remove();\n        DomQuery(pre1).append('<br><br>').append(pre2.childNodes);\n      };\n      isPre = NodeType.matchNodeNames(['pre']);\n      if (!rng.collapsed) {\n        blocks = editor.selection.getSelectedBlocks();\n        each$9(filter$3(filter$3(blocks, isPre), hasPreSibling), function (pre) {\n          joinPre(pre.previousSibling, pre);\n        });\n      }\n    });\n    var Hooks = { postProcess: postProcess };\n\n    var each$a = Tools.each;\n    var ElementUtils = function (dom) {\n      this.compare = function (node1, node2) {\n        if (node1.nodeName !== node2.nodeName) {\n          return false;\n        }\n        var getAttribs = function (node) {\n          var attribs = {};\n          each$a(dom.getAttribs(node), function (attr) {\n            var name = attr.nodeName.toLowerCase();\n            if (name.indexOf('_') !== 0 && name !== 'style' && name.indexOf('data-') !== 0) {\n              attribs[name] = dom.getAttrib(node, name);\n            }\n          });\n          return attribs;\n        };\n        var compareObjects = function (obj1, obj2) {\n          var value, name;\n          for (name in obj1) {\n            if (obj1.hasOwnProperty(name)) {\n              value = obj2[name];\n              if (typeof value === 'undefined') {\n                return false;\n              }\n              if (obj1[name] !== value) {\n                return false;\n              }\n              delete obj2[name];\n            }\n          }\n          for (name in obj2) {\n            if (obj2.hasOwnProperty(name)) {\n              return false;\n            }\n          }\n          return true;\n        };\n        if (!compareObjects(getAttribs(node1), getAttribs(node2))) {\n          return false;\n        }\n        if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {\n          return false;\n        }\n        return !Bookmarks.isBookmarkNode(node1) && !Bookmarks.isBookmarkNode(node2);\n      };\n    };\n\n    var MCE_ATTR_RE = /^(src|href|style)$/;\n    var each$b = Tools.each;\n    var isEq$4 = FormatUtils.isEq;\n    var isTableCell$2 = function (node) {\n      return /^(TH|TD)$/.test(node.nodeName);\n    };\n    var isChildOfInlineParent = function (dom, node, parent) {\n      return dom.isChildOf(node, parent) && node !== parent && !dom.isBlock(parent);\n    };\n    var getContainer = function (ed, rng, start) {\n      var container, offset, lastIdx;\n      container = rng[start ? 'startContainer' : 'endContainer'];\n      offset = rng[start ? 'startOffset' : 'endOffset'];\n      if (NodeType.isElement(container)) {\n        lastIdx = container.childNodes.length - 1;\n        if (!start && offset) {\n          offset--;\n        }\n        container = container.childNodes[offset > lastIdx ? lastIdx : offset];\n      }\n      if (NodeType.isText(container) && start && offset >= container.nodeValue.length) {\n        container = new TreeWalker(container, ed.getBody()).next() || container;\n      }\n      if (NodeType.isText(container) && !start && offset === 0) {\n        container = new TreeWalker(container, ed.getBody()).prev() || container;\n      }\n      return container;\n    };\n    var wrap$2 = function (dom, node, name, attrs) {\n      var wrapper = dom.create(name, attrs);\n      node.parentNode.insertBefore(wrapper, node);\n      wrapper.appendChild(node);\n      return wrapper;\n    };\n    var wrapWithSiblings = function (dom, node, next, name, attrs) {\n      var start = Element.fromDom(node);\n      var wrapper = Element.fromDom(dom.create(name, attrs));\n      var siblings = next ? nextSiblings(start) : prevSiblings(start);\n      append$1(wrapper, siblings);\n      if (next) {\n        before(start, wrapper);\n        prepend(wrapper, start);\n      } else {\n        after(start, wrapper);\n        append(wrapper, start);\n      }\n      return wrapper.dom();\n    };\n    var matchName$1 = function (dom, node, format) {\n      if (isEq$4(node, format.inline)) {\n        return true;\n      }\n      if (isEq$4(node, format.block)) {\n        return true;\n      }\n      if (format.selector) {\n        return NodeType.isElement(node) && dom.is(node, format.selector);\n      }\n    };\n    var isColorFormatAndAnchor = function (node, format) {\n      return format.links && node.tagName === 'A';\n    };\n    var find$3 = function (dom, node, next, inc) {\n      node = FormatUtils.getNonWhiteSpaceSibling(node, next, inc);\n      return !node || (node.nodeName === 'BR' || dom.isBlock(node));\n    };\n    var removeNode$1 = function (ed, node, format) {\n      var parentNode = node.parentNode;\n      var rootBlockElm;\n      var dom = ed.dom, forcedRootBlock = Settings.getForcedRootBlock(ed);\n      if (format.block) {\n        if (!forcedRootBlock) {\n          if (dom.isBlock(node) && !dom.isBlock(parentNode)) {\n            if (!find$3(dom, node, false) && !find$3(dom, node.firstChild, true, 1)) {\n              node.insertBefore(dom.create('br'), node.firstChild);\n            }\n            if (!find$3(dom, node, true) && !find$3(dom, node.lastChild, false, 1)) {\n              node.appendChild(dom.create('br'));\n            }\n          }\n        } else {\n          if (parentNode === dom.getRoot()) {\n            if (!format.list_block || !isEq$4(node, format.list_block)) {\n              each$b(Tools.grep(node.childNodes), function (node) {\n                if (FormatUtils.isValid(ed, forcedRootBlock, node.nodeName.toLowerCase())) {\n                  if (!rootBlockElm) {\n                    rootBlockElm = wrap$2(dom, node, forcedRootBlock);\n                    dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs);\n                  } else {\n                    rootBlockElm.appendChild(node);\n                  }\n                } else {\n                  rootBlockElm = 0;\n                }\n              });\n            }\n          }\n        }\n      }\n      if (format.selector && format.inline && !isEq$4(format.inline, node)) {\n        return;\n      }\n      dom.remove(node, 1);\n    };\n    var removeFormat = function (ed, format, vars, node, compareNode) {\n      var i, attrs, stylesModified;\n      var dom = ed.dom;\n      if (!matchName$1(dom, node, format) && !isColorFormatAndAnchor(node, format)) {\n        return false;\n      }\n      if (format.remove !== 'all') {\n        each$b(format.styles, function (value, name) {\n          value = FormatUtils.normalizeStyleValue(dom, FormatUtils.replaceVars(value, vars), name);\n          if (typeof name === 'number') {\n            name = value;\n            compareNode = 0;\n          }\n          if (format.remove_similar || (!compareNode || isEq$4(FormatUtils.getStyle(dom, compareNode, name), value))) {\n            dom.setStyle(node, name, '');\n          }\n          stylesModified = 1;\n        });\n        if (stylesModified && dom.getAttrib(node, 'style') === '') {\n          node.removeAttribute('style');\n          node.removeAttribute('data-mce-style');\n        }\n        each$b(format.attributes, function (value, name) {\n          var valueOut;\n          value = FormatUtils.replaceVars(value, vars);\n          if (typeof name === 'number') {\n            name = value;\n            compareNode = 0;\n          }\n          if (format.remove_similar || (!compareNode || isEq$4(dom.getAttrib(compareNode, name), value))) {\n            if (name === 'class') {\n              value = dom.getAttrib(node, name);\n              if (value) {\n                valueOut = '';\n                each$b(value.split(/\\s+/), function (cls) {\n                  if (/mce\\-\\w+/.test(cls)) {\n                    valueOut += (valueOut ? ' ' : '') + cls;\n                  }\n                });\n                if (valueOut) {\n                  dom.setAttrib(node, name, valueOut);\n                  return;\n                }\n              }\n            }\n            if (name === 'class') {\n              node.removeAttribute('className');\n            }\n            if (MCE_ATTR_RE.test(name)) {\n              node.removeAttribute('data-mce-' + name);\n            }\n            node.removeAttribute(name);\n          }\n        });\n        each$b(format.classes, function (value) {\n          value = FormatUtils.replaceVars(value, vars);\n          if (!compareNode || dom.hasClass(compareNode, value)) {\n            dom.removeClass(node, value);\n          }\n        });\n        attrs = dom.getAttribs(node);\n        for (i = 0; i < attrs.length; i++) {\n          var attrName = attrs[i].nodeName;\n          if (attrName.indexOf('_') !== 0 && attrName.indexOf('data-') !== 0) {\n            return false;\n          }\n        }\n      }\n      if (format.remove !== 'none') {\n        removeNode$1(ed, node, format);\n        return true;\n      }\n    };\n    var findFormatRoot = function (editor, container, name, vars, similar) {\n      var formatRoot;\n      each$b(FormatUtils.getParents(editor.dom, container.parentNode).reverse(), function (parent) {\n        var format;\n        if (!formatRoot && parent.id !== '_start' && parent.id !== '_end') {\n          format = MatchFormat.matchNode(editor, parent, name, vars, similar);\n          if (format && format.split !== false) {\n            formatRoot = parent;\n          }\n        }\n      });\n      return formatRoot;\n    };\n    var wrapAndSplit = function (editor, formatList, formatRoot, container, target, split, format, vars) {\n      var parent, clone, lastClone, firstClone, i, formatRootParent;\n      var dom = editor.dom;\n      if (formatRoot) {\n        formatRootParent = formatRoot.parentNode;\n        for (parent = container.parentNode; parent && parent !== formatRootParent; parent = parent.parentNode) {\n          clone = dom.clone(parent, false);\n          for (i = 0; i < formatList.length; i++) {\n            if (removeFormat(editor, formatList[i], vars, clone, clone)) {\n              clone = 0;\n              break;\n            }\n          }\n          if (clone) {\n            if (lastClone) {\n              clone.appendChild(lastClone);\n            }\n            if (!firstClone) {\n              firstClone = clone;\n            }\n            lastClone = clone;\n          }\n        }\n        if (split && (!format.mixed || !dom.isBlock(formatRoot))) {\n          container = dom.split(formatRoot, container);\n        }\n        if (lastClone) {\n          target.parentNode.insertBefore(lastClone, target);\n          firstClone.appendChild(target);\n        }\n      }\n      return container;\n    };\n    var remove$7 = function (ed, name, vars, node, similar) {\n      var formatList = ed.formatter.get(name), format = formatList[0];\n      var bookmark, rng, contentEditable = true;\n      var dom = ed.dom;\n      var selection = ed.selection;\n      var splitToFormatRoot = function (container) {\n        var formatRoot = findFormatRoot(ed, container, name, vars, similar);\n        return wrapAndSplit(ed, formatList, formatRoot, container, container, true, format, vars);\n      };\n      var isRemoveBookmarkNode = function (node) {\n        return Bookmarks.isBookmarkNode(node) && NodeType.isElement(node) && (node.id === '_start' || node.id === '_end');\n      };\n      var process = function (node) {\n        var children, i, l, lastContentEditable, hasContentEditableState;\n        if (NodeType.isElement(node) && dom.getContentEditable(node)) {\n          lastContentEditable = contentEditable;\n          contentEditable = dom.getContentEditable(node) === 'true';\n          hasContentEditableState = true;\n        }\n        children = Tools.grep(node.childNodes);\n        if (contentEditable && !hasContentEditableState) {\n          for (i = 0, l = formatList.length; i < l; i++) {\n            if (removeFormat(ed, formatList[i], vars, node, node)) {\n              break;\n            }\n          }\n        }\n        if (format.deep) {\n          if (children.length) {\n            for (i = 0, l = children.length; i < l; i++) {\n              process(children[i]);\n            }\n            if (hasContentEditableState) {\n              contentEditable = lastContentEditable;\n            }\n          }\n        }\n      };\n      var unwrap = function (start) {\n        var node = dom.get(start ? '_start' : '_end');\n        var out = node[start ? 'firstChild' : 'lastChild'];\n        if (isRemoveBookmarkNode(out)) {\n          out = out[start ? 'firstChild' : 'lastChild'];\n        }\n        if (NodeType.isText(out) && out.data.length === 0) {\n          out = start ? node.previousSibling || node.nextSibling : node.nextSibling || node.previousSibling;\n        }\n        dom.remove(node, true);\n        return out;\n      };\n      var removeRngStyle = function (rng) {\n        var startContainer, endContainer;\n        var commonAncestorContainer = rng.commonAncestorContainer;\n        rng = ExpandRange.expandRng(ed, rng, formatList, true);\n        if (format.split) {\n          rng = split$1(rng);\n          startContainer = getContainer(ed, rng, true);\n          endContainer = getContainer(ed, rng);\n          if (startContainer !== endContainer) {\n            if (/^(TR|TH|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {\n              if (startContainer.nodeName === 'TR') {\n                startContainer = startContainer.firstChild.firstChild || startContainer;\n              } else {\n                startContainer = startContainer.firstChild || startContainer;\n              }\n            }\n            if (commonAncestorContainer && /^T(HEAD|BODY|FOOT|R)$/.test(commonAncestorContainer.nodeName) && isTableCell$2(endContainer) && endContainer.firstChild) {\n              endContainer = endContainer.firstChild || endContainer;\n            }\n            if (isChildOfInlineParent(dom, startContainer, endContainer)) {\n              var marker = Option.from(startContainer.firstChild).getOr(startContainer);\n              splitToFormatRoot(wrapWithSiblings(dom, marker, true, 'span', {\n                'id': '_start',\n                'data-mce-type': 'bookmark'\n              }));\n              unwrap(true);\n              return;\n            }\n            if (isChildOfInlineParent(dom, endContainer, startContainer)) {\n              var marker = Option.from(endContainer.lastChild).getOr(endContainer);\n              splitToFormatRoot(wrapWithSiblings(dom, marker, false, 'span', {\n                'id': '_end',\n                'data-mce-type': 'bookmark'\n              }));\n              unwrap(false);\n              return;\n            }\n            startContainer = wrap$2(dom, startContainer, 'span', {\n              'id': '_start',\n              'data-mce-type': 'bookmark'\n            });\n            endContainer = wrap$2(dom, endContainer, 'span', {\n              'id': '_end',\n              'data-mce-type': 'bookmark'\n            });\n            splitToFormatRoot(startContainer);\n            splitToFormatRoot(endContainer);\n            startContainer = unwrap(true);\n            endContainer = unwrap();\n          } else {\n            startContainer = endContainer = splitToFormatRoot(startContainer);\n          }\n          rng.startContainer = startContainer.parentNode ? startContainer.parentNode : startContainer;\n          rng.startOffset = dom.nodeIndex(startContainer);\n          rng.endContainer = endContainer.parentNode ? endContainer.parentNode : endContainer;\n          rng.endOffset = dom.nodeIndex(endContainer) + 1;\n        }\n        RangeWalk.walk(dom, rng, function (nodes) {\n          each$b(nodes, function (node) {\n            process(node);\n            if (NodeType.isElement(node) && ed.dom.getStyle(node, 'text-decoration') === 'underline' && node.parentNode && FormatUtils.getTextDecoration(dom, node.parentNode) === 'underline') {\n              removeFormat(ed, {\n                deep: false,\n                exact: true,\n                inline: 'span',\n                styles: { textDecoration: 'underline' }\n              }, null, node);\n            }\n          });\n        });\n      };\n      if (node) {\n        if (node.nodeType) {\n          rng = dom.createRng();\n          rng.setStartBefore(node);\n          rng.setEndAfter(node);\n          removeRngStyle(rng);\n        } else {\n          removeRngStyle(node);\n        }\n        return;\n      }\n      if (dom.getContentEditable(selection.getNode()) === 'false') {\n        node = selection.getNode();\n        for (var i = 0, l = formatList.length; i < l; i++) {\n          if (formatList[i].ceFalseOverride) {\n            if (removeFormat(ed, formatList[i], vars, node, node)) {\n              break;\n            }\n          }\n        }\n        return;\n      }\n      if (!selection.isCollapsed() || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) {\n        bookmark = GetBookmark.getPersistentBookmark(ed.selection, true);\n        removeRngStyle(selection.getRng());\n        selection.moveToBookmark(bookmark);\n        if (format.inline && MatchFormat.match(ed, name, vars, selection.getStart())) {\n          FormatUtils.moveStart(dom, selection, selection.getRng());\n        }\n        ed.nodeChanged();\n      } else {\n        removeCaretFormat(ed, name, vars, similar);\n      }\n    };\n    var RemoveFormat = {\n      removeFormat: removeFormat,\n      remove: remove$7\n    };\n\n    var each$c = Tools.each;\n    var isElementNode = function (node) {\n      return node && node.nodeType === 1 && !Bookmarks.isBookmarkNode(node) && !isCaretNode(node) && !NodeType.isBogus(node);\n    };\n    var findElementSibling = function (node, siblingName) {\n      var sibling;\n      for (sibling = node; sibling; sibling = sibling[siblingName]) {\n        if (sibling.nodeType === 3 && sibling.nodeValue.length !== 0) {\n          return node;\n        }\n        if (sibling.nodeType === 1 && !Bookmarks.isBookmarkNode(sibling)) {\n          return sibling;\n        }\n      }\n      return node;\n    };\n    var mergeSiblingsNodes = function (dom, prev, next) {\n      var sibling, tmpSibling;\n      var elementUtils = new ElementUtils(dom);\n      if (prev && next) {\n        prev = findElementSibling(prev, 'previousSibling');\n        next = findElementSibling(next, 'nextSibling');\n        if (elementUtils.compare(prev, next)) {\n          for (sibling = prev.nextSibling; sibling && sibling !== next;) {\n            tmpSibling = sibling;\n            sibling = sibling.nextSibling;\n            prev.appendChild(tmpSibling);\n          }\n          dom.remove(next);\n          Tools.each(Tools.grep(next.childNodes), function (node) {\n            prev.appendChild(node);\n          });\n          return prev;\n        }\n      }\n      return next;\n    };\n    var processChildElements = function (node, filter, process) {\n      each$c(node.childNodes, function (node) {\n        if (isElementNode(node)) {\n          if (filter(node)) {\n            process(node);\n          }\n          if (node.hasChildNodes()) {\n            processChildElements(node, filter, process);\n          }\n        }\n      });\n    };\n    var hasStyle = function (dom, name) {\n      return curry(function (name, node) {\n        return !!(node && FormatUtils.getStyle(dom, node, name));\n      }, name);\n    };\n    var applyStyle = function (dom, name, value) {\n      return curry(function (name, value, node) {\n        dom.setStyle(node, name, value);\n        if (node.getAttribute('style') === '') {\n          node.removeAttribute('style');\n        }\n        unwrapEmptySpan(dom, node);\n      }, name, value);\n    };\n    var unwrapEmptySpan = function (dom, node) {\n      if (node.nodeName === 'SPAN' && dom.getAttribs(node).length === 0) {\n        dom.remove(node, true);\n      }\n    };\n    var processUnderlineAndColor = function (dom, node) {\n      var textDecoration;\n      if (node.nodeType === 1 && node.parentNode && node.parentNode.nodeType === 1) {\n        textDecoration = FormatUtils.getTextDecoration(dom, node.parentNode);\n        if (dom.getStyle(node, 'color') && textDecoration) {\n          dom.setStyle(node, 'text-decoration', textDecoration);\n        } else if (dom.getStyle(node, 'text-decoration') === textDecoration) {\n          dom.setStyle(node, 'text-decoration', null);\n        }\n      }\n    };\n    var mergeUnderlineAndColor = function (dom, format, vars, node) {\n      if (format.styles.color || format.styles.textDecoration) {\n        Tools.walk(node, curry(processUnderlineAndColor, dom), 'childNodes');\n        processUnderlineAndColor(dom, node);\n      }\n    };\n    var mergeBackgroundColorAndFontSize = function (dom, format, vars, node) {\n      if (format.styles && format.styles.backgroundColor) {\n        processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'backgroundColor', FormatUtils.replaceVars(format.styles.backgroundColor, vars)));\n      }\n    };\n    var mergeSubSup = function (dom, format, vars, node) {\n      if (format.inline === 'sub' || format.inline === 'sup') {\n        processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'fontSize', ''));\n        dom.remove(dom.select(format.inline === 'sup' ? 'sub' : 'sup', node), true);\n      }\n    };\n    var mergeSiblings = function (dom, format, vars, node) {\n      if (node && format.merge_siblings !== false) {\n        node = mergeSiblingsNodes(dom, FormatUtils.getNonWhiteSpaceSibling(node), node);\n        node = mergeSiblingsNodes(dom, node, FormatUtils.getNonWhiteSpaceSibling(node, true));\n      }\n    };\n    var clearChildStyles = function (dom, format, node) {\n      if (format.clear_child_styles) {\n        var selector = format.links ? '*:not(a)' : '*';\n        each$c(dom.select(selector, node), function (node) {\n          if (isElementNode(node)) {\n            each$c(format.styles, function (value, name) {\n              dom.setStyle(node, name, '');\n            });\n          }\n        });\n      }\n    };\n    var mergeWithChildren = function (editor, formatList, vars, node) {\n      each$c(formatList, function (format) {\n        each$c(editor.dom.select(format.inline, node), function (child) {\n          if (!isElementNode(child)) {\n            return;\n          }\n          RemoveFormat.removeFormat(editor, format, vars, child, format.exact ? child : null);\n        });\n        clearChildStyles(editor.dom, format, node);\n      });\n    };\n    var mergeWithParents = function (editor, format, name, vars, node) {\n      if (MatchFormat.matchNode(editor, node.parentNode, name, vars)) {\n        if (RemoveFormat.removeFormat(editor, format, vars, node)) {\n          return;\n        }\n      }\n      if (format.merge_with_parents) {\n        editor.dom.getParent(node.parentNode, function (parent) {\n          if (MatchFormat.matchNode(editor, parent, name, vars)) {\n            RemoveFormat.removeFormat(editor, format, vars, node);\n            return true;\n          }\n        });\n      }\n    };\n    var MergeFormats = {\n      mergeWithChildren: mergeWithChildren,\n      mergeUnderlineAndColor: mergeUnderlineAndColor,\n      mergeBackgroundColorAndFontSize: mergeBackgroundColorAndFontSize,\n      mergeSubSup: mergeSubSup,\n      mergeSiblings: mergeSiblings,\n      mergeWithParents: mergeWithParents\n    };\n\n    var createRange$1 = function (sc, so, ec, eo) {\n      var rng = domGlobals.document.createRange();\n      rng.setStart(sc, so);\n      rng.setEnd(ec, eo);\n      return rng;\n    };\n    var normalizeBlockSelectionRange = function (rng) {\n      var startPos = CaretPosition$1.fromRangeStart(rng);\n      var endPos = CaretPosition$1.fromRangeEnd(rng);\n      var rootNode = rng.commonAncestorContainer;\n      return CaretFinder.fromPosition(false, rootNode, endPos).map(function (newEndPos) {\n        if (!isInSameBlock(startPos, endPos, rootNode) && isInSameBlock(startPos, newEndPos, rootNode)) {\n          return createRange$1(startPos.container(), startPos.offset(), newEndPos.container(), newEndPos.offset());\n        } else {\n          return rng;\n        }\n      }).getOr(rng);\n    };\n    var normalize$1 = function (rng) {\n      return rng.collapsed ? rng : normalizeBlockSelectionRange(rng);\n    };\n    var RangeNormalizer = { normalize: normalize$1 };\n\n    var each$d = Tools.each;\n    var isElementNode$1 = function (node) {\n      return node && node.nodeType === 1 && !Bookmarks.isBookmarkNode(node) && !isCaretNode(node) && !NodeType.isBogus(node);\n    };\n    var applyFormat = function (ed, name, vars, node) {\n      var formatList = ed.formatter.get(name);\n      var format = formatList[0];\n      var bookmark, rng;\n      var isCollapsed = !node && ed.selection.isCollapsed();\n      var dom = ed.dom, selection = ed.selection;\n      var setElementFormat = function (elm, fmt) {\n        fmt = fmt || format;\n        if (elm) {\n          if (fmt.onformat) {\n            fmt.onformat(elm, fmt, vars, node);\n          }\n          each$d(fmt.styles, function (value, name) {\n            dom.setStyle(elm, name, FormatUtils.replaceVars(value, vars));\n          });\n          if (fmt.styles) {\n            var styleVal = dom.getAttrib(elm, 'style');\n            if (styleVal) {\n              elm.setAttribute('data-mce-style', styleVal);\n            }\n          }\n          each$d(fmt.attributes, function (value, name) {\n            dom.setAttrib(elm, name, FormatUtils.replaceVars(value, vars));\n          });\n          each$d(fmt.classes, function (value) {\n            value = FormatUtils.replaceVars(value, vars);\n            if (!dom.hasClass(elm, value)) {\n              dom.addClass(elm, value);\n            }\n          });\n        }\n      };\n      var applyNodeStyle = function (formatList, node) {\n        var found = false;\n        if (!format.selector) {\n          return false;\n        }\n        each$d(formatList, function (format) {\n          if ('collapsed' in format && format.collapsed !== isCollapsed) {\n            return;\n          }\n          if (dom.is(node, format.selector) && !isCaretNode(node)) {\n            setElementFormat(node, format);\n            found = true;\n            return false;\n          }\n        });\n        return found;\n      };\n      var applyRngStyle = function (dom, rng, bookmark, nodeSpecific) {\n        var newWrappers = [];\n        var wrapName, wrapElm, contentEditable = true;\n        wrapName = format.inline || format.block;\n        wrapElm = dom.create(wrapName);\n        setElementFormat(wrapElm);\n        RangeWalk.walk(dom, rng, function (nodes) {\n          var currentWrapElm;\n          var process = function (node) {\n            var nodeName, parentName, hasContentEditableState, lastContentEditable;\n            lastContentEditable = contentEditable;\n            nodeName = node.nodeName.toLowerCase();\n            parentName = node.parentNode.nodeName.toLowerCase();\n            if (node.nodeType === 1 && dom.getContentEditable(node)) {\n              lastContentEditable = contentEditable;\n              contentEditable = dom.getContentEditable(node) === 'true';\n              hasContentEditableState = true;\n            }\n            if (FormatUtils.isEq(nodeName, 'br')) {\n              currentWrapElm = 0;\n              if (format.block) {\n                dom.remove(node);\n              }\n              return;\n            }\n            if (format.wrapper && MatchFormat.matchNode(ed, node, name, vars)) {\n              currentWrapElm = 0;\n              return;\n            }\n            if (contentEditable && !hasContentEditableState && format.block && !format.wrapper && FormatUtils.isTextBlock(ed, nodeName) && FormatUtils.isValid(ed, parentName, wrapName)) {\n              node = dom.rename(node, wrapName);\n              setElementFormat(node);\n              newWrappers.push(node);\n              currentWrapElm = 0;\n              return;\n            }\n            if (format.selector) {\n              var found = applyNodeStyle(formatList, node);\n              if (!format.inline || found) {\n                currentWrapElm = 0;\n                return;\n              }\n            }\n            if (contentEditable && !hasContentEditableState && FormatUtils.isValid(ed, wrapName, nodeName) && FormatUtils.isValid(ed, parentName, wrapName) && !(!nodeSpecific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && !isCaretNode(node) && (!format.inline || !dom.isBlock(node))) {\n              if (!currentWrapElm) {\n                currentWrapElm = dom.clone(wrapElm, false);\n                node.parentNode.insertBefore(currentWrapElm, node);\n                newWrappers.push(currentWrapElm);\n              }\n              currentWrapElm.appendChild(node);\n            } else {\n              currentWrapElm = 0;\n              each$d(Tools.grep(node.childNodes), process);\n              if (hasContentEditableState) {\n                contentEditable = lastContentEditable;\n              }\n              currentWrapElm = 0;\n            }\n          };\n          each$d(nodes, process);\n        });\n        if (format.links === true) {\n          each$d(newWrappers, function (node) {\n            var process = function (node) {\n              if (node.nodeName === 'A') {\n                setElementFormat(node, format);\n              }\n              each$d(Tools.grep(node.childNodes), process);\n            };\n            process(node);\n          });\n        }\n        each$d(newWrappers, function (node) {\n          var childCount;\n          var getChildCount = function (node) {\n            var count = 0;\n            each$d(node.childNodes, function (node) {\n              if (!FormatUtils.isWhiteSpaceNode(node) && !Bookmarks.isBookmarkNode(node)) {\n                count++;\n              }\n            });\n            return count;\n          };\n          var getChildElementNode = function (root) {\n            var child = false;\n            each$d(root.childNodes, function (node) {\n              if (isElementNode$1(node)) {\n                child = node;\n                return false;\n              }\n            });\n            return child;\n          };\n          var mergeStyles = function (node) {\n            var child, clone;\n            child = getChildElementNode(node);\n            if (child && !Bookmarks.isBookmarkNode(child) && MatchFormat.matchName(dom, child, format)) {\n              clone = dom.clone(child, false);\n              setElementFormat(clone);\n              dom.replace(clone, node, true);\n              dom.remove(child, 1);\n            }\n            return clone || node;\n          };\n          childCount = getChildCount(node);\n          if ((newWrappers.length > 1 || !dom.isBlock(node)) && childCount === 0) {\n            dom.remove(node, 1);\n            return;\n          }\n          if (format.inline || format.wrapper) {\n            if (!format.exact && childCount === 1) {\n              node = mergeStyles(node);\n            }\n            MergeFormats.mergeWithChildren(ed, formatList, vars, node);\n            MergeFormats.mergeWithParents(ed, format, name, vars, node);\n            MergeFormats.mergeBackgroundColorAndFontSize(dom, format, vars, node);\n            MergeFormats.mergeSubSup(dom, format, vars, node);\n            MergeFormats.mergeSiblings(dom, format, vars, node);\n          }\n        });\n      };\n      if (dom.getContentEditable(selection.getNode()) === 'false') {\n        node = selection.getNode();\n        for (var i = 0, l = formatList.length; i < l; i++) {\n          if (formatList[i].ceFalseOverride && dom.is(node, formatList[i].selector)) {\n            setElementFormat(node, formatList[i]);\n            return;\n          }\n        }\n        return;\n      }\n      if (format) {\n        if (node) {\n          if (node.nodeType) {\n            if (!applyNodeStyle(formatList, node)) {\n              rng = dom.createRng();\n              rng.setStartBefore(node);\n              rng.setEndAfter(node);\n              applyRngStyle(dom, ExpandRange.expandRng(ed, rng, formatList), null, true);\n            }\n          } else {\n            applyRngStyle(dom, node, null, true);\n          }\n        } else {\n          if (!isCollapsed || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) {\n            var curSelNode = ed.selection.getNode();\n            if (!ed.settings.forced_root_block && formatList[0].defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) {\n              applyFormat(ed, formatList[0].defaultBlock);\n            }\n            ed.selection.setRng(RangeNormalizer.normalize(ed.selection.getRng()));\n            bookmark = GetBookmark.getPersistentBookmark(ed.selection, true);\n            applyRngStyle(dom, ExpandRange.expandRng(ed, selection.getRng(), formatList));\n            if (format.styles) {\n              MergeFormats.mergeUnderlineAndColor(dom, format, vars, curSelNode);\n            }\n            selection.moveToBookmark(bookmark);\n            FormatUtils.moveStart(dom, selection, selection.getRng());\n            ed.nodeChanged();\n          } else {\n            applyCaretFormat(ed, name, vars);\n          }\n        }\n        Hooks.postProcess(name, ed);\n      }\n    };\n    var ApplyFormat = { applyFormat: applyFormat };\n\n    var setup$6 = function (registeredFormatListeners, editor) {\n      var currentFormats = Cell({});\n      registeredFormatListeners.set({});\n      editor.on('NodeChange', function (e) {\n        updateAndFireChangeCallbacks(editor, e.element, currentFormats, registeredFormatListeners.get());\n      });\n    };\n    var updateAndFireChangeCallbacks = function (editor, elm, currentFormats, formatChangeData) {\n      var formatsList = keys(currentFormats.get());\n      var newFormats = {};\n      var matchedFormats = {};\n      var parents = filter(FormatUtils.getParents(editor.dom, elm), function (node) {\n        return node.nodeType === 1 && !node.getAttribute('data-mce-bogus');\n      });\n      each$1(formatChangeData, function (data, format) {\n        Tools.each(parents, function (node) {\n          if (editor.formatter.matchNode(node, format, {}, data.similar)) {\n            if (formatsList.indexOf(format) === -1) {\n              each(data.callbacks, function (callback) {\n                callback(true, {\n                  node: node,\n                  format: format,\n                  parents: parents\n                });\n              });\n              newFormats[format] = data.callbacks;\n            }\n            matchedFormats[format] = data.callbacks;\n            return false;\n          }\n          if (MatchFormat.matchesUnInheritedFormatSelector(editor, node, format)) {\n            return false;\n          }\n        });\n      });\n      var remainingFormats = filterRemainingFormats(currentFormats.get(), matchedFormats, elm, parents);\n      currentFormats.set(__assign(__assign({}, newFormats), remainingFormats));\n    };\n    var filterRemainingFormats = function (currentFormats, matchedFormats, elm, parents) {\n      return bifilter(currentFormats, function (callbacks, format) {\n        if (!has(matchedFormats, format)) {\n          each(callbacks, function (callback) {\n            callback(false, {\n              node: elm,\n              format: format,\n              parents: parents\n            });\n          });\n          return false;\n        } else {\n          return true;\n        }\n      }).t;\n    };\n    var addListeners = function (registeredFormatListeners, formats, callback, similar) {\n      var formatChangeItems = registeredFormatListeners.get();\n      each(formats.split(','), function (format) {\n        if (!formatChangeItems[format]) {\n          formatChangeItems[format] = {\n            similar: similar,\n            callbacks: []\n          };\n        }\n        formatChangeItems[format].callbacks.push(callback);\n      });\n      registeredFormatListeners.set(formatChangeItems);\n    };\n    var removeListeners = function (registeredFormatListeners, formats, callback) {\n      var formatChangeItems = registeredFormatListeners.get();\n      each(formats.split(','), function (format) {\n        formatChangeItems[format].callbacks = filter(formatChangeItems[format].callbacks, function (c) {\n          return c !== callback;\n        });\n        if (formatChangeItems[format].callbacks.length === 0) {\n          delete formatChangeItems[format];\n        }\n      });\n      registeredFormatListeners.set(formatChangeItems);\n    };\n    var formatChanged = function (editor, registeredFormatListeners, formats, callback, similar) {\n      if (registeredFormatListeners.get() === null) {\n        setup$6(registeredFormatListeners, editor);\n      }\n      addListeners(registeredFormatListeners, formats, callback, similar);\n      return {\n        unbind: function () {\n          return removeListeners(registeredFormatListeners, formats, callback);\n        }\n      };\n    };\n\n    var get$7 = function (dom) {\n      var formats = {\n        valigntop: [{\n            selector: 'td,th',\n            styles: { verticalAlign: 'top' }\n          }],\n        valignmiddle: [{\n            selector: 'td,th',\n            styles: { verticalAlign: 'middle' }\n          }],\n        valignbottom: [{\n            selector: 'td,th',\n            styles: { verticalAlign: 'bottom' }\n          }],\n        alignleft: [\n          {\n            selector: 'figure.image',\n            collapsed: false,\n            classes: 'align-left',\n            ceFalseOverride: true,\n            preview: 'font-family font-size'\n          },\n          {\n            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',\n            styles: { textAlign: 'left' },\n            inherit: false,\n            preview: false,\n            defaultBlock: 'div'\n          },\n          {\n            selector: 'img,table',\n            collapsed: false,\n            styles: { float: 'left' },\n            preview: 'font-family font-size'\n          }\n        ],\n        aligncenter: [\n          {\n            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',\n            styles: { textAlign: 'center' },\n            inherit: false,\n            preview: 'font-family font-size',\n            defaultBlock: 'div'\n          },\n          {\n            selector: 'figure.image',\n            collapsed: false,\n            classes: 'align-center',\n            ceFalseOverride: true,\n            preview: 'font-family font-size'\n          },\n          {\n            selector: 'img',\n            collapsed: false,\n            styles: {\n              display: 'block',\n              marginLeft: 'auto',\n              marginRight: 'auto'\n            },\n            preview: false\n          },\n          {\n            selector: 'table',\n            collapsed: false,\n            styles: {\n              marginLeft: 'auto',\n              marginRight: 'auto'\n            },\n            preview: 'font-family font-size'\n          }\n        ],\n        alignright: [\n          {\n            selector: 'figure.image',\n            collapsed: false,\n            classes: 'align-right',\n            ceFalseOverride: true,\n            preview: 'font-family font-size'\n          },\n          {\n            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',\n            styles: { textAlign: 'right' },\n            inherit: false,\n            preview: 'font-family font-size',\n            defaultBlock: 'div'\n          },\n          {\n            selector: 'img,table',\n            collapsed: false,\n            styles: { float: 'right' },\n            preview: 'font-family font-size'\n          }\n        ],\n        alignjustify: [{\n            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',\n            styles: { textAlign: 'justify' },\n            inherit: false,\n            defaultBlock: 'div',\n            preview: 'font-family font-size'\n          }],\n        bold: [\n          {\n            inline: 'strong',\n            remove: 'all'\n          },\n          {\n            inline: 'span',\n            styles: { fontWeight: 'bold' }\n          },\n          {\n            inline: 'b',\n            remove: 'all'\n          }\n        ],\n        italic: [\n          {\n            inline: 'em',\n            remove: 'all'\n          },\n          {\n            inline: 'span',\n            styles: { fontStyle: 'italic' }\n          },\n          {\n            inline: 'i',\n            remove: 'all'\n          }\n        ],\n        underline: [\n          {\n            inline: 'span',\n            styles: { textDecoration: 'underline' },\n            exact: true\n          },\n          {\n            inline: 'u',\n            remove: 'all'\n          }\n        ],\n        strikethrough: [\n          {\n            inline: 'span',\n            styles: { textDecoration: 'line-through' },\n            exact: true\n          },\n          {\n            inline: 'strike',\n            remove: 'all'\n          }\n        ],\n        forecolor: {\n          inline: 'span',\n          styles: { color: '%value' },\n          links: true,\n          remove_similar: true,\n          clear_child_styles: true\n        },\n        hilitecolor: {\n          inline: 'span',\n          styles: { backgroundColor: '%value' },\n          links: true,\n          remove_similar: true,\n          clear_child_styles: true\n        },\n        fontname: {\n          inline: 'span',\n          toggle: false,\n          styles: { fontFamily: '%value' },\n          clear_child_styles: true\n        },\n        fontsize: {\n          inline: 'span',\n          toggle: false,\n          styles: { fontSize: '%value' },\n          clear_child_styles: true\n        },\n        fontsize_class: {\n          inline: 'span',\n          attributes: { class: '%value' }\n        },\n        blockquote: {\n          block: 'blockquote',\n          wrapper: true,\n          remove: 'all'\n        },\n        subscript: { inline: 'sub' },\n        superscript: { inline: 'sup' },\n        code: { inline: 'code' },\n        link: {\n          inline: 'a',\n          selector: 'a',\n          remove: 'all',\n          split: true,\n          deep: true,\n          onmatch: function () {\n            return true;\n          },\n          onformat: function (elm, fmt, vars) {\n            Tools.each(vars, function (value, key) {\n              dom.setAttrib(elm, key, value);\n            });\n          }\n        },\n        removeformat: [\n          {\n            selector: 'b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins',\n            remove: 'all',\n            split: true,\n            expand: false,\n            block_expand: true,\n            deep: true\n          },\n          {\n            selector: 'span',\n            attributes: [\n              'style',\n              'class'\n            ],\n            remove: 'empty',\n            split: true,\n            expand: false,\n            deep: true\n          },\n          {\n            selector: '*',\n            attributes: [\n              'style',\n              'class'\n            ],\n            split: false,\n            expand: false,\n            deep: true\n          }\n        ]\n      };\n      Tools.each('p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp'.split(/\\s/), function (name) {\n        formats[name] = {\n          block: name,\n          remove: 'all'\n        };\n      });\n      return formats;\n    };\n    var DefaultFormats = { get: get$7 };\n\n    function FormatRegistry(editor) {\n      var formats = {};\n      var get = function (name) {\n        return name ? formats[name] : formats;\n      };\n      var has$1 = function (name) {\n        return has(formats, name);\n      };\n      var register = function (name, format) {\n        if (name) {\n          if (typeof name !== 'string') {\n            Tools.each(name, function (format, name) {\n              register(name, format);\n            });\n          } else {\n            if (!isArray(format)) {\n              format = [format];\n            }\n            Tools.each(format, function (format) {\n              if (typeof format.deep === 'undefined') {\n                format.deep = !format.selector;\n              }\n              if (typeof format.split === 'undefined') {\n                format.split = !format.selector || format.inline;\n              }\n              if (typeof format.remove === 'undefined' && format.selector && !format.inline) {\n                format.remove = 'none';\n              }\n              if (format.selector && format.inline) {\n                format.mixed = true;\n                format.block_expand = true;\n              }\n              if (typeof format.classes === 'string') {\n                format.classes = format.classes.split(/\\s+/);\n              }\n            });\n            formats[name] = format;\n          }\n        }\n      };\n      var unregister = function (name) {\n        if (name && formats[name]) {\n          delete formats[name];\n        }\n        return formats;\n      };\n      register(DefaultFormats.get(editor.dom));\n      register(editor.settings.formats);\n      return {\n        get: get,\n        has: has$1,\n        register: register,\n        unregister: unregister\n      };\n    }\n\n    var each$e = Tools.each;\n    var dom = DOMUtils$1.DOM;\n    var parsedSelectorToHtml = function (ancestry, editor) {\n      var elm, item, fragment;\n      var schema = editor && editor.schema || Schema({});\n      var decorate = function (elm, item) {\n        if (item.classes.length) {\n          dom.addClass(elm, item.classes.join(' '));\n        }\n        dom.setAttribs(elm, item.attrs);\n      };\n      var createElement = function (sItem) {\n        var elm;\n        item = typeof sItem === 'string' ? {\n          name: sItem,\n          classes: [],\n          attrs: {}\n        } : sItem;\n        elm = dom.create(item.name);\n        decorate(elm, item);\n        return elm;\n      };\n      var getRequiredParent = function (elm, candidate) {\n        var name = typeof elm !== 'string' ? elm.nodeName.toLowerCase() : elm;\n        var elmRule = schema.getElementRule(name);\n        var parentsRequired = elmRule && elmRule.parentsRequired;\n        if (parentsRequired && parentsRequired.length) {\n          return candidate && Tools.inArray(parentsRequired, candidate) !== -1 ? candidate : parentsRequired[0];\n        } else {\n          return false;\n        }\n      };\n      var wrapInHtml = function (elm, ancestry, siblings) {\n        var parent, parentCandidate, parentRequired;\n        var ancestor = ancestry.length > 0 && ancestry[0];\n        var ancestorName = ancestor && ancestor.name;\n        parentRequired = getRequiredParent(elm, ancestorName);\n        if (parentRequired) {\n          if (ancestorName === parentRequired) {\n            parentCandidate = ancestry[0];\n            ancestry = ancestry.slice(1);\n          } else {\n            parentCandidate = parentRequired;\n          }\n        } else if (ancestor) {\n          parentCandidate = ancestry[0];\n          ancestry = ancestry.slice(1);\n        } else if (!siblings) {\n          return elm;\n        }\n        if (parentCandidate) {\n          parent = createElement(parentCandidate);\n          parent.appendChild(elm);\n        }\n        if (siblings) {\n          if (!parent) {\n            parent = dom.create('div');\n            parent.appendChild(elm);\n          }\n          Tools.each(siblings, function (sibling) {\n            var siblingElm = createElement(sibling);\n            parent.insertBefore(siblingElm, elm);\n          });\n        }\n        return wrapInHtml(parent, ancestry, parentCandidate && parentCandidate.siblings);\n      };\n      if (ancestry && ancestry.length) {\n        item = ancestry[0];\n        elm = createElement(item);\n        fragment = dom.create('div');\n        fragment.appendChild(wrapInHtml(elm, ancestry.slice(1), item.siblings));\n        return fragment;\n      } else {\n        return '';\n      }\n    };\n    var selectorToHtml = function (selector, editor) {\n      return parsedSelectorToHtml(parseSelector(selector), editor);\n    };\n    var parseSelectorItem = function (item) {\n      var tagName;\n      var obj = {\n        classes: [],\n        attrs: {}\n      };\n      item = obj.selector = Tools.trim(item);\n      if (item !== '*') {\n        tagName = item.replace(/(?:([#\\.]|::?)([\\w\\-]+)|(\\[)([^\\]]+)\\]?)/g, function ($0, $1, $2, $3, $4) {\n          switch ($1) {\n          case '#':\n            obj.attrs.id = $2;\n            break;\n          case '.':\n            obj.classes.push($2);\n            break;\n          case ':':\n            if (Tools.inArray('checked disabled enabled read-only required'.split(' '), $2) !== -1) {\n              obj.attrs[$2] = $2;\n            }\n            break;\n          }\n          if ($3 === '[') {\n            var m = $4.match(/([\\w\\-]+)(?:\\=\\\"([^\\\"]+))?/);\n            if (m) {\n              obj.attrs[m[1]] = m[2];\n            }\n          }\n          return '';\n        });\n      }\n      obj.name = tagName || 'div';\n      return obj;\n    };\n    var parseSelector = function (selector) {\n      if (!selector || typeof selector !== 'string') {\n        return [];\n      }\n      selector = selector.split(/\\s*,\\s*/)[0];\n      selector = selector.replace(/\\s*(~\\+|~|\\+|>)\\s*/g, '$1');\n      return Tools.map(selector.split(/(?:>|\\s+(?![^\\[\\]]+\\]))/), function (item) {\n        var siblings = Tools.map(item.split(/(?:~\\+|~|\\+)/), parseSelectorItem);\n        var obj = siblings.pop();\n        if (siblings.length) {\n          obj.siblings = siblings;\n        }\n        return obj;\n      }).reverse();\n    };\n    var getCssText = function (editor, format) {\n      var name, previewFrag, previewElm, items;\n      var previewCss = '', parentFontSize, previewStyles;\n      previewStyles = editor.settings.preview_styles;\n      if (previewStyles === false) {\n        return '';\n      }\n      if (typeof previewStyles !== 'string') {\n        previewStyles = 'font-family font-size font-weight font-style text-decoration ' + 'text-transform color background-color border border-radius outline text-shadow';\n      }\n      var removeVars = function (val) {\n        return val.replace(/%(\\w+)/g, '');\n      };\n      if (typeof format === 'string') {\n        format = editor.formatter.get(format);\n        if (!format) {\n          return;\n        }\n        format = format[0];\n      }\n      if ('preview' in format) {\n        previewStyles = format.preview;\n        if (previewStyles === false) {\n          return '';\n        }\n      }\n      name = format.block || format.inline || 'span';\n      items = parseSelector(format.selector);\n      if (items.length) {\n        if (!items[0].name) {\n          items[0].name = name;\n        }\n        name = format.selector;\n        previewFrag = parsedSelectorToHtml(items, editor);\n      } else {\n        previewFrag = parsedSelectorToHtml([name], editor);\n      }\n      previewElm = dom.select(name, previewFrag)[0] || previewFrag.firstChild;\n      each$e(format.styles, function (value, name) {\n        value = removeVars(value);\n        if (value) {\n          dom.setStyle(previewElm, name, value);\n        }\n      });\n      each$e(format.attributes, function (value, name) {\n        value = removeVars(value);\n        if (value) {\n          dom.setAttrib(previewElm, name, value);\n        }\n      });\n      each$e(format.classes, function (value) {\n        value = removeVars(value);\n        if (!dom.hasClass(previewElm, value)) {\n          dom.addClass(previewElm, value);\n        }\n      });\n      editor.fire('PreviewFormats');\n      dom.setStyles(previewFrag, {\n        position: 'absolute',\n        left: -65535\n      });\n      editor.getBody().appendChild(previewFrag);\n      parentFontSize = dom.getStyle(editor.getBody(), 'fontSize', true);\n      parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0;\n      each$e(previewStyles.split(' '), function (name) {\n        var value = dom.getStyle(previewElm, name, true);\n        if (name === 'background-color' && /transparent|rgba\\s*\\([^)]+,\\s*0\\)/.test(value)) {\n          value = dom.getStyle(editor.getBody(), name, true);\n          if (dom.toHex(value).toLowerCase() === '#ffffff') {\n            return;\n          }\n        }\n        if (name === 'color') {\n          if (dom.toHex(value).toLowerCase() === '#000000') {\n            return;\n          }\n        }\n        if (name === 'font-size') {\n          if (/em|%$/.test(value)) {\n            if (parentFontSize === 0) {\n              return;\n            }\n            var numValue = parseFloat(value) / (/%$/.test(value) ? 100 : 1);\n            value = numValue * parentFontSize + 'px';\n          }\n        }\n        if (name === 'border' && value) {\n          previewCss += 'padding:0 2px;';\n        }\n        previewCss += name + ':' + value + ';';\n      });\n      editor.fire('AfterPreviewFormats');\n      dom.remove(previewFrag);\n      return previewCss;\n    };\n    var Preview = {\n      getCssText: getCssText,\n      parseSelector: parseSelector,\n      selectorToHtml: selectorToHtml\n    };\n\n    var toggle = function (editor, formats, name, vars, node) {\n      var fmt = formats.get(name);\n      if (MatchFormat.match(editor, name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle)) {\n        RemoveFormat.remove(editor, name, vars, node);\n      } else {\n        ApplyFormat.applyFormat(editor, name, vars, node);\n      }\n    };\n    var ToggleFormat = { toggle: toggle };\n\n    var setup$7 = function (editor) {\n      editor.addShortcut('meta+b', '', 'Bold');\n      editor.addShortcut('meta+i', '', 'Italic');\n      editor.addShortcut('meta+u', '', 'Underline');\n      for (var i = 1; i <= 6; i++) {\n        editor.addShortcut('access+' + i, '', [\n          'FormatBlock',\n          false,\n          'h' + i\n        ]);\n      }\n      editor.addShortcut('access+7', '', [\n        'FormatBlock',\n        false,\n        'p'\n      ]);\n      editor.addShortcut('access+8', '', [\n        'FormatBlock',\n        false,\n        'div'\n      ]);\n      editor.addShortcut('access+9', '', [\n        'FormatBlock',\n        false,\n        'address'\n      ]);\n    };\n    var FormatShortcuts = { setup: setup$7 };\n\n    var Formatter = function (editor) {\n      var formats = FormatRegistry(editor);\n      var formatChangeState = Cell(null);\n      FormatShortcuts.setup(editor);\n      setup$5(editor);\n      return {\n        get: formats.get,\n        has: formats.has,\n        register: formats.register,\n        unregister: formats.unregister,\n        apply: curry(ApplyFormat.applyFormat, editor),\n        remove: curry(RemoveFormat.remove, editor),\n        toggle: curry(ToggleFormat.toggle, editor, formats),\n        match: curry(MatchFormat.match, editor),\n        matchAll: curry(MatchFormat.matchAll, editor),\n        matchNode: curry(MatchFormat.matchNode, editor),\n        canApply: curry(MatchFormat.canApply, editor),\n        formatChanged: curry(formatChanged, editor, formatChangeState),\n        getCssText: curry(Preview.getCssText, editor)\n      };\n    };\n\n    var register$1 = function (htmlParser, settings, dom) {\n      htmlParser.addAttributeFilter('data-mce-tabindex', function (nodes, name) {\n        var i = nodes.length, node;\n        while (i--) {\n          node = nodes[i];\n          node.attr('tabindex', node.attr('data-mce-tabindex'));\n          node.attr(name, null);\n        }\n      });\n      htmlParser.addAttributeFilter('src,href,style', function (nodes, name) {\n        var i = nodes.length, node, value;\n        var internalName = 'data-mce-' + name;\n        var urlConverter = settings.url_converter;\n        var urlConverterScope = settings.url_converter_scope;\n        while (i--) {\n          node = nodes[i];\n          value = node.attr(internalName);\n          if (value !== undefined) {\n            node.attr(name, value.length > 0 ? value : null);\n            node.attr(internalName, null);\n          } else {\n            value = node.attr(name);\n            if (name === 'style') {\n              value = dom.serializeStyle(dom.parseStyle(value), node.name);\n            } else if (urlConverter) {\n              value = urlConverter.call(urlConverterScope, value, name, node.name);\n            }\n            node.attr(name, value.length > 0 ? value : null);\n          }\n        }\n      });\n      htmlParser.addAttributeFilter('class', function (nodes) {\n        var i = nodes.length, node, value;\n        while (i--) {\n          node = nodes[i];\n          value = node.attr('class');\n          if (value) {\n            value = node.attr('class').replace(/(?:^|\\s)mce-item-\\w+(?!\\S)/g, '');\n            node.attr('class', value.length > 0 ? value : null);\n          }\n        }\n      });\n      htmlParser.addAttributeFilter('data-mce-type', function (nodes, name, args) {\n        var i = nodes.length, node;\n        while (i--) {\n          node = nodes[i];\n          if (node.attr('data-mce-type') === 'bookmark' && !args.cleanup) {\n            var hasChildren = Option.from(node.firstChild).exists(function (firstChild) {\n              return !Zwsp.isZwsp(firstChild.value);\n            });\n            if (hasChildren) {\n              node.unwrap();\n            } else {\n              node.remove();\n            }\n          }\n        }\n      });\n      htmlParser.addNodeFilter('noscript', function (nodes) {\n        var i = nodes.length, node;\n        while (i--) {\n          node = nodes[i].firstChild;\n          if (node) {\n            node.value = Entities.decode(node.value);\n          }\n        }\n      });\n      htmlParser.addNodeFilter('script,style', function (nodes, name) {\n        var i = nodes.length, node, value, type;\n        var trim = function (value) {\n          return value.replace(/(<!--\\[CDATA\\[|\\]\\]-->)/g, '\\n').replace(/^[\\r\\n]*|[\\r\\n]*$/g, '').replace(/^\\s*((<!--)?(\\s*\\/\\/)?\\s*<!\\[CDATA\\[|(<!--\\s*)?\\/\\*\\s*<!\\[CDATA\\[\\s*\\*\\/|(\\/\\/)?\\s*<!--|\\/\\*\\s*<!--\\s*\\*\\/)\\s*[\\r\\n]*/gi, '').replace(/\\s*(\\/\\*\\s*\\]\\]>\\s*\\*\\/(-->)?|\\s*\\/\\/\\s*\\]\\]>(-->)?|\\/\\/\\s*(-->)?|\\]\\]>|\\/\\*\\s*-->\\s*\\*\\/|\\s*-->\\s*)\\s*$/g, '');\n        };\n        while (i--) {\n          node = nodes[i];\n          value = node.firstChild ? node.firstChild.value : '';\n          if (name === 'script') {\n            type = node.attr('type');\n            if (type) {\n              node.attr('type', type === 'mce-no/type' ? null : type.replace(/^mce\\-/, ''));\n            }\n            if (settings.element_format === 'xhtml' && value.length > 0) {\n              node.firstChild.value = '// <![CDATA[\\n' + trim(value) + '\\n// ]]>';\n            }\n          } else {\n            if (settings.element_format === 'xhtml' && value.length > 0) {\n              node.firstChild.value = '<!--\\n' + trim(value) + '\\n-->';\n            }\n          }\n        }\n      });\n      htmlParser.addNodeFilter('#comment', function (nodes) {\n        var i = nodes.length, node;\n        while (i--) {\n          node = nodes[i];\n          if (node.value.indexOf('[CDATA[') === 0) {\n            node.name = '#cdata';\n            node.type = 4;\n            node.value = node.value.replace(/^\\[CDATA\\[|\\]\\]$/g, '');\n          } else if (node.value.indexOf('mce:protected ') === 0) {\n            node.name = '#text';\n            node.type = 3;\n            node.raw = true;\n            node.value = unescape(node.value).substr(14);\n          }\n        }\n      });\n      htmlParser.addNodeFilter('xml:namespace,input', function (nodes, name) {\n        var i = nodes.length, node;\n        while (i--) {\n          node = nodes[i];\n          if (node.type === 7) {\n            node.remove();\n          } else if (node.type === 1) {\n            if (name === 'input' && !node.attr('type')) {\n              node.attr('type', 'text');\n            }\n          }\n        }\n      });\n      htmlParser.addAttributeFilter('data-mce-type', function (nodes) {\n        each(nodes, function (node) {\n          if (node.attr('data-mce-type') === 'format-caret') {\n            if (node.isEmpty(htmlParser.schema.getNonEmptyElements())) {\n              node.remove();\n            } else {\n              node.unwrap();\n            }\n          }\n        });\n      });\n      htmlParser.addAttributeFilter('data-mce-src,data-mce-href,data-mce-style,' + 'data-mce-selected,data-mce-expando,' + 'data-mce-type,data-mce-resize', function (nodes, name) {\n        var i = nodes.length;\n        while (i--) {\n          nodes[i].attr(name, null);\n        }\n      });\n    };\n    var trimTrailingBr = function (rootNode) {\n      var brNode1, brNode2;\n      var isBr = function (node) {\n        return node && node.name === 'br';\n      };\n      brNode1 = rootNode.lastChild;\n      if (isBr(brNode1)) {\n        brNode2 = brNode1.prev;\n        if (isBr(brNode2)) {\n          brNode1.remove();\n          brNode2.remove();\n        }\n      }\n    };\n    var DomSerializerFilters = {\n      register: register$1,\n      trimTrailingBr: trimTrailingBr\n    };\n\n    var preProcess = function (editor, node, args) {\n      var impl, doc, oldDoc;\n      var dom = editor.dom;\n      node = node.cloneNode(true);\n      impl = domGlobals.document.implementation;\n      if (impl.createHTMLDocument) {\n        doc = impl.createHTMLDocument('');\n        Tools.each(node.nodeName === 'BODY' ? node.childNodes : [node], function (node) {\n          doc.body.appendChild(doc.importNode(node, true));\n        });\n        if (node.nodeName !== 'BODY') {\n          node = doc.body.firstChild;\n        } else {\n          node = doc.body;\n        }\n        oldDoc = dom.doc;\n        dom.doc = doc;\n      }\n      Events.firePreProcess(editor, merge(args, { node: node }));\n      if (oldDoc) {\n        dom.doc = oldDoc;\n      }\n      return node;\n    };\n    var shouldFireEvent = function (editor, args) {\n      return editor && editor.hasEventListeners('PreProcess') && !args.no_events;\n    };\n    var process = function (editor, node, args) {\n      return shouldFireEvent(editor, args) ? preProcess(editor, node, args) : node;\n    };\n    var DomSerializerPreProcess = { process: process };\n\n    var removeAttrs = function (node, names) {\n      each(names, function (name) {\n        node.attr(name, null);\n      });\n    };\n    var addFontToSpansFilter = function (domParser, styles, fontSizes) {\n      domParser.addNodeFilter('font', function (nodes) {\n        each(nodes, function (node) {\n          var props = styles.parse(node.attr('style'));\n          var color = node.attr('color');\n          var face = node.attr('face');\n          var size = node.attr('size');\n          if (color) {\n            props.color = color;\n          }\n          if (face) {\n            props['font-family'] = face;\n          }\n          if (size) {\n            props['font-size'] = fontSizes[parseInt(node.attr('size'), 10) - 1];\n          }\n          node.name = 'span';\n          node.attr('style', styles.serialize(props));\n          removeAttrs(node, [\n            'color',\n            'face',\n            'size'\n          ]);\n        });\n      });\n    };\n    var addStrikeToSpanFilter = function (domParser, styles) {\n      domParser.addNodeFilter('strike', function (nodes) {\n        each(nodes, function (node) {\n          var props = styles.parse(node.attr('style'));\n          props['text-decoration'] = 'line-through';\n          node.name = 'span';\n          node.attr('style', styles.serialize(props));\n        });\n      });\n    };\n    var addFilters = function (domParser, settings) {\n      var styles = Styles();\n      if (settings.convert_fonts_to_spans) {\n        addFontToSpansFilter(domParser, styles, Tools.explode(settings.font_size_legacy_values));\n      }\n      addStrikeToSpanFilter(domParser, styles);\n    };\n    var register$2 = function (domParser, settings) {\n      if (settings.inline_styles) {\n        addFilters(domParser, settings);\n      }\n    };\n    var LegacyFilter = { register: register$2 };\n\n    var paddEmptyNode = function (settings, args, blockElements, node) {\n      var brPreferred = settings.padd_empty_with_br || args.insert;\n      if (brPreferred && blockElements[node.name]) {\n        node.empty().append(new Node$1('br', 1)).shortEnded = true;\n      } else {\n        node.empty().append(new Node$1('#text', 3)).value = '\\xA0';\n      }\n    };\n    var isPaddedWithNbsp = function (node) {\n      return hasOnlyChild(node, '#text') && node.firstChild.value === '\\xA0';\n    };\n    var hasOnlyChild = function (node, name) {\n      return node && node.firstChild && node.firstChild === node.lastChild && node.firstChild.name === name;\n    };\n    var isPadded = function (schema, node) {\n      var rule = schema.getElementRule(node.name);\n      return rule && rule.paddEmpty;\n    };\n    var isEmpty$2 = function (schema, nonEmptyElements, whitespaceElements, node) {\n      return node.isEmpty(nonEmptyElements, whitespaceElements, function (node) {\n        return isPadded(schema, node);\n      });\n    };\n    var isLineBreakNode = function (node, blockElements) {\n      return node && (blockElements[node.name] || node.name === 'br');\n    };\n\n    var register$3 = function (parser, settings) {\n      var schema = parser.schema;\n      if (settings.remove_trailing_brs) {\n        parser.addNodeFilter('br', function (nodes, _, args) {\n          var i;\n          var l = nodes.length;\n          var node;\n          var blockElements = Tools.extend({}, schema.getBlockElements());\n          var nonEmptyElements = schema.getNonEmptyElements();\n          var parent, lastParent, prev, prevName;\n          var whiteSpaceElements = schema.getNonEmptyElements();\n          var elementRule, textNode;\n          blockElements.body = 1;\n          for (i = 0; i < l; i++) {\n            node = nodes[i];\n            parent = node.parent;\n            if (blockElements[node.parent.name] && node === parent.lastChild) {\n              prev = node.prev;\n              while (prev) {\n                prevName = prev.name;\n                if (prevName !== 'span' || prev.attr('data-mce-type') !== 'bookmark') {\n                  if (prevName !== 'br') {\n                    break;\n                  }\n                  if (prevName === 'br') {\n                    node = null;\n                    break;\n                  }\n                }\n                prev = prev.prev;\n              }\n              if (node) {\n                node.remove();\n                if (isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, parent)) {\n                  elementRule = schema.getElementRule(parent.name);\n                  if (elementRule) {\n                    if (elementRule.removeEmpty) {\n                      parent.remove();\n                    } else if (elementRule.paddEmpty) {\n                      paddEmptyNode(settings, args, blockElements, parent);\n                    }\n                  }\n                }\n              }\n            } else {\n              lastParent = node;\n              while (parent && parent.firstChild === lastParent && parent.lastChild === lastParent) {\n                lastParent = parent;\n                if (blockElements[parent.name]) {\n                  break;\n                }\n                parent = parent.parent;\n              }\n              if (lastParent === parent && settings.padd_empty_with_br !== true) {\n                textNode = new Node$1('#text', 3);\n                textNode.value = '\\xA0';\n                node.replace(textNode);\n              }\n            }\n          }\n        });\n      }\n      parser.addAttributeFilter('href', function (nodes) {\n        var i = nodes.length, node;\n        var appendRel = function (rel) {\n          var parts = rel.split(' ').filter(function (p) {\n            return p.length > 0;\n          });\n          return parts.concat(['noopener']).sort().join(' ');\n        };\n        var addNoOpener = function (rel) {\n          var newRel = rel ? Tools.trim(rel) : '';\n          if (!/\\b(noopener)\\b/g.test(newRel)) {\n            return appendRel(newRel);\n          } else {\n            return newRel;\n          }\n        };\n        if (!settings.allow_unsafe_link_target) {\n          while (i--) {\n            node = nodes[i];\n            if (node.name === 'a' && node.attr('target') === '_blank') {\n              node.attr('rel', addNoOpener(node.attr('rel')));\n            }\n          }\n        }\n      });\n      if (!settings.allow_html_in_named_anchor) {\n        parser.addAttributeFilter('id,name', function (nodes) {\n          var i = nodes.length, sibling, prevSibling, parent, node;\n          while (i--) {\n            node = nodes[i];\n            if (node.name === 'a' && node.firstChild && !node.attr('href')) {\n              parent = node.parent;\n              sibling = node.lastChild;\n              do {\n                prevSibling = sibling.prev;\n                parent.insert(sibling, node);\n                sibling = prevSibling;\n              } while (sibling);\n            }\n          }\n        });\n      }\n      if (settings.fix_list_elements) {\n        parser.addNodeFilter('ul,ol', function (nodes) {\n          var i = nodes.length, node, parentNode;\n          while (i--) {\n            node = nodes[i];\n            parentNode = node.parent;\n            if (parentNode.name === 'ul' || parentNode.name === 'ol') {\n              if (node.prev && node.prev.name === 'li') {\n                node.prev.append(node);\n              } else {\n                var li = new Node$1('li', 1);\n                li.attr('style', 'list-style-type: none');\n                node.wrap(li);\n              }\n            }\n          }\n        });\n      }\n      if (settings.validate && schema.getValidClasses()) {\n        parser.addAttributeFilter('class', function (nodes) {\n          var i = nodes.length, node, classList, ci, className, classValue;\n          var validClasses = schema.getValidClasses();\n          var validClassesMap, valid;\n          while (i--) {\n            node = nodes[i];\n            classList = node.attr('class').split(' ');\n            classValue = '';\n            for (ci = 0; ci < classList.length; ci++) {\n              className = classList[ci];\n              valid = false;\n              validClassesMap = validClasses['*'];\n              if (validClassesMap && validClassesMap[className]) {\n                valid = true;\n              }\n              validClassesMap = validClasses[node.name];\n              if (!valid && validClassesMap && validClassesMap[className]) {\n                valid = true;\n              }\n              if (valid) {\n                if (classValue) {\n                  classValue += ' ';\n                }\n                classValue += className;\n              }\n            }\n            if (!classValue.length) {\n              classValue = null;\n            }\n            node.attr('class', classValue);\n          }\n        });\n      }\n    };\n\n    var makeMap$4 = Tools.makeMap, each$f = Tools.each, explode$2 = Tools.explode, extend$2 = Tools.extend;\n    var DomParser = function (settings, schema) {\n      if (schema === void 0) {\n        schema = Schema();\n      }\n      var nodeFilters = {};\n      var attributeFilters = [];\n      var matchedNodes = {};\n      var matchedAttributes = {};\n      settings = settings || {};\n      settings.validate = 'validate' in settings ? settings.validate : true;\n      settings.root_name = settings.root_name || 'body';\n      var fixInvalidChildren = function (nodes) {\n        var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i;\n        var nonEmptyElements, whitespaceElements, nonSplitableElements, textBlockElements, specialElements, sibling, nextNode;\n        nonSplitableElements = makeMap$4('tr,td,th,tbody,thead,tfoot,table');\n        nonEmptyElements = schema.getNonEmptyElements();\n        whitespaceElements = schema.getWhiteSpaceElements();\n        textBlockElements = schema.getTextBlockElements();\n        specialElements = schema.getSpecialElements();\n        for (ni = 0; ni < nodes.length; ni++) {\n          node = nodes[ni];\n          if (!node.parent || node.fixed) {\n            continue;\n          }\n          if (textBlockElements[node.name] && node.parent.name === 'li') {\n            sibling = node.next;\n            while (sibling) {\n              if (textBlockElements[sibling.name]) {\n                sibling.name = 'li';\n                sibling.fixed = true;\n                node.parent.insert(sibling, node.parent);\n              } else {\n                break;\n              }\n              sibling = sibling.next;\n            }\n            node.unwrap(node);\n            continue;\n          }\n          parents = [node];\n          for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent) {\n            parents.push(parent);\n          }\n          if (parent && parents.length > 1) {\n            parents.reverse();\n            newParent = currentNode = filterNode(parents[0].clone());\n            for (i = 0; i < parents.length - 1; i++) {\n              if (schema.isValidChild(currentNode.name, parents[i].name)) {\n                tempNode = filterNode(parents[i].clone());\n                currentNode.append(tempNode);\n              } else {\n                tempNode = currentNode;\n              }\n              for (childNode = parents[i].firstChild; childNode && childNode !== parents[i + 1];) {\n                nextNode = childNode.next;\n                tempNode.append(childNode);\n                childNode = nextNode;\n              }\n              currentNode = tempNode;\n            }\n            if (!isEmpty$2(schema, nonEmptyElements, whitespaceElements, newParent)) {\n              parent.insert(newParent, parents[0], true);\n              parent.insert(node, newParent);\n            } else {\n              parent.insert(node, parents[0], true);\n            }\n            parent = parents[0];\n            if (isEmpty$2(schema, nonEmptyElements, whitespaceElements, parent) || hasOnlyChild(parent, 'br')) {\n              parent.empty().remove();\n            }\n          } else if (node.parent) {\n            if (node.name === 'li') {\n              sibling = node.prev;\n              if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) {\n                sibling.append(node);\n                continue;\n              }\n              sibling = node.next;\n              if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) {\n                sibling.insert(node, sibling.firstChild, true);\n                continue;\n              }\n              node.wrap(filterNode(new Node$1('ul', 1)));\n              continue;\n            }\n            if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) {\n              node.wrap(filterNode(new Node$1('div', 1)));\n            } else {\n              if (specialElements[node.name]) {\n                node.empty().remove();\n              } else {\n                node.unwrap();\n              }\n            }\n          }\n        }\n      };\n      var filterNode = function (node) {\n        var i, name, list;\n        name = node.name;\n        if (name in nodeFilters) {\n          list = matchedNodes[name];\n          if (list) {\n            list.push(node);\n          } else {\n            matchedNodes[name] = [node];\n          }\n        }\n        i = attributeFilters.length;\n        while (i--) {\n          name = attributeFilters[i].name;\n          if (name in node.attributes.map) {\n            list = matchedAttributes[name];\n            if (list) {\n              list.push(node);\n            } else {\n              matchedAttributes[name] = [node];\n            }\n          }\n        }\n        return node;\n      };\n      var addNodeFilter = function (name, callback) {\n        each$f(explode$2(name), function (name) {\n          var list = nodeFilters[name];\n          if (!list) {\n            nodeFilters[name] = list = [];\n          }\n          list.push(callback);\n        });\n      };\n      var getNodeFilters = function () {\n        var out = [];\n        for (var name in nodeFilters) {\n          if (nodeFilters.hasOwnProperty(name)) {\n            out.push({\n              name: name,\n              callbacks: nodeFilters[name]\n            });\n          }\n        }\n        return out;\n      };\n      var addAttributeFilter = function (name, callback) {\n        each$f(explode$2(name), function (name) {\n          var i;\n          for (i = 0; i < attributeFilters.length; i++) {\n            if (attributeFilters[i].name === name) {\n              attributeFilters[i].callbacks.push(callback);\n              return;\n            }\n          }\n          attributeFilters.push({\n            name: name,\n            callbacks: [callback]\n          });\n        });\n      };\n      var getAttributeFilters = function () {\n        return [].concat(attributeFilters);\n      };\n      var parse = function (html, args) {\n        var parser, nodes, i, l, fi, fl, list, name;\n        var blockElements;\n        var invalidChildren = [];\n        var isInWhiteSpacePreservedElement;\n        var node;\n        var getRootBlockName = function (name) {\n          if (name === false) {\n            return '';\n          } else if (name === true) {\n            return 'p';\n          } else {\n            return name;\n          }\n        };\n        args = args || {};\n        matchedNodes = {};\n        matchedAttributes = {};\n        blockElements = extend$2(makeMap$4('script,style,head,html,body,title,meta,param'), schema.getBlockElements());\n        var nonEmptyElements = schema.getNonEmptyElements();\n        var children = schema.children;\n        var validate = settings.validate;\n        var forcedRootBlockName = 'forced_root_block' in args ? args.forced_root_block : settings.forced_root_block;\n        var rootBlockName = getRootBlockName(forcedRootBlockName);\n        var whiteSpaceElements = schema.getWhiteSpaceElements();\n        var startWhiteSpaceRegExp = /^[ \\t\\r\\n]+/;\n        var endWhiteSpaceRegExp = /[ \\t\\r\\n]+$/;\n        var allWhiteSpaceRegExp = /[ \\t\\r\\n]+/g;\n        var isAllWhiteSpaceRegExp = /^[ \\t\\r\\n]+$/;\n        isInWhiteSpacePreservedElement = whiteSpaceElements.hasOwnProperty(args.context) || whiteSpaceElements.hasOwnProperty(settings.root_name);\n        var addRootBlocks = function () {\n          var node = rootNode.firstChild, next, rootBlockNode;\n          var trim = function (rootBlockNode) {\n            if (rootBlockNode) {\n              node = rootBlockNode.firstChild;\n              if (node && node.type === 3) {\n                node.value = node.value.replace(startWhiteSpaceRegExp, '');\n              }\n              node = rootBlockNode.lastChild;\n              if (node && node.type === 3) {\n                node.value = node.value.replace(endWhiteSpaceRegExp, '');\n              }\n            }\n          };\n          if (!schema.isValidChild(rootNode.name, rootBlockName.toLowerCase())) {\n            return;\n          }\n          while (node) {\n            next = node.next;\n            if (node.type === 3 || node.type === 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type')) {\n              if (!rootBlockNode) {\n                rootBlockNode = createNode(rootBlockName, 1);\n                rootBlockNode.attr(settings.forced_root_block_attrs);\n                rootNode.insert(rootBlockNode, node);\n                rootBlockNode.append(node);\n              } else {\n                rootBlockNode.append(node);\n              }\n            } else {\n              trim(rootBlockNode);\n              rootBlockNode = null;\n            }\n            node = next;\n          }\n          trim(rootBlockNode);\n        };\n        var createNode = function (name, type) {\n          var node = new Node$1(name, type);\n          var list;\n          if (name in nodeFilters) {\n            list = matchedNodes[name];\n            if (list) {\n              list.push(node);\n            } else {\n              matchedNodes[name] = [node];\n            }\n          }\n          return node;\n        };\n        var removeWhitespaceBefore = function (node) {\n          var textNode, textNodeNext, textVal, sibling;\n          var blockElements = schema.getBlockElements();\n          for (textNode = node.prev; textNode && textNode.type === 3;) {\n            textVal = textNode.value.replace(endWhiteSpaceRegExp, '');\n            if (textVal.length > 0) {\n              textNode.value = textVal;\n              return;\n            }\n            textNodeNext = textNode.next;\n            if (textNodeNext) {\n              if (textNodeNext.type === 3 && textNodeNext.value.length) {\n                textNode = textNode.prev;\n                continue;\n              }\n              if (!blockElements[textNodeNext.name] && textNodeNext.name !== 'script' && textNodeNext.name !== 'style') {\n                textNode = textNode.prev;\n                continue;\n              }\n            }\n            sibling = textNode.prev;\n            textNode.remove();\n            textNode = sibling;\n          }\n        };\n        var cloneAndExcludeBlocks = function (input) {\n          var name;\n          var output = {};\n          for (name in input) {\n            if (name !== 'li' && name !== 'p') {\n              output[name] = input[name];\n            }\n          }\n          return output;\n        };\n        parser = SaxParser$1({\n          validate: validate,\n          allow_script_urls: settings.allow_script_urls,\n          allow_conditional_comments: settings.allow_conditional_comments,\n          self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()),\n          cdata: function (text) {\n            node.append(createNode('#cdata', 4)).value = text;\n          },\n          text: function (text, raw) {\n            var textNode;\n            if (!isInWhiteSpacePreservedElement) {\n              text = text.replace(allWhiteSpaceRegExp, ' ');\n              if (isLineBreakNode(node.lastChild, blockElements)) {\n                text = text.replace(startWhiteSpaceRegExp, '');\n              }\n            }\n            if (text.length !== 0) {\n              textNode = createNode('#text', 3);\n              textNode.raw = !!raw;\n              node.append(textNode).value = text;\n            }\n          },\n          comment: function (text) {\n            node.append(createNode('#comment', 8)).value = text;\n          },\n          pi: function (name, text) {\n            node.append(createNode(name, 7)).value = text;\n            removeWhitespaceBefore(node);\n          },\n          doctype: function (text) {\n            var newNode;\n            newNode = node.append(createNode('#doctype', 10));\n            newNode.value = text;\n            removeWhitespaceBefore(node);\n          },\n          start: function (name, attrs, empty) {\n            var newNode, attrFiltersLen, elementRule, attrName, parent;\n            elementRule = validate ? schema.getElementRule(name) : {};\n            if (elementRule) {\n              newNode = createNode(elementRule.outputName || name, 1);\n              newNode.attributes = attrs;\n              newNode.shortEnded = empty;\n              node.append(newNode);\n              parent = children[node.name];\n              if (parent && children[newNode.name] && !parent[newNode.name]) {\n                invalidChildren.push(newNode);\n              }\n              attrFiltersLen = attributeFilters.length;\n              while (attrFiltersLen--) {\n                attrName = attributeFilters[attrFiltersLen].name;\n                if (attrName in attrs.map) {\n                  list = matchedAttributes[attrName];\n                  if (list) {\n                    list.push(newNode);\n                  } else {\n                    matchedAttributes[attrName] = [newNode];\n                  }\n                }\n              }\n              if (blockElements[name]) {\n                removeWhitespaceBefore(newNode);\n              }\n              if (!empty) {\n                node = newNode;\n              }\n              if (!isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {\n                isInWhiteSpacePreservedElement = true;\n              }\n            }\n          },\n          end: function (name) {\n            var textNode, elementRule, text, sibling, tempNode;\n            elementRule = validate ? schema.getElementRule(name) : {};\n            if (elementRule) {\n              if (blockElements[name]) {\n                if (!isInWhiteSpacePreservedElement) {\n                  textNode = node.firstChild;\n                  if (textNode && textNode.type === 3) {\n                    text = textNode.value.replace(startWhiteSpaceRegExp, '');\n                    if (text.length > 0) {\n                      textNode.value = text;\n                      textNode = textNode.next;\n                    } else {\n                      sibling = textNode.next;\n                      textNode.remove();\n                      textNode = sibling;\n                      while (textNode && textNode.type === 3) {\n                        text = textNode.value;\n                        sibling = textNode.next;\n                        if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {\n                          textNode.remove();\n                          textNode = sibling;\n                        }\n                        textNode = sibling;\n                      }\n                    }\n                  }\n                  textNode = node.lastChild;\n                  if (textNode && textNode.type === 3) {\n                    text = textNode.value.replace(endWhiteSpaceRegExp, '');\n                    if (text.length > 0) {\n                      textNode.value = text;\n                      textNode = textNode.prev;\n                    } else {\n                      sibling = textNode.prev;\n                      textNode.remove();\n                      textNode = sibling;\n                      while (textNode && textNode.type === 3) {\n                        text = textNode.value;\n                        sibling = textNode.prev;\n                        if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {\n                          textNode.remove();\n                          textNode = sibling;\n                        }\n                        textNode = sibling;\n                      }\n                    }\n                  }\n                }\n              }\n              if (isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {\n                isInWhiteSpacePreservedElement = false;\n              }\n              if (elementRule.removeEmpty && isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, node)) {\n                if (!node.attr('name') && !node.attr('id')) {\n                  tempNode = node.parent;\n                  if (blockElements[node.name]) {\n                    node.empty().remove();\n                  } else {\n                    node.unwrap();\n                  }\n                  node = tempNode;\n                  return;\n                }\n              }\n              if (elementRule.paddEmpty && (isPaddedWithNbsp(node) || isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, node))) {\n                paddEmptyNode(settings, args, blockElements, node);\n              }\n              node = node.parent;\n            }\n          }\n        }, schema);\n        var rootNode = node = new Node$1(args.context || settings.root_name, 11);\n        parser.parse(html);\n        if (validate && invalidChildren.length) {\n          if (!args.context) {\n            fixInvalidChildren(invalidChildren);\n          } else {\n            args.invalid = true;\n          }\n        }\n        if (rootBlockName && (rootNode.name === 'body' || args.isRootContent)) {\n          addRootBlocks();\n        }\n        if (!args.invalid) {\n          for (name in matchedNodes) {\n            if (!matchedNodes.hasOwnProperty(name)) {\n              continue;\n            }\n            list = nodeFilters[name];\n            nodes = matchedNodes[name];\n            fi = nodes.length;\n            while (fi--) {\n              if (!nodes[fi].parent) {\n                nodes.splice(fi, 1);\n              }\n            }\n            for (i = 0, l = list.length; i < l; i++) {\n              list[i](nodes, name, args);\n            }\n          }\n          for (i = 0, l = attributeFilters.length; i < l; i++) {\n            list = attributeFilters[i];\n            if (list.name in matchedAttributes) {\n              nodes = matchedAttributes[list.name];\n              fi = nodes.length;\n              while (fi--) {\n                if (!nodes[fi].parent) {\n                  nodes.splice(fi, 1);\n                }\n              }\n              for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) {\n                list.callbacks[fi](nodes, list.name, args);\n              }\n            }\n          }\n        }\n        return rootNode;\n      };\n      var exports = {\n        schema: schema,\n        addAttributeFilter: addAttributeFilter,\n        getAttributeFilters: getAttributeFilters,\n        addNodeFilter: addNodeFilter,\n        getNodeFilters: getNodeFilters,\n        filterNode: filterNode,\n        parse: parse\n      };\n      register$3(exports, settings);\n      LegacyFilter.register(exports, settings);\n      return exports;\n    };\n\n    var addTempAttr = function (htmlParser, tempAttrs, name) {\n      if (Tools.inArray(tempAttrs, name) === -1) {\n        htmlParser.addAttributeFilter(name, function (nodes, name) {\n          var i = nodes.length;\n          while (i--) {\n            nodes[i].attr(name, null);\n          }\n        });\n        tempAttrs.push(name);\n      }\n    };\n    var postProcess$1 = function (editor, args, content) {\n      if (!args.no_events && editor) {\n        var outArgs = Events.firePostProcess(editor, merge(args, { content: content }));\n        return outArgs.content;\n      } else {\n        return content;\n      }\n    };\n    var getHtmlFromNode = function (dom, node, args) {\n      var html = Zwsp.trim(args.getInner ? node.innerHTML : dom.getOuterHTML(node));\n      return args.selection || isWsPreserveElement(Element.fromDom(node)) ? html : Tools.trim(html);\n    };\n    var parseHtml = function (htmlParser, html, args) {\n      var parserArgs = args.selection ? merge({ forced_root_block: false }, args) : args;\n      var rootNode = htmlParser.parse(html, parserArgs);\n      DomSerializerFilters.trimTrailingBr(rootNode);\n      return rootNode;\n    };\n    var serializeNode = function (settings, schema, node) {\n      var htmlSerializer = Serializer(settings, schema);\n      return htmlSerializer.serialize(node);\n    };\n    var toHtml = function (editor, settings, schema, rootNode, args) {\n      var content = serializeNode(settings, schema, rootNode);\n      return postProcess$1(editor, args, content);\n    };\n    var DomSerializer = function (settings, editor) {\n      var dom, schema, htmlParser;\n      var tempAttrs = ['data-mce-selected'];\n      dom = editor && editor.dom ? editor.dom : DOMUtils$1.DOM;\n      schema = editor && editor.schema ? editor.schema : Schema(settings);\n      settings.entity_encoding = settings.entity_encoding || 'named';\n      settings.remove_trailing_brs = 'remove_trailing_brs' in settings ? settings.remove_trailing_brs : true;\n      htmlParser = DomParser(settings, schema);\n      DomSerializerFilters.register(htmlParser, settings, dom);\n      var serialize = function (node, parserArgs) {\n        var args = merge({ format: 'html' }, parserArgs ? parserArgs : {});\n        var targetNode = DomSerializerPreProcess.process(editor, node, args);\n        var html = getHtmlFromNode(dom, targetNode, args);\n        var rootNode = parseHtml(htmlParser, html, args);\n        return args.format === 'tree' ? rootNode : toHtml(editor, settings, schema, rootNode, args);\n      };\n      return {\n        schema: schema,\n        addNodeFilter: htmlParser.addNodeFilter,\n        addAttributeFilter: htmlParser.addAttributeFilter,\n        serialize: serialize,\n        addRules: function (rules) {\n          schema.addValidElements(rules);\n        },\n        setRules: function (rules) {\n          schema.setValidElements(rules);\n        },\n        addTempAttr: curry(addTempAttr, htmlParser, tempAttrs),\n        getTempAttrs: function () {\n          return tempAttrs;\n        }\n      };\n    };\n\n    var Serializer$1 = function (settings, editor) {\n      var domSerializer = DomSerializer(settings, editor);\n      return {\n        schema: domSerializer.schema,\n        addNodeFilter: domSerializer.addNodeFilter,\n        addAttributeFilter: domSerializer.addAttributeFilter,\n        serialize: domSerializer.serialize,\n        addRules: domSerializer.addRules,\n        setRules: domSerializer.setRules,\n        addTempAttr: domSerializer.addTempAttr,\n        getTempAttrs: domSerializer.getTempAttrs\n      };\n    };\n\n    function BookmarkManager(selection) {\n      return {\n        getBookmark: curry(Bookmarks.getBookmark, selection),\n        moveToBookmark: curry(Bookmarks.moveToBookmark, selection)\n      };\n    }\n    (function (BookmarkManager) {\n      BookmarkManager.isBookmarkNode = Bookmarks.isBookmarkNode;\n    }(BookmarkManager || (BookmarkManager = {})));\n    var BookmarkManager$1 = BookmarkManager;\n\n    var isContentEditableFalse$a = NodeType.isContentEditableFalse;\n    var isContentEditableTrue$5 = NodeType.isContentEditableTrue;\n    var getContentEditableRoot$1 = function (root, node) {\n      while (node && node !== root) {\n        if (isContentEditableTrue$5(node) || isContentEditableFalse$a(node)) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return null;\n    };\n    var ControlSelection = function (selection, editor) {\n      var dom = editor.dom, each = Tools.each;\n      var selectedElm, selectedElmGhost, resizeHelper, resizeHandles, selectedHandle;\n      var startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted;\n      var width, height;\n      var editableDoc = editor.getDoc(), rootDocument = domGlobals.document;\n      var abs = Math.abs, round = Math.round, rootElement = editor.getBody();\n      var startScrollWidth, startScrollHeight;\n      resizeHandles = {\n        nw: [\n          0,\n          0,\n          -1,\n          -1\n        ],\n        ne: [\n          1,\n          0,\n          1,\n          -1\n        ],\n        se: [\n          1,\n          1,\n          1,\n          1\n        ],\n        sw: [\n          0,\n          1,\n          -1,\n          1\n        ]\n      };\n      var isImage = function (elm) {\n        return elm && (elm.nodeName === 'IMG' || editor.dom.is(elm, 'figure.image'));\n      };\n      var isEventOnImageOutsideRange = function (evt, range) {\n        if (evt.type === 'longpress' || evt.type.indexOf('touch') === 0) {\n          var touch = evt.touches[0];\n          return isImage(evt.target) && !RangePoint.isXYWithinRange(touch.clientX, touch.clientY, range);\n        } else {\n          return isImage(evt.target) && !RangePoint.isXYWithinRange(evt.clientX, evt.clientY, range);\n        }\n      };\n      var contextMenuSelectImage = function (evt) {\n        var target = evt.target;\n        if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {\n          editor.selection.select(target);\n        }\n      };\n      var getResizeTarget = function (elm) {\n        return editor.dom.is(elm, 'figure.image') ? elm.querySelector('img') : elm;\n      };\n      var isResizable = function (elm) {\n        var selector = editor.settings.object_resizing;\n        if (selector === false || Env.iOS) {\n          return false;\n        }\n        if (typeof selector !== 'string') {\n          selector = 'table,img,figure.image,div';\n        }\n        if (elm.getAttribute('data-mce-resize') === 'false') {\n          return false;\n        }\n        if (elm === editor.getBody()) {\n          return false;\n        }\n        return is(Element.fromDom(elm), selector);\n      };\n      var resizeGhostElement = function (e) {\n        var deltaX, deltaY, proportional;\n        var resizeHelperX, resizeHelperY;\n        deltaX = e.screenX - startX;\n        deltaY = e.screenY - startY;\n        width = deltaX * selectedHandle[2] + startW;\n        height = deltaY * selectedHandle[3] + startH;\n        width = width < 5 ? 5 : width;\n        height = height < 5 ? 5 : height;\n        if (isImage(selectedElm) && editor.settings.resize_img_proportional !== false) {\n          proportional = !VK.modifierPressed(e);\n        } else {\n          proportional = VK.modifierPressed(e) || isImage(selectedElm) && selectedHandle[2] * selectedHandle[3] !== 0;\n        }\n        if (proportional) {\n          if (abs(deltaX) > abs(deltaY)) {\n            height = round(width * ratio);\n            width = round(height / ratio);\n          } else {\n            width = round(height / ratio);\n            height = round(width * ratio);\n          }\n        }\n        dom.setStyles(getResizeTarget(selectedElmGhost), {\n          width: width,\n          height: height\n        });\n        resizeHelperX = selectedHandle.startPos.x + deltaX;\n        resizeHelperY = selectedHandle.startPos.y + deltaY;\n        resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0;\n        resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0;\n        dom.setStyles(resizeHelper, {\n          left: resizeHelperX,\n          top: resizeHelperY,\n          display: 'block'\n        });\n        resizeHelper.innerHTML = width + ' &times; ' + height;\n        if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {\n          dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width));\n        }\n        if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {\n          dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height));\n        }\n        deltaX = rootElement.scrollWidth - startScrollWidth;\n        deltaY = rootElement.scrollHeight - startScrollHeight;\n        if (deltaX + deltaY !== 0) {\n          dom.setStyles(resizeHelper, {\n            left: resizeHelperX - deltaX,\n            top: resizeHelperY - deltaY\n          });\n        }\n        if (!resizeStarted) {\n          Events.fireObjectResizeStart(editor, selectedElm, startW, startH);\n          resizeStarted = true;\n        }\n      };\n      var endGhostResize = function () {\n        resizeStarted = false;\n        var setSizeProp = function (name, value) {\n          if (value) {\n            if (selectedElm.style[name] || !editor.schema.isValid(selectedElm.nodeName.toLowerCase(), name)) {\n              dom.setStyle(getResizeTarget(selectedElm), name, value);\n            } else {\n              dom.setAttrib(getResizeTarget(selectedElm), name, value);\n            }\n          }\n        };\n        setSizeProp('width', width);\n        setSizeProp('height', height);\n        dom.unbind(editableDoc, 'mousemove', resizeGhostElement);\n        dom.unbind(editableDoc, 'mouseup', endGhostResize);\n        if (rootDocument !== editableDoc) {\n          dom.unbind(rootDocument, 'mousemove', resizeGhostElement);\n          dom.unbind(rootDocument, 'mouseup', endGhostResize);\n        }\n        dom.remove(selectedElmGhost);\n        dom.remove(resizeHelper);\n        showResizeRect(selectedElm);\n        Events.fireObjectResized(editor, selectedElm, width, height);\n        dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style'));\n        editor.nodeChanged();\n      };\n      var showResizeRect = function (targetElm) {\n        var position, targetWidth, targetHeight, e, rect;\n        hideResizeRect();\n        unbindResizeHandleEvents();\n        position = dom.getPos(targetElm, rootElement);\n        selectedElmX = position.x;\n        selectedElmY = position.y;\n        rect = targetElm.getBoundingClientRect();\n        targetWidth = rect.width || rect.right - rect.left;\n        targetHeight = rect.height || rect.bottom - rect.top;\n        if (selectedElm !== targetElm) {\n          selectedElm = targetElm;\n          width = height = 0;\n        }\n        e = editor.fire('ObjectSelected', { target: targetElm });\n        if (isResizable(targetElm) && !e.isDefaultPrevented()) {\n          each(resizeHandles, function (handle, name) {\n            var handleElm;\n            var startDrag = function (e) {\n              startX = e.screenX;\n              startY = e.screenY;\n              startW = getResizeTarget(selectedElm).clientWidth;\n              startH = getResizeTarget(selectedElm).clientHeight;\n              ratio = startH / startW;\n              selectedHandle = handle;\n              handle.startPos = {\n                x: targetWidth * handle[0] + selectedElmX,\n                y: targetHeight * handle[1] + selectedElmY\n              };\n              startScrollWidth = rootElement.scrollWidth;\n              startScrollHeight = rootElement.scrollHeight;\n              selectedElmGhost = selectedElm.cloneNode(true);\n              dom.addClass(selectedElmGhost, 'mce-clonedresizable');\n              dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');\n              selectedElmGhost.contentEditable = false;\n              selectedElmGhost.unSelectabe = true;\n              dom.setStyles(selectedElmGhost, {\n                left: selectedElmX,\n                top: selectedElmY,\n                margin: 0\n              });\n              selectedElmGhost.removeAttribute('data-mce-selected');\n              rootElement.appendChild(selectedElmGhost);\n              dom.bind(editableDoc, 'mousemove', resizeGhostElement);\n              dom.bind(editableDoc, 'mouseup', endGhostResize);\n              if (rootDocument !== editableDoc) {\n                dom.bind(rootDocument, 'mousemove', resizeGhostElement);\n                dom.bind(rootDocument, 'mouseup', endGhostResize);\n              }\n              resizeHelper = dom.add(rootElement, 'div', {\n                'class': 'mce-resize-helper',\n                'data-mce-bogus': 'all'\n              }, startW + ' &times; ' + startH);\n            };\n            handleElm = dom.get('mceResizeHandle' + name);\n            if (handleElm) {\n              dom.remove(handleElm);\n            }\n            handleElm = dom.add(rootElement, 'div', {\n              'id': 'mceResizeHandle' + name,\n              'data-mce-bogus': 'all',\n              'class': 'mce-resizehandle',\n              'unselectable': true,\n              'style': 'cursor:' + name + '-resize; margin:0; padding:0'\n            });\n            if (Env.ie === 11) {\n              handleElm.contentEditable = false;\n            }\n            dom.bind(handleElm, 'mousedown', function (e) {\n              e.stopImmediatePropagation();\n              e.preventDefault();\n              startDrag(e);\n            });\n            handle.elm = handleElm;\n            dom.setStyles(handleElm, {\n              left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2,\n              top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2\n            });\n          });\n        } else {\n          hideResizeRect();\n        }\n        selectedElm.setAttribute('data-mce-selected', '1');\n      };\n      var hideResizeRect = function () {\n        var name, handleElm;\n        unbindResizeHandleEvents();\n        if (selectedElm) {\n          selectedElm.removeAttribute('data-mce-selected');\n        }\n        for (name in resizeHandles) {\n          handleElm = dom.get('mceResizeHandle' + name);\n          if (handleElm) {\n            dom.unbind(handleElm);\n            dom.remove(handleElm);\n          }\n        }\n      };\n      var updateResizeRect = function (e) {\n        var startElm, controlElm;\n        var isChildOrEqual = function (node, parent) {\n          if (node) {\n            do {\n              if (node === parent) {\n                return true;\n              }\n            } while (node = node.parentNode);\n          }\n        };\n        if (resizeStarted || editor.removed) {\n          return;\n        }\n        each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function (img) {\n          img.removeAttribute('data-mce-selected');\n        });\n        controlElm = e.type === 'mousedown' ? e.target : selection.getNode();\n        controlElm = dom.$(controlElm).closest('table,img,figure.image,hr')[0];\n        if (isChildOrEqual(controlElm, rootElement)) {\n          disableGeckoResize();\n          startElm = selection.getStart(true);\n          if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) {\n            showResizeRect(controlElm);\n            return;\n          }\n        }\n        hideResizeRect();\n      };\n      var isWithinContentEditableFalse = function (elm) {\n        return isContentEditableFalse$a(getContentEditableRoot$1(editor.getBody(), elm));\n      };\n      var unbindResizeHandleEvents = function () {\n        for (var name in resizeHandles) {\n          var handle = resizeHandles[name];\n          if (handle.elm) {\n            dom.unbind(handle.elm);\n            delete handle.elm;\n          }\n        }\n      };\n      var disableGeckoResize = function () {\n        try {\n          editor.getDoc().execCommand('enableObjectResizing', false, false);\n        } catch (ex) {\n        }\n      };\n      editor.on('init', function () {\n        disableGeckoResize();\n        if (Env.browser.isIE() || Env.browser.isEdge()) {\n          editor.on('mousedown click', function (e) {\n            var target = e.target, nodeName = target.nodeName;\n            if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName) && !isWithinContentEditableFalse(target)) {\n              if (e.button !== 2) {\n                editor.selection.select(target, nodeName === 'TABLE');\n              }\n              if (e.type === 'mousedown') {\n                editor.nodeChanged();\n              }\n            }\n          });\n          editor.dom.bind(rootElement, 'mscontrolselect', function (e) {\n            var delayedSelect = function (node) {\n              Delay.setEditorTimeout(editor, function () {\n                editor.selection.select(node);\n              });\n            };\n            if (isWithinContentEditableFalse(e.target)) {\n              e.preventDefault();\n              delayedSelect(e.target);\n              return;\n            }\n            if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) {\n              e.preventDefault();\n              if (e.target.tagName === 'IMG') {\n                delayedSelect(e.target);\n              }\n            }\n          });\n        }\n        var throttledUpdateResizeRect = Delay.throttle(function (e) {\n          if (!editor.composing) {\n            updateResizeRect(e);\n          }\n        });\n        editor.on('nodechange ResizeEditor ResizeWindow drop FullscreenStateChanged', throttledUpdateResizeRect);\n        editor.on('keyup compositionend', function (e) {\n          if (selectedElm && selectedElm.nodeName === 'TABLE') {\n            throttledUpdateResizeRect(e);\n          }\n        });\n        editor.on('hide blur', hideResizeRect);\n        editor.on('contextmenu longpress', contextMenuSelectImage, true);\n      });\n      editor.on('remove', unbindResizeHandleEvents);\n      var destroy = function () {\n        selectedElm = selectedElmGhost = null;\n      };\n      return {\n        isResizable: isResizable,\n        showResizeRect: showResizeRect,\n        hideResizeRect: hideResizeRect,\n        updateResizeRect: updateResizeRect,\n        destroy: destroy\n      };\n    };\n\n    function Dimension (name, getOffset) {\n      var set = function (element, h) {\n        if (!isNumber(h) && !h.match(/^[0-9]+$/)) {\n          throw new Error(name + '.set accepts only positive integer values. Value was ' + h);\n        }\n        var dom = element.dom();\n        if (isSupported(dom)) {\n          dom.style[name] = h + 'px';\n        }\n      };\n      var get = function (element) {\n        var r = getOffset(element);\n        if (r <= 0 || r === null) {\n          var css = get$2(element, name);\n          return parseFloat(css) || 0;\n        }\n        return r;\n      };\n      var getOuter = get;\n      var aggregate = function (element, properties) {\n        return foldl(properties, function (acc, property) {\n          var val = get$2(element, property);\n          var value = val === undefined ? 0 : parseInt(val, 10);\n          return isNaN(value) ? acc : acc + value;\n        }, 0);\n      };\n      var max = function (element, value, properties) {\n        var cumulativeInclusions = aggregate(element, properties);\n        var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;\n        return absoluteMax;\n      };\n      return {\n        set: set,\n        get: get,\n        getOuter: getOuter,\n        aggregate: aggregate,\n        max: max\n      };\n    }\n\n    var api$1 = Dimension('height', function (element) {\n      var dom = element.dom();\n      return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;\n    });\n    var get$8 = function (element) {\n      return api$1.get(element);\n    };\n\n    var walkUp = function (navigation, doc) {\n      var frame = navigation.view(doc);\n      return frame.fold(constant([]), function (f) {\n        var parent = navigation.owner(f);\n        var rest = walkUp(navigation, parent);\n        return [f].concat(rest);\n      });\n    };\n    var pathTo = function (element, navigation) {\n      var d = navigation.owner(element);\n      return walkUp(navigation, d);\n    };\n\n    var view = function (doc) {\n      var element = doc.dom() === domGlobals.document ? Option.none() : Option.from(doc.dom().defaultView.frameElement);\n      return element.map(Element.fromDom);\n    };\n    var owner$1 = function (element) {\n      return owner(element);\n    };\n\n    var Navigation = /*#__PURE__*/Object.freeze({\n        view: view,\n        owner: owner$1\n    });\n\n    var find$4 = function (element) {\n      var doc = Element.fromDom(domGlobals.document);\n      var scroll = get$3(doc);\n      var frames = pathTo(element, Navigation);\n      var offset = viewport(element);\n      var r = foldr(frames, function (b, a) {\n        var loc = viewport(a);\n        return {\n          left: b.left + loc.left(),\n          top: b.top + loc.top()\n        };\n      }, {\n        left: 0,\n        top: 0\n      });\n      return Position$1(r.left + offset.left() + scroll.left(), r.top + offset.top() + scroll.top());\n    };\n\n    var excludeFromDescend = function (element) {\n      return name(element) === 'textarea';\n    };\n    var descend = function (element, offset) {\n      var children$1 = children(element);\n      if (children$1.length === 0 || excludeFromDescend(element)) {\n        return {\n          element: element,\n          offset: offset\n        };\n      } else if (offset < children$1.length && !excludeFromDescend(children$1[offset])) {\n        return {\n          element: children$1[offset],\n          offset: 0\n        };\n      } else {\n        var last = children$1[children$1.length - 1];\n        if (excludeFromDescend(last)) {\n          return {\n            element: element,\n            offset: offset\n          };\n        } else {\n          if (name(last) === 'img') {\n            return {\n              element: last,\n              offset: 1\n            };\n          } else if (isText$1(last)) {\n            return {\n              element: last,\n              offset: get$6(last).length\n            };\n          } else {\n            return {\n              element: last,\n              offset: children(last).length\n            };\n          }\n        }\n      }\n    };\n    var markerInfo = function (element, cleanupFun) {\n      var pos = absolute(element);\n      var height = get$8(element);\n      return {\n        element: element,\n        bottom: pos.top() + height,\n        pos: pos,\n        cleanup: cleanupFun\n      };\n    };\n    var createMarker = function (element, offset) {\n      var startPoint = descend(element, offset);\n      var span = Element.fromHtml('<span data-mce-bogus=\"all\">' + Zwsp.ZWSP + '</span>');\n      before(startPoint.element, span);\n      return markerInfo(span, function () {\n        return remove$1(span);\n      });\n    };\n    var elementMarker = function (element) {\n      return markerInfo(Element.fromDom(element), noop);\n    };\n    var withMarker = function (editor, f, rng, alignToTop) {\n      preserveWith(editor, function (_s, _e) {\n        return applyWithMarker(editor, f, rng, alignToTop);\n      }, rng);\n    };\n    var applyWithMarker = function (editor, f, rng, alignToTop) {\n      var body = Element.fromDom(editor.getBody());\n      var doc = Element.fromDom(editor.getDoc());\n      reflow(body);\n      var scrollTop = get$3(doc).top();\n      var marker = createMarker(Element.fromDom(rng.startContainer), rng.startOffset);\n      f(doc, scrollTop, marker, alignToTop);\n      marker.cleanup();\n    };\n    var withElement = function (editor, element, f, alignToTop) {\n      var doc = Element.fromDom(editor.getDoc());\n      var scrollTop = get$3(doc).top();\n      f(doc, scrollTop, element, alignToTop);\n    };\n    var preserveWith = function (editor, f, rng) {\n      var startElement = rng.startContainer;\n      var startOffset = rng.startOffset;\n      var endElement = rng.endContainer;\n      var endOffset = rng.endOffset;\n      f(Element.fromDom(startElement), Element.fromDom(endElement));\n      var newRng = editor.dom.createRng();\n      newRng.setStart(startElement, startOffset);\n      newRng.setEnd(endElement, endOffset);\n      editor.selection.setRng(rng);\n    };\n    var fireScrollIntoViewEvent = function (editor, elm, alignToTop) {\n      var scrollEvent = editor.fire('ScrollIntoView', {\n        elm: elm,\n        alignToTop: alignToTop\n      });\n      return scrollEvent.isDefaultPrevented();\n    };\n    var scrollTo = function (marker, viewHeight, alignToTop, doc) {\n      var pos = marker.pos;\n      if (alignToTop) {\n        to(pos.left(), pos.top(), doc);\n      } else {\n        var y = pos.top() - viewHeight + (marker.bottom - pos.top());\n        to(pos.left(), y, doc);\n      }\n    };\n    var intoWindowIfNeeded = function (doc, scrollTop, viewHeight, marker, alignToTop) {\n      if (marker.pos.top() < scrollTop) {\n        scrollTo(marker, viewHeight, alignToTop !== false, doc);\n      } else if (marker.bottom > viewHeight + scrollTop) {\n        scrollTo(marker, viewHeight, alignToTop === true, doc);\n      }\n    };\n    var intoWindow = function (doc, scrollTop, marker, alignToTop) {\n      var viewHeight = doc.dom().defaultView.innerHeight;\n      intoWindowIfNeeded(doc, scrollTop, viewHeight, marker, alignToTop);\n    };\n    var intoFrame = function (editor, doc, scrollTop, marker, alignToTop) {\n      var frameViewHeight = doc.dom().defaultView.innerHeight;\n      intoWindowIfNeeded(doc, scrollTop, frameViewHeight, marker, alignToTop);\n      var op = find$4(marker.element);\n      var viewportBounds = getBounds(domGlobals.window);\n      if (op.top() < viewportBounds.y()) {\n        intoView(marker.element, alignToTop !== false);\n      } else if (op.top() > viewportBounds.bottom()) {\n        intoView(marker.element, alignToTop === true);\n      }\n    };\n    var rangeIntoWindow = function (editor, rng, alignToTop) {\n      return withMarker(editor, curry(intoWindow), rng, alignToTop);\n    };\n    var elementIntoWindow = function (editor, element, alignToTop) {\n      return withElement(editor, elementMarker(element), curry(intoWindow), alignToTop);\n    };\n    var rangeIntoFrame = function (editor, rng, alignToTop) {\n      return withMarker(editor, curry(intoFrame, editor), rng, alignToTop);\n    };\n    var elementIntoFrame = function (editor, element, alignToTop) {\n      return withElement(editor, elementMarker(element), curry(intoFrame, editor), alignToTop);\n    };\n    var elementIntoView = function (editor, element, alignToTop) {\n      if (fireScrollIntoViewEvent(editor, element, alignToTop)) {\n        return;\n      }\n      var scroller = editor.inline ? elementIntoWindow : elementIntoFrame;\n      scroller(editor, element, alignToTop);\n    };\n    var rangeIntoView = function (editor, rng, alignToTop) {\n      var scroller = editor.inline ? rangeIntoWindow : rangeIntoFrame;\n      scroller(editor, rng, alignToTop);\n    };\n    var ScrollIntoView = {\n      scrollElementIntoView: elementIntoView,\n      scrollRangeIntoView: rangeIntoView\n    };\n\n    var hasCeProperty = function (node) {\n      return NodeType.isContentEditableTrue(node) || NodeType.isContentEditableFalse(node);\n    };\n    var findParent = function (node, rootNode, predicate) {\n      while (node && node !== rootNode) {\n        if (predicate(node)) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return null;\n    };\n    var findClosestIeRange = function (clientX, clientY, doc) {\n      var element, rng, rects;\n      element = doc.elementFromPoint(clientX, clientY);\n      rng = doc.body.createTextRange();\n      if (!element || element.tagName === 'HTML') {\n        element = doc.body;\n      }\n      rng.moveToElementText(element);\n      rects = Tools.toArray(rng.getClientRects());\n      rects = rects.sort(function (a, b) {\n        a = Math.abs(Math.max(a.top - clientY, a.bottom - clientY));\n        b = Math.abs(Math.max(b.top - clientY, b.bottom - clientY));\n        return a - b;\n      });\n      if (rects.length > 0) {\n        clientY = (rects[0].bottom + rects[0].top) / 2;\n        try {\n          rng.moveToPoint(clientX, clientY);\n          rng.collapse(true);\n          return rng;\n        } catch (ex) {\n        }\n      }\n      return null;\n    };\n    var moveOutOfContentEditableFalse = function (rng, rootNode) {\n      var parentElement = rng && rng.parentElement ? rng.parentElement() : null;\n      return NodeType.isContentEditableFalse(findParent(parentElement, rootNode, hasCeProperty)) ? null : rng;\n    };\n    var fromPoint$1 = function (clientX, clientY, doc) {\n      var rng, point;\n      var pointDoc = doc;\n      if (pointDoc.caretPositionFromPoint) {\n        point = pointDoc.caretPositionFromPoint(clientX, clientY);\n        if (point) {\n          rng = doc.createRange();\n          rng.setStart(point.offsetNode, point.offset);\n          rng.collapse(true);\n        }\n      } else if (doc.caretRangeFromPoint) {\n        rng = doc.caretRangeFromPoint(clientX, clientY);\n      } else if (pointDoc.body.createTextRange) {\n        rng = pointDoc.body.createTextRange();\n        try {\n          rng.moveToPoint(clientX, clientY);\n          rng.collapse(true);\n        } catch (ex) {\n          rng = findClosestIeRange(clientX, clientY, doc);\n        }\n        return moveOutOfContentEditableFalse(rng, doc.body);\n      }\n      return rng;\n    };\n    var CaretRangeFromPoint = { fromPoint: fromPoint$1 };\n\n    var processRanges = function (editor, ranges) {\n      return map(ranges, function (range) {\n        var evt = editor.fire('GetSelectionRange', { range: range });\n        return evt.range !== range ? evt.range : range;\n      });\n    };\n    var EventProcessRanges = { processRanges: processRanges };\n\n    var fromElements = function (elements, scope) {\n      var doc = scope || domGlobals.document;\n      var fragment = doc.createDocumentFragment();\n      each(elements, function (element) {\n        fragment.appendChild(element.dom());\n      });\n      return Element.fromDom(fragment);\n    };\n\n    var tableModel = Immutable('element', 'width', 'rows');\n    var tableRow = Immutable('element', 'cells');\n    var cellPosition = Immutable('x', 'y');\n    var getSpan = function (td, key) {\n      var value = parseInt(get$1(td, key), 10);\n      return isNaN(value) ? 1 : value;\n    };\n    var fillout = function (table, x, y, tr, td) {\n      var rowspan = getSpan(td, 'rowspan');\n      var colspan = getSpan(td, 'colspan');\n      var rows = table.rows();\n      for (var y2 = y; y2 < y + rowspan; y2++) {\n        if (!rows[y2]) {\n          rows[y2] = tableRow(deep(tr), []);\n        }\n        for (var x2 = x; x2 < x + colspan; x2++) {\n          var cells = rows[y2].cells();\n          cells[x2] = y2 === y && x2 === x ? td : shallow(td);\n        }\n      }\n    };\n    var cellExists = function (table, x, y) {\n      var rows = table.rows();\n      var cells = rows[y] ? rows[y].cells() : [];\n      return !!cells[x];\n    };\n    var skipCellsX = function (table, x, y) {\n      while (cellExists(table, x, y)) {\n        x++;\n      }\n      return x;\n    };\n    var getWidth = function (rows) {\n      return foldl(rows, function (acc, row) {\n        return row.cells().length > acc ? row.cells().length : acc;\n      }, 0);\n    };\n    var findElementPos = function (table, element) {\n      var rows = table.rows();\n      for (var y = 0; y < rows.length; y++) {\n        var cells = rows[y].cells();\n        for (var x = 0; x < cells.length; x++) {\n          if (eq(cells[x], element)) {\n            return Option.some(cellPosition(x, y));\n          }\n        }\n      }\n      return Option.none();\n    };\n    var extractRows = function (table, sx, sy, ex, ey) {\n      var newRows = [];\n      var rows = table.rows();\n      for (var y = sy; y <= ey; y++) {\n        var cells = rows[y].cells();\n        var slice = sx < ex ? cells.slice(sx, ex + 1) : cells.slice(ex, sx + 1);\n        newRows.push(tableRow(rows[y].element(), slice));\n      }\n      return newRows;\n    };\n    var subTable = function (table, startPos, endPos) {\n      var sx = startPos.x(), sy = startPos.y();\n      var ex = endPos.x(), ey = endPos.y();\n      var newRows = sy < ey ? extractRows(table, sx, sy, ex, ey) : extractRows(table, sx, ey, ex, sy);\n      return tableModel(table.element(), getWidth(newRows), newRows);\n    };\n    var createDomTable = function (table, rows) {\n      var tableElement = shallow(table.element());\n      var tableBody = Element.fromTag('tbody');\n      append$1(tableBody, rows);\n      append(tableElement, tableBody);\n      return tableElement;\n    };\n    var modelRowsToDomRows = function (table) {\n      return map(table.rows(), function (row) {\n        var cells = map(row.cells(), function (cell) {\n          var td = deep(cell);\n          remove(td, 'colspan');\n          remove(td, 'rowspan');\n          return td;\n        });\n        var tr = shallow(row.element());\n        append$1(tr, cells);\n        return tr;\n      });\n    };\n    var fromDom$1 = function (tableElm) {\n      var table = tableModel(shallow(tableElm), 0, []);\n      each(descendants$1(tableElm, 'tr'), function (tr, y) {\n        each(descendants$1(tr, 'td,th'), function (td, x) {\n          fillout(table, skipCellsX(table, x, y), y, tr, td);\n        });\n      });\n      return tableModel(table.element(), getWidth(table.rows()), table.rows());\n    };\n    var toDom = function (table) {\n      return createDomTable(table, modelRowsToDomRows(table));\n    };\n    var subsection = function (table, startElement, endElement) {\n      return findElementPos(table, startElement).bind(function (startPos) {\n        return findElementPos(table, endElement).map(function (endPos) {\n          return subTable(table, startPos, endPos);\n        });\n      });\n    };\n    var SimpleTableModel = {\n      fromDom: fromDom$1,\n      toDom: toDom,\n      subsection: subsection\n    };\n\n    var getRanges = function (selection) {\n      var ranges = [];\n      if (selection) {\n        for (var i = 0; i < selection.rangeCount; i++) {\n          ranges.push(selection.getRangeAt(i));\n        }\n      }\n      return ranges;\n    };\n    var getSelectedNodes = function (ranges) {\n      return bind(ranges, function (range) {\n        var node = getSelectedNode(range);\n        return node ? [Element.fromDom(node)] : [];\n      });\n    };\n    var hasMultipleRanges = function (selection) {\n      return getRanges(selection).length > 1;\n    };\n    var MultiRange = {\n      getRanges: getRanges,\n      getSelectedNodes: getSelectedNodes,\n      hasMultipleRanges: hasMultipleRanges\n    };\n\n    var getCellsFromRanges = function (ranges) {\n      return filter(MultiRange.getSelectedNodes(ranges), isTableCell);\n    };\n    var getCellsFromElement = function (elm) {\n      return descendants$1(elm, 'td[data-mce-selected],th[data-mce-selected]');\n    };\n    var getCellsFromElementOrRanges = function (ranges, element) {\n      var selectedCells = getCellsFromElement(element);\n      var rangeCells = getCellsFromRanges(ranges);\n      return selectedCells.length > 0 ? selectedCells : rangeCells;\n    };\n    var getCellsFromEditor = function (editor) {\n      return getCellsFromElementOrRanges(MultiRange.getRanges(editor.selection.getSel()), Element.fromDom(editor.getBody()));\n    };\n    var TableCellSelection = {\n      getCellsFromRanges: getCellsFromRanges,\n      getCellsFromElement: getCellsFromElement,\n      getCellsFromElementOrRanges: getCellsFromElementOrRanges,\n      getCellsFromEditor: getCellsFromEditor\n    };\n\n    var findParentListContainer = function (parents) {\n      return find(parents, function (elm) {\n        return name(elm) === 'ul' || name(elm) === 'ol';\n      });\n    };\n    var getFullySelectedListWrappers = function (parents, rng) {\n      return find(parents, function (elm) {\n        return name(elm) === 'li' && hasAllContentsSelected(elm, rng);\n      }).fold(constant([]), function (li) {\n        return findParentListContainer(parents).map(function (listCont) {\n          return [\n            Element.fromTag('li'),\n            Element.fromTag(name(listCont))\n          ];\n        }).getOr([]);\n      });\n    };\n    var wrap$3 = function (innerElm, elms) {\n      var wrapped = foldl(elms, function (acc, elm) {\n        append(elm, acc);\n        return elm;\n      }, innerElm);\n      return elms.length > 0 ? fromElements([wrapped]) : wrapped;\n    };\n    var directListWrappers = function (commonAnchorContainer) {\n      if (isListItem(commonAnchorContainer)) {\n        return parent(commonAnchorContainer).filter(isList).fold(constant([]), function (listElm) {\n          return [\n            commonAnchorContainer,\n            listElm\n          ];\n        });\n      } else {\n        return isList(commonAnchorContainer) ? [commonAnchorContainer] : [];\n      }\n    };\n    var getWrapElements = function (rootNode, rng) {\n      var commonAnchorContainer = Element.fromDom(rng.commonAncestorContainer);\n      var parents = Parents.parentsAndSelf(commonAnchorContainer, rootNode);\n      var wrapElements = filter(parents, function (elm) {\n        return isInline(elm) || isHeading(elm);\n      });\n      var listWrappers = getFullySelectedListWrappers(parents, rng);\n      var allWrappers = wrapElements.concat(listWrappers.length ? listWrappers : directListWrappers(commonAnchorContainer));\n      return map(allWrappers, shallow);\n    };\n    var emptyFragment = function () {\n      return fromElements([]);\n    };\n    var getFragmentFromRange = function (rootNode, rng) {\n      return wrap$3(Element.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng));\n    };\n    var getParentTable = function (rootElm, cell) {\n      return ancestor$1(cell, 'table', curry(eq, rootElm));\n    };\n    var getTableFragment = function (rootNode, selectedTableCells) {\n      return getParentTable(rootNode, selectedTableCells[0]).bind(function (tableElm) {\n        var firstCell = selectedTableCells[0];\n        var lastCell = selectedTableCells[selectedTableCells.length - 1];\n        var fullTableModel = SimpleTableModel.fromDom(tableElm);\n        return SimpleTableModel.subsection(fullTableModel, firstCell, lastCell).map(function (sectionedTableModel) {\n          return fromElements([SimpleTableModel.toDom(sectionedTableModel)]);\n        });\n      }).getOrThunk(emptyFragment);\n    };\n    var getSelectionFragment = function (rootNode, ranges) {\n      return ranges.length > 0 && ranges[0].collapsed ? emptyFragment() : getFragmentFromRange(rootNode, ranges[0]);\n    };\n    var read$2 = function (rootNode, ranges) {\n      var selectedCells = TableCellSelection.getCellsFromElementOrRanges(ranges, rootNode);\n      return selectedCells.length > 0 ? getTableFragment(rootNode, selectedCells) : getSelectionFragment(rootNode, ranges);\n    };\n    var FragmentReader = { read: read$2 };\n\n    var getTextContent = function (editor) {\n      return Option.from(editor.selection.getRng()).map(function (rng) {\n        var bin = editor.dom.add(editor.getBody(), 'div', {\n          'data-mce-bogus': 'all',\n          'style': 'overflow: hidden; opacity: 0;'\n        }, rng.cloneContents());\n        var text = Zwsp.trim(bin.innerText);\n        editor.dom.remove(bin);\n        return text;\n      }).getOr('');\n    };\n    var getHtmlContent = function (editor, args) {\n      var rng = editor.selection.getRng(), tmpElm = editor.dom.create('body');\n      var sel = editor.selection.getSel();\n      var fragment;\n      var ranges = EventProcessRanges.processRanges(editor, MultiRange.getRanges(sel));\n      fragment = args.contextual ? FragmentReader.read(Element.fromDom(editor.getBody()), ranges).dom() : rng.cloneContents();\n      if (fragment) {\n        tmpElm.appendChild(fragment);\n      }\n      return editor.selection.serializer.serialize(tmpElm, args);\n    };\n    var getContent$1 = function (editor, args) {\n      if (args === void 0) {\n        args = {};\n      }\n      args.get = true;\n      args.format = args.format || 'html';\n      args.selection = true;\n      args = editor.fire('BeforeGetContent', args);\n      if (args.isDefaultPrevented()) {\n        editor.fire('GetContent', args);\n        return args.content;\n      }\n      if (args.format === 'text') {\n        return getTextContent(editor);\n      } else {\n        args.getInner = true;\n        var content = getHtmlContent(editor, args);\n        if (args.format === 'tree') {\n          return content;\n        } else {\n          args.content = editor.selection.isCollapsed() ? '' : content;\n          editor.fire('GetContent', args);\n          return args.content;\n        }\n      }\n    };\n    var GetSelectionContent = { getContent: getContent$1 };\n\n    var findParent$1 = function (node, rootNode, predicate) {\n      while (node && node !== rootNode) {\n        if (predicate(node)) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return null;\n    };\n    var hasParent = function (node, rootNode, predicate) {\n      return findParent$1(node, rootNode, predicate) !== null;\n    };\n    var hasParentWithName = function (node, rootNode, name) {\n      return hasParent(node, rootNode, function (node) {\n        return node.nodeName === name;\n      });\n    };\n    var isTable$3 = function (node) {\n      return node && node.nodeName === 'TABLE';\n    };\n    var isTableCell$3 = function (node) {\n      return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);\n    };\n    var isCeFalseCaretContainer = function (node, rootNode) {\n      return isCaretContainer(node) && hasParent(node, rootNode, isCaretNode) === false;\n    };\n    var hasBrBeforeAfter = function (dom, node, left) {\n      var walker = new TreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || dom.getRoot());\n      while (node = walker[left ? 'prev' : 'next']()) {\n        if (NodeType.isBr(node)) {\n          return true;\n        }\n      }\n    };\n    var isPrevNode = function (node, name) {\n      return node.previousSibling && node.previousSibling.nodeName === name;\n    };\n    var hasContentEditableFalseParent = function (body, node) {\n      while (node && node !== body) {\n        if (NodeType.isContentEditableFalse(node)) {\n          return true;\n        }\n        node = node.parentNode;\n      }\n      return false;\n    };\n    var findTextNodeRelative = function (dom, isAfterNode, collapsed, left, startNode) {\n      var lastInlineElement;\n      var body = dom.getRoot();\n      var node;\n      var nonEmptyElementsMap = dom.schema.getNonEmptyElements();\n      var parentBlockContainer = dom.getParent(startNode.parentNode, dom.isBlock) || body;\n      if (left && NodeType.isBr(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) {\n        return Option.some(CaretPosition(startNode.parentNode, dom.nodeIndex(startNode)));\n      }\n      var walker = new TreeWalker(startNode, parentBlockContainer);\n      while (node = walker[left ? 'prev' : 'next']()) {\n        if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) {\n          return Option.none();\n        }\n        if (NodeType.isText(node) && node.nodeValue.length > 0) {\n          if (hasParentWithName(node, body, 'A') === false) {\n            return Option.some(CaretPosition(node, left ? node.nodeValue.length : 0));\n          }\n          return Option.none();\n        }\n        if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {\n          return Option.none();\n        }\n        lastInlineElement = node;\n      }\n      if (collapsed && lastInlineElement) {\n        return Option.some(CaretPosition(lastInlineElement, 0));\n      }\n      return Option.none();\n    };\n    var normalizeEndPoint = function (dom, collapsed, start, rng) {\n      var container, offset;\n      var body = dom.getRoot();\n      var node, nonEmptyElementsMap;\n      var directionLeft, isAfterNode, normalized = false;\n      container = rng[(start ? 'start' : 'end') + 'Container'];\n      offset = rng[(start ? 'start' : 'end') + 'Offset'];\n      isAfterNode = NodeType.isElement(container) && offset === container.childNodes.length;\n      nonEmptyElementsMap = dom.schema.getNonEmptyElements();\n      directionLeft = start;\n      if (isCaretContainer(container)) {\n        return Option.none();\n      }\n      if (NodeType.isElement(container) && offset > container.childNodes.length - 1) {\n        directionLeft = false;\n      }\n      if (NodeType.isDocument(container)) {\n        container = body;\n        offset = 0;\n      }\n      if (container === body) {\n        if (directionLeft) {\n          node = container.childNodes[offset > 0 ? offset - 1 : 0];\n          if (node) {\n            if (isCaretContainer(node)) {\n              return Option.none();\n            }\n            if (nonEmptyElementsMap[node.nodeName] || isTable$3(node)) {\n              return Option.none();\n            }\n          }\n        }\n        if (container.hasChildNodes()) {\n          offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1);\n          container = container.childNodes[offset];\n          offset = NodeType.isText(container) && isAfterNode ? container.data.length : 0;\n          if (!collapsed && container === body.lastChild && isTable$3(container)) {\n            return Option.none();\n          }\n          if (hasContentEditableFalseParent(body, container) || isCaretContainer(container)) {\n            return Option.none();\n          }\n          if (container.hasChildNodes() && isTable$3(container) === false) {\n            node = container;\n            var walker = new TreeWalker(container, body);\n            do {\n              if (NodeType.isContentEditableFalse(node) || isCaretContainer(node)) {\n                normalized = false;\n                break;\n              }\n              if (NodeType.isText(node) && node.nodeValue.length > 0) {\n                offset = directionLeft ? 0 : node.nodeValue.length;\n                container = node;\n                normalized = true;\n                break;\n              }\n              if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCell$3(node)) {\n                offset = dom.nodeIndex(node);\n                container = node.parentNode;\n                if (!directionLeft) {\n                  offset++;\n                }\n                normalized = true;\n                break;\n              }\n            } while (node = directionLeft ? walker.next() : walker.prev());\n          }\n        }\n      }\n      if (collapsed) {\n        if (NodeType.isText(container) && offset === 0) {\n          findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(function (pos) {\n            container = pos.container();\n            offset = pos.offset();\n            normalized = true;\n          });\n        }\n        if (NodeType.isElement(container)) {\n          node = container.childNodes[offset];\n          if (!node) {\n            node = container.childNodes[offset - 1];\n          }\n          if (node && NodeType.isBr(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) {\n            findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(function (pos) {\n              container = pos.container();\n              offset = pos.offset();\n              normalized = true;\n            });\n          }\n        }\n      }\n      if (directionLeft && !collapsed && NodeType.isText(container) && offset === container.nodeValue.length) {\n        findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(function (pos) {\n          container = pos.container();\n          offset = pos.offset();\n          normalized = true;\n        });\n      }\n      return normalized ? Option.some(CaretPosition(container, offset)) : Option.none();\n    };\n    var normalize$2 = function (dom, rng) {\n      var collapsed = rng.collapsed, normRng = rng.cloneRange();\n      var startPos = CaretPosition.fromRangeStart(rng);\n      normalizeEndPoint(dom, collapsed, true, normRng).each(function (pos) {\n        if (!collapsed || !CaretPosition.isAbove(startPos, pos)) {\n          normRng.setStart(pos.container(), pos.offset());\n        }\n      });\n      if (!collapsed) {\n        normalizeEndPoint(dom, collapsed, false, normRng).each(function (pos) {\n          normRng.setEnd(pos.container(), pos.offset());\n        });\n      }\n      if (collapsed) {\n        normRng.collapse(true);\n      }\n      return RangeCompare.isEq(rng, normRng) ? Option.none() : Option.some(normRng);\n    };\n    var NormalizeRange = { normalize: normalize$2 };\n\n    var prependData = function (target, data) {\n      target.insertData(0, data);\n    };\n    var removeEmpty = function (text) {\n      if (text.dom().length === 0) {\n        remove$1(text);\n        return Option.none();\n      }\n      return Option.some(text);\n    };\n    var rngSetContent = function (rng, fragment) {\n      var firstChild = Option.from(fragment.firstChild).map(Element.fromDom);\n      var lastChild = Option.from(fragment.lastChild).map(Element.fromDom);\n      rng.deleteContents();\n      rng.insertNode(fragment);\n      var prevText = firstChild.bind(prevSibling).filter(isText$1).bind(removeEmpty);\n      var nextText = lastChild.bind(nextSibling).filter(isText$1).bind(removeEmpty);\n      lift2(prevText, firstChild.filter(isText$1), function (prev, start) {\n        prependData(start.dom(), prev.dom().data);\n        remove$1(prev);\n      });\n      lift2(nextText, lastChild.filter(isText$1), function (next, end) {\n        var oldLength = end.dom().length;\n        end.dom().appendData(next.dom().data);\n        rng.setEnd(end.dom(), oldLength);\n        remove$1(next);\n      });\n      rng.collapse(false);\n    };\n    var setupArgs = function (args, content) {\n      args = args || { format: 'html' };\n      args.set = true;\n      args.selection = true;\n      args.content = content;\n      return args;\n    };\n    var setContent$1 = function (editor, content, args) {\n      args = setupArgs(args, content);\n      if (!args.no_events) {\n        args = editor.fire('BeforeSetContent', args);\n        if (args.isDefaultPrevented()) {\n          editor.fire('SetContent', args);\n          return;\n        }\n      }\n      var rng = editor.selection.getRng();\n      rngSetContent(rng, rng.createContextualFragment(args.content));\n      editor.selection.setRng(rng);\n      ScrollIntoView.scrollRangeIntoView(editor, rng);\n      if (!args.no_events) {\n        editor.fire('SetContent', args);\n      }\n    };\n    var SetSelectionContent = { setContent: setContent$1 };\n\n    var getEndpointElement = function (root, rng, start, real, resolve) {\n      var container = start ? rng.startContainer : rng.endContainer;\n      var offset = start ? rng.startOffset : rng.endOffset;\n      return Option.from(container).map(Element.fromDom).map(function (elm) {\n        return !real || !rng.collapsed ? child(elm, resolve(elm, offset)).getOr(elm) : elm;\n      }).bind(function (elm) {\n        return isElement$1(elm) ? Option.some(elm) : parent(elm);\n      }).map(function (elm) {\n        return elm.dom();\n      }).getOr(root);\n    };\n    var getStart$2 = function (root, rng, real) {\n      return getEndpointElement(root, rng, true, real, function (elm, offset) {\n        return Math.min(childNodesCount(elm), offset);\n      });\n    };\n    var getEnd = function (root, rng, real) {\n      return getEndpointElement(root, rng, false, real, function (elm, offset) {\n        return offset > 0 ? offset - 1 : offset;\n      });\n    };\n    var skipEmptyTextNodes = function (node, forwards) {\n      var orig = node;\n      while (node && NodeType.isText(node) && node.length === 0) {\n        node = forwards ? node.nextSibling : node.previousSibling;\n      }\n      return node || orig;\n    };\n    var getNode$1 = function (root, rng) {\n      var elm, startContainer, endContainer, startOffset, endOffset;\n      if (!rng) {\n        return root;\n      }\n      startContainer = rng.startContainer;\n      endContainer = rng.endContainer;\n      startOffset = rng.startOffset;\n      endOffset = rng.endOffset;\n      elm = rng.commonAncestorContainer;\n      if (!rng.collapsed) {\n        if (startContainer === endContainer) {\n          if (endOffset - startOffset < 2) {\n            if (startContainer.hasChildNodes()) {\n              elm = startContainer.childNodes[startOffset];\n            }\n          }\n        }\n        if (startContainer.nodeType === 3 && endContainer.nodeType === 3) {\n          if (startContainer.length === startOffset) {\n            startContainer = skipEmptyTextNodes(startContainer.nextSibling, true);\n          } else {\n            startContainer = startContainer.parentNode;\n          }\n          if (endOffset === 0) {\n            endContainer = skipEmptyTextNodes(endContainer.previousSibling, false);\n          } else {\n            endContainer = endContainer.parentNode;\n          }\n          if (startContainer && startContainer === endContainer) {\n            return startContainer;\n          }\n        }\n      }\n      if (elm && elm.nodeType === 3) {\n        return elm.parentNode;\n      }\n      return elm;\n    };\n    var getSelectedBlocks = function (dom, rng, startElm, endElm) {\n      var node, root;\n      var selectedBlocks = [];\n      root = dom.getRoot();\n      startElm = dom.getParent(startElm || getStart$2(root, rng, rng.collapsed), dom.isBlock);\n      endElm = dom.getParent(endElm || getEnd(root, rng, rng.collapsed), dom.isBlock);\n      if (startElm && startElm !== root) {\n        selectedBlocks.push(startElm);\n      }\n      if (startElm && endElm && startElm !== endElm) {\n        node = startElm;\n        var walker = new TreeWalker(startElm, root);\n        while ((node = walker.next()) && node !== endElm) {\n          if (dom.isBlock(node)) {\n            selectedBlocks.push(node);\n          }\n        }\n      }\n      if (endElm && startElm !== endElm && endElm !== root) {\n        selectedBlocks.push(endElm);\n      }\n      return selectedBlocks;\n    };\n    var select$1 = function (dom, node, content) {\n      return Option.from(node).map(function (node) {\n        var idx = dom.nodeIndex(node);\n        var rng = dom.createRng();\n        rng.setStart(node.parentNode, idx);\n        rng.setEnd(node.parentNode, idx + 1);\n        if (content) {\n          moveEndPoint$1(dom, rng, node, true);\n          moveEndPoint$1(dom, rng, node, false);\n        }\n        return rng;\n      });\n    };\n\n    var deleteFromCallbackMap = function (callbackMap, selector, callback) {\n      if (callbackMap && callbackMap.hasOwnProperty(selector)) {\n        var newCallbacks = filter(callbackMap[selector], function (cb) {\n          return cb !== callback;\n        });\n        if (newCallbacks.length === 0) {\n          delete callbackMap[selector];\n        } else {\n          callbackMap[selector] = newCallbacks;\n        }\n      }\n    };\n    function SelectorChanged (dom, editor) {\n      var selectorChangedData;\n      var currentSelectors;\n      return {\n        selectorChangedWithUnbind: function (selector, callback) {\n          if (!selectorChangedData) {\n            selectorChangedData = {};\n            currentSelectors = {};\n            editor.on('NodeChange', function (e) {\n              var node = e.element, parents = dom.getParents(node, null, dom.getRoot()), matchedSelectors = {};\n              Tools.each(selectorChangedData, function (callbacks, selector) {\n                Tools.each(parents, function (node) {\n                  if (dom.is(node, selector)) {\n                    if (!currentSelectors[selector]) {\n                      Tools.each(callbacks, function (callback) {\n                        callback(true, {\n                          node: node,\n                          selector: selector,\n                          parents: parents\n                        });\n                      });\n                      currentSelectors[selector] = callbacks;\n                    }\n                    matchedSelectors[selector] = callbacks;\n                    return false;\n                  }\n                });\n              });\n              Tools.each(currentSelectors, function (callbacks, selector) {\n                if (!matchedSelectors[selector]) {\n                  delete currentSelectors[selector];\n                  Tools.each(callbacks, function (callback) {\n                    callback(false, {\n                      node: node,\n                      selector: selector,\n                      parents: parents\n                    });\n                  });\n                }\n              });\n            });\n          }\n          if (!selectorChangedData[selector]) {\n            selectorChangedData[selector] = [];\n          }\n          selectorChangedData[selector].push(callback);\n          return {\n            unbind: function () {\n              deleteFromCallbackMap(selectorChangedData, selector, callback);\n              deleteFromCallbackMap(currentSelectors, selector, callback);\n            }\n          };\n        }\n      };\n    }\n\n    var isNativeIeSelection = function (rng) {\n      return !!rng.select;\n    };\n    var isAttachedToDom = function (node) {\n      return !!(node && node.ownerDocument) && contains$2(Element.fromDom(node.ownerDocument), Element.fromDom(node));\n    };\n    var isValidRange = function (rng) {\n      if (!rng) {\n        return false;\n      } else if (isNativeIeSelection(rng)) {\n        return true;\n      } else {\n        return isAttachedToDom(rng.startContainer) && isAttachedToDom(rng.endContainer);\n      }\n    };\n    var Selection$1 = function (dom, win, serializer, editor) {\n      var bookmarkManager;\n      var controlSelection;\n      var selectedRange;\n      var explicitRange;\n      var selectorChangedWithUnbind = SelectorChanged(dom, editor).selectorChangedWithUnbind;\n      var setCursorLocation = function (node, offset) {\n        var rng = dom.createRng();\n        if (!node) {\n          moveEndPoint$1(dom, rng, editor.getBody(), true);\n          setRng(rng);\n        } else {\n          rng.setStart(node, offset);\n          rng.setEnd(node, offset);\n          setRng(rng);\n          collapse(false);\n        }\n      };\n      var getContent = function (args) {\n        return GetSelectionContent.getContent(editor, args);\n      };\n      var setContent = function (content, args) {\n        return SetSelectionContent.setContent(editor, content, args);\n      };\n      var getStart = function (real) {\n        return getStart$2(editor.getBody(), getRng(), real);\n      };\n      var getEnd$1 = function (real) {\n        return getEnd(editor.getBody(), getRng(), real);\n      };\n      var getBookmark = function (type, normalized) {\n        return bookmarkManager.getBookmark(type, normalized);\n      };\n      var moveToBookmark = function (bookmark) {\n        return bookmarkManager.moveToBookmark(bookmark);\n      };\n      var select = function (node, content) {\n        select$1(dom, node, content).each(setRng);\n        return node;\n      };\n      var isCollapsed = function () {\n        var rng = getRng(), sel = getSel();\n        if (!rng || rng.item) {\n          return false;\n        }\n        if (rng.compareEndPoints) {\n          return rng.compareEndPoints('StartToEnd', rng) === 0;\n        }\n        return !sel || rng.collapsed;\n      };\n      var collapse = function (toStart) {\n        var rng = getRng();\n        rng.collapse(!!toStart);\n        setRng(rng);\n      };\n      var getSel = function () {\n        return win.getSelection ? win.getSelection() : win.document.selection;\n      };\n      var getRng = function () {\n        var selection, rng, elm, doc;\n        var tryCompareBoundaryPoints = function (how, sourceRange, destinationRange) {\n          try {\n            return sourceRange.compareBoundaryPoints(how, destinationRange);\n          } catch (ex) {\n            return -1;\n          }\n        };\n        if (!win) {\n          return null;\n        }\n        doc = win.document;\n        if (typeof doc === 'undefined' || doc === null) {\n          return null;\n        }\n        if (editor.bookmark !== undefined && EditorFocus.hasFocus(editor) === false) {\n          var bookmark = SelectionBookmark.getRng(editor);\n          if (bookmark.isSome()) {\n            return bookmark.map(function (r) {\n              return EventProcessRanges.processRanges(editor, [r])[0];\n            }).getOr(doc.createRange());\n          }\n        }\n        try {\n          if ((selection = getSel()) && !NodeType.isRestrictedNode(selection.anchorNode)) {\n            if (selection.rangeCount > 0) {\n              rng = selection.getRangeAt(0);\n            } else {\n              rng = selection.createRange ? selection.createRange() : doc.createRange();\n            }\n          }\n        } catch (ex) {\n        }\n        rng = EventProcessRanges.processRanges(editor, [rng])[0];\n        if (!rng) {\n          rng = doc.createRange ? doc.createRange() : doc.body.createTextRange();\n        }\n        if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) {\n          elm = dom.getRoot();\n          rng.setStart(elm, 0);\n          rng.setEnd(elm, 0);\n        }\n        if (selectedRange && explicitRange) {\n          if (tryCompareBoundaryPoints(rng.START_TO_START, rng, selectedRange) === 0 && tryCompareBoundaryPoints(rng.END_TO_END, rng, selectedRange) === 0) {\n            rng = explicitRange;\n          } else {\n            selectedRange = null;\n            explicitRange = null;\n          }\n        }\n        return rng;\n      };\n      var setRng = function (rng, forward) {\n        var sel, node, evt;\n        if (!isValidRange(rng)) {\n          return;\n        }\n        var ieRange = isNativeIeSelection(rng) ? rng : null;\n        if (ieRange) {\n          explicitRange = null;\n          try {\n            ieRange.select();\n          } catch (ex) {\n          }\n          return;\n        }\n        sel = getSel();\n        evt = editor.fire('SetSelectionRange', {\n          range: rng,\n          forward: forward\n        });\n        rng = evt.range;\n        if (sel) {\n          explicitRange = rng;\n          try {\n            sel.removeAllRanges();\n            sel.addRange(rng);\n          } catch (ex) {\n          }\n          if (forward === false && sel.extend) {\n            sel.collapse(rng.endContainer, rng.endOffset);\n            sel.extend(rng.startContainer, rng.startOffset);\n          }\n          selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n        }\n        if (!rng.collapsed && rng.startContainer === rng.endContainer && sel.setBaseAndExtent && !Env.ie) {\n          if (rng.endOffset - rng.startOffset < 2) {\n            if (rng.startContainer.hasChildNodes()) {\n              node = rng.startContainer.childNodes[rng.startOffset];\n              if (node && node.tagName === 'IMG') {\n                sel.setBaseAndExtent(rng.startContainer, rng.startOffset, rng.endContainer, rng.endOffset);\n                if (sel.anchorNode !== rng.startContainer || sel.focusNode !== rng.endContainer) {\n                  sel.setBaseAndExtent(node, 0, node, 1);\n                }\n              }\n            }\n          }\n        }\n        editor.fire('AfterSetSelectionRange', {\n          range: rng,\n          forward: forward\n        });\n      };\n      var setNode = function (elm) {\n        setContent(dom.getOuterHTML(elm));\n        return elm;\n      };\n      var getNode = function () {\n        return getNode$1(editor.getBody(), getRng());\n      };\n      var getSelectedBlocks$1 = function (startElm, endElm) {\n        return getSelectedBlocks(dom, getRng(), startElm, endElm);\n      };\n      var isForward = function () {\n        var sel = getSel();\n        var anchorRange, focusRange;\n        if (!sel || !sel.anchorNode || !sel.focusNode) {\n          return true;\n        }\n        anchorRange = dom.createRng();\n        anchorRange.setStart(sel.anchorNode, sel.anchorOffset);\n        anchorRange.collapse(true);\n        focusRange = dom.createRng();\n        focusRange.setStart(sel.focusNode, sel.focusOffset);\n        focusRange.collapse(true);\n        return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0;\n      };\n      var normalize = function () {\n        var rng = getRng();\n        var sel = getSel();\n        if (!MultiRange.hasMultipleRanges(sel) && hasAnyRanges(editor)) {\n          var normRng = NormalizeRange.normalize(dom, rng);\n          normRng.each(function (normRng) {\n            setRng(normRng, isForward());\n          });\n          return normRng.getOr(rng);\n        }\n        return rng;\n      };\n      var selectorChanged = function (selector, callback) {\n        selectorChangedWithUnbind(selector, callback);\n        return exports;\n      };\n      var getScrollContainer = function () {\n        var scrollContainer;\n        var node = dom.getRoot();\n        while (node && node.nodeName !== 'BODY') {\n          if (node.scrollHeight > node.clientHeight) {\n            scrollContainer = node;\n            break;\n          }\n          node = node.parentNode;\n        }\n        return scrollContainer;\n      };\n      var scrollIntoView = function (elm, alignToTop) {\n        return ScrollIntoView.scrollElementIntoView(editor, elm, alignToTop);\n      };\n      var placeCaretAt = function (clientX, clientY) {\n        return setRng(CaretRangeFromPoint.fromPoint(clientX, clientY, editor.getDoc()));\n      };\n      var getBoundingClientRect = function () {\n        var rng = getRng();\n        return rng.collapsed ? CaretPosition$1.fromRangeStart(rng).getClientRects()[0] : rng.getBoundingClientRect();\n      };\n      var destroy = function () {\n        win = selectedRange = explicitRange = null;\n        controlSelection.destroy();\n      };\n      var exports = {\n        bookmarkManager: null,\n        controlSelection: null,\n        dom: dom,\n        win: win,\n        serializer: serializer,\n        editor: editor,\n        collapse: collapse,\n        setCursorLocation: setCursorLocation,\n        getContent: getContent,\n        setContent: setContent,\n        getBookmark: getBookmark,\n        moveToBookmark: moveToBookmark,\n        select: select,\n        isCollapsed: isCollapsed,\n        isForward: isForward,\n        setNode: setNode,\n        getNode: getNode,\n        getSel: getSel,\n        setRng: setRng,\n        getRng: getRng,\n        getStart: getStart,\n        getEnd: getEnd$1,\n        getSelectedBlocks: getSelectedBlocks$1,\n        normalize: normalize,\n        selectorChanged: selectorChanged,\n        selectorChangedWithUnbind: selectorChangedWithUnbind,\n        getScrollContainer: getScrollContainer,\n        scrollIntoView: scrollIntoView,\n        placeCaretAt: placeCaretAt,\n        getBoundingClientRect: getBoundingClientRect,\n        destroy: destroy\n      };\n      bookmarkManager = BookmarkManager$1(exports);\n      controlSelection = ControlSelection(exports, editor);\n      exports.bookmarkManager = bookmarkManager;\n      exports.controlSelection = controlSelection;\n      return exports;\n    };\n\n    var isText$8 = NodeType.isText;\n    var startsWithCaretContainer$1 = function (node) {\n      return isText$8(node) && node.data[0] === Zwsp.ZWSP;\n    };\n    var endsWithCaretContainer$1 = function (node) {\n      return isText$8(node) && node.data[node.data.length - 1] === Zwsp.ZWSP;\n    };\n    var createZwsp = function (node) {\n      return node.ownerDocument.createTextNode(Zwsp.ZWSP);\n    };\n    var insertBefore = function (node) {\n      if (isText$8(node.previousSibling)) {\n        if (endsWithCaretContainer$1(node.previousSibling)) {\n          return node.previousSibling;\n        } else {\n          node.previousSibling.appendData(Zwsp.ZWSP);\n          return node.previousSibling;\n        }\n      } else if (isText$8(node)) {\n        if (startsWithCaretContainer$1(node)) {\n          return node;\n        } else {\n          node.insertData(0, Zwsp.ZWSP);\n          return node;\n        }\n      } else {\n        var newNode = createZwsp(node);\n        node.parentNode.insertBefore(newNode, node);\n        return newNode;\n      }\n    };\n    var insertAfter = function (node) {\n      if (isText$8(node.nextSibling)) {\n        if (startsWithCaretContainer$1(node.nextSibling)) {\n          return node.nextSibling;\n        } else {\n          node.nextSibling.insertData(0, Zwsp.ZWSP);\n          return node.nextSibling;\n        }\n      } else if (isText$8(node)) {\n        if (endsWithCaretContainer$1(node)) {\n          return node;\n        } else {\n          node.appendData(Zwsp.ZWSP);\n          return node;\n        }\n      } else {\n        var newNode = createZwsp(node);\n        if (node.nextSibling) {\n          node.parentNode.insertBefore(newNode, node.nextSibling);\n        } else {\n          node.parentNode.appendChild(newNode);\n        }\n        return newNode;\n      }\n    };\n    var insertInline$1 = function (before, node) {\n      return before ? insertBefore(node) : insertAfter(node);\n    };\n    var insertInlineBefore = curry(insertInline$1, true);\n    var insertInlineAfter = curry(insertInline$1, false);\n\n    var insertInlinePos = function (pos, before) {\n      if (NodeType.isText(pos.container())) {\n        return insertInline$1(before, pos.container());\n      } else {\n        return insertInline$1(before, pos.getNode());\n      }\n    };\n    var isPosCaretContainer = function (pos, caret) {\n      var caretNode = caret.get();\n      return caretNode && pos.container() === caretNode && isCaretContainerInline(caretNode);\n    };\n    var renderCaret = function (caret, location) {\n      return location.fold(function (element) {\n        CaretContainerRemove.remove(caret.get());\n        var text = insertInlineBefore(element);\n        caret.set(text);\n        return Option.some(CaretPosition$1(text, text.length - 1));\n      }, function (element) {\n        return CaretFinder.firstPositionIn(element).map(function (pos) {\n          if (!isPosCaretContainer(pos, caret)) {\n            CaretContainerRemove.remove(caret.get());\n            var text = insertInlinePos(pos, true);\n            caret.set(text);\n            return CaretPosition$1(text, 1);\n          } else {\n            return CaretPosition$1(caret.get(), 1);\n          }\n        });\n      }, function (element) {\n        return CaretFinder.lastPositionIn(element).map(function (pos) {\n          if (!isPosCaretContainer(pos, caret)) {\n            CaretContainerRemove.remove(caret.get());\n            var text = insertInlinePos(pos, false);\n            caret.set(text);\n            return CaretPosition$1(text, text.length - 1);\n          } else {\n            return CaretPosition$1(caret.get(), caret.get().length - 1);\n          }\n        });\n      }, function (element) {\n        CaretContainerRemove.remove(caret.get());\n        var text = insertInlineAfter(element);\n        caret.set(text);\n        return Option.some(CaretPosition$1(text, 1));\n      });\n    };\n    var BoundaryCaret = { renderCaret: renderCaret };\n\n    var strongRtl = /[\\u0591-\\u07FF\\uFB1D-\\uFDFF\\uFE70-\\uFEFC]/;\n    var hasStrongRtl = function (text) {\n      return strongRtl.test(text);\n    };\n\n    var isInlineTarget = function (editor, elm) {\n      return is(Element.fromDom(elm), Settings.getInlineBoundarySelector(editor));\n    };\n    var isRtl$1 = function (element) {\n      return DOMUtils$1.DOM.getStyle(element, 'direction', true) === 'rtl' || hasStrongRtl(element.textContent);\n    };\n    var findInlineParents = function (isInlineTarget, rootNode, pos) {\n      return filter(DOMUtils$1.DOM.getParents(pos.container(), '*', rootNode), isInlineTarget);\n    };\n    var findRootInline = function (isInlineTarget, rootNode, pos) {\n      var parents = findInlineParents(isInlineTarget, rootNode, pos);\n      return Option.from(parents[parents.length - 1]);\n    };\n    var hasSameParentBlock = function (rootNode, node1, node2) {\n      var block1 = getParentBlock(node1, rootNode);\n      var block2 = getParentBlock(node2, rootNode);\n      return block1 && block1 === block2;\n    };\n    var isAtZwsp = function (pos) {\n      return isBeforeInline(pos) || isAfterInline(pos);\n    };\n    var normalizePosition = function (forward, pos) {\n      if (!pos) {\n        return pos;\n      }\n      var container = pos.container(), offset = pos.offset();\n      if (forward) {\n        if (isCaretContainerInline(container)) {\n          if (NodeType.isText(container.nextSibling)) {\n            return CaretPosition$1(container.nextSibling, 0);\n          } else {\n            return CaretPosition$1.after(container);\n          }\n        } else {\n          return isBeforeInline(pos) ? CaretPosition$1(container, offset + 1) : pos;\n        }\n      } else {\n        if (isCaretContainerInline(container)) {\n          if (NodeType.isText(container.previousSibling)) {\n            return CaretPosition$1(container.previousSibling, container.previousSibling.data.length);\n          } else {\n            return CaretPosition$1.before(container);\n          }\n        } else {\n          return isAfterInline(pos) ? CaretPosition$1(container, offset - 1) : pos;\n        }\n      }\n    };\n    var normalizeForwards = curry(normalizePosition, true);\n    var normalizeBackwards = curry(normalizePosition, false);\n    var InlineUtils = {\n      isInlineTarget: isInlineTarget,\n      findRootInline: findRootInline,\n      isRtl: isRtl$1,\n      isAtZwsp: isAtZwsp,\n      normalizePosition: normalizePosition,\n      normalizeForwards: normalizeForwards,\n      normalizeBackwards: normalizeBackwards,\n      hasSameParentBlock: hasSameParentBlock\n    };\n\n    var evaluateUntil = function (fns, args) {\n      for (var i = 0; i < fns.length; i++) {\n        var result = fns[i].apply(null, args);\n        if (result.isSome()) {\n          return result;\n        }\n      }\n      return Option.none();\n    };\n    var LazyEvaluator = { evaluateUntil: evaluateUntil };\n\n    var Location = Adt.generate([\n      { before: ['element'] },\n      { start: ['element'] },\n      { end: ['element'] },\n      { after: ['element'] }\n    ]);\n    var rescope = function (rootNode, node) {\n      var parentBlock = getParentBlock(node, rootNode);\n      return parentBlock ? parentBlock : rootNode;\n    };\n    var before$4 = function (isInlineTarget, rootNode, pos) {\n      var nPos = InlineUtils.normalizeForwards(pos);\n      var scope = rescope(rootNode, nPos.container());\n      return InlineUtils.findRootInline(isInlineTarget, scope, nPos).fold(function () {\n        return CaretFinder.nextPosition(scope, nPos).bind(curry(InlineUtils.findRootInline, isInlineTarget, scope)).map(function (inline) {\n          return Location.before(inline);\n        });\n      }, Option.none);\n    };\n    var isNotInsideFormatCaretContainer = function (rootNode, elm) {\n      return getParentCaretContainer(rootNode, elm) === null;\n    };\n    var findInsideRootInline = function (isInlineTarget, rootNode, pos) {\n      return InlineUtils.findRootInline(isInlineTarget, rootNode, pos).filter(curry(isNotInsideFormatCaretContainer, rootNode));\n    };\n    var start$1 = function (isInlineTarget, rootNode, pos) {\n      var nPos = InlineUtils.normalizeBackwards(pos);\n      return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {\n        var prevPos = CaretFinder.prevPosition(inline, nPos);\n        return prevPos.isNone() ? Option.some(Location.start(inline)) : Option.none();\n      });\n    };\n    var end = function (isInlineTarget, rootNode, pos) {\n      var nPos = InlineUtils.normalizeForwards(pos);\n      return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {\n        var nextPos = CaretFinder.nextPosition(inline, nPos);\n        return nextPos.isNone() ? Option.some(Location.end(inline)) : Option.none();\n      });\n    };\n    var after$3 = function (isInlineTarget, rootNode, pos) {\n      var nPos = InlineUtils.normalizeBackwards(pos);\n      var scope = rescope(rootNode, nPos.container());\n      return InlineUtils.findRootInline(isInlineTarget, scope, nPos).fold(function () {\n        return CaretFinder.prevPosition(scope, nPos).bind(curry(InlineUtils.findRootInline, isInlineTarget, scope)).map(function (inline) {\n          return Location.after(inline);\n        });\n      }, Option.none);\n    };\n    var isValidLocation = function (location) {\n      return InlineUtils.isRtl(getElement(location)) === false;\n    };\n    var readLocation = function (isInlineTarget, rootNode, pos) {\n      var location = LazyEvaluator.evaluateUntil([\n        before$4,\n        start$1,\n        end,\n        after$3\n      ], [\n        isInlineTarget,\n        rootNode,\n        pos\n      ]);\n      return location.filter(isValidLocation);\n    };\n    var getElement = function (location) {\n      return location.fold(identity, identity, identity, identity);\n    };\n    var getName = function (location) {\n      return location.fold(constant('before'), constant('start'), constant('end'), constant('after'));\n    };\n    var outside = function (location) {\n      return location.fold(Location.before, Location.before, Location.after, Location.after);\n    };\n    var inside = function (location) {\n      return location.fold(Location.start, Location.start, Location.end, Location.end);\n    };\n    var isEq$5 = function (location1, location2) {\n      return getName(location1) === getName(location2) && getElement(location1) === getElement(location2);\n    };\n    var betweenInlines = function (forward, isInlineTarget, rootNode, from, to, location) {\n      return lift2(InlineUtils.findRootInline(isInlineTarget, rootNode, from), InlineUtils.findRootInline(isInlineTarget, rootNode, to), function (fromInline, toInline) {\n        if (fromInline !== toInline && InlineUtils.hasSameParentBlock(rootNode, fromInline, toInline)) {\n          return Location.after(forward ? fromInline : toInline);\n        } else {\n          return location;\n        }\n      }).getOr(location);\n    };\n    var skipNoMovement = function (fromLocation, toLocation) {\n      return fromLocation.fold(constant(true), function (fromLocation) {\n        return !isEq$5(fromLocation, toLocation);\n      });\n    };\n    var findLocationTraverse = function (forward, isInlineTarget, rootNode, fromLocation, pos) {\n      var from = InlineUtils.normalizePosition(forward, pos);\n      var to = CaretFinder.fromPosition(forward, rootNode, from).map(curry(InlineUtils.normalizePosition, forward));\n      var location = to.fold(function () {\n        return fromLocation.map(outside);\n      }, function (to) {\n        return readLocation(isInlineTarget, rootNode, to).map(curry(betweenInlines, forward, isInlineTarget, rootNode, from, to)).filter(curry(skipNoMovement, fromLocation));\n      });\n      return location.filter(isValidLocation);\n    };\n    var findLocationSimple = function (forward, location) {\n      if (forward) {\n        return location.fold(compose(Option.some, Location.start), Option.none, compose(Option.some, Location.after), Option.none);\n      } else {\n        return location.fold(Option.none, compose(Option.some, Location.before), Option.none, compose(Option.some, Location.end));\n      }\n    };\n    var findLocation = function (forward, isInlineTarget, rootNode, pos) {\n      var from = InlineUtils.normalizePosition(forward, pos);\n      var fromLocation = readLocation(isInlineTarget, rootNode, from);\n      return readLocation(isInlineTarget, rootNode, from).bind(curry(findLocationSimple, forward)).orThunk(function () {\n        return findLocationTraverse(forward, isInlineTarget, rootNode, fromLocation, pos);\n      });\n    };\n    var BoundaryLocation = {\n      readLocation: readLocation,\n      findLocation: findLocation,\n      prevLocation: curry(findLocation, false),\n      nextLocation: curry(findLocation, true),\n      getElement: getElement,\n      outside: outside,\n      inside: inside\n    };\n\n    var hasSelectionModifyApi = function (editor) {\n      return isFunction(editor.selection.getSel().modify);\n    };\n    var moveRel = function (forward, selection, pos) {\n      var delta = forward ? 1 : -1;\n      selection.setRng(CaretPosition$1(pos.container(), pos.offset() + delta).toRange());\n      selection.getSel().modify('move', forward ? 'forward' : 'backward', 'word');\n      return true;\n    };\n    var moveByWord = function (forward, editor) {\n      var rng = editor.selection.getRng();\n      var pos = forward ? CaretPosition$1.fromRangeEnd(rng) : CaretPosition$1.fromRangeStart(rng);\n      if (!hasSelectionModifyApi(editor)) {\n        return false;\n      } else if (forward && isBeforeInline(pos)) {\n        return moveRel(true, editor.selection, pos);\n      } else if (!forward && isAfterInline(pos)) {\n        return moveRel(false, editor.selection, pos);\n      } else {\n        return false;\n      }\n    };\n    var WordSelection = {\n      hasSelectionModifyApi: hasSelectionModifyApi,\n      moveByWord: moveByWord\n    };\n\n    var setCaretPosition = function (editor, pos) {\n      var rng = editor.dom.createRng();\n      rng.setStart(pos.container(), pos.offset());\n      rng.setEnd(pos.container(), pos.offset());\n      editor.selection.setRng(rng);\n    };\n    var isFeatureEnabled = function (editor) {\n      return editor.settings.inline_boundaries !== false;\n    };\n    var setSelected = function (state, elm) {\n      if (state) {\n        elm.setAttribute('data-mce-selected', 'inline-boundary');\n      } else {\n        elm.removeAttribute('data-mce-selected');\n      }\n    };\n    var renderCaretLocation = function (editor, caret, location) {\n      return BoundaryCaret.renderCaret(caret, location).map(function (pos) {\n        setCaretPosition(editor, pos);\n        return location;\n      });\n    };\n    var findLocation$1 = function (editor, caret, forward) {\n      var rootNode = editor.getBody();\n      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);\n      var location = BoundaryLocation.findLocation(forward, isInlineTarget, rootNode, from);\n      return location.bind(function (location) {\n        return renderCaretLocation(editor, caret, location);\n      });\n    };\n    var toggleInlines = function (isInlineTarget, dom, elms) {\n      var selectedInlines = filter(dom.select('*[data-mce-selected=\"inline-boundary\"]'), isInlineTarget);\n      var targetInlines = filter(elms, isInlineTarget);\n      each(difference(selectedInlines, targetInlines), curry(setSelected, false));\n      each(difference(targetInlines, selectedInlines), curry(setSelected, true));\n    };\n    var safeRemoveCaretContainer = function (editor, caret) {\n      if (editor.selection.isCollapsed() && editor.composing !== true && caret.get()) {\n        var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n        if (CaretPosition$1.isTextPosition(pos) && InlineUtils.isAtZwsp(pos) === false) {\n          setCaretPosition(editor, CaretContainerRemove.removeAndReposition(caret.get(), pos));\n          caret.set(null);\n        }\n      }\n    };\n    var renderInsideInlineCaret = function (isInlineTarget, editor, caret, elms) {\n      if (editor.selection.isCollapsed()) {\n        var inlines = filter(elms, isInlineTarget);\n        each(inlines, function (inline) {\n          var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n          BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), pos).bind(function (location) {\n            return renderCaretLocation(editor, caret, location);\n          });\n        });\n      }\n    };\n    var move$1 = function (editor, caret, forward) {\n      return function () {\n        return isFeatureEnabled(editor) ? findLocation$1(editor, caret, forward).isSome() : false;\n      };\n    };\n    var moveWord = function (forward, editor, caret) {\n      return function () {\n        return isFeatureEnabled(editor) ? WordSelection.moveByWord(forward, editor) : false;\n      };\n    };\n    var setupSelectedState = function (editor) {\n      var caret = Cell(null);\n      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);\n      editor.on('NodeChange', function (e) {\n        if (isFeatureEnabled(editor)) {\n          toggleInlines(isInlineTarget, editor.dom, e.parents);\n          safeRemoveCaretContainer(editor, caret);\n          renderInsideInlineCaret(isInlineTarget, editor, caret, e.parents);\n        }\n      });\n      return caret;\n    };\n    var moveNextWord = curry(moveWord, true);\n    var movePrevWord = curry(moveWord, false);\n    var BoundarySelection = {\n      move: move$1,\n      moveNextWord: moveNextWord,\n      movePrevWord: movePrevWord,\n      setupSelectedState: setupSelectedState,\n      setCaretPosition: setCaretPosition\n    };\n\n    var BreakType;\n    (function (BreakType) {\n      BreakType[BreakType['Br'] = 0] = 'Br';\n      BreakType[BreakType['Block'] = 1] = 'Block';\n      BreakType[BreakType['Wrap'] = 2] = 'Wrap';\n      BreakType[BreakType['Eol'] = 3] = 'Eol';\n    }(BreakType || (BreakType = {})));\n    var flip = function (direction, positions) {\n      return direction === HDirection.Backwards ? positions.reverse() : positions;\n    };\n    var walk$3 = function (direction, caretWalker, pos) {\n      return direction === HDirection.Forwards ? caretWalker.next(pos) : caretWalker.prev(pos);\n    };\n    var getBreakType = function (scope, direction, currentPos, nextPos) {\n      if (NodeType.isBr(nextPos.getNode(direction === HDirection.Forwards))) {\n        return BreakType.Br;\n      } else if (isInSameBlock(currentPos, nextPos) === false) {\n        return BreakType.Block;\n      } else {\n        return BreakType.Wrap;\n      }\n    };\n    var getPositionsUntil = function (predicate, direction, scope, start) {\n      var caretWalker = CaretWalker(scope);\n      var currentPos = start, nextPos;\n      var positions = [];\n      while (currentPos) {\n        nextPos = walk$3(direction, caretWalker, currentPos);\n        if (!nextPos) {\n          break;\n        }\n        if (NodeType.isBr(nextPos.getNode(false))) {\n          if (direction === HDirection.Forwards) {\n            return {\n              positions: flip(direction, positions).concat([nextPos]),\n              breakType: BreakType.Br,\n              breakAt: Option.some(nextPos)\n            };\n          } else {\n            return {\n              positions: flip(direction, positions),\n              breakType: BreakType.Br,\n              breakAt: Option.some(nextPos)\n            };\n          }\n        }\n        if (!nextPos.isVisible()) {\n          currentPos = nextPos;\n          continue;\n        }\n        if (predicate(currentPos, nextPos)) {\n          var breakType = getBreakType(scope, direction, currentPos, nextPos);\n          return {\n            positions: flip(direction, positions),\n            breakType: breakType,\n            breakAt: Option.some(nextPos)\n          };\n        }\n        positions.push(nextPos);\n        currentPos = nextPos;\n      }\n      return {\n        positions: flip(direction, positions),\n        breakType: BreakType.Eol,\n        breakAt: Option.none()\n      };\n    };\n    var getAdjacentLinePositions = function (direction, getPositionsUntilBreak, scope, start) {\n      return getPositionsUntilBreak(scope, start).breakAt.map(function (pos) {\n        var positions = getPositionsUntilBreak(scope, pos).positions;\n        return direction === HDirection.Backwards ? positions.concat(pos) : [pos].concat(positions);\n      }).getOr([]);\n    };\n    var findClosestHorizontalPositionFromPoint = function (positions, x) {\n      return foldl(positions, function (acc, newPos) {\n        return acc.fold(function () {\n          return Option.some(newPos);\n        }, function (lastPos) {\n          return lift2(head(lastPos.getClientRects()), head(newPos.getClientRects()), function (lastRect, newRect) {\n            var lastDist = Math.abs(x - lastRect.left);\n            var newDist = Math.abs(x - newRect.left);\n            return newDist <= lastDist ? newPos : lastPos;\n          }).or(acc);\n        });\n      }, Option.none());\n    };\n    var findClosestHorizontalPosition = function (positions, pos) {\n      return head(pos.getClientRects()).bind(function (targetRect) {\n        return findClosestHorizontalPositionFromPoint(positions, targetRect.left);\n      });\n    };\n    var getPositionsUntilPreviousLine = curry(getPositionsUntil, CaretPosition.isAbove, -1);\n    var getPositionsUntilNextLine = curry(getPositionsUntil, CaretPosition.isBelow, 1);\n    var isAtFirstLine = function (scope, pos) {\n      return getPositionsUntilPreviousLine(scope, pos).breakAt.isNone();\n    };\n    var isAtLastLine = function (scope, pos) {\n      return getPositionsUntilNextLine(scope, pos).breakAt.isNone();\n    };\n    var getPositionsAbove = curry(getAdjacentLinePositions, -1, getPositionsUntilPreviousLine);\n    var getPositionsBelow = curry(getAdjacentLinePositions, 1, getPositionsUntilNextLine);\n    var getFirstLinePositions = function (scope) {\n      return CaretFinder.firstPositionIn(scope).map(function (pos) {\n        return [pos].concat(getPositionsUntilNextLine(scope, pos).positions);\n      }).getOr([]);\n    };\n    var getLastLinePositions = function (scope) {\n      return CaretFinder.lastPositionIn(scope).map(function (pos) {\n        return getPositionsUntilPreviousLine(scope, pos).positions.concat(pos);\n      }).getOr([]);\n    };\n\n    var isContentEditableFalse$b = NodeType.isContentEditableFalse;\n    var getSelectedNode$1 = getSelectedNode;\n    var moveToCeFalseHorizontally = function (direction, editor, getNextPosFn, range) {\n      var forwards = direction === HDirection.Forwards;\n      var isBeforeContentEditableFalseFn = forwards ? isBeforeContentEditableFalse : isAfterContentEditableFalse;\n      if (!range.collapsed) {\n        var node = getSelectedNode$1(range);\n        if (isContentEditableFalse$b(node)) {\n          return showCaret(direction, editor, node, direction === HDirection.Backwards, true);\n        }\n      }\n      var rangeIsInContainerBlock = isRangeInCaretContainerBlock(range);\n      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);\n      if (isBeforeContentEditableFalseFn(caretPosition)) {\n        return selectNode(editor, caretPosition.getNode(!forwards));\n      }\n      var nextCaretPosition = InlineUtils.normalizePosition(forwards, getNextPosFn(caretPosition));\n      if (!nextCaretPosition) {\n        if (rangeIsInContainerBlock) {\n          return range;\n        }\n        return null;\n      }\n      if (isBeforeContentEditableFalseFn(nextCaretPosition)) {\n        return showCaret(direction, editor, nextCaretPosition.getNode(!forwards), forwards, true);\n      }\n      var peekCaretPosition = getNextPosFn(nextCaretPosition);\n      if (peekCaretPosition && isBeforeContentEditableFalseFn(peekCaretPosition)) {\n        if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {\n          return showCaret(direction, editor, peekCaretPosition.getNode(!forwards), forwards, true);\n        }\n      }\n      if (rangeIsInContainerBlock) {\n        return renderRangeCaret(editor, nextCaretPosition.toRange(), true);\n      }\n      return null;\n    };\n    var moveToCeFalseVertically = function (direction, editor, walkerFn, range) {\n      var caretPosition, linePositions, nextLinePositions;\n      var closestNextLineRect, caretClientRect, clientX;\n      var dist1, dist2, contentEditableFalseNode;\n      contentEditableFalseNode = getSelectedNode$1(range);\n      caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);\n      linePositions = walkerFn(editor.getBody(), isAboveLine(1), caretPosition);\n      nextLinePositions = filter(linePositions, isLine(1));\n      caretClientRect = ArrUtils.last(caretPosition.getClientRects());\n      if (isBeforeContentEditableFalse(caretPosition) || isBeforeTable(caretPosition)) {\n        contentEditableFalseNode = caretPosition.getNode();\n      }\n      if (isAfterContentEditableFalse(caretPosition) || isAfterTable(caretPosition)) {\n        contentEditableFalseNode = caretPosition.getNode(true);\n      }\n      if (!caretClientRect) {\n        return null;\n      }\n      clientX = caretClientRect.left;\n      closestNextLineRect = findClosestClientRect(nextLinePositions, clientX);\n      if (closestNextLineRect) {\n        if (isContentEditableFalse$b(closestNextLineRect.node)) {\n          dist1 = Math.abs(clientX - closestNextLineRect.left);\n          dist2 = Math.abs(clientX - closestNextLineRect.right);\n          return showCaret(direction, editor, closestNextLineRect.node, dist1 < dist2, true);\n        }\n      }\n      if (contentEditableFalseNode) {\n        var caretPositions = positionsUntil(direction, editor.getBody(), isAboveLine(1), contentEditableFalseNode);\n        closestNextLineRect = findClosestClientRect(filter(caretPositions, isLine(1)), clientX);\n        if (closestNextLineRect) {\n          return renderRangeCaret(editor, closestNextLineRect.position.toRange(), true);\n        }\n        closestNextLineRect = ArrUtils.last(filter(caretPositions, isLine(0)));\n        if (closestNextLineRect) {\n          return renderRangeCaret(editor, closestNextLineRect.position.toRange(), true);\n        }\n      }\n    };\n    var createTextBlock = function (editor) {\n      var textBlock = editor.dom.create(Settings.getForcedRootBlock(editor));\n      if (!Env.ie || Env.ie >= 11) {\n        textBlock.innerHTML = '<br data-mce-bogus=\"1\">';\n      }\n      return textBlock;\n    };\n    var exitPreBlock = function (editor, direction, range) {\n      var pre, caretPos, newBlock;\n      var caretWalker = CaretWalker(editor.getBody());\n      var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);\n      var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);\n      if (range.collapsed && editor.settings.forced_root_block) {\n        pre = editor.dom.getParent(range.startContainer, 'PRE');\n        if (!pre) {\n          return;\n        }\n        if (direction === 1) {\n          caretPos = getNextVisualCaretPosition(CaretPosition$1.fromRangeStart(range));\n        } else {\n          caretPos = getPrevVisualCaretPosition(CaretPosition$1.fromRangeStart(range));\n        }\n        if (!caretPos) {\n          newBlock = createTextBlock(editor);\n          if (direction === 1) {\n            editor.$(pre).after(newBlock);\n          } else {\n            editor.$(pre).before(newBlock);\n          }\n          editor.selection.select(newBlock, true);\n          editor.selection.collapse();\n        }\n      }\n    };\n    var getHorizontalRange = function (editor, forward) {\n      var caretWalker = CaretWalker(editor.getBody());\n      var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);\n      var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);\n      var newRange;\n      var direction = forward ? HDirection.Forwards : HDirection.Backwards;\n      var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition;\n      var range = editor.selection.getRng();\n      newRange = moveToCeFalseHorizontally(direction, editor, getNextPosFn, range);\n      if (newRange) {\n        return newRange;\n      }\n      newRange = exitPreBlock(editor, direction, range);\n      if (newRange) {\n        return newRange;\n      }\n      return null;\n    };\n    var getVerticalRange = function (editor, down) {\n      var newRange;\n      var direction = down ? 1 : -1;\n      var walkerFn = down ? downUntil : upUntil;\n      var range = editor.selection.getRng();\n      newRange = moveToCeFalseVertically(direction, editor, walkerFn, range);\n      if (newRange) {\n        return newRange;\n      }\n      newRange = exitPreBlock(editor, direction, range);\n      if (newRange) {\n        return newRange;\n      }\n      return null;\n    };\n    var moveH = function (editor, forward) {\n      return function () {\n        var newRng = getHorizontalRange(editor, forward);\n        if (newRng) {\n          editor.selection.setRng(newRng);\n          return true;\n        } else {\n          return false;\n        }\n      };\n    };\n    var moveV = function (editor, down) {\n      return function () {\n        var newRng = getVerticalRange(editor, down);\n        if (newRng) {\n          editor.selection.setRng(newRng);\n          return true;\n        } else {\n          return false;\n        }\n      };\n    };\n    var isCefPosition = function (forward) {\n      return function (pos) {\n        return forward ? isAfterContentEditableFalse(pos) : isBeforeContentEditableFalse(pos);\n      };\n    };\n    var moveToLineEndPoint = function (editor, forward) {\n      return function () {\n        var from = forward ? CaretPosition$1.fromRangeEnd(editor.selection.getRng()) : CaretPosition$1.fromRangeStart(editor.selection.getRng());\n        var result = forward ? getPositionsUntilNextLine(editor.getBody(), from) : getPositionsUntilPreviousLine(editor.getBody(), from);\n        var to = forward ? last(result.positions) : head(result.positions);\n        return to.filter(isCefPosition(forward)).fold(constant(false), function (pos) {\n          editor.selection.setRng(pos.toRange());\n          return true;\n        });\n      };\n    };\n\n    var deflate = function (rect, delta) {\n      return {\n        left: rect.left - delta,\n        top: rect.top - delta,\n        right: rect.right + delta * 2,\n        bottom: rect.bottom + delta * 2,\n        width: rect.width + delta,\n        height: rect.height + delta\n      };\n    };\n    var getCorners = function (getYAxisValue, tds) {\n      return bind(tds, function (td) {\n        var rect = deflate(clone$1(td.getBoundingClientRect()), -1);\n        return [\n          {\n            x: rect.left,\n            y: getYAxisValue(rect),\n            cell: td\n          },\n          {\n            x: rect.right,\n            y: getYAxisValue(rect),\n            cell: td\n          }\n        ];\n      });\n    };\n    var findClosestCorner = function (corners, x, y) {\n      return foldl(corners, function (acc, newCorner) {\n        return acc.fold(function () {\n          return Option.some(newCorner);\n        }, function (oldCorner) {\n          var oldDist = Math.sqrt(Math.abs(oldCorner.x - x) + Math.abs(oldCorner.y - y));\n          var newDist = Math.sqrt(Math.abs(newCorner.x - x) + Math.abs(newCorner.y - y));\n          return Option.some(newDist < oldDist ? newCorner : oldCorner);\n        });\n      }, Option.none());\n    };\n    var getClosestCell = function (getYAxisValue, isTargetCorner, table, x, y) {\n      var cells = descendants$1(Element.fromDom(table), 'td,th,caption').map(function (e) {\n        return e.dom();\n      });\n      var corners = filter(getCorners(getYAxisValue, cells), function (corner) {\n        return isTargetCorner(corner, y);\n      });\n      return findClosestCorner(corners, x, y).map(function (corner) {\n        return corner.cell;\n      });\n    };\n    var getBottomValue = function (rect) {\n      return rect.bottom;\n    };\n    var getTopValue = function (rect) {\n      return rect.top;\n    };\n    var isAbove$1 = function (corner, y) {\n      return corner.y < y;\n    };\n    var isBelow$1 = function (corner, y) {\n      return corner.y > y;\n    };\n    var getClosestCellAbove = curry(getClosestCell, getBottomValue, isAbove$1);\n    var getClosestCellBelow = curry(getClosestCell, getTopValue, isBelow$1);\n    var findClosestPositionInAboveCell = function (table, pos) {\n      return head(pos.getClientRects()).bind(function (rect) {\n        return getClosestCellAbove(table, rect.left, rect.top);\n      }).bind(function (cell) {\n        return findClosestHorizontalPosition(getLastLinePositions(cell), pos);\n      });\n    };\n    var findClosestPositionInBelowCell = function (table, pos) {\n      return last(pos.getClientRects()).bind(function (rect) {\n        return getClosestCellBelow(table, rect.left, rect.top);\n      }).bind(function (cell) {\n        return findClosestHorizontalPosition(getFirstLinePositions(cell), pos);\n      });\n    };\n\n    var moveToRange = function (editor, rng) {\n      editor.selection.setRng(rng);\n      ScrollIntoView.scrollRangeIntoView(editor, rng);\n    };\n    var hasNextBreak = function (getPositionsUntil, scope, lineInfo) {\n      return lineInfo.breakAt.map(function (breakPos) {\n        return getPositionsUntil(scope, breakPos).breakAt.isSome();\n      }).getOr(false);\n    };\n    var startsWithWrapBreak = function (lineInfo) {\n      return lineInfo.breakType === BreakType.Wrap && lineInfo.positions.length === 0;\n    };\n    var startsWithBrBreak = function (lineInfo) {\n      return lineInfo.breakType === BreakType.Br && lineInfo.positions.length === 1;\n    };\n    var isAtTableCellLine = function (getPositionsUntil, scope, pos) {\n      var lineInfo = getPositionsUntil(scope, pos);\n      if (startsWithWrapBreak(lineInfo) || !NodeType.isBr(pos.getNode()) && startsWithBrBreak(lineInfo)) {\n        return !hasNextBreak(getPositionsUntil, scope, lineInfo);\n      } else {\n        return lineInfo.breakAt.isNone();\n      }\n    };\n    var isAtFirstTableCellLine = curry(isAtTableCellLine, getPositionsUntilPreviousLine);\n    var isAtLastTableCellLine = curry(isAtTableCellLine, getPositionsUntilNextLine);\n    var isCaretAtStartOrEndOfTable = function (forward, rng, table) {\n      var caretPos = CaretPosition$1.fromRangeStart(rng);\n      return CaretFinder.positionIn(!forward, table).map(function (pos) {\n        return pos.isEqual(caretPos);\n      }).getOr(false);\n    };\n    var navigateHorizontally = function (editor, forward, table, td) {\n      var rng = editor.selection.getRng();\n      var direction = forward ? 1 : -1;\n      if (isFakeCaretTableBrowser() && isCaretAtStartOrEndOfTable(forward, rng, table)) {\n        var newRng = showCaret(direction, editor, table, !forward, true);\n        moveToRange(editor, newRng);\n        return true;\n      }\n      return false;\n    };\n    var getClosestAbovePosition = function (root, table, start) {\n      return findClosestPositionInAboveCell(table, start).orThunk(function () {\n        return head(start.getClientRects()).bind(function (rect) {\n          return findClosestHorizontalPositionFromPoint(getPositionsAbove(root, CaretPosition$1.before(table)), rect.left);\n        });\n      }).getOr(CaretPosition$1.before(table));\n    };\n    var getClosestBelowPosition = function (root, table, start) {\n      return findClosestPositionInBelowCell(table, start).orThunk(function () {\n        return head(start.getClientRects()).bind(function (rect) {\n          return findClosestHorizontalPositionFromPoint(getPositionsBelow(root, CaretPosition$1.after(table)), rect.left);\n        });\n      }).getOr(CaretPosition$1.after(table));\n    };\n    var getTable = function (previous, pos) {\n      var node = pos.getNode(previous);\n      return NodeType.isElement(node) && node.nodeName === 'TABLE' ? Option.some(node) : Option.none();\n    };\n    var renderBlock = function (down, editor, table, pos) {\n      var forcedRootBlock = Settings.getForcedRootBlock(editor);\n      if (forcedRootBlock) {\n        editor.undoManager.transact(function () {\n          var element = Element.fromTag(forcedRootBlock);\n          setAll(element, Settings.getForcedRootBlockAttrs(editor));\n          append(element, Element.fromTag('br'));\n          if (down) {\n            after(Element.fromDom(table), element);\n          } else {\n            before(Element.fromDom(table), element);\n          }\n          var rng = editor.dom.createRng();\n          rng.setStart(element.dom(), 0);\n          rng.setEnd(element.dom(), 0);\n          moveToRange(editor, rng);\n        });\n      } else {\n        moveToRange(editor, pos.toRange());\n      }\n    };\n    var moveCaret = function (editor, down, pos) {\n      var table = down ? getTable(true, pos) : getTable(false, pos);\n      var last = down === false;\n      table.fold(function () {\n        return moveToRange(editor, pos.toRange());\n      }, function (table) {\n        return CaretFinder.positionIn(last, editor.getBody()).filter(function (lastPos) {\n          return lastPos.isEqual(pos);\n        }).fold(function () {\n          return moveToRange(editor, pos.toRange());\n        }, function (_) {\n          return renderBlock(down, editor, table, pos);\n        });\n      });\n    };\n    var navigateVertically = function (editor, down, table, td) {\n      var rng = editor.selection.getRng();\n      var pos = CaretPosition$1.fromRangeStart(rng);\n      var root = editor.getBody();\n      if (!down && isAtFirstTableCellLine(td, pos)) {\n        var newPos = getClosestAbovePosition(root, table, pos);\n        moveCaret(editor, down, newPos);\n        return true;\n      } else if (down && isAtLastTableCellLine(td, pos)) {\n        var newPos = getClosestBelowPosition(root, table, pos);\n        moveCaret(editor, down, newPos);\n        return true;\n      } else {\n        return false;\n      }\n    };\n    var moveH$1 = function (editor, forward) {\n      return function () {\n        return Option.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) {\n          return Option.from(editor.dom.getParent(td, 'table')).map(function (table) {\n            return navigateHorizontally(editor, forward, table);\n          });\n        }).getOr(false);\n      };\n    };\n    var moveV$1 = function (editor, forward) {\n      return function () {\n        return Option.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) {\n          return Option.from(editor.dom.getParent(td, 'table')).map(function (table) {\n            return navigateVertically(editor, forward, table, td);\n          });\n        }).getOr(false);\n      };\n    };\n\n    var isTarget = function (node) {\n      return contains(['figcaption'], name(node));\n    };\n    var rangeBefore = function (target) {\n      var rng = domGlobals.document.createRange();\n      rng.setStartBefore(target.dom());\n      rng.setEndBefore(target.dom());\n      return rng;\n    };\n    var insertElement = function (root, elm, forward) {\n      if (forward) {\n        append(root, elm);\n      } else {\n        prepend(root, elm);\n      }\n    };\n    var insertBr = function (root, forward) {\n      var br = Element.fromTag('br');\n      insertElement(root, br, forward);\n      return rangeBefore(br);\n    };\n    var insertBlock$1 = function (root, forward, blockName, attrs) {\n      var block = Element.fromTag(blockName);\n      var br = Element.fromTag('br');\n      setAll(block, attrs);\n      append(block, br);\n      insertElement(root, block, forward);\n      return rangeBefore(br);\n    };\n    var insertEmptyLine = function (root, rootBlockName, attrs, forward) {\n      if (rootBlockName === '') {\n        return insertBr(root, forward);\n      } else {\n        return insertBlock$1(root, forward, rootBlockName, attrs);\n      }\n    };\n    var getClosestTargetBlock = function (pos, root) {\n      var isRoot = curry(eq, root);\n      return closest(Element.fromDom(pos.container()), isBlock, isRoot).filter(isTarget);\n    };\n    var isAtFirstOrLastLine = function (root, forward, pos) {\n      return forward ? isAtLastLine(root.dom(), pos) : isAtFirstLine(root.dom(), pos);\n    };\n    var moveCaretToNewEmptyLine = function (editor, forward) {\n      var root = Element.fromDom(editor.getBody());\n      var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n      var rootBlock = Settings.getForcedRootBlock(editor);\n      var rootBlockAttrs = Settings.getForcedRootBlockAttrs(editor);\n      return getClosestTargetBlock(pos, root).exists(function () {\n        if (isAtFirstOrLastLine(root, forward, pos)) {\n          var rng = insertEmptyLine(root, rootBlock, rootBlockAttrs, forward);\n          editor.selection.setRng(rng);\n          return true;\n        } else {\n          return false;\n        }\n      });\n    };\n    var moveV$2 = function (editor, forward) {\n      return function () {\n        if (editor.selection.isCollapsed()) {\n          return moveCaretToNewEmptyLine(editor, forward);\n        } else {\n          return false;\n        }\n      };\n    };\n\n    var defaultPatterns = function (patterns) {\n      return map(patterns, function (pattern) {\n        return merge({\n          shiftKey: false,\n          altKey: false,\n          ctrlKey: false,\n          metaKey: false,\n          keyCode: 0,\n          action: noop\n        }, pattern);\n      });\n    };\n    var matchesEvent = function (pattern, evt) {\n      return evt.keyCode === pattern.keyCode && evt.shiftKey === pattern.shiftKey && evt.altKey === pattern.altKey && evt.ctrlKey === pattern.ctrlKey && evt.metaKey === pattern.metaKey;\n    };\n    var match$1 = function (patterns, evt) {\n      return bind(defaultPatterns(patterns), function (pattern) {\n        return matchesEvent(pattern, evt) ? [pattern] : [];\n      });\n    };\n    var action = function (f) {\n      var x = [];\n      for (var _i = 1; _i < arguments.length; _i++) {\n        x[_i - 1] = arguments[_i];\n      }\n      var args = Array.prototype.slice.call(arguments, 1);\n      return function () {\n        return f.apply(null, args);\n      };\n    };\n    var execute = function (patterns, evt) {\n      return find(match$1(patterns, evt), function (pattern) {\n        return pattern.action();\n      });\n    };\n    var MatchKeys = {\n      match: match$1,\n      action: action,\n      execute: execute\n    };\n\n    var executeKeydownOverride = function (editor, caret, evt) {\n      var os = detect$3().os;\n      MatchKeys.execute([\n        {\n          keyCode: VK.RIGHT,\n          action: moveH(editor, true)\n        },\n        {\n          keyCode: VK.LEFT,\n          action: moveH(editor, false)\n        },\n        {\n          keyCode: VK.UP,\n          action: moveV(editor, false)\n        },\n        {\n          keyCode: VK.DOWN,\n          action: moveV(editor, true)\n        },\n        {\n          keyCode: VK.RIGHT,\n          action: moveH$1(editor, true)\n        },\n        {\n          keyCode: VK.LEFT,\n          action: moveH$1(editor, false)\n        },\n        {\n          keyCode: VK.UP,\n          action: moveV$1(editor, false)\n        },\n        {\n          keyCode: VK.DOWN,\n          action: moveV$1(editor, true)\n        },\n        {\n          keyCode: VK.RIGHT,\n          action: BoundarySelection.move(editor, caret, true)\n        },\n        {\n          keyCode: VK.LEFT,\n          action: BoundarySelection.move(editor, caret, false)\n        },\n        {\n          keyCode: VK.RIGHT,\n          ctrlKey: !os.isOSX(),\n          altKey: os.isOSX(),\n          action: BoundarySelection.moveNextWord(editor, caret)\n        },\n        {\n          keyCode: VK.LEFT,\n          ctrlKey: !os.isOSX(),\n          altKey: os.isOSX(),\n          action: BoundarySelection.movePrevWord(editor, caret)\n        },\n        {\n          keyCode: VK.UP,\n          action: moveV$2(editor, false)\n        },\n        {\n          keyCode: VK.DOWN,\n          action: moveV$2(editor, true)\n        }\n      ], evt).each(function (_) {\n        evt.preventDefault();\n      });\n    };\n    var setup$8 = function (editor, caret) {\n      editor.on('keydown', function (evt) {\n        if (evt.isDefaultPrevented() === false) {\n          executeKeydownOverride(editor, caret, evt);\n        }\n      });\n    };\n    var ArrowKeys = { setup: setup$8 };\n\n    var isBeforeRoot = function (rootNode) {\n      return function (elm) {\n        return eq(rootNode, Element.fromDom(elm.dom().parentNode));\n      };\n    };\n    var getParentBlock$1 = function (rootNode, elm) {\n      return contains$2(rootNode, elm) ? closest(elm, function (element) {\n        return isTextBlock(element) || isListItem(element);\n      }, isBeforeRoot(rootNode)) : Option.none();\n    };\n    var placeCaretInEmptyBody = function (editor) {\n      var body = editor.getBody();\n      var node = body.firstChild && editor.dom.isBlock(body.firstChild) ? body.firstChild : body;\n      editor.selection.setCursorLocation(node, 0);\n    };\n    var paddEmptyBody = function (editor) {\n      if (editor.dom.isEmpty(editor.getBody())) {\n        editor.setContent('');\n        placeCaretInEmptyBody(editor);\n      }\n    };\n    var willDeleteLastPositionInElement = function (forward, fromPos, elm) {\n      return lift2(CaretFinder.firstPositionIn(elm), CaretFinder.lastPositionIn(elm), function (firstPos, lastPos) {\n        var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos);\n        var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos);\n        var normalizedFromPos = InlineUtils.normalizePosition(false, fromPos);\n        if (forward) {\n          return CaretFinder.nextPosition(elm, normalizedFromPos).map(function (nextPos) {\n            return nextPos.isEqual(normalizedLastPos) && fromPos.isEqual(normalizedFirstPos);\n          }).getOr(false);\n        } else {\n          return CaretFinder.prevPosition(elm, normalizedFromPos).map(function (prevPos) {\n            return prevPos.isEqual(normalizedFirstPos) && fromPos.isEqual(normalizedLastPos);\n          }).getOr(false);\n        }\n      }).getOr(true);\n    };\n    var DeleteUtils = {\n      getParentBlock: getParentBlock$1,\n      paddEmptyBody: paddEmptyBody,\n      willDeleteLastPositionInElement: willDeleteLastPositionInElement\n    };\n\n    var blockPosition = function (block, position) {\n      return {\n        block: constant(block),\n        position: constant(position)\n      };\n    };\n    var blockBoundary = function (from, to) {\n      return {\n        from: constant(from),\n        to: constant(to)\n      };\n    };\n    var getBlockPosition = function (rootNode, pos) {\n      var rootElm = Element.fromDom(rootNode);\n      var containerElm = Element.fromDom(pos.container());\n      return DeleteUtils.getParentBlock(rootElm, containerElm).map(function (block) {\n        return blockPosition(block, pos);\n      });\n    };\n    var isDifferentBlocks = function (blockBoundary) {\n      return eq(blockBoundary.from().block(), blockBoundary.to().block()) === false;\n    };\n    var hasSameParent = function (blockBoundary) {\n      return parent(blockBoundary.from().block()).bind(function (parent1) {\n        return parent(blockBoundary.to().block()).filter(function (parent2) {\n          return eq(parent1, parent2);\n        });\n      }).isSome();\n    };\n    var isEditable = function (blockBoundary) {\n      return NodeType.isContentEditableFalse(blockBoundary.from().block().dom()) === false && NodeType.isContentEditableFalse(blockBoundary.to().block().dom()) === false;\n    };\n    var skipLastBr = function (rootNode, forward, blockPosition) {\n      if (NodeType.isBr(blockPosition.position().getNode()) && Empty.isEmpty(blockPosition.block()) === false) {\n        return CaretFinder.positionIn(false, blockPosition.block().dom()).bind(function (lastPositionInBlock) {\n          if (lastPositionInBlock.isEqual(blockPosition.position())) {\n            return CaretFinder.fromPosition(forward, rootNode, lastPositionInBlock).bind(function (to) {\n              return getBlockPosition(rootNode, to);\n            });\n          } else {\n            return Option.some(blockPosition);\n          }\n        }).getOr(blockPosition);\n      } else {\n        return blockPosition;\n      }\n    };\n    var readFromRange = function (rootNode, forward, rng) {\n      var fromBlockPos = getBlockPosition(rootNode, CaretPosition$1.fromRangeStart(rng));\n      var toBlockPos = fromBlockPos.bind(function (blockPos) {\n        return CaretFinder.fromPosition(forward, rootNode, blockPos.position()).bind(function (to) {\n          return getBlockPosition(rootNode, to).map(function (blockPos) {\n            return skipLastBr(rootNode, forward, blockPos);\n          });\n        });\n      });\n      return lift2(fromBlockPos, toBlockPos, blockBoundary).filter(function (blockBoundary) {\n        return isDifferentBlocks(blockBoundary) && hasSameParent(blockBoundary) && isEditable(blockBoundary);\n      });\n    };\n    var read$3 = function (rootNode, forward, rng) {\n      return rng.collapsed ? readFromRange(rootNode, forward, rng) : Option.none();\n    };\n    var BlockMergeBoundary = { read: read$3 };\n\n    var getChildrenUntilBlockBoundary = function (block) {\n      var children$1 = children(block);\n      return findIndex(children$1, isBlock).fold(function () {\n        return children$1;\n      }, function (index) {\n        return children$1.slice(0, index);\n      });\n    };\n    var extractChildren = function (block) {\n      var children = getChildrenUntilBlockBoundary(block);\n      each(children, remove$1);\n      return children;\n    };\n    var removeEmptyRoot = function (rootNode, block) {\n      var parents = Parents.parentsAndSelf(block, rootNode);\n      return find(parents.reverse(), Empty.isEmpty).each(remove$1);\n    };\n    var isEmptyBefore = function (el) {\n      return filter(prevSiblings(el), function (el) {\n        return !Empty.isEmpty(el);\n      }).length === 0;\n    };\n    var nestedBlockMerge = function (rootNode, fromBlock, toBlock, insertionPoint) {\n      if (Empty.isEmpty(toBlock)) {\n        PaddingBr.fillWithPaddingBr(toBlock);\n        return CaretFinder.firstPositionIn(toBlock.dom());\n      }\n      if (isEmptyBefore(insertionPoint) && Empty.isEmpty(fromBlock)) {\n        before(insertionPoint, Element.fromTag('br'));\n      }\n      var position = CaretFinder.prevPosition(toBlock.dom(), CaretPosition$1.before(insertionPoint.dom()));\n      each(extractChildren(fromBlock), function (child) {\n        before(insertionPoint, child);\n      });\n      removeEmptyRoot(rootNode, fromBlock);\n      return position;\n    };\n    var sidelongBlockMerge = function (rootNode, fromBlock, toBlock) {\n      if (Empty.isEmpty(toBlock)) {\n        remove$1(toBlock);\n        if (Empty.isEmpty(fromBlock)) {\n          PaddingBr.fillWithPaddingBr(fromBlock);\n        }\n        return CaretFinder.firstPositionIn(fromBlock.dom());\n      }\n      var position = CaretFinder.lastPositionIn(toBlock.dom());\n      each(extractChildren(fromBlock), function (child) {\n        append(toBlock, child);\n      });\n      removeEmptyRoot(rootNode, fromBlock);\n      return position;\n    };\n    var findInsertionPoint = function (toBlock, block) {\n      var parentsAndSelf = Parents.parentsAndSelf(block, toBlock);\n      return Option.from(parentsAndSelf[parentsAndSelf.length - 1]);\n    };\n    var getInsertionPoint = function (fromBlock, toBlock) {\n      return contains$2(toBlock, fromBlock) ? findInsertionPoint(toBlock, fromBlock) : Option.none();\n    };\n    var trimBr = function (first, block) {\n      CaretFinder.positionIn(first, block.dom()).map(function (position) {\n        return position.getNode();\n      }).map(Element.fromDom).filter(isBr$1).each(remove$1);\n    };\n    var mergeBlockInto = function (rootNode, fromBlock, toBlock) {\n      trimBr(true, fromBlock);\n      trimBr(false, toBlock);\n      return getInsertionPoint(fromBlock, toBlock).fold(curry(sidelongBlockMerge, rootNode, fromBlock, toBlock), curry(nestedBlockMerge, rootNode, fromBlock, toBlock));\n    };\n    var mergeBlocks = function (rootNode, forward, block1, block2) {\n      return forward ? mergeBlockInto(rootNode, block2, block1) : mergeBlockInto(rootNode, block1, block2);\n    };\n    var MergeBlocks = { mergeBlocks: mergeBlocks };\n\n    var backspaceDelete = function (editor, forward) {\n      var rootNode = Element.fromDom(editor.getBody());\n      var position = BlockMergeBoundary.read(rootNode.dom(), forward, editor.selection.getRng()).bind(function (blockBoundary) {\n        return MergeBlocks.mergeBlocks(rootNode, forward, blockBoundary.from().block(), blockBoundary.to().block());\n      });\n      position.each(function (pos) {\n        editor.selection.setRng(pos.toRange());\n      });\n      return position.isSome();\n    };\n    var BlockBoundaryDelete = { backspaceDelete: backspaceDelete };\n\n    var deleteRangeMergeBlocks = function (rootNode, selection) {\n      var rng = selection.getRng();\n      return lift2(DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.startContainer)), DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.endContainer)), function (block1, block2) {\n        if (eq(block1, block2) === false) {\n          rng.deleteContents();\n          MergeBlocks.mergeBlocks(rootNode, true, block1, block2).each(function (pos) {\n            selection.setRng(pos.toRange());\n          });\n          return true;\n        } else {\n          return false;\n        }\n      }).getOr(false);\n    };\n    var isRawNodeInTable = function (root, rawNode) {\n      var node = Element.fromDom(rawNode);\n      var isRoot = curry(eq, root);\n      return ancestor(node, isTableCell, isRoot).isSome();\n    };\n    var isSelectionInTable = function (root, rng) {\n      return isRawNodeInTable(root, rng.startContainer) || isRawNodeInTable(root, rng.endContainer);\n    };\n    var isEverythingSelected = function (root, rng) {\n      var noPrevious = CaretFinder.prevPosition(root.dom(), CaretPosition$1.fromRangeStart(rng)).isNone();\n      var noNext = CaretFinder.nextPosition(root.dom(), CaretPosition$1.fromRangeEnd(rng)).isNone();\n      return !isSelectionInTable(root, rng) && noPrevious && noNext;\n    };\n    var emptyEditor = function (editor) {\n      editor.setContent('');\n      editor.selection.setCursorLocation();\n      return true;\n    };\n    var deleteRange = function (editor) {\n      var rootNode = Element.fromDom(editor.getBody());\n      var rng = editor.selection.getRng();\n      return isEverythingSelected(rootNode, rng) ? emptyEditor(editor) : deleteRangeMergeBlocks(rootNode, editor.selection);\n    };\n    var backspaceDelete$1 = function (editor, forward) {\n      return editor.selection.isCollapsed() ? false : deleteRange(editor);\n    };\n    var BlockRangeDelete = { backspaceDelete: backspaceDelete$1 };\n\n    var isBr$5 = function (pos) {\n      return getElementFromPosition(pos).exists(isBr$1);\n    };\n    var findBr = function (forward, root, pos) {\n      var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);\n      var scope = head(parentBlocks).getOr(root);\n      return CaretFinder.fromPosition(forward, scope.dom(), pos).filter(isBr$5);\n    };\n    var isBeforeBr = function (root, pos) {\n      return getElementFromPosition(pos).exists(isBr$1) || findBr(true, root, pos).isSome();\n    };\n    var isAfterBr = function (root, pos) {\n      return getElementFromPrevPosition(pos).exists(isBr$1) || findBr(false, root, pos).isSome();\n    };\n    var findPreviousBr = curry(findBr, false);\n    var findNextBr = curry(findBr, true);\n\n    var isCompoundElement = function (node) {\n      return isTableCell(Element.fromDom(node)) || isListItem(Element.fromDom(node));\n    };\n    var DeleteAction = Adt.generate([\n      { remove: ['element'] },\n      { moveToElement: ['element'] },\n      { moveToPosition: ['position'] }\n    ]);\n    var isAtContentEditableBlockCaret = function (forward, from) {\n      var elm = from.getNode(forward === false);\n      var caretLocation = forward ? 'after' : 'before';\n      return NodeType.isElement(elm) && elm.getAttribute('data-mce-caret') === caretLocation;\n    };\n    var isDeleteFromCefDifferentBlocks = function (root, forward, from, to) {\n      var inSameBlock = function (elm) {\n        return isInline(Element.fromDom(elm)) && !isInSameBlock(from, to, root);\n      };\n      return getRelativeCefElm(!forward, from).fold(function () {\n        return getRelativeCefElm(forward, to).fold(constant(false), inSameBlock);\n      }, inSameBlock);\n    };\n    var deleteEmptyBlockOrMoveToCef = function (root, forward, from, to) {\n      var toCefElm = to.getNode(forward === false);\n      return DeleteUtils.getParentBlock(Element.fromDom(root), Element.fromDom(from.getNode())).map(function (blockElm) {\n        return Empty.isEmpty(blockElm) ? DeleteAction.remove(blockElm.dom()) : DeleteAction.moveToElement(toCefElm);\n      }).orThunk(function () {\n        return Option.some(DeleteAction.moveToElement(toCefElm));\n      });\n    };\n    var findCefPosition = function (root, forward, from) {\n      return CaretFinder.fromPosition(forward, root, from).bind(function (to) {\n        if (isCompoundElement(to.getNode())) {\n          return Option.none();\n        } else if (isDeleteFromCefDifferentBlocks(root, forward, from, to)) {\n          return Option.none();\n        } else if (forward && NodeType.isContentEditableFalse(to.getNode())) {\n          return deleteEmptyBlockOrMoveToCef(root, forward, from, to);\n        } else if (forward === false && NodeType.isContentEditableFalse(to.getNode(true))) {\n          return deleteEmptyBlockOrMoveToCef(root, forward, from, to);\n        } else if (forward && isAfterContentEditableFalse(from)) {\n          return Option.some(DeleteAction.moveToPosition(to));\n        } else if (forward === false && isBeforeContentEditableFalse(from)) {\n          return Option.some(DeleteAction.moveToPosition(to));\n        } else {\n          return Option.none();\n        }\n      });\n    };\n    var getContentEditableBlockAction = function (forward, elm) {\n      if (forward && NodeType.isContentEditableFalse(elm.nextSibling)) {\n        return Option.some(DeleteAction.moveToElement(elm.nextSibling));\n      } else if (forward === false && NodeType.isContentEditableFalse(elm.previousSibling)) {\n        return Option.some(DeleteAction.moveToElement(elm.previousSibling));\n      } else {\n        return Option.none();\n      }\n    };\n    var skipMoveToActionFromInlineCefToContent = function (root, from, deleteAction) {\n      return deleteAction.fold(function (elm) {\n        return Option.some(DeleteAction.remove(elm));\n      }, function (elm) {\n        return Option.some(DeleteAction.moveToElement(elm));\n      }, function (to) {\n        if (isInSameBlock(from, to, root)) {\n          return Option.none();\n        } else {\n          return Option.some(DeleteAction.moveToPosition(to));\n        }\n      });\n    };\n    var getContentEditableAction = function (root, forward, from) {\n      if (isAtContentEditableBlockCaret(forward, from)) {\n        return getContentEditableBlockAction(forward, from.getNode(forward === false)).fold(function () {\n          return findCefPosition(root, forward, from);\n        }, Option.some);\n      } else {\n        return findCefPosition(root, forward, from).bind(function (deleteAction) {\n          return skipMoveToActionFromInlineCefToContent(root, from, deleteAction);\n        });\n      }\n    };\n    var read$4 = function (root, forward, rng) {\n      var normalizedRange = normalizeRange(forward ? 1 : -1, root, rng);\n      var from = CaretPosition$1.fromRangeStart(normalizedRange);\n      var rootElement = Element.fromDom(root);\n      if (forward === false && isAfterContentEditableFalse(from)) {\n        return Option.some(DeleteAction.remove(from.getNode(true)));\n      } else if (forward && isBeforeContentEditableFalse(from)) {\n        return Option.some(DeleteAction.remove(from.getNode()));\n      } else if (forward === false && isBeforeContentEditableFalse(from) && isAfterBr(rootElement, from)) {\n        return findPreviousBr(rootElement, from).map(function (br) {\n          return DeleteAction.remove(br.getNode());\n        });\n      } else if (forward && isAfterContentEditableFalse(from) && isBeforeBr(rootElement, from)) {\n        return findNextBr(rootElement, from).map(function (br) {\n          return DeleteAction.remove(br.getNode());\n        });\n      } else {\n        return getContentEditableAction(root, forward, from);\n      }\n    };\n\n    var deleteElement$1 = function (editor, forward) {\n      return function (element) {\n        editor._selectionOverrides.hideFakeCaret();\n        DeleteElement.deleteElement(editor, forward, Element.fromDom(element));\n        return true;\n      };\n    };\n    var moveToElement = function (editor, forward) {\n      return function (element) {\n        var pos = forward ? CaretPosition$1.before(element) : CaretPosition$1.after(element);\n        editor.selection.setRng(pos.toRange());\n        return true;\n      };\n    };\n    var moveToPosition = function (editor) {\n      return function (pos) {\n        editor.selection.setRng(pos.toRange());\n        return true;\n      };\n    };\n    var getAncestorCe = function (editor, node) {\n      return Option.from(getContentEditableRoot$2(editor.getBody(), node));\n    };\n    var backspaceDeleteCaret = function (editor, forward) {\n      var selectedNode = editor.selection.getNode();\n      return getAncestorCe(editor, selectedNode).filter(NodeType.isContentEditableFalse).fold(function () {\n        var result = read$4(editor.getBody(), forward, editor.selection.getRng()).map(function (deleteAction) {\n          return deleteAction.fold(deleteElement$1(editor, forward), moveToElement(editor, forward), moveToPosition(editor));\n        });\n        return result.getOr(false);\n      }, function () {\n        return true;\n      });\n    };\n    var deleteOffscreenSelection = function (rootElement) {\n      each(descendants$1(rootElement, '.mce-offscreen-selection'), remove$1);\n    };\n    var backspaceDeleteRange = function (editor, forward) {\n      var selectedNode = editor.selection.getNode();\n      if (NodeType.isContentEditableFalse(selectedNode)) {\n        var hasCefAncestor = getAncestorCe(editor, selectedNode.parentNode).filter(NodeType.isContentEditableFalse);\n        return hasCefAncestor.fold(function () {\n          deleteOffscreenSelection(Element.fromDom(editor.getBody()));\n          DeleteElement.deleteElement(editor, forward, Element.fromDom(editor.selection.getNode()));\n          DeleteUtils.paddEmptyBody(editor);\n          return true;\n        }, function () {\n          return true;\n        });\n      }\n      return false;\n    };\n    var getContentEditableRoot$2 = function (root, node) {\n      while (node && node !== root) {\n        if (NodeType.isContentEditableTrue(node) || NodeType.isContentEditableFalse(node)) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return null;\n    };\n    var paddEmptyElement = function (editor) {\n      var br;\n      var ceRoot = getContentEditableRoot$2(editor.getBody(), editor.selection.getNode());\n      if (NodeType.isContentEditableTrue(ceRoot) && editor.dom.isBlock(ceRoot) && editor.dom.isEmpty(ceRoot)) {\n        br = editor.dom.create('br', { 'data-mce-bogus': '1' });\n        editor.dom.setHTML(ceRoot, '');\n        ceRoot.appendChild(br);\n        editor.selection.setRng(CaretPosition$1.before(br).toRange());\n      }\n      return true;\n    };\n    var backspaceDelete$2 = function (editor, forward) {\n      if (editor.selection.isCollapsed()) {\n        return backspaceDeleteCaret(editor, forward);\n      } else {\n        return backspaceDeleteRange(editor, forward);\n      }\n    };\n    var CefDelete = {\n      backspaceDelete: backspaceDelete$2,\n      paddEmptyElement: paddEmptyElement\n    };\n\n    var trimEmptyTextNode$1 = function (dom, node) {\n      if (NodeType.isText(node) && node.data.length === 0) {\n        dom.remove(node);\n      }\n    };\n    var deleteContentAndShowCaret = function (editor, range, node, direction, forward, peekCaretPosition) {\n      var caretRange = showCaret(direction, editor, peekCaretPosition.getNode(!forward), forward, true);\n      if (range.collapsed) {\n        var deleteRange = range.cloneRange();\n        if (forward) {\n          deleteRange.setEnd(caretRange.startContainer, caretRange.startOffset);\n        } else {\n          deleteRange.setStart(caretRange.endContainer, caretRange.endOffset);\n        }\n        deleteRange.deleteContents();\n      } else {\n        range.deleteContents();\n      }\n      editor.selection.setRng(caretRange);\n      trimEmptyTextNode$1(editor.dom, node);\n      return true;\n    };\n    var deleteCefBoundaryText = function (editor, forward) {\n      var range = editor.selection.getRng();\n      if (!NodeType.isText(range.commonAncestorContainer)) {\n        return false;\n      }\n      var direction = forward ? HDirection.Forwards : HDirection.Backwards;\n      var caretWalker = CaretWalker(editor.getBody());\n      var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);\n      var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);\n      var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition;\n      var isBeforeContentEditableFalseFn = forward ? isBeforeContentEditableFalse : isAfterContentEditableFalse;\n      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);\n      var nextCaretPosition = InlineUtils.normalizePosition(forward, getNextPosFn(caretPosition));\n      if (!nextCaretPosition || !isMoveInsideSameBlock(caretPosition, nextCaretPosition)) {\n        return false;\n      } else if (isBeforeContentEditableFalseFn(nextCaretPosition)) {\n        return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, nextCaretPosition);\n      }\n      var peekCaretPosition = getNextPosFn(nextCaretPosition);\n      if (peekCaretPosition && isBeforeContentEditableFalseFn(peekCaretPosition)) {\n        if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {\n          return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, peekCaretPosition);\n        }\n      }\n      return false;\n    };\n    var backspaceDelete$3 = function (editor, forward) {\n      return deleteCefBoundaryText(editor, forward);\n    };\n    var CefBoundaryDelete = { backspaceDelete: backspaceDelete$3 };\n\n    var isFeatureEnabled$1 = function (editor) {\n      return editor.settings.inline_boundaries !== false;\n    };\n    var rangeFromPositions = function (from, to) {\n      var range = domGlobals.document.createRange();\n      range.setStart(from.container(), from.offset());\n      range.setEnd(to.container(), to.offset());\n      return range;\n    };\n    var hasOnlyTwoOrLessPositionsLeft = function (elm) {\n      return lift2(CaretFinder.firstPositionIn(elm), CaretFinder.lastPositionIn(elm), function (firstPos, lastPos) {\n        var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos);\n        var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos);\n        return CaretFinder.nextPosition(elm, normalizedFirstPos).map(function (pos) {\n          return pos.isEqual(normalizedLastPos);\n        }).getOr(true);\n      }).getOr(true);\n    };\n    var setCaretLocation = function (editor, caret) {\n      return function (location) {\n        return BoundaryCaret.renderCaret(caret, location).map(function (pos) {\n          BoundarySelection.setCaretPosition(editor, pos);\n          return true;\n        }).getOr(false);\n      };\n    };\n    var deleteFromTo = function (editor, caret, from, to) {\n      var rootNode = editor.getBody();\n      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);\n      editor.undoManager.ignore(function () {\n        editor.selection.setRng(rangeFromPositions(from, to));\n        editor.execCommand('Delete');\n        BoundaryLocation.readLocation(isInlineTarget, rootNode, CaretPosition$1.fromRangeStart(editor.selection.getRng())).map(BoundaryLocation.inside).map(setCaretLocation(editor, caret));\n      });\n      editor.nodeChanged();\n    };\n    var rescope$1 = function (rootNode, node) {\n      var parentBlock = getParentBlock(node, rootNode);\n      return parentBlock ? parentBlock : rootNode;\n    };\n    var backspaceDeleteCollapsed = function (editor, caret, forward, from) {\n      var rootNode = rescope$1(editor.getBody(), from.container());\n      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);\n      var fromLocation = BoundaryLocation.readLocation(isInlineTarget, rootNode, from);\n      return fromLocation.bind(function (location) {\n        if (forward) {\n          return location.fold(constant(Option.some(BoundaryLocation.inside(location))), Option.none, constant(Option.some(BoundaryLocation.outside(location))), Option.none);\n        } else {\n          return location.fold(Option.none, constant(Option.some(BoundaryLocation.outside(location))), Option.none, constant(Option.some(BoundaryLocation.inside(location))));\n        }\n      }).map(setCaretLocation(editor, caret)).getOrThunk(function () {\n        var toPosition = CaretFinder.navigate(forward, rootNode, from);\n        var toLocation = toPosition.bind(function (pos) {\n          return BoundaryLocation.readLocation(isInlineTarget, rootNode, pos);\n        });\n        if (fromLocation.isSome() && toLocation.isSome()) {\n          return InlineUtils.findRootInline(isInlineTarget, rootNode, from).map(function (elm) {\n            if (hasOnlyTwoOrLessPositionsLeft(elm)) {\n              DeleteElement.deleteElement(editor, forward, Element.fromDom(elm));\n              return true;\n            } else {\n              return false;\n            }\n          }).getOr(false);\n        } else {\n          return toLocation.bind(function (_) {\n            return toPosition.map(function (to) {\n              if (forward) {\n                deleteFromTo(editor, caret, from, to);\n              } else {\n                deleteFromTo(editor, caret, to, from);\n              }\n              return true;\n            });\n          }).getOr(false);\n        }\n      });\n    };\n    var backspaceDelete$4 = function (editor, caret, forward) {\n      if (editor.selection.isCollapsed() && isFeatureEnabled$1(editor)) {\n        var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n        return backspaceDeleteCollapsed(editor, caret, forward, from);\n      }\n      return false;\n    };\n    var BoundaryDelete = { backspaceDelete: backspaceDelete$4 };\n\n    var getParentInlines = function (rootElm, startElm) {\n      var parents = Parents.parentsAndSelf(startElm, rootElm);\n      return findIndex(parents, isBlock).fold(constant(parents), function (index) {\n        return parents.slice(0, index);\n      });\n    };\n    var hasOnlyOneChild = function (elm) {\n      return children(elm).length === 1;\n    };\n    var deleteLastPosition = function (forward, editor, target, parentInlines) {\n      var isFormatElement$1 = curry(isFormatElement, editor);\n      var formatNodes = map(filter(parentInlines, isFormatElement$1), function (elm) {\n        return elm.dom();\n      });\n      if (formatNodes.length === 0) {\n        DeleteElement.deleteElement(editor, forward, target);\n      } else {\n        var pos = replaceWithCaretFormat(target.dom(), formatNodes);\n        editor.selection.setRng(pos.toRange());\n      }\n    };\n    var deleteCaret = function (editor, forward) {\n      var rootElm = Element.fromDom(editor.getBody());\n      var startElm = Element.fromDom(editor.selection.getStart());\n      var parentInlines = filter(getParentInlines(rootElm, startElm), hasOnlyOneChild);\n      return last(parentInlines).map(function (target) {\n        var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n        if (DeleteUtils.willDeleteLastPositionInElement(forward, fromPos, target.dom()) && !isEmptyCaretFormatElement(target)) {\n          deleteLastPosition(forward, editor, target, parentInlines);\n          return true;\n        } else {\n          return false;\n        }\n      }).getOr(false);\n    };\n    var backspaceDelete$5 = function (editor, forward) {\n      return editor.selection.isCollapsed() ? deleteCaret(editor, forward) : false;\n    };\n    var InlineFormatDelete = { backspaceDelete: backspaceDelete$5 };\n\n    var tableCellRng = function (start, end) {\n      return {\n        start: constant(start),\n        end: constant(end)\n      };\n    };\n    var tableSelection = function (rng, table, cells) {\n      return {\n        rng: constant(rng),\n        table: constant(table),\n        cells: constant(cells)\n      };\n    };\n    var deleteAction = Adt.generate([\n      { removeTable: ['element'] },\n      { emptyCells: ['cells'] }\n    ]);\n    var isRootFromElement = function (root) {\n      return function (cur) {\n        return eq(root, cur);\n      };\n    };\n    var getClosestCell$1 = function (container, isRoot) {\n      return closest$1(Element.fromDom(container), 'td,th', isRoot);\n    };\n    var getClosestTable = function (cell, isRoot) {\n      return ancestor$1(cell, 'table', isRoot);\n    };\n    var isExpandedCellRng = function (cellRng) {\n      return eq(cellRng.start(), cellRng.end()) === false;\n    };\n    var getTableFromCellRng = function (cellRng, isRoot) {\n      return getClosestTable(cellRng.start(), isRoot).bind(function (startParentTable) {\n        return getClosestTable(cellRng.end(), isRoot).bind(function (endParentTable) {\n          return someIf(eq(startParentTable, endParentTable), startParentTable);\n        });\n      });\n    };\n    var getTableCells = function (table) {\n      return descendants$1(table, 'td,th');\n    };\n    var getCellRangeFromStartTable = function (cellRng, isRoot) {\n      return getClosestTable(cellRng.start(), isRoot).bind(function (table) {\n        return last(getTableCells(table)).map(function (endCell) {\n          return tableCellRng(cellRng.start(), endCell);\n        });\n      });\n    };\n    var partialSelection = function (isRoot, rng) {\n      var startCell = getClosestCell$1(rng.startContainer, isRoot);\n      var endCell = getClosestCell$1(rng.endContainer, isRoot);\n      return rng.collapsed ? Option.none() : lift2(startCell, endCell, tableCellRng).fold(function () {\n        return startCell.fold(function () {\n          return endCell.bind(function (endCell) {\n            return getClosestTable(endCell, isRoot).bind(function (table) {\n              return head(getTableCells(table)).map(function (startCell) {\n                return tableCellRng(startCell, endCell);\n              });\n            });\n          });\n        }, function (startCell) {\n          return getClosestTable(startCell, isRoot).bind(function (table) {\n            return last(getTableCells(table)).map(function (endCell) {\n              return tableCellRng(startCell, endCell);\n            });\n          });\n        });\n      }, function (cellRng) {\n        return isWithinSameTable(isRoot, cellRng) ? Option.none() : getCellRangeFromStartTable(cellRng, isRoot);\n      });\n    };\n    var isWithinSameTable = function (isRoot, cellRng) {\n      return getTableFromCellRng(cellRng, isRoot).isSome();\n    };\n    var getCellRng = function (rng, isRoot) {\n      var startCell = getClosestCell$1(rng.startContainer, isRoot);\n      var endCell = getClosestCell$1(rng.endContainer, isRoot);\n      return lift2(startCell, endCell, tableCellRng).filter(isExpandedCellRng).filter(function (cellRng) {\n        return isWithinSameTable(isRoot, cellRng);\n      }).orThunk(function () {\n        return partialSelection(isRoot, rng);\n      });\n    };\n    var getTableSelectionFromCellRng = function (cellRng, isRoot) {\n      return getTableFromCellRng(cellRng, isRoot).map(function (table) {\n        return tableSelection(cellRng, table, getTableCells(table));\n      });\n    };\n    var getTableSelectionFromRng = function (root, rng) {\n      var isRoot = isRootFromElement(root);\n      return getCellRng(rng, isRoot).bind(function (cellRng) {\n        return getTableSelectionFromCellRng(cellRng, isRoot);\n      });\n    };\n    var getCellIndex = function (cells, cell) {\n      return findIndex(cells, function (x) {\n        return eq(x, cell);\n      });\n    };\n    var getSelectedCells = function (tableSelection) {\n      return lift2(getCellIndex(tableSelection.cells(), tableSelection.rng().start()), getCellIndex(tableSelection.cells(), tableSelection.rng().end()), function (startIndex, endIndex) {\n        return tableSelection.cells().slice(startIndex, endIndex + 1);\n      });\n    };\n    var getAction = function (tableSelection) {\n      return getSelectedCells(tableSelection).map(function (selected) {\n        var cells = tableSelection.cells();\n        return selected.length === cells.length ? deleteAction.removeTable(tableSelection.table()) : deleteAction.emptyCells(selected);\n      });\n    };\n    var getActionFromRange = function (root, rng) {\n      return getTableSelectionFromRng(root, rng).bind(getAction);\n    };\n\n    var emptyCells = function (editor, cells) {\n      each(cells, PaddingBr.fillWithPaddingBr);\n      editor.selection.setCursorLocation(cells[0].dom(), 0);\n      return true;\n    };\n    var deleteTableElement = function (editor, table) {\n      DeleteElement.deleteElement(editor, false, table);\n      return true;\n    };\n    var deleteCellRange = function (editor, rootElm, rng) {\n      return getActionFromRange(rootElm, rng).map(function (action) {\n        return action.fold(curry(deleteTableElement, editor), curry(emptyCells, editor));\n      });\n    };\n    var deleteCaptionRange = function (editor, caption) {\n      return emptyElement(editor, caption);\n    };\n    var deleteTableRange = function (editor, rootElm, rng, startElm) {\n      return getParentCaption(rootElm, startElm).fold(function () {\n        return deleteCellRange(editor, rootElm, rng);\n      }, function (caption) {\n        return deleteCaptionRange(editor, caption);\n      }).getOr(false);\n    };\n    var deleteRange$1 = function (editor, startElm) {\n      var rootNode = Element.fromDom(editor.getBody());\n      var rng = editor.selection.getRng();\n      var selectedCells = TableCellSelection.getCellsFromEditor(editor);\n      return selectedCells.length !== 0 ? emptyCells(editor, selectedCells) : deleteTableRange(editor, rootNode, rng, startElm);\n    };\n    var getParentCell = function (rootElm, elm) {\n      return find(Parents.parentsAndSelf(elm, rootElm), isTableCell);\n    };\n    var getParentCaption = function (rootElm, elm) {\n      return find(Parents.parentsAndSelf(elm, rootElm), function (elm) {\n        return name(elm) === 'caption';\n      });\n    };\n    var deleteBetweenCells = function (editor, rootElm, forward, fromCell, from) {\n      return CaretFinder.navigate(forward, editor.getBody(), from).bind(function (to) {\n        return getParentCell(rootElm, Element.fromDom(to.getNode())).map(function (toCell) {\n          return eq(toCell, fromCell) === false;\n        });\n      });\n    };\n    var emptyElement = function (editor, elm) {\n      PaddingBr.fillWithPaddingBr(elm);\n      editor.selection.setCursorLocation(elm.dom(), 0);\n      return Option.some(true);\n    };\n    var isDeleteOfLastCharPos = function (fromCaption, forward, from, to) {\n      return CaretFinder.firstPositionIn(fromCaption.dom()).bind(function (first) {\n        return CaretFinder.lastPositionIn(fromCaption.dom()).map(function (last) {\n          return forward ? from.isEqual(first) && to.isEqual(last) : from.isEqual(last) && to.isEqual(first);\n        });\n      }).getOr(true);\n    };\n    var emptyCaretCaption = function (editor, elm) {\n      return emptyElement(editor, elm);\n    };\n    var validateCaretCaption = function (rootElm, fromCaption, to) {\n      return getParentCaption(rootElm, Element.fromDom(to.getNode())).map(function (toCaption) {\n        return eq(toCaption, fromCaption) === false;\n      });\n    };\n    var deleteCaretInsideCaption = function (editor, rootElm, forward, fromCaption, from) {\n      return CaretFinder.navigate(forward, editor.getBody(), from).bind(function (to) {\n        return isDeleteOfLastCharPos(fromCaption, forward, from, to) ? emptyCaretCaption(editor, fromCaption) : validateCaretCaption(rootElm, fromCaption, to);\n      }).or(Option.some(true));\n    };\n    var deleteCaretCells = function (editor, forward, rootElm, startElm) {\n      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n      return getParentCell(rootElm, startElm).bind(function (fromCell) {\n        return Empty.isEmpty(fromCell) ? emptyElement(editor, fromCell) : deleteBetweenCells(editor, rootElm, forward, fromCell, from);\n      }).getOr(false);\n    };\n    var deleteCaretCaption = function (editor, forward, rootElm, fromCaption) {\n      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n      return Empty.isEmpty(fromCaption) ? emptyElement(editor, fromCaption) : deleteCaretInsideCaption(editor, rootElm, forward, fromCaption, from);\n    };\n    var isNearTable = function (forward, pos) {\n      return forward ? isBeforeTable(pos) : isAfterTable(pos);\n    };\n    var isBeforeOrAfterTable = function (editor, forward) {\n      var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n      return isNearTable(forward, fromPos) || CaretFinder.fromPosition(forward, editor.getBody(), fromPos).map(function (pos) {\n        return isNearTable(forward, pos);\n      }).getOr(false);\n    };\n    var deleteCaret$1 = function (editor, forward, startElm) {\n      var rootElm = Element.fromDom(editor.getBody());\n      return getParentCaption(rootElm, startElm).fold(function () {\n        return deleteCaretCells(editor, forward, rootElm, startElm) || isBeforeOrAfterTable(editor, forward);\n      }, function (fromCaption) {\n        return deleteCaretCaption(editor, forward, rootElm, fromCaption).getOr(false);\n      });\n    };\n    var backspaceDelete$6 = function (editor, forward) {\n      var startElm = Element.fromDom(editor.selection.getStart(true));\n      var cells = TableCellSelection.getCellsFromEditor(editor);\n      return editor.selection.isCollapsed() && cells.length === 0 ? deleteCaret$1(editor, forward, startElm) : deleteRange$1(editor, startElm);\n    };\n    var TableDelete = { backspaceDelete: backspaceDelete$6 };\n\n    var deleteCaret$2 = function (editor, forward) {\n      var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n      return CaretFinder.fromPosition(forward, editor.getBody(), fromPos).filter(function (pos) {\n        return forward ? isBeforeImageBlock(pos) : isAfterImageBlock(pos);\n      }).bind(function (pos) {\n        return Option.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, pos));\n      }).map(function (elm) {\n        editor.selection.select(elm);\n        return true;\n      }).getOr(false);\n    };\n    var backspaceDelete$7 = function (editor, forward) {\n      return editor.selection.isCollapsed() ? deleteCaret$2(editor, forward) : false;\n    };\n    var PageBreakDelete = { backspaceDelete: backspaceDelete$7 };\n\n    var isEditable$1 = function (target) {\n      return closest(target, function (elm) {\n        return NodeType.isContentEditableTrue(elm.dom()) || NodeType.isContentEditableFalse(elm.dom());\n      }).exists(function (elm) {\n        return NodeType.isContentEditableTrue(elm.dom());\n      });\n    };\n    var parseIndentValue = function (value) {\n      var number = parseInt(value, 10);\n      return isNaN(number) ? 0 : number;\n    };\n    var getIndentStyleName = function (useMargin, element) {\n      var indentStyleName = useMargin || isTable$1(element) ? 'margin' : 'padding';\n      var suffix = get$2(element, 'direction') === 'rtl' ? '-right' : '-left';\n      return indentStyleName + suffix;\n    };\n    var indentElement = function (dom, command, useMargin, value, unit, element) {\n      var indentStyleName = getIndentStyleName(useMargin, Element.fromDom(element));\n      if (command === 'outdent') {\n        var styleValue = Math.max(0, parseIndentValue(element.style[indentStyleName]) - value);\n        dom.setStyle(element, indentStyleName, styleValue ? styleValue + unit : '');\n      } else {\n        var styleValue = parseIndentValue(element.style[indentStyleName]) + value + unit;\n        dom.setStyle(element, indentStyleName, styleValue);\n      }\n    };\n    var validateBlocks = function (editor, blocks) {\n      return forall(blocks, function (block) {\n        var indentStyleName = getIndentStyleName(Settings.shouldIndentUseMargin(editor), block);\n        var intentValue = getRaw(block, indentStyleName).map(parseIndentValue).getOr(0);\n        var contentEditable = editor.dom.getContentEditable(block.dom());\n        return contentEditable !== 'false' && intentValue > 0;\n      });\n    };\n    var canOutdent = function (editor) {\n      var blocks = getBlocksToIndent(editor);\n      return editor.readonly !== true && (blocks.length > 1 || validateBlocks(editor, blocks));\n    };\n    var isListComponent = function (el) {\n      return isList(el) || isListItem(el);\n    };\n    var parentIsListComponent = function (el) {\n      return parent(el).map(isListComponent).getOr(false);\n    };\n    var getBlocksToIndent = function (editor) {\n      return filter(map(editor.selection.getSelectedBlocks(), Element.fromDom), function (el) {\n        return !isListComponent(el) && !parentIsListComponent(el) && isEditable$1(el);\n      });\n    };\n    var handle = function (editor, command) {\n      var dom = editor.dom, selection = editor.selection, formatter = editor.formatter;\n      var indentation = Settings.getIndentation(editor);\n      var indentUnit = /[a-z%]+$/i.exec(indentation)[0];\n      var indentValue = parseInt(indentation, 10);\n      var useMargin = Settings.shouldIndentUseMargin(editor);\n      var forcedRootBlock = Settings.getForcedRootBlock(editor);\n      if (!editor.queryCommandState('InsertUnorderedList') && !editor.queryCommandState('InsertOrderedList')) {\n        if (forcedRootBlock === '' && !dom.getParent(selection.getNode(), dom.isBlock)) {\n          formatter.apply('div');\n        }\n      }\n      each(getBlocksToIndent(editor), function (block) {\n        indentElement(dom, command, useMargin, indentValue, indentUnit, block.dom());\n      });\n    };\n\n    var navigateIgnoreEmptyTextNodes = function (forward, root, from) {\n      return CaretFinder.navigateIgnore(forward, root, from, isEmptyText);\n    };\n    var getClosestBlock = function (root, pos) {\n      return find(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);\n    };\n    var isAtBeforeAfterBlockBoundary = function (forward, root, pos) {\n      return navigateIgnoreEmptyTextNodes(forward, root.dom(), pos).forall(function (newPos) {\n        return getClosestBlock(root, pos).fold(function () {\n          return isInSameBlock(newPos, pos, root.dom()) === false;\n        }, function (fromBlock) {\n          return isInSameBlock(newPos, pos, root.dom()) === false && contains$2(fromBlock, Element.fromDom(newPos.container()));\n        });\n      });\n    };\n    var isAtBlockBoundary = function (forward, root, pos) {\n      return getClosestBlock(root, pos).fold(function () {\n        return navigateIgnoreEmptyTextNodes(forward, root.dom(), pos).forall(function (newPos) {\n          return isInSameBlock(newPos, pos, root.dom()) === false;\n        });\n      }, function (parent) {\n        return navigateIgnoreEmptyTextNodes(forward, parent.dom(), pos).isNone();\n      });\n    };\n    var isAtStartOfBlock = curry(isAtBlockBoundary, false);\n    var isAtEndOfBlock = curry(isAtBlockBoundary, true);\n    var isBeforeBlock = curry(isAtBeforeAfterBlockBoundary, false);\n    var isAfterBlock = curry(isAtBeforeAfterBlockBoundary, true);\n\n    var backspaceDelete$8 = function (editor, _caret, _forward) {\n      if (editor.selection.isCollapsed() && canOutdent(editor)) {\n        var dom = editor.dom;\n        var rng = editor.selection.getRng();\n        var pos = CaretPosition$1.fromRangeStart(rng);\n        var block = dom.getParent(rng.startContainer, dom.isBlock);\n        if (block !== null && isAtStartOfBlock(Element.fromDom(block), pos)) {\n          handle(editor, 'outdent');\n          return true;\n        }\n      }\n      return false;\n    };\n    var Outdent = { backspaceDelete: backspaceDelete$8 };\n\n    var executeKeydownOverride$1 = function (editor, caret, evt) {\n      MatchKeys.execute([\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(Outdent.backspaceDelete, editor, false)\n        },\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(CefDelete.backspaceDelete, editor, false)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(CefDelete.backspaceDelete, editor, true)\n        },\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(CefBoundaryDelete.backspaceDelete, editor, false)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(CefBoundaryDelete.backspaceDelete, editor, true)\n        },\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(BoundaryDelete.backspaceDelete, editor, caret, false)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(BoundaryDelete.backspaceDelete, editor, caret, true)\n        },\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(TableDelete.backspaceDelete, editor, false)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(TableDelete.backspaceDelete, editor, true)\n        },\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(PageBreakDelete.backspaceDelete, editor, false)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(PageBreakDelete.backspaceDelete, editor, true)\n        },\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(BlockRangeDelete.backspaceDelete, editor, false)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(BlockRangeDelete.backspaceDelete, editor, true)\n        },\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(BlockBoundaryDelete.backspaceDelete, editor, false)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(BlockBoundaryDelete.backspaceDelete, editor, true)\n        },\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(InlineFormatDelete.backspaceDelete, editor, false)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(InlineFormatDelete.backspaceDelete, editor, true)\n        }\n      ], evt).each(function (_) {\n        evt.preventDefault();\n      });\n    };\n    var executeKeyupOverride = function (editor, evt) {\n      MatchKeys.execute([\n        {\n          keyCode: VK.BACKSPACE,\n          action: MatchKeys.action(CefDelete.paddEmptyElement, editor)\n        },\n        {\n          keyCode: VK.DELETE,\n          action: MatchKeys.action(CefDelete.paddEmptyElement, editor)\n        }\n      ], evt);\n    };\n    var setup$9 = function (editor, caret) {\n      editor.on('keydown', function (evt) {\n        if (evt.isDefaultPrevented() === false) {\n          executeKeydownOverride$1(editor, caret, evt);\n        }\n      });\n      editor.on('keyup', function (evt) {\n        if (evt.isDefaultPrevented() === false) {\n          executeKeyupOverride(editor, evt);\n        }\n      });\n    };\n    var DeleteBackspaceKeys = { setup: setup$9 };\n\n    var firstNonWhiteSpaceNodeSibling = function (node) {\n      while (node) {\n        if (node.nodeType === 1 || node.nodeType === 3 && node.data && /[\\r\\n\\s]/.test(node.data)) {\n          return node;\n        }\n        node = node.nextSibling;\n      }\n    };\n    var moveToCaretPosition = function (editor, root) {\n      var node, rng, lastNode = root;\n      var dom = editor.dom;\n      var moveCaretBeforeOnEnterElementsMap = editor.schema.getMoveCaretBeforeOnEnterElements();\n      if (!root) {\n        return;\n      }\n      if (/^(LI|DT|DD)$/.test(root.nodeName)) {\n        var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);\n        if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {\n          root.insertBefore(dom.doc.createTextNode('\\xA0'), root.firstChild);\n        }\n      }\n      rng = dom.createRng();\n      root.normalize();\n      if (root.hasChildNodes()) {\n        var walker = new TreeWalker(root, root);\n        while (node = walker.current()) {\n          if (NodeType.isText(node)) {\n            rng.setStart(node, 0);\n            rng.setEnd(node, 0);\n            break;\n          }\n          if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) {\n            rng.setStartBefore(node);\n            rng.setEndBefore(node);\n            break;\n          }\n          lastNode = node;\n          node = walker.next();\n        }\n        if (!node) {\n          rng.setStart(lastNode, 0);\n          rng.setEnd(lastNode, 0);\n        }\n      } else {\n        if (NodeType.isBr(root)) {\n          if (root.nextSibling && dom.isBlock(root.nextSibling)) {\n            rng.setStartBefore(root);\n            rng.setEndBefore(root);\n          } else {\n            rng.setStartAfter(root);\n            rng.setEndAfter(root);\n          }\n        } else {\n          rng.setStart(root, 0);\n          rng.setEnd(root, 0);\n        }\n      }\n      editor.selection.setRng(rng);\n      editor.selection.scrollIntoView(root);\n    };\n    var getEditableRoot = function (dom, node) {\n      var root = dom.getRoot();\n      var parent, editableRoot;\n      parent = node;\n      while (parent !== root && dom.getContentEditable(parent) !== 'false') {\n        if (dom.getContentEditable(parent) === 'true') {\n          editableRoot = parent;\n        }\n        parent = parent.parentNode;\n      }\n      return parent !== root ? editableRoot : root;\n    };\n    var getParentBlock$2 = function (editor) {\n      return Option.from(editor.dom.getParent(editor.selection.getStart(true), editor.dom.isBlock));\n    };\n    var getParentBlockName = function (editor) {\n      return getParentBlock$2(editor).fold(constant(''), function (parentBlock) {\n        return parentBlock.nodeName.toUpperCase();\n      });\n    };\n    var isListItemParentBlock = function (editor) {\n      return getParentBlock$2(editor).filter(function (elm) {\n        return isListItem(Element.fromDom(elm));\n      }).isSome();\n    };\n    var NewLineUtils = {\n      moveToCaretPosition: moveToCaretPosition,\n      getEditableRoot: getEditableRoot,\n      getParentBlock: getParentBlock$2,\n      getParentBlockName: getParentBlockName,\n      isListItemParentBlock: isListItemParentBlock\n    };\n\n    var hasFirstChild = function (elm, name) {\n      return elm.firstChild && elm.firstChild.nodeName === name;\n    };\n    var hasParent$1 = function (elm, parentName) {\n      return elm && elm.parentNode && elm.parentNode.nodeName === parentName;\n    };\n    var isListBlock = function (elm) {\n      return elm && /^(OL|UL|LI)$/.test(elm.nodeName);\n    };\n    var isNestedList = function (elm) {\n      return isListBlock(elm) && isListBlock(elm.parentNode);\n    };\n    var getContainerBlock = function (containerBlock) {\n      var containerBlockParent = containerBlock.parentNode;\n      if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {\n        return containerBlockParent;\n      }\n      return containerBlock;\n    };\n    var isFirstOrLastLi = function (containerBlock, parentBlock, first) {\n      var node = containerBlock[first ? 'firstChild' : 'lastChild'];\n      while (node) {\n        if (NodeType.isElement(node)) {\n          break;\n        }\n        node = node[first ? 'nextSibling' : 'previousSibling'];\n      }\n      return node === parentBlock;\n    };\n    var insert = function (editor, createNewBlock, containerBlock, parentBlock, newBlockName) {\n      var dom = editor.dom;\n      var rng = editor.selection.getRng();\n      if (containerBlock === editor.getBody()) {\n        return;\n      }\n      if (isNestedList(containerBlock)) {\n        newBlockName = 'LI';\n      }\n      var newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR');\n      if (isFirstOrLastLi(containerBlock, parentBlock, true) && isFirstOrLastLi(containerBlock, parentBlock, false)) {\n        if (hasParent$1(containerBlock, 'LI')) {\n          dom.insertAfter(newBlock, getContainerBlock(containerBlock));\n        } else {\n          dom.replace(newBlock, containerBlock);\n        }\n      } else if (isFirstOrLastLi(containerBlock, parentBlock, true)) {\n        if (hasParent$1(containerBlock, 'LI')) {\n          dom.insertAfter(newBlock, getContainerBlock(containerBlock));\n          newBlock.appendChild(dom.doc.createTextNode(' '));\n          newBlock.appendChild(containerBlock);\n        } else {\n          containerBlock.parentNode.insertBefore(newBlock, containerBlock);\n        }\n      } else if (isFirstOrLastLi(containerBlock, parentBlock, false)) {\n        dom.insertAfter(newBlock, getContainerBlock(containerBlock));\n      } else {\n        containerBlock = getContainerBlock(containerBlock);\n        var tmpRng = rng.cloneRange();\n        tmpRng.setStartAfter(parentBlock);\n        tmpRng.setEndAfter(containerBlock);\n        var fragment = tmpRng.extractContents();\n        if (newBlockName === 'LI' && hasFirstChild(fragment, 'LI')) {\n          newBlock = fragment.firstChild;\n          dom.insertAfter(fragment, containerBlock);\n        } else {\n          dom.insertAfter(fragment, containerBlock);\n          dom.insertAfter(newBlock, containerBlock);\n        }\n      }\n      dom.remove(parentBlock);\n      NewLineUtils.moveToCaretPosition(editor, newBlock);\n    };\n    var InsertLi = { insert: insert };\n\n    var trimZwsp = function (fragment) {\n      each(descendants(Element.fromDom(fragment), isText$1), function (text) {\n        var rawNode = text.dom();\n        rawNode.nodeValue = Zwsp.trim(rawNode.nodeValue);\n      });\n    };\n    var isEmptyAnchor = function (dom, elm) {\n      return elm && elm.nodeName === 'A' && dom.isEmpty(elm);\n    };\n    var isTableCell$4 = function (node) {\n      return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);\n    };\n    var emptyBlock = function (elm) {\n      elm.innerHTML = '<br data-mce-bogus=\"1\">';\n    };\n    var containerAndSiblingName = function (container, nodeName) {\n      return container.nodeName === nodeName || container.previousSibling && container.previousSibling.nodeName === nodeName;\n    };\n    var canSplitBlock = function (dom, node) {\n      return node && dom.isBlock(node) && !/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position) && dom.getContentEditable(node) !== 'true';\n    };\n    var trimInlineElementsOnLeftSideOfBlock = function (dom, nonEmptyElementsMap, block) {\n      var node = block;\n      var firstChilds = [];\n      var i;\n      if (!node) {\n        return;\n      }\n      while (node = node.firstChild) {\n        if (dom.isBlock(node)) {\n          return;\n        }\n        if (NodeType.isElement(node) && !nonEmptyElementsMap[node.nodeName.toLowerCase()]) {\n          firstChilds.push(node);\n        }\n      }\n      i = firstChilds.length;\n      while (i--) {\n        node = firstChilds[i];\n        if (!node.hasChildNodes() || node.firstChild === node.lastChild && node.firstChild.nodeValue === '') {\n          dom.remove(node);\n        } else {\n          if (isEmptyAnchor(dom, node)) {\n            dom.remove(node);\n          }\n        }\n      }\n    };\n    var normalizeZwspOffset = function (start, container, offset) {\n      if (NodeType.isText(container) === false) {\n        return offset;\n      } else if (start) {\n        return offset === 1 && container.data.charAt(offset - 1) === Zwsp.ZWSP ? 0 : offset;\n      } else {\n        return offset === container.data.length - 1 && container.data.charAt(offset) === Zwsp.ZWSP ? container.data.length : offset;\n      }\n    };\n    var includeZwspInRange = function (rng) {\n      var newRng = rng.cloneRange();\n      newRng.setStart(rng.startContainer, normalizeZwspOffset(true, rng.startContainer, rng.startOffset));\n      newRng.setEnd(rng.endContainer, normalizeZwspOffset(false, rng.endContainer, rng.endOffset));\n      return newRng;\n    };\n    var trimLeadingLineBreaks = function (node) {\n      do {\n        if (NodeType.isText(node)) {\n          node.nodeValue = node.nodeValue.replace(/^[\\r\\n]+/, '');\n        }\n        node = node.firstChild;\n      } while (node);\n    };\n    var getEditableRoot$1 = function (dom, node) {\n      var root = dom.getRoot();\n      var parent, editableRoot;\n      parent = node;\n      while (parent !== root && dom.getContentEditable(parent) !== 'false') {\n        if (dom.getContentEditable(parent) === 'true') {\n          editableRoot = parent;\n        }\n        parent = parent.parentNode;\n      }\n      return parent !== root ? editableRoot : root;\n    };\n    var setForcedBlockAttrs = function (editor, node) {\n      var forcedRootBlockName = Settings.getForcedRootBlock(editor);\n      if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) {\n        editor.dom.setAttribs(node, Settings.getForcedRootBlockAttrs(editor));\n      }\n    };\n    var wrapSelfAndSiblingsInDefaultBlock = function (editor, newBlockName, rng, container, offset) {\n      var newBlock, parentBlock, startNode, node, next, rootBlockName;\n      var blockName = newBlockName || 'P';\n      var dom = editor.dom, editableRoot = getEditableRoot$1(dom, container);\n      parentBlock = dom.getParent(container, dom.isBlock);\n      if (!parentBlock || !canSplitBlock(dom, parentBlock)) {\n        parentBlock = parentBlock || editableRoot;\n        if (parentBlock === editor.getBody() || isTableCell$4(parentBlock)) {\n          rootBlockName = parentBlock.nodeName.toLowerCase();\n        } else {\n          rootBlockName = parentBlock.parentNode.nodeName.toLowerCase();\n        }\n        if (!parentBlock.hasChildNodes()) {\n          newBlock = dom.create(blockName);\n          setForcedBlockAttrs(editor, newBlock);\n          parentBlock.appendChild(newBlock);\n          rng.setStart(newBlock, 0);\n          rng.setEnd(newBlock, 0);\n          return newBlock;\n        }\n        node = container;\n        while (node.parentNode !== parentBlock) {\n          node = node.parentNode;\n        }\n        while (node && !dom.isBlock(node)) {\n          startNode = node;\n          node = node.previousSibling;\n        }\n        if (startNode && editor.schema.isValidChild(rootBlockName, blockName.toLowerCase())) {\n          newBlock = dom.create(blockName);\n          setForcedBlockAttrs(editor, newBlock);\n          startNode.parentNode.insertBefore(newBlock, startNode);\n          node = startNode;\n          while (node && !dom.isBlock(node)) {\n            next = node.nextSibling;\n            newBlock.appendChild(node);\n            node = next;\n          }\n          rng.setStart(container, offset);\n          rng.setEnd(container, offset);\n        }\n      }\n      return container;\n    };\n    var addBrToBlockIfNeeded = function (dom, block) {\n      var lastChild;\n      block.normalize();\n      lastChild = block.lastChild;\n      if (!lastChild || /^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true))) {\n        dom.add(block, 'br');\n      }\n    };\n    var insert$1 = function (editor, evt) {\n      var tmpRng, editableRoot, container, offset, parentBlock, shiftKey;\n      var newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;\n      var dom = editor.dom;\n      var schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements();\n      var rng = editor.selection.getRng();\n      var createNewBlock = function (name) {\n        var node = container, block, clonedNode, caretNode;\n        var textInlineElements = schema.getTextInlineElements();\n        if (name || parentBlockName === 'TABLE' || parentBlockName === 'HR') {\n          block = dom.create(name || newBlockName);\n          setForcedBlockAttrs(editor, block);\n        } else {\n          block = parentBlock.cloneNode(false);\n        }\n        caretNode = block;\n        if (Settings.shouldKeepStyles(editor) === false) {\n          dom.setAttrib(block, 'style', null);\n          dom.setAttrib(block, 'class', null);\n        } else {\n          do {\n            if (textInlineElements[node.nodeName]) {\n              if (isCaretNode(node) || Bookmarks.isBookmarkNode(node)) {\n                continue;\n              }\n              clonedNode = node.cloneNode(false);\n              dom.setAttrib(clonedNode, 'id', '');\n              if (block.hasChildNodes()) {\n                clonedNode.appendChild(block.firstChild);\n                block.appendChild(clonedNode);\n              } else {\n                caretNode = clonedNode;\n                block.appendChild(clonedNode);\n              }\n            }\n          } while ((node = node.parentNode) && node !== editableRoot);\n        }\n        emptyBlock(caretNode);\n        return block;\n      };\n      var isCaretAtStartOrEndOfBlock = function (start) {\n        var node, name;\n        var normalizedOffset = normalizeZwspOffset(start, container, offset);\n        if (NodeType.isText(container) && (start ? normalizedOffset > 0 : normalizedOffset < container.nodeValue.length)) {\n          return false;\n        }\n        if (container.parentNode === parentBlock && isAfterLastNodeInContainer && !start) {\n          return true;\n        }\n        if (start && NodeType.isElement(container) && container === parentBlock.firstChild) {\n          return true;\n        }\n        if (containerAndSiblingName(container, 'TABLE') || containerAndSiblingName(container, 'HR')) {\n          return isAfterLastNodeInContainer && !start || !isAfterLastNodeInContainer && start;\n        }\n        var walker = new TreeWalker(container, parentBlock);\n        if (NodeType.isText(container)) {\n          if (start && normalizedOffset === 0) {\n            walker.prev();\n          } else if (!start && normalizedOffset === container.nodeValue.length) {\n            walker.next();\n          }\n        }\n        while (node = walker.current()) {\n          if (NodeType.isElement(node)) {\n            if (!node.getAttribute('data-mce-bogus')) {\n              name = node.nodeName.toLowerCase();\n              if (nonEmptyElementsMap[name] && name !== 'br') {\n                return false;\n              }\n            }\n          } else if (NodeType.isText(node) && !/^[ \\t\\r\\n]*$/.test(node.nodeValue)) {\n            return false;\n          }\n          if (start) {\n            walker.prev();\n          } else {\n            walker.next();\n          }\n        }\n        return true;\n      };\n      var insertNewBlockAfter = function () {\n        if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName !== 'HGROUP') {\n          newBlock = createNewBlock(newBlockName);\n        } else {\n          newBlock = createNewBlock();\n        }\n        if (Settings.shouldEndContainerOnEmptyBlock(editor) && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) {\n          newBlock = dom.split(containerBlock, parentBlock);\n        } else {\n          dom.insertAfter(newBlock, parentBlock);\n        }\n        NewLineUtils.moveToCaretPosition(editor, newBlock);\n      };\n      NormalizeRange.normalize(dom, rng).each(function (normRng) {\n        rng.setStart(normRng.startContainer, normRng.startOffset);\n        rng.setEnd(normRng.endContainer, normRng.endOffset);\n      });\n      container = rng.startContainer;\n      offset = rng.startOffset;\n      newBlockName = Settings.getForcedRootBlock(editor);\n      shiftKey = !!(evt && evt.shiftKey);\n      var ctrlKey = !!(evt && evt.ctrlKey);\n      if (NodeType.isElement(container) && container.hasChildNodes()) {\n        isAfterLastNodeInContainer = offset > container.childNodes.length - 1;\n        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;\n        if (isAfterLastNodeInContainer && NodeType.isText(container)) {\n          offset = container.nodeValue.length;\n        } else {\n          offset = 0;\n        }\n      }\n      editableRoot = getEditableRoot$1(dom, container);\n      if (!editableRoot) {\n        return;\n      }\n      if (newBlockName && !shiftKey || !newBlockName && shiftKey) {\n        container = wrapSelfAndSiblingsInDefaultBlock(editor, newBlockName, rng, container, offset);\n      }\n      parentBlock = dom.getParent(container, dom.isBlock);\n      containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;\n      parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : '';\n      containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';\n      if (containerBlockName === 'LI' && !ctrlKey) {\n        parentBlock = containerBlock;\n        containerBlock = containerBlock.parentNode;\n        parentBlockName = containerBlockName;\n      }\n      if (/^(LI|DT|DD)$/.test(parentBlockName)) {\n        if (dom.isEmpty(parentBlock)) {\n          InsertLi.insert(editor, createNewBlock, containerBlock, parentBlock, newBlockName);\n          return;\n        }\n      }\n      if (newBlockName && parentBlock === editor.getBody()) {\n        return;\n      }\n      newBlockName = newBlockName || 'P';\n      if (isCaretContainerBlock(parentBlock)) {\n        newBlock = showCaretContainerBlock(parentBlock);\n        if (dom.isEmpty(parentBlock)) {\n          emptyBlock(parentBlock);\n        }\n        NewLineUtils.moveToCaretPosition(editor, newBlock);\n      } else if (isCaretAtStartOrEndOfBlock()) {\n        insertNewBlockAfter();\n      } else if (isCaretAtStartOrEndOfBlock(true)) {\n        newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock);\n        NewLineUtils.moveToCaretPosition(editor, containerAndSiblingName(parentBlock, 'HR') ? newBlock : parentBlock);\n      } else {\n        tmpRng = includeZwspInRange(rng).cloneRange();\n        tmpRng.setEndAfter(parentBlock);\n        fragment = tmpRng.extractContents();\n        trimZwsp(fragment);\n        trimLeadingLineBreaks(fragment);\n        newBlock = fragment.firstChild;\n        dom.insertAfter(fragment, parentBlock);\n        trimInlineElementsOnLeftSideOfBlock(dom, nonEmptyElementsMap, newBlock);\n        addBrToBlockIfNeeded(dom, parentBlock);\n        if (dom.isEmpty(parentBlock)) {\n          emptyBlock(parentBlock);\n        }\n        newBlock.normalize();\n        if (dom.isEmpty(newBlock)) {\n          dom.remove(newBlock);\n          insertNewBlockAfter();\n        } else {\n          NewLineUtils.moveToCaretPosition(editor, newBlock);\n        }\n      }\n      dom.setAttrib(newBlock, 'id', '');\n      editor.fire('NewBlock', { newBlock: newBlock });\n    };\n    var InsertBlock = { insert: insert$1 };\n\n    var hasRightSideContent = function (schema, container, parentBlock) {\n      var walker = new TreeWalker(container, parentBlock);\n      var node;\n      var nonEmptyElementsMap = schema.getNonEmptyElements();\n      while (node = walker.next()) {\n        if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) {\n          return true;\n        }\n      }\n    };\n    var scrollToBr = function (dom, selection, brElm) {\n      var marker = dom.create('span', {}, '&nbsp;');\n      brElm.parentNode.insertBefore(marker, brElm);\n      selection.scrollIntoView(marker);\n      dom.remove(marker);\n    };\n    var moveSelectionToBr = function (dom, selection, brElm, extraBr) {\n      var rng = dom.createRng();\n      if (!extraBr) {\n        rng.setStartAfter(brElm);\n        rng.setEndAfter(brElm);\n      } else {\n        rng.setStartBefore(brElm);\n        rng.setEndBefore(brElm);\n      }\n      selection.setRng(rng);\n    };\n    var insertBrAtCaret = function (editor, evt) {\n      var selection = editor.selection;\n      var dom = editor.dom;\n      var rng = selection.getRng();\n      var brElm;\n      var extraBr;\n      NormalizeRange.normalize(dom, rng).each(function (normRng) {\n        rng.setStart(normRng.startContainer, normRng.startOffset);\n        rng.setEnd(normRng.endContainer, normRng.endOffset);\n      });\n      var offset = rng.startOffset;\n      var container = rng.startContainer;\n      if (container.nodeType === 1 && container.hasChildNodes()) {\n        var isAfterLastNodeInContainer = offset > container.childNodes.length - 1;\n        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;\n        if (isAfterLastNodeInContainer && container.nodeType === 3) {\n          offset = container.nodeValue.length;\n        } else {\n          offset = 0;\n        }\n      }\n      var parentBlock = dom.getParent(container, dom.isBlock);\n      var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;\n      var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';\n      var isControlKey = !!(evt && evt.ctrlKey);\n      if (containerBlockName === 'LI' && !isControlKey) {\n        parentBlock = containerBlock;\n      }\n      if (container && container.nodeType === 3 && offset >= container.nodeValue.length) {\n        if (!hasRightSideContent(editor.schema, container, parentBlock)) {\n          brElm = dom.create('br');\n          rng.insertNode(brElm);\n          rng.setStartAfter(brElm);\n          rng.setEndAfter(brElm);\n          extraBr = true;\n        }\n      }\n      brElm = dom.create('br');\n      rangeInsertNode(dom, rng, brElm);\n      scrollToBr(dom, selection, brElm);\n      moveSelectionToBr(dom, selection, brElm, extraBr);\n      editor.undoManager.add();\n    };\n    var insertBrBefore = function (editor, inline) {\n      var br = Element.fromTag('br');\n      before(Element.fromDom(inline), br);\n      editor.undoManager.add();\n    };\n    var insertBrAfter = function (editor, inline) {\n      if (!hasBrAfter(editor.getBody(), inline)) {\n        after(Element.fromDom(inline), Element.fromTag('br'));\n      }\n      var br = Element.fromTag('br');\n      after(Element.fromDom(inline), br);\n      scrollToBr(editor.dom, editor.selection, br.dom());\n      moveSelectionToBr(editor.dom, editor.selection, br.dom(), false);\n      editor.undoManager.add();\n    };\n    var isBeforeBr$1 = function (pos) {\n      return NodeType.isBr(pos.getNode());\n    };\n    var hasBrAfter = function (rootNode, startNode) {\n      if (isBeforeBr$1(CaretPosition$1.after(startNode))) {\n        return true;\n      } else {\n        return CaretFinder.nextPosition(rootNode, CaretPosition$1.after(startNode)).map(function (pos) {\n          return NodeType.isBr(pos.getNode());\n        }).getOr(false);\n      }\n    };\n    var isAnchorLink = function (elm) {\n      return elm && elm.nodeName === 'A' && 'href' in elm;\n    };\n    var isInsideAnchor = function (location) {\n      return location.fold(constant(false), isAnchorLink, isAnchorLink, constant(false));\n    };\n    var readInlineAnchorLocation = function (editor) {\n      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);\n      var position = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n      return BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), position).filter(isInsideAnchor);\n    };\n    var insertBrOutsideAnchor = function (editor, location) {\n      location.fold(noop, curry(insertBrBefore, editor), curry(insertBrAfter, editor), noop);\n    };\n    var insert$2 = function (editor, evt) {\n      var anchorLocation = readInlineAnchorLocation(editor);\n      if (anchorLocation.isSome()) {\n        anchorLocation.each(curry(insertBrOutsideAnchor, editor));\n      } else {\n        insertBrAtCaret(editor, evt);\n      }\n    };\n    var InsertBr = { insert: insert$2 };\n\n    var matchesSelector = function (editor, selector) {\n      return NewLineUtils.getParentBlock(editor).filter(function (parentBlock) {\n        return selector.length > 0 && is(Element.fromDom(parentBlock), selector);\n      }).isSome();\n    };\n    var shouldInsertBr = function (editor) {\n      return matchesSelector(editor, Settings.getBrNewLineSelector(editor));\n    };\n    var shouldBlockNewLine = function (editor) {\n      return matchesSelector(editor, Settings.getNoNewLineSelector(editor));\n    };\n    var ContextSelectors = {\n      shouldInsertBr: shouldInsertBr,\n      shouldBlockNewLine: shouldBlockNewLine\n    };\n\n    var newLineAction = Adt.generate([\n      { br: [] },\n      { block: [] },\n      { none: [] }\n    ]);\n    var shouldBlockNewLine$1 = function (editor, shiftKey) {\n      return ContextSelectors.shouldBlockNewLine(editor);\n    };\n    var isBrMode = function (requiredState) {\n      return function (editor, shiftKey) {\n        var brMode = Settings.getForcedRootBlock(editor) === '';\n        return brMode === requiredState;\n      };\n    };\n    var inListBlock = function (requiredState) {\n      return function (editor, shiftKey) {\n        return NewLineUtils.isListItemParentBlock(editor) === requiredState;\n      };\n    };\n    var inBlock = function (blockName, requiredState) {\n      return function (editor, shiftKey) {\n        var state = NewLineUtils.getParentBlockName(editor) === blockName.toUpperCase();\n        return state === requiredState;\n      };\n    };\n    var inPreBlock = function (requiredState) {\n      return inBlock('pre', requiredState);\n    };\n    var inSummaryBlock = function () {\n      return inBlock('summary', true);\n    };\n    var shouldPutBrInPre$1 = function (requiredState) {\n      return function (editor, shiftKey) {\n        return Settings.shouldPutBrInPre(editor) === requiredState;\n      };\n    };\n    var inBrContext = function (editor, shiftKey) {\n      return ContextSelectors.shouldInsertBr(editor);\n    };\n    var hasShiftKey = function (editor, shiftKey) {\n      return shiftKey;\n    };\n    var canInsertIntoEditableRoot = function (editor) {\n      var forcedRootBlock = Settings.getForcedRootBlock(editor);\n      var rootEditable = NewLineUtils.getEditableRoot(editor.dom, editor.selection.getStart());\n      return rootEditable && editor.schema.isValidChild(rootEditable.nodeName, forcedRootBlock ? forcedRootBlock : 'P');\n    };\n    var match$2 = function (predicates, action) {\n      return function (editor, shiftKey) {\n        var isMatch = foldl(predicates, function (res, p) {\n          return res && p(editor, shiftKey);\n        }, true);\n        return isMatch ? Option.some(action) : Option.none();\n      };\n    };\n    var getAction$1 = function (editor, evt) {\n      return LazyEvaluator.evaluateUntil([\n        match$2([shouldBlockNewLine$1], newLineAction.none()),\n        match$2([inSummaryBlock()], newLineAction.br()),\n        match$2([\n          inPreBlock(true),\n          shouldPutBrInPre$1(false),\n          hasShiftKey\n        ], newLineAction.br()),\n        match$2([\n          inPreBlock(true),\n          shouldPutBrInPre$1(false)\n        ], newLineAction.block()),\n        match$2([\n          inPreBlock(true),\n          shouldPutBrInPre$1(true),\n          hasShiftKey\n        ], newLineAction.block()),\n        match$2([\n          inPreBlock(true),\n          shouldPutBrInPre$1(true)\n        ], newLineAction.br()),\n        match$2([\n          inListBlock(true),\n          hasShiftKey\n        ], newLineAction.br()),\n        match$2([inListBlock(true)], newLineAction.block()),\n        match$2([\n          isBrMode(true),\n          hasShiftKey,\n          canInsertIntoEditableRoot\n        ], newLineAction.block()),\n        match$2([isBrMode(true)], newLineAction.br()),\n        match$2([inBrContext], newLineAction.br()),\n        match$2([\n          isBrMode(false),\n          hasShiftKey\n        ], newLineAction.br()),\n        match$2([canInsertIntoEditableRoot], newLineAction.block())\n      ], [\n        editor,\n        !!(evt && evt.shiftKey)\n      ]).getOr(newLineAction.none());\n    };\n    var NewLineAction = { getAction: getAction$1 };\n\n    var insert$3 = function (editor, evt) {\n      NewLineAction.getAction(editor, evt).fold(function () {\n        InsertBr.insert(editor, evt);\n      }, function () {\n        InsertBlock.insert(editor, evt);\n      }, noop);\n    };\n    var InsertNewLine = { insert: insert$3 };\n\n    var handleEnterKeyEvent = function (editor, event) {\n      if (event.isDefaultPrevented()) {\n        return;\n      }\n      event.preventDefault();\n      endTypingLevelIgnoreLocks(editor.undoManager);\n      editor.undoManager.transact(function () {\n        if (editor.selection.isCollapsed() === false) {\n          editor.execCommand('Delete');\n        }\n        InsertNewLine.insert(editor, event);\n      });\n    };\n    var setup$a = function (editor) {\n      editor.on('keydown', function (event) {\n        if (event.keyCode === VK.ENTER) {\n          handleEnterKeyEvent(editor, event);\n        }\n      });\n    };\n    var EnterKey = { setup: setup$a };\n\n    var insertTextAtPosition = function (text, pos) {\n      var container = pos.container();\n      var offset = pos.offset();\n      if (NodeType.isText(container)) {\n        container.insertData(offset, text);\n        return Option.some(CaretPosition(container, offset + text.length));\n      } else {\n        return getElementFromPosition(pos).map(function (elm) {\n          var textNode = Element.fromText(text);\n          if (pos.isAtEnd()) {\n            after(elm, textNode);\n          } else {\n            before(elm, textNode);\n          }\n          return CaretPosition(textNode.dom(), text.length);\n        });\n      }\n    };\n    var insertNbspAtPosition = curry(insertTextAtPosition, '\\xA0');\n    var insertSpaceAtPosition = curry(insertTextAtPosition, ' ');\n\n    var nbsp = '\\xA0';\n    var isInMiddleOfText = function (pos) {\n      return CaretPosition.isTextPosition(pos) && !pos.isAtStart() && !pos.isAtEnd();\n    };\n    var getClosestBlock$1 = function (root, pos) {\n      var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);\n      return head(parentBlocks).getOr(root);\n    };\n    var hasSpaceBefore = function (root, pos) {\n      if (isInMiddleOfText(pos)) {\n        return isAfterSpace(pos);\n      } else {\n        return isAfterSpace(pos) || CaretFinder.prevPosition(getClosestBlock$1(root, pos).dom(), pos).exists(isAfterSpace);\n      }\n    };\n    var hasSpaceAfter = function (root, pos) {\n      if (isInMiddleOfText(pos)) {\n        return isBeforeSpace(pos);\n      } else {\n        return isBeforeSpace(pos) || CaretFinder.nextPosition(getClosestBlock$1(root, pos).dom(), pos).exists(isBeforeSpace);\n      }\n    };\n    var isPreValue = function (value) {\n      return contains([\n        'pre',\n        'pre-wrap'\n      ], value);\n    };\n    var isInPre = function (pos) {\n      return getElementFromPosition(pos).bind(function (elm) {\n        return closest(elm, isElement$1);\n      }).exists(function (elm) {\n        return isPreValue(get$2(elm, 'white-space'));\n      });\n    };\n    var isAtBeginningOfBody = function (root, pos) {\n      return CaretFinder.prevPosition(root.dom(), pos).isNone();\n    };\n    var isAtEndOfBody = function (root, pos) {\n      return CaretFinder.nextPosition(root.dom(), pos).isNone();\n    };\n    var isAtLineBoundary = function (root, pos) {\n      return isAtBeginningOfBody(root, pos) || isAtEndOfBody(root, pos) || isAtStartOfBlock(root, pos) || isAtEndOfBlock(root, pos) || isAfterBr(root, pos) || isBeforeBr(root, pos);\n    };\n    var needsToHaveNbsp = function (root, pos) {\n      if (isInPre(pos)) {\n        return false;\n      } else {\n        return isAtLineBoundary(root, pos) || hasSpaceBefore(root, pos) || hasSpaceAfter(root, pos);\n      }\n    };\n    var needsToBeNbspLeft = function (root, pos) {\n      if (isInPre(pos)) {\n        return false;\n      } else {\n        return isAtStartOfBlock(root, pos) || isBeforeBlock(root, pos) || isAfterBr(root, pos) || hasSpaceBefore(root, pos);\n      }\n    };\n    var leanRight = function (pos) {\n      var container = pos.container();\n      var offset = pos.offset();\n      if (NodeType.isText(container) && offset < container.data.length) {\n        return CaretPosition(container, offset + 1);\n      } else {\n        return pos;\n      }\n    };\n    var needsToBeNbspRight = function (root, pos) {\n      var afterPos = leanRight(pos);\n      if (isInPre(afterPos)) {\n        return false;\n      } else {\n        return isAtEndOfBlock(root, afterPos) || isAfterBlock(root, afterPos) || isBeforeBr(root, afterPos) || hasSpaceAfter(root, afterPos);\n      }\n    };\n    var needsToBeNbsp = function (root, pos) {\n      return needsToBeNbspLeft(root, pos) || needsToBeNbspRight(root, pos);\n    };\n    var isNbspAt = function (text, offset) {\n      return isNbsp(text.charAt(offset));\n    };\n    var hasNbsp = function (pos) {\n      var container = pos.container();\n      return NodeType.isText(container) && contains$1(container.data, nbsp);\n    };\n    var normalizeNbspMiddle = function (text) {\n      var chars = text.split('');\n      return map(chars, function (chr, i) {\n        if (isNbsp(chr) && i > 0 && i < chars.length - 1 && isContent(chars[i - 1]) && isContent(chars[i + 1])) {\n          return ' ';\n        } else {\n          return chr;\n        }\n      }).join('');\n    };\n    var normalizeNbspAtStart = function (root, node) {\n      var text = node.data;\n      var firstPos = CaretPosition(node, 0);\n      if (isNbspAt(text, 0) && !needsToBeNbsp(root, firstPos)) {\n        node.data = ' ' + text.slice(1);\n        return true;\n      } else {\n        return false;\n      }\n    };\n    var normalizeNbspInMiddleOfTextNode = function (node) {\n      var text = node.data;\n      var newText = normalizeNbspMiddle(text);\n      if (newText !== text) {\n        node.data = newText;\n        return true;\n      } else {\n        return false;\n      }\n    };\n    var normalizeNbspAtEnd = function (root, node) {\n      var text = node.data;\n      var lastPos = CaretPosition(node, text.length - 1);\n      if (isNbspAt(text, text.length - 1) && !needsToBeNbsp(root, lastPos)) {\n        node.data = text.slice(0, -1) + ' ';\n        return true;\n      } else {\n        return false;\n      }\n    };\n    var normalizeNbsps = function (root, pos) {\n      return Option.some(pos).filter(hasNbsp).bind(function (pos) {\n        var container = pos.container();\n        var normalized = normalizeNbspAtStart(root, container) || normalizeNbspInMiddleOfTextNode(container) || normalizeNbspAtEnd(root, container);\n        return normalized ? Option.some(pos) : Option.none();\n      });\n    };\n    var normalizeNbspsInEditor = function (editor) {\n      var root = Element.fromDom(editor.getBody());\n      if (editor.selection.isCollapsed()) {\n        normalizeNbsps(root, CaretPosition.fromRangeStart(editor.selection.getRng())).each(function (pos) {\n          editor.selection.setRng(pos.toRange());\n        });\n      }\n    };\n\n    var locationToCaretPosition = function (root) {\n      return function (location) {\n        return location.fold(function (element) {\n          return CaretFinder.prevPosition(root.dom(), CaretPosition$1.before(element));\n        }, function (element) {\n          return CaretFinder.firstPositionIn(element);\n        }, function (element) {\n          return CaretFinder.lastPositionIn(element);\n        }, function (element) {\n          return CaretFinder.nextPosition(root.dom(), CaretPosition$1.after(element));\n        });\n      };\n    };\n    var insertInlineBoundarySpaceOrNbsp = function (root, pos) {\n      return function (checkPos) {\n        return needsToHaveNbsp(root, checkPos) ? insertNbspAtPosition(pos) : insertSpaceAtPosition(pos);\n      };\n    };\n    var setSelection$1 = function (editor) {\n      return function (pos) {\n        editor.selection.setRng(pos.toRange());\n        editor.nodeChanged();\n        return true;\n      };\n    };\n    var insertSpaceOrNbspAtSelection = function (editor) {\n      var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n      var root = Element.fromDom(editor.getBody());\n      if (editor.selection.isCollapsed()) {\n        var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);\n        var caretPosition = CaretPosition$1.fromRangeStart(editor.selection.getRng());\n        return BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), caretPosition).bind(locationToCaretPosition(root)).bind(insertInlineBoundarySpaceOrNbsp(root, pos)).exists(setSelection$1(editor));\n      } else {\n        return false;\n      }\n    };\n\n    var executeKeydownOverride$2 = function (editor, evt) {\n      MatchKeys.execute([{\n          keyCode: VK.SPACEBAR,\n          action: MatchKeys.action(insertSpaceOrNbspAtSelection, editor)\n        }], evt).each(function (_) {\n        evt.preventDefault();\n      });\n    };\n    var setup$b = function (editor) {\n      editor.on('keydown', function (evt) {\n        if (evt.isDefaultPrevented() === false) {\n          executeKeydownOverride$2(editor, evt);\n        }\n      });\n    };\n    var SpaceKey = { setup: setup$b };\n\n    var findBlockCaretContainer = function (editor) {\n      return descendant(Element.fromDom(editor.getBody()), '*[data-mce-caret]').fold(constant(null), function (elm) {\n        return elm.dom();\n      });\n    };\n    var removeIeControlRect = function (editor) {\n      editor.selection.setRng(editor.selection.getRng());\n    };\n    var showBlockCaretContainer = function (editor, blockCaretContainer) {\n      if (blockCaretContainer.hasAttribute('data-mce-caret')) {\n        showCaretContainerBlock(blockCaretContainer);\n        removeIeControlRect(editor);\n        editor.selection.scrollIntoView(blockCaretContainer);\n      }\n    };\n    var handleBlockContainer = function (editor, e) {\n      var blockCaretContainer = findBlockCaretContainer(editor);\n      if (!blockCaretContainer) {\n        return;\n      }\n      if (e.type === 'compositionstart') {\n        e.preventDefault();\n        e.stopPropagation();\n        showBlockCaretContainer(editor, blockCaretContainer);\n        return;\n      }\n      if (hasContent(blockCaretContainer)) {\n        showBlockCaretContainer(editor, blockCaretContainer);\n        editor.undoManager.add();\n      }\n    };\n    var setup$c = function (editor) {\n      editor.on('keyup compositionstart', curry(handleBlockContainer, editor));\n    };\n    var CaretContainerInput = { setup: setup$c };\n\n    var browser$5 = detect$3().browser;\n    var setupIeInput = function (editor) {\n      var keypressThrotter = first(function () {\n        if (!editor.composing) {\n          normalizeNbspsInEditor(editor);\n        }\n      }, 0);\n      if (browser$5.isIE()) {\n        editor.on('keypress', function (e) {\n          keypressThrotter.throttle();\n        });\n        editor.on('remove', function (e) {\n          keypressThrotter.cancel();\n        });\n      }\n    };\n    var setup$d = function (editor) {\n      setupIeInput(editor);\n      editor.on('input', function (e) {\n        if (e.isComposing === false) {\n          normalizeNbspsInEditor(editor);\n        }\n      });\n    };\n\n    var executeKeydownOverride$3 = function (editor, evt) {\n      MatchKeys.execute([\n        {\n          keyCode: VK.END,\n          action: moveToLineEndPoint(editor, true)\n        },\n        {\n          keyCode: VK.HOME,\n          action: moveToLineEndPoint(editor, false)\n        }\n      ], evt).each(function (_) {\n        evt.preventDefault();\n      });\n    };\n    var setup$e = function (editor) {\n      editor.on('keydown', function (evt) {\n        if (evt.isDefaultPrevented() === false) {\n          executeKeydownOverride$3(editor, evt);\n        }\n      });\n    };\n    var HomeEndKeys = { setup: setup$e };\n\n    var setup$f = function (editor) {\n      var caret = BoundarySelection.setupSelectedState(editor);\n      CaretContainerInput.setup(editor);\n      ArrowKeys.setup(editor, caret);\n      DeleteBackspaceKeys.setup(editor, caret);\n      EnterKey.setup(editor);\n      SpaceKey.setup(editor);\n      setup$d(editor);\n      HomeEndKeys.setup(editor);\n    };\n    var KeyboardOverrides = { setup: setup$f };\n\n    var Quirks = function (editor) {\n      var each = Tools.each;\n      var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, settings = editor.settings, parser = editor.parser;\n      var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit;\n      var mceInternalUrlPrefix = 'data:text/mce-internal,';\n      var mceInternalDataType = isIE ? 'Text' : 'URL';\n      var setEditorCommandState = function (cmd, state) {\n        try {\n          editor.getDoc().execCommand(cmd, false, state);\n        } catch (ex) {\n        }\n      };\n      var isDefaultPrevented = function (e) {\n        return e.isDefaultPrevented();\n      };\n      var setMceInternalContent = function (e) {\n        var selectionHtml, internalContent;\n        if (e.dataTransfer) {\n          if (editor.selection.isCollapsed() && e.target.tagName === 'IMG') {\n            selection.select(e.target);\n          }\n          selectionHtml = editor.selection.getContent();\n          if (selectionHtml.length > 0) {\n            internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml);\n            e.dataTransfer.setData(mceInternalDataType, internalContent);\n          }\n        }\n      };\n      var getMceInternalContent = function (e) {\n        var internalContent;\n        if (e.dataTransfer) {\n          internalContent = e.dataTransfer.getData(mceInternalDataType);\n          if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) {\n            internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(',');\n            return {\n              id: unescape(internalContent[0]),\n              html: unescape(internalContent[1])\n            };\n          }\n        }\n        return null;\n      };\n      var insertClipboardContents = function (content, internal) {\n        if (editor.queryCommandSupported('mceInsertClipboardContent')) {\n          editor.execCommand('mceInsertClipboardContent', false, {\n            content: content,\n            internal: internal\n          });\n        } else {\n          editor.execCommand('mceInsertContent', false, content);\n        }\n      };\n      var emptyEditorWhenDeleting = function () {\n        var serializeRng = function (rng) {\n          var body = dom.create('body');\n          var contents = rng.cloneContents();\n          body.appendChild(contents);\n          return selection.serializer.serialize(body, { format: 'html' });\n        };\n        var allContentsSelected = function (rng) {\n          var selection = serializeRng(rng);\n          var allRng = dom.createRng();\n          allRng.selectNode(editor.getBody());\n          var allSelection = serializeRng(allRng);\n          return selection === allSelection;\n        };\n        editor.on('keydown', function (e) {\n          var keyCode = e.keyCode;\n          var isCollapsed, body;\n          if (!isDefaultPrevented(e) && (keyCode === DELETE || keyCode === BACKSPACE)) {\n            isCollapsed = editor.selection.isCollapsed();\n            body = editor.getBody();\n            if (isCollapsed && !dom.isEmpty(body)) {\n              return;\n            }\n            if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) {\n              return;\n            }\n            e.preventDefault();\n            editor.setContent('');\n            if (body.firstChild && dom.isBlock(body.firstChild)) {\n              editor.selection.setCursorLocation(body.firstChild, 0);\n            } else {\n              editor.selection.setCursorLocation(body, 0);\n            }\n            editor.nodeChanged();\n          }\n        });\n      };\n      var selectAll = function () {\n        editor.shortcuts.add('meta+a', null, 'SelectAll');\n      };\n      var inputMethodFocus = function () {\n        if (!editor.inline) {\n          dom.bind(editor.getDoc(), 'mousedown mouseup', function (e) {\n            var rng;\n            if (e.target === editor.getDoc().documentElement) {\n              rng = selection.getRng();\n              editor.getBody().focus();\n              if (e.type === 'mousedown') {\n                if (isCaretContainer(rng.startContainer)) {\n                  return;\n                }\n                selection.placeCaretAt(e.clientX, e.clientY);\n              } else {\n                selection.setRng(rng);\n              }\n            }\n          });\n        }\n      };\n      var removeHrOnBackspace = function () {\n        editor.on('keydown', function (e) {\n          if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {\n            if (!editor.getBody().getElementsByTagName('hr').length) {\n              return;\n            }\n            if (selection.isCollapsed() && selection.getRng().startOffset === 0) {\n              var node = selection.getNode();\n              var previousSibling = node.previousSibling;\n              if (node.nodeName === 'HR') {\n                dom.remove(node);\n                e.preventDefault();\n                return;\n              }\n              if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'hr') {\n                dom.remove(previousSibling);\n                e.preventDefault();\n              }\n            }\n          }\n        });\n      };\n      var focusBody = function () {\n        if (!domGlobals.Range.prototype.getClientRects) {\n          editor.on('mousedown', function (e) {\n            if (!isDefaultPrevented(e) && e.target.nodeName === 'HTML') {\n              var body_1 = editor.getBody();\n              body_1.blur();\n              Delay.setEditorTimeout(editor, function () {\n                body_1.focus();\n              });\n            }\n          });\n        }\n      };\n      var selectControlElements = function () {\n        editor.on('click', function (e) {\n          var target = e.target;\n          if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== 'false') {\n            e.preventDefault();\n            editor.selection.select(target);\n            editor.nodeChanged();\n          }\n          if (target.nodeName === 'A' && dom.hasClass(target, 'mce-item-anchor')) {\n            e.preventDefault();\n            selection.select(target);\n          }\n        });\n      };\n      var removeStylesWhenDeletingAcrossBlockElements = function () {\n        var getAttributeApplyFunction = function () {\n          var template = dom.getAttribs(selection.getStart().cloneNode(false));\n          return function () {\n            var target = selection.getStart();\n            if (target !== editor.getBody()) {\n              dom.setAttrib(target, 'style', null);\n              each(template, function (attr) {\n                target.setAttributeNode(attr.cloneNode(true));\n              });\n            }\n          };\n        };\n        var isSelectionAcrossElements = function () {\n          return !selection.isCollapsed() && dom.getParent(selection.getStart(), dom.isBlock) !== dom.getParent(selection.getEnd(), dom.isBlock);\n        };\n        editor.on('keypress', function (e) {\n          var applyAttributes;\n          if (!isDefaultPrevented(e) && (e.keyCode === 8 || e.keyCode === 46) && isSelectionAcrossElements()) {\n            applyAttributes = getAttributeApplyFunction();\n            editor.getDoc().execCommand('delete', false, null);\n            applyAttributes();\n            e.preventDefault();\n            return false;\n          }\n        });\n        dom.bind(editor.getDoc(), 'cut', function (e) {\n          var applyAttributes;\n          if (!isDefaultPrevented(e) && isSelectionAcrossElements()) {\n            applyAttributes = getAttributeApplyFunction();\n            Delay.setEditorTimeout(editor, function () {\n              applyAttributes();\n            });\n          }\n        });\n      };\n      var disableBackspaceIntoATable = function () {\n        editor.on('keydown', function (e) {\n          if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {\n            if (selection.isCollapsed() && selection.getRng().startOffset === 0) {\n              var previousSibling = selection.getNode().previousSibling;\n              if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'table') {\n                e.preventDefault();\n                return false;\n              }\n            }\n          }\n        });\n      };\n      var removeBlockQuoteOnBackSpace = function () {\n        editor.on('keydown', function (e) {\n          var rng, container, offset, root, parent;\n          if (isDefaultPrevented(e) || e.keyCode !== VK.BACKSPACE) {\n            return;\n          }\n          rng = selection.getRng();\n          container = rng.startContainer;\n          offset = rng.startOffset;\n          root = dom.getRoot();\n          parent = container;\n          if (!rng.collapsed || offset !== 0) {\n            return;\n          }\n          while (parent && parent.parentNode && parent.parentNode.firstChild === parent && parent.parentNode !== root) {\n            parent = parent.parentNode;\n          }\n          if (parent.tagName === 'BLOCKQUOTE') {\n            editor.formatter.toggle('blockquote', null, parent);\n            rng = dom.createRng();\n            rng.setStart(container, 0);\n            rng.setEnd(container, 0);\n            selection.setRng(rng);\n          }\n        });\n      };\n      var setGeckoEditingOptions = function () {\n        var setOpts = function () {\n          setEditorCommandState('StyleWithCSS', false);\n          setEditorCommandState('enableInlineTableEditing', false);\n          if (!settings.object_resizing) {\n            setEditorCommandState('enableObjectResizing', false);\n          }\n        };\n        if (!settings.readonly) {\n          editor.on('BeforeExecCommand mousedown', setOpts);\n        }\n      };\n      var addBrAfterLastLinks = function () {\n        var fixLinks = function () {\n          each(dom.select('a'), function (node) {\n            var parentNode = node.parentNode;\n            var root = dom.getRoot();\n            if (parentNode.lastChild === node) {\n              while (parentNode && !dom.isBlock(parentNode)) {\n                if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {\n                  return;\n                }\n                parentNode = parentNode.parentNode;\n              }\n              dom.add(parentNode, 'br', { 'data-mce-bogus': 1 });\n            }\n          });\n        };\n        editor.on('SetContent ExecCommand', function (e) {\n          if (e.type === 'setcontent' || e.command === 'mceInsertLink') {\n            fixLinks();\n          }\n        });\n      };\n      var setDefaultBlockType = function () {\n        if (settings.forced_root_block) {\n          editor.on('init', function () {\n            setEditorCommandState('DefaultParagraphSeparator', Settings.getForcedRootBlock(editor));\n          });\n        }\n      };\n      var normalizeSelection = function () {\n        editor.on('keyup focusin mouseup', function (e) {\n          if (!VK.modifierPressed(e)) {\n            selection.normalize();\n          }\n        }, true);\n      };\n      var showBrokenImageIcon = function () {\n        editor.contentStyles.push('img:-moz-broken {' + '-moz-force-broken-image-icon:1;' + 'min-width:24px;' + 'min-height:24px' + '}');\n      };\n      var restoreFocusOnKeyDown = function () {\n        if (!editor.inline) {\n          editor.on('keydown', function () {\n            if (domGlobals.document.activeElement === domGlobals.document.body) {\n              editor.getWin().focus();\n            }\n          });\n        }\n      };\n      var bodyHeight = function () {\n        if (!editor.inline) {\n          editor.contentStyles.push('body {min-height: 150px}');\n          editor.on('click', function (e) {\n            var rng;\n            if (e.target.nodeName === 'HTML') {\n              if (Env.ie > 11) {\n                editor.getBody().focus();\n                return;\n              }\n              rng = editor.selection.getRng();\n              editor.getBody().focus();\n              editor.selection.setRng(rng);\n              editor.selection.normalize();\n              editor.nodeChanged();\n            }\n          });\n        }\n      };\n      var blockCmdArrowNavigation = function () {\n        if (Env.mac) {\n          editor.on('keydown', function (e) {\n            if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode === 37 || e.keyCode === 39)) {\n              e.preventDefault();\n              var selection_1 = editor.selection.getSel();\n              selection_1.modify('move', e.keyCode === 37 ? 'backward' : 'forward', 'lineboundary');\n            }\n          });\n        }\n      };\n      var disableAutoUrlDetect = function () {\n        setEditorCommandState('AutoUrlDetect', false);\n      };\n      var tapLinksAndImages = function () {\n        editor.on('click', function (e) {\n          var elm = e.target;\n          do {\n            if (elm.tagName === 'A') {\n              e.preventDefault();\n              return;\n            }\n          } while (elm = elm.parentNode);\n        });\n        editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}');\n      };\n      var blockFormSubmitInsideEditor = function () {\n        editor.on('init', function () {\n          editor.dom.bind(editor.getBody(), 'submit', function (e) {\n            e.preventDefault();\n          });\n        });\n      };\n      var removeAppleInterchangeBrs = function () {\n        parser.addNodeFilter('br', function (nodes) {\n          var i = nodes.length;\n          while (i--) {\n            if (nodes[i].attr('class') === 'Apple-interchange-newline') {\n              nodes[i].remove();\n            }\n          }\n        });\n      };\n      var ieInternalDragAndDrop = function () {\n        editor.on('dragstart', function (e) {\n          setMceInternalContent(e);\n        });\n        editor.on('drop', function (e) {\n          if (!isDefaultPrevented(e)) {\n            var internalContent = getMceInternalContent(e);\n            if (internalContent && internalContent.id !== editor.id) {\n              e.preventDefault();\n              var rng = CaretRangeFromPoint.fromPoint(e.x, e.y, editor.getDoc());\n              selection.setRng(rng);\n              insertClipboardContents(internalContent.html, true);\n            }\n          }\n        });\n      };\n      var refreshContentEditable = function () {\n      };\n      var isHidden = function () {\n        var sel;\n        if (!isGecko || editor.removed) {\n          return false;\n        }\n        sel = editor.selection.getSel();\n        return !sel || !sel.rangeCount || sel.rangeCount === 0;\n      };\n      removeBlockQuoteOnBackSpace();\n      emptyEditorWhenDeleting();\n      if (!Env.windowsPhone) {\n        normalizeSelection();\n      }\n      if (isWebKit) {\n        inputMethodFocus();\n        selectControlElements();\n        setDefaultBlockType();\n        blockFormSubmitInsideEditor();\n        disableBackspaceIntoATable();\n        removeAppleInterchangeBrs();\n        if (Env.iOS) {\n          restoreFocusOnKeyDown();\n          bodyHeight();\n          tapLinksAndImages();\n        } else {\n          selectAll();\n        }\n      }\n      if (Env.ie >= 11) {\n        bodyHeight();\n        disableBackspaceIntoATable();\n      }\n      if (Env.ie) {\n        selectAll();\n        disableAutoUrlDetect();\n        ieInternalDragAndDrop();\n      }\n      if (isGecko) {\n        removeHrOnBackspace();\n        focusBody();\n        removeStylesWhenDeletingAcrossBlockElements();\n        setGeckoEditingOptions();\n        addBrAfterLastLinks();\n        showBrokenImageIcon();\n        blockCmdArrowNavigation();\n        disableBackspaceIntoATable();\n      }\n      return {\n        refreshContentEditable: refreshContentEditable,\n        isHidden: isHidden\n      };\n    };\n\n    var isTextBlockNode = function (node) {\n      return NodeType.isElement(node) && isTextBlock(Element.fromDom(node));\n    };\n    var normalizeSelection$1 = function (editor) {\n      var rng = editor.selection.getRng();\n      var startPos = CaretPosition.fromRangeStart(rng);\n      var endPos = CaretPosition.fromRangeEnd(rng);\n      if (CaretPosition.isElementPosition(startPos)) {\n        var container = startPos.container();\n        if (isTextBlockNode(container)) {\n          CaretFinder.firstPositionIn(container).each(function (pos) {\n            return rng.setStart(pos.container(), pos.offset());\n          });\n        }\n      }\n      if (CaretPosition.isElementPosition(endPos)) {\n        var container = startPos.container();\n        if (isTextBlockNode(container)) {\n          CaretFinder.lastPositionIn(container).each(function (pos) {\n            return rng.setEnd(pos.container(), pos.offset());\n          });\n        }\n      }\n      editor.selection.setRng(RangeNormalizer.normalize(rng));\n    };\n    var setup$g = function (editor) {\n      editor.on('click', function (e) {\n        if (e.detail >= 3) {\n          normalizeSelection$1(editor);\n        }\n      });\n    };\n\n    var preventSummaryToggle = function (editor) {\n      editor.on('click', function (e) {\n        if (editor.dom.getParent(e.target, 'details')) {\n          e.preventDefault();\n        }\n      });\n    };\n    var filterDetails = function (editor) {\n      editor.parser.addNodeFilter('details', function (elms) {\n        each(elms, function (details) {\n          details.attr('data-mce-open', details.attr('open'));\n          details.attr('open', 'open');\n        });\n      });\n      editor.serializer.addNodeFilter('details', function (elms) {\n        each(elms, function (details) {\n          var open = details.attr('data-mce-open');\n          details.attr('open', isString(open) ? open : null);\n          details.attr('data-mce-open', null);\n        });\n      });\n    };\n    var setup$h = function (editor) {\n      preventSummaryToggle(editor);\n      filterDetails(editor);\n    };\n\n    var DOM$3 = DOMUtils$1.DOM;\n    var appendStyle = function (editor, text) {\n      var head = Element.fromDom(editor.getDoc().head);\n      var tag = Element.fromTag('style');\n      set(tag, 'type', 'text/css');\n      append(tag, Element.fromText(text));\n      append(head, tag);\n    };\n    var createParser = function (editor) {\n      var parser = DomParser(editor.settings, editor.schema);\n      parser.addAttributeFilter('src,href,style,tabindex', function (nodes, name) {\n        var i = nodes.length, node;\n        var dom = editor.dom;\n        var value, internalName;\n        while (i--) {\n          node = nodes[i];\n          value = node.attr(name);\n          internalName = 'data-mce-' + name;\n          if (!node.attr(internalName)) {\n            if (value.indexOf('data:') === 0 || value.indexOf('blob:') === 0) {\n              continue;\n            }\n            if (name === 'style') {\n              value = dom.serializeStyle(dom.parseStyle(value), node.name);\n              if (!value.length) {\n                value = null;\n              }\n              node.attr(internalName, value);\n              node.attr(name, value);\n            } else if (name === 'tabindex') {\n              node.attr(internalName, value);\n              node.attr(name, null);\n            } else {\n              node.attr(internalName, editor.convertURL(value, name, node.name));\n            }\n          }\n        }\n      });\n      parser.addNodeFilter('script', function (nodes) {\n        var i = nodes.length, node, type;\n        while (i--) {\n          node = nodes[i];\n          type = node.attr('type') || 'no/type';\n          if (type.indexOf('mce-') !== 0) {\n            node.attr('type', 'mce-' + type);\n          }\n        }\n      });\n      parser.addNodeFilter('#cdata', function (nodes) {\n        var i = nodes.length, node;\n        while (i--) {\n          node = nodes[i];\n          node.type = 8;\n          node.name = '#comment';\n          node.value = '[CDATA[' + node.value + ']]';\n        }\n      });\n      parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function (nodes) {\n        var i = nodes.length, node;\n        var nonEmptyElements = editor.schema.getNonEmptyElements();\n        while (i--) {\n          node = nodes[i];\n          if (node.isEmpty(nonEmptyElements) && node.getAll('br').length === 0) {\n            node.append(new Node$1('br', 1)).shortEnded = true;\n          }\n        }\n      });\n      return parser;\n    };\n    var autoFocus = function (editor) {\n      if (editor.settings.auto_focus) {\n        Delay.setEditorTimeout(editor, function () {\n          var focusEditor;\n          if (editor.settings.auto_focus === true) {\n            focusEditor = editor;\n          } else {\n            focusEditor = editor.editorManager.get(editor.settings.auto_focus);\n          }\n          if (!focusEditor.destroyed) {\n            focusEditor.focus();\n          }\n        }, 100);\n      }\n    };\n    var initEditor = function (editor) {\n      editor.bindPendingEventDelegates();\n      editor.initialized = true;\n      editor.fire('init');\n      editor.focus(true);\n      editor.nodeChanged({ initial: true });\n      editor.execCallback('init_instance_callback', editor);\n      autoFocus(editor);\n    };\n    var getStyleSheetLoader = function (editor) {\n      return editor.inline ? DOM$3.styleSheetLoader : editor.dom.styleSheetLoader;\n    };\n    var initContentBody = function (editor, skipWrite) {\n      var settings = editor.settings;\n      var targetElm = editor.getElement();\n      var doc = editor.getDoc(), body, contentCssText;\n      if (!settings.inline) {\n        editor.getElement().style.visibility = editor.orgVisibility;\n      }\n      if (!skipWrite && !editor.inline) {\n        doc.open();\n        doc.write(editor.iframeHTML);\n        doc.close();\n      }\n      if (editor.inline) {\n        editor.on('remove', function () {\n          var bodyEl = this.getBody();\n          DOM$3.removeClass(bodyEl, 'mce-content-body');\n          DOM$3.removeClass(bodyEl, 'mce-edit-focus');\n          DOM$3.setAttrib(bodyEl, 'contentEditable', null);\n        });\n        DOM$3.addClass(targetElm, 'mce-content-body');\n        editor.contentDocument = doc = domGlobals.document;\n        editor.contentWindow = domGlobals.window;\n        editor.bodyElement = targetElm;\n        editor.contentAreaContainer = targetElm;\n        settings.root_name = targetElm.nodeName.toLowerCase();\n      }\n      body = editor.getBody();\n      body.disabled = true;\n      editor.readonly = settings.readonly;\n      if (!editor.readonly) {\n        if (editor.inline && DOM$3.getStyle(body, 'position', true) === 'static') {\n          body.style.position = 'relative';\n        }\n        body.contentEditable = editor.getParam('content_editable_state', true);\n      }\n      body.disabled = false;\n      editor.editorUpload = EditorUpload(editor);\n      editor.schema = Schema(settings);\n      editor.dom = DOMUtils$1(doc, {\n        keep_values: true,\n        url_converter: editor.convertURL,\n        url_converter_scope: editor,\n        hex_colors: settings.force_hex_style_colors,\n        update_styles: true,\n        root_element: editor.inline ? editor.getBody() : null,\n        collect: function () {\n          return editor.inline;\n        },\n        schema: editor.schema,\n        contentCssCors: Settings.shouldUseContentCssCors(editor),\n        referrerPolicy: Settings.getReferrerPolicy(editor),\n        onSetAttrib: function (e) {\n          editor.fire('SetAttrib', e);\n        }\n      });\n      editor.parser = createParser(editor);\n      editor.serializer = Serializer$1(settings, editor);\n      editor.selection = Selection$1(editor.dom, editor.getWin(), editor.serializer, editor);\n      editor.annotator = Annotator(editor);\n      editor.formatter = Formatter(editor);\n      editor.undoManager = UndoManager(editor);\n      editor._nodeChangeDispatcher = new NodeChange(editor);\n      editor._selectionOverrides = SelectionOverrides(editor);\n      setup$h(editor);\n      setup$g(editor);\n      KeyboardOverrides.setup(editor);\n      ForceBlocks.setup(editor);\n      editor.fire('PreInit');\n      if (!settings.browser_spellcheck && !settings.gecko_spellcheck) {\n        doc.body.spellcheck = false;\n        DOM$3.setAttrib(body, 'spellcheck', 'false');\n      }\n      editor.quirks = Quirks(editor);\n      editor.fire('PostRender');\n      var directionality = Settings.getDirectionality(editor);\n      if (directionality !== undefined) {\n        body.dir = directionality;\n      }\n      if (settings.protect) {\n        editor.on('BeforeSetContent', function (e) {\n          Tools.each(settings.protect, function (pattern) {\n            e.content = e.content.replace(pattern, function (str) {\n              return '<!--mce:protected ' + escape(str) + '-->';\n            });\n          });\n        });\n      }\n      editor.on('SetContent', function () {\n        editor.addVisual(editor.getBody());\n      });\n      editor.load({\n        initial: true,\n        format: 'html'\n      });\n      editor.startContent = editor.getContent({ format: 'raw' });\n      editor.on('compositionstart compositionend', function (e) {\n        editor.composing = e.type === 'compositionstart';\n      });\n      if (editor.contentStyles.length > 0) {\n        contentCssText = '';\n        Tools.each(editor.contentStyles, function (style) {\n          contentCssText += style + '\\r\\n';\n        });\n        editor.dom.addStyle(contentCssText);\n      }\n      getStyleSheetLoader(editor).loadAll(editor.contentCSS, function (_) {\n        initEditor(editor);\n      }, function (urls) {\n        initEditor(editor);\n      });\n      if (settings.content_style) {\n        appendStyle(editor, settings.content_style);\n      }\n    };\n    var InitContentBody = { initContentBody: initContentBody };\n\n    var DOM$4 = DOMUtils$1.DOM;\n    var relaxDomain = function (editor, ifr) {\n      if (domGlobals.document.domain !== domGlobals.window.location.hostname && Env.browser.isIE()) {\n        var bodyUuid = Uuid.uuid('mce');\n        editor[bodyUuid] = function () {\n          InitContentBody.initContentBody(editor);\n        };\n        var domainRelaxUrl = 'javascript:(function(){' + 'document.open();document.domain=\"' + domGlobals.document.domain + '\";' + 'var ed = window.parent.tinymce.get(\"' + editor.id + '\");document.write(ed.iframeHTML);' + 'document.close();ed.' + bodyUuid + '(true);})()';\n        DOM$4.setAttrib(ifr, 'src', domainRelaxUrl);\n        return true;\n      }\n      return false;\n    };\n    var createIframeElement = function (id, title, height, customAttrs) {\n      var iframe = Element.fromTag('iframe');\n      setAll(iframe, customAttrs);\n      setAll(iframe, {\n        id: id + '_ifr',\n        frameBorder: '0',\n        allowTransparency: 'true',\n        title: title\n      });\n      add$3(iframe, 'tox-edit-area__iframe');\n      return iframe;\n    };\n    var getIframeHtml = function (editor) {\n      var bodyId, bodyClass, iframeHTML;\n      iframeHTML = Settings.getDocType(editor) + '<html><head>';\n      if (Settings.getDocumentBaseUrl(editor) !== editor.documentBaseUrl) {\n        iframeHTML += '<base href=\"' + editor.documentBaseURI.getURI() + '\" />';\n      }\n      iframeHTML += '<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />';\n      bodyId = Settings.getBodyId(editor);\n      bodyClass = Settings.getBodyClass(editor);\n      if (Settings.getContentSecurityPolicy(editor)) {\n        iframeHTML += '<meta http-equiv=\"Content-Security-Policy\" content=\"' + Settings.getContentSecurityPolicy(editor) + '\" />';\n      }\n      iframeHTML += '</head><body id=\"' + bodyId + '\" class=\"mce-content-body ' + bodyClass + '\" data-id=\"' + editor.id + '\"><br></body></html>';\n      return iframeHTML;\n    };\n    var createIframe = function (editor, o) {\n      var title = editor.editorManager.translate('Rich Text Area. Press ALT-0 for help.');\n      var ifr = createIframeElement(editor.id, title, o.height, Settings.getIframeAttrs(editor)).dom();\n      ifr.onload = function () {\n        ifr.onload = null;\n        editor.fire('load');\n      };\n      var isDomainRelaxed = relaxDomain(editor, ifr);\n      editor.contentAreaContainer = o.iframeContainer;\n      editor.iframeElement = ifr;\n      editor.iframeHTML = getIframeHtml(editor);\n      DOM$4.add(o.iframeContainer, ifr);\n      return isDomainRelaxed;\n    };\n    var init$1 = function (editor, boxInfo) {\n      var isDomainRelaxed = createIframe(editor, boxInfo);\n      if (boxInfo.editorContainer) {\n        DOM$4.get(boxInfo.editorContainer).style.display = editor.orgDisplay;\n        editor.hidden = DOM$4.isHidden(boxInfo.editorContainer);\n      }\n      editor.getElement().style.display = 'none';\n      DOM$4.setAttrib(editor.id, 'aria-hidden', 'true');\n      if (!isDomainRelaxed) {\n        InitContentBody.initContentBody(editor);\n      }\n    };\n    var InitIframe = { init: init$1 };\n\n    var isContentCssSkinName = function (url) {\n      return /^[a-z0-9\\-]+$/i.test(url);\n    };\n    var getContentCssUrls = function (editor) {\n      var contentCss = Settings.getContentCss(editor);\n      var skinUrl = editor.editorManager.baseURL + '/skins/content';\n      var suffix = editor.editorManager.suffix;\n      var contentCssFile = 'content' + suffix + '.css';\n      var inline = editor.inline === true;\n      return map(contentCss, function (url) {\n        if (isContentCssSkinName(url) && !inline) {\n          return skinUrl + '/' + url + '/' + contentCssFile;\n        } else {\n          return editor.documentBaseURI.toAbsolute(url);\n        }\n      });\n    };\n    var appendContentCssFromSettings = function (editor) {\n      editor.contentCSS = editor.contentCSS.concat(getContentCssUrls(editor));\n    };\n\n    var DOM$5 = DOMUtils$1.DOM;\n    var initPlugin = function (editor, initializedPlugins, plugin) {\n      var Plugin = PluginManager.get(plugin);\n      var pluginUrl = PluginManager.urls[plugin] || editor.documentBaseUrl.replace(/\\/$/, '');\n      plugin = Tools.trim(plugin);\n      if (Plugin && Tools.inArray(initializedPlugins, plugin) === -1) {\n        Tools.each(PluginManager.dependencies(plugin), function (dep) {\n          initPlugin(editor, initializedPlugins, dep);\n        });\n        if (editor.plugins[plugin]) {\n          return;\n        }\n        try {\n          var pluginInstance = new Plugin(editor, pluginUrl, editor.$);\n          editor.plugins[plugin] = pluginInstance;\n          if (pluginInstance.init) {\n            pluginInstance.init(editor, pluginUrl);\n            initializedPlugins.push(plugin);\n          }\n        } catch (e) {\n          ErrorReporter.pluginInitError(editor, plugin, e);\n        }\n      }\n    };\n    var trimLegacyPrefix = function (name) {\n      return name.replace(/^\\-/, '');\n    };\n    var initPlugins = function (editor) {\n      var initializedPlugins = [];\n      Tools.each(editor.settings.plugins.split(/[ ,]/), function (name) {\n        initPlugin(editor, initializedPlugins, trimLegacyPrefix(name));\n      });\n    };\n    var initIcons = function (editor) {\n      var iconPackName = Tools.trim(editor.settings.icons);\n      var currentIcons = editor.ui.registry.getAll().icons;\n      var defaultIcons = getAll();\n      var loadIcons = __assign(__assign({}, defaultIcons), IconManager.get(iconPackName).icons);\n      each$1(loadIcons, function (svgData, icon) {\n        if (!has(currentIcons, icon)) {\n          editor.ui.registry.addIcon(icon, svgData);\n        }\n      });\n    };\n    var initTheme = function (editor) {\n      var theme = editor.settings.theme;\n      if (isString(theme)) {\n        editor.settings.theme = trimLegacyPrefix(theme);\n        var Theme = ThemeManager.get(theme);\n        editor.theme = new Theme(editor, ThemeManager.urls[theme]);\n        if (editor.theme.init) {\n          editor.theme.init(editor, ThemeManager.urls[theme] || editor.documentBaseUrl.replace(/\\/$/, ''), editor.$);\n        }\n      } else {\n        editor.theme = {};\n      }\n    };\n    var renderFromLoadedTheme = function (editor) {\n      return editor.theme.renderUI();\n    };\n    var renderFromThemeFunc = function (editor) {\n      var elm = editor.getElement();\n      var theme = editor.settings.theme;\n      var info = theme(editor, elm);\n      if (info.editorContainer.nodeType) {\n        info.editorContainer.id = info.editorContainer.id || editor.id + '_parent';\n      }\n      if (info.iframeContainer && info.iframeContainer.nodeType) {\n        info.iframeContainer.id = info.iframeContainer.id || editor.id + '_iframecontainer';\n      }\n      info.height = info.iframeHeight ? info.iframeHeight : elm.offsetHeight;\n      return info;\n    };\n    var createThemeFalseResult = function (element) {\n      return {\n        editorContainer: element,\n        iframeContainer: element\n      };\n    };\n    var renderThemeFalseIframe = function (targetElement) {\n      var iframeContainer = DOM$5.create('div');\n      DOM$5.insertAfter(iframeContainer, targetElement);\n      return createThemeFalseResult(iframeContainer);\n    };\n    var renderThemeFalse = function (editor) {\n      var targetElement = editor.getElement();\n      return editor.inline ? createThemeFalseResult(null) : renderThemeFalseIframe(targetElement);\n    };\n    var renderThemeUi = function (editor) {\n      var elm = editor.getElement();\n      editor.orgDisplay = elm.style.display;\n      if (isString(editor.settings.theme)) {\n        return renderFromLoadedTheme(editor);\n      } else if (isFunction(editor.settings.theme)) {\n        return renderFromThemeFunc(editor);\n      } else {\n        return renderThemeFalse(editor);\n      }\n    };\n    var init$2 = function (editor) {\n      editor.fire('ScriptsLoaded');\n      initIcons(editor);\n      initTheme(editor);\n      initPlugins(editor);\n      var boxInfo = renderThemeUi(editor);\n      editor.editorContainer = boxInfo.editorContainer ? boxInfo.editorContainer : null;\n      appendContentCssFromSettings(editor);\n      if (editor.inline) {\n        return InitContentBody.initContentBody(editor);\n      } else {\n        return InitIframe.init(editor, boxInfo);\n      }\n    };\n    var Init = { init: init$2 };\n\n    var DOM$6 = DOMUtils$1.DOM;\n    var hasSkipLoadPrefix = function (name) {\n      return name.charAt(0) === '-';\n    };\n    var loadLanguage = function (scriptLoader, editor) {\n      var languageCode = Settings.getLanguageCode(editor);\n      var languageUrl = Settings.getLanguageUrl(editor);\n      if (I18n.hasCode(languageCode) === false && languageCode !== 'en') {\n        var url_1 = languageUrl !== '' ? languageUrl : editor.editorManager.baseURL + '/langs/' + languageCode + '.js';\n        scriptLoader.add(url_1, noop, undefined, function () {\n          ErrorReporter.languageLoadError(url_1, languageCode);\n        });\n      }\n    };\n    var loadTheme = function (scriptLoader, editor, suffix, callback) {\n      var settings = editor.settings, theme = settings.theme;\n      if (isString(theme)) {\n        if (!hasSkipLoadPrefix(theme) && !ThemeManager.urls.hasOwnProperty(theme)) {\n          var themeUrl = settings.theme_url;\n          if (themeUrl) {\n            ThemeManager.load(theme, editor.documentBaseURI.toAbsolute(themeUrl));\n          } else {\n            ThemeManager.load(theme, 'themes/' + theme + '/theme' + suffix + '.js');\n          }\n        }\n        scriptLoader.loadQueue(function () {\n          ThemeManager.waitFor(theme, callback);\n        });\n      } else {\n        callback();\n      }\n    };\n    var getIconsUrlMetaFromUrl = function (editor) {\n      return Option.from(Settings.getIconsUrl(editor)).filter(function (url) {\n        return url.length > 0;\n      }).map(function (url) {\n        return {\n          url: url,\n          name: Option.none()\n        };\n      });\n    };\n    var getIconsUrlMetaFromName = function (editor) {\n      return Option.from(Settings.getIconPackName(editor)).filter(function (name) {\n        return name.length > 0 && !IconManager.has(name);\n      }).map(function (name) {\n        return {\n          url: editor.editorManager.baseURL + '/icons/' + name + '/icons.js',\n          name: Option.some(name)\n        };\n      });\n    };\n    var loadIcons = function (scriptLoader, editor) {\n      getIconsUrlMetaFromUrl(editor).orThunk(function () {\n        return getIconsUrlMetaFromName(editor);\n      }).each(function (urlMeta) {\n        scriptLoader.add(urlMeta.url, noop, undefined, function () {\n          ErrorReporter.iconsLoadError(urlMeta.url, urlMeta.name.getOrUndefined());\n        });\n      });\n    };\n    var loadPlugins = function (settings, suffix) {\n      if (isArray(settings.plugins)) {\n        settings.plugins = settings.plugins.join(' ');\n      }\n      Tools.each(settings.external_plugins, function (url, name) {\n        PluginManager.load(name, url, noop, undefined, function () {\n          ErrorReporter.pluginLoadError(name, url);\n        });\n        settings.plugins += ' ' + name;\n      });\n      Tools.each(settings.plugins.split(/[ ,]/), function (plugin) {\n        plugin = Tools.trim(plugin);\n        if (plugin && !PluginManager.urls[plugin]) {\n          if (hasSkipLoadPrefix(plugin)) {\n            plugin = plugin.substr(1, plugin.length);\n            var dependencies = PluginManager.dependencies(plugin);\n            Tools.each(dependencies, function (dep) {\n              var defaultSettings = {\n                prefix: 'plugins/',\n                resource: dep,\n                suffix: '/plugin' + suffix + '.js'\n              };\n              dep = PluginManager.createUrl(defaultSettings, dep);\n              PluginManager.load(dep.resource, dep, noop, undefined, function () {\n                ErrorReporter.pluginLoadError(dep.prefix + dep.resource + dep.suffix, dep.resource);\n              });\n            });\n          } else {\n            var url_2 = {\n              prefix: 'plugins/',\n              resource: plugin,\n              suffix: '/plugin' + suffix + '.js'\n            };\n            PluginManager.load(plugin, url_2, noop, undefined, function () {\n              ErrorReporter.pluginLoadError(url_2.prefix + url_2.resource + url_2.suffix, plugin);\n            });\n          }\n        }\n      });\n    };\n    var loadScripts = function (editor, suffix) {\n      var scriptLoader = ScriptLoader.ScriptLoader;\n      loadTheme(scriptLoader, editor, suffix, function () {\n        loadLanguage(scriptLoader, editor);\n        loadIcons(scriptLoader, editor);\n        loadPlugins(editor.settings, suffix);\n        scriptLoader.loadQueue(function () {\n          if (!editor.removed) {\n            Init.init(editor);\n          }\n        }, editor, function () {\n          if (!editor.removed) {\n            Init.init(editor);\n          }\n        });\n      });\n    };\n    var render = function (editor) {\n      var settings = editor.settings, id = editor.id;\n      I18n.setCode(Settings.getLanguageCode(editor));\n      var readyHandler = function () {\n        DOM$6.unbind(domGlobals.window, 'ready', readyHandler);\n        editor.render();\n      };\n      if (!EventUtils.Event.domLoaded) {\n        DOM$6.bind(domGlobals.window, 'ready', readyHandler);\n        return;\n      }\n      if (!editor.getElement()) {\n        return;\n      }\n      if (!Env.contentEditable) {\n        return;\n      }\n      if (!settings.inline) {\n        editor.orgVisibility = editor.getElement().style.visibility;\n        editor.getElement().style.visibility = 'hidden';\n      } else {\n        editor.inline = true;\n      }\n      var form = editor.getElement().form || DOM$6.getParent(id, 'form');\n      if (form) {\n        editor.formElement = form;\n        if (settings.hidden_input && !NodeType.isTextareaOrInput(editor.getElement())) {\n          DOM$6.insertAfter(DOM$6.create('input', {\n            type: 'hidden',\n            name: id\n          }), id);\n          editor.hasHiddenInput = true;\n        }\n        editor.formEventDelegate = function (e) {\n          editor.fire(e.type, e);\n        };\n        DOM$6.bind(form, 'submit reset', editor.formEventDelegate);\n        editor.on('reset', function () {\n          editor.resetContent();\n        });\n        if (settings.submit_patch && !form.submit.nodeType && !form.submit.length && !form._mceOldSubmit) {\n          form._mceOldSubmit = form.submit;\n          form.submit = function () {\n            editor.editorManager.triggerSave();\n            editor.setDirty(false);\n            return form._mceOldSubmit(form);\n          };\n        }\n      }\n      editor.windowManager = WindowManager(editor);\n      editor.notificationManager = NotificationManager(editor);\n      if (settings.encoding === 'xml') {\n        editor.on('GetContent', function (e) {\n          if (e.save) {\n            e.content = DOM$6.encode(e.content);\n          }\n        });\n      }\n      if (settings.add_form_submit_trigger) {\n        editor.on('submit', function () {\n          if (editor.initialized) {\n            editor.save();\n          }\n        });\n      }\n      if (settings.add_unload_trigger) {\n        editor._beforeUnload = function () {\n          if (editor.initialized && !editor.destroyed && !editor.isHidden()) {\n            editor.save({\n              format: 'raw',\n              no_events: true,\n              set_dirty: false\n            });\n          }\n        };\n        editor.editorManager.on('BeforeUnload', editor._beforeUnload);\n      }\n      editor.editorManager.add(editor);\n      loadScripts(editor, editor.suffix);\n    };\n    var Render = { render: render };\n\n    var internalContentEditableAttr = 'data-mce-contenteditable';\n    var toggleClass = function (elm, cls, state) {\n      if (has$2(elm, cls) && state === false) {\n        remove$4(elm, cls);\n      } else if (state) {\n        add$3(elm, cls);\n      }\n    };\n    var setEditorCommandState = function (editor, cmd, state) {\n      try {\n        editor.getDoc().execCommand(cmd, false, state);\n      } catch (ex) {\n      }\n    };\n    var setContentEditable = function (elm, state) {\n      elm.dom().contentEditable = state ? 'true' : 'false';\n    };\n    var switchOffContentEditableTrue = function (elm) {\n      each(descendants$1(elm, '*[contenteditable=\"true\"]'), function (elm) {\n        set(elm, internalContentEditableAttr, 'true');\n        setContentEditable(elm, false);\n      });\n    };\n    var switchOnContentEditableTrue = function (elm) {\n      each(descendants$1(elm, '*[' + internalContentEditableAttr + '=\"true\"]'), function (elm) {\n        remove(elm, internalContentEditableAttr);\n        setContentEditable(elm, true);\n      });\n    };\n    var removeFakeSelection = function (editor) {\n      Option.from(editor.selection.getNode()).each(function (elm) {\n        elm.removeAttribute('data-mce-selected');\n      });\n    };\n    var restoreFakeSelection = function (editor) {\n      editor.selection.setRng(editor.selection.getRng());\n    };\n    var toggleReadOnly = function (editor, state) {\n      var body = Element.fromDom(editor.getBody());\n      toggleClass(body, 'mce-content-readonly', state);\n      if (state) {\n        editor.selection.controlSelection.hideResizeRect();\n        editor._selectionOverrides.hideFakeCaret();\n        removeFakeSelection(editor);\n        editor.readonly = true;\n        setContentEditable(body, false);\n        switchOffContentEditableTrue(body);\n      } else {\n        editor.readonly = false;\n        setContentEditable(body, true);\n        switchOnContentEditableTrue(body);\n        setEditorCommandState(editor, 'StyleWithCSS', false);\n        setEditorCommandState(editor, 'enableInlineTableEditing', false);\n        setEditorCommandState(editor, 'enableObjectResizing', false);\n        if (EditorFocus.hasEditorOrUiFocus(editor)) {\n          editor.focus();\n        }\n        restoreFakeSelection(editor);\n        editor.nodeChanged();\n      }\n    };\n    var isReadOnly = function (editor) {\n      return editor.readonly === true;\n    };\n    var registerFilters = function (editor) {\n      editor.parser.addAttributeFilter('contenteditable', function (nodes) {\n        if (isReadOnly(editor)) {\n          each(nodes, function (node) {\n            node.attr(internalContentEditableAttr, node.attr('contenteditable'));\n            node.attr('contenteditable', 'false');\n          });\n        }\n      });\n      editor.serializer.addAttributeFilter(internalContentEditableAttr, function (nodes) {\n        if (isReadOnly(editor)) {\n          each(nodes, function (node) {\n            node.attr('contenteditable', node.attr(internalContentEditableAttr));\n          });\n        }\n      });\n      editor.serializer.addTempAttr(internalContentEditableAttr);\n    };\n    var registerReadOnlyContentFilters = function (editor) {\n      if (editor.serializer) {\n        registerFilters(editor);\n      } else {\n        editor.on('PreInit', function () {\n          registerFilters(editor);\n        });\n      }\n    };\n    var isClickEvent = function (e) {\n      return e.type === 'click';\n    };\n    var preventReadOnlyEvents = function (e) {\n      var target = e.target;\n      if (isClickEvent(e) && target.tagName === 'A' && !VK.metaKeyPressed(e)) {\n        e.preventDefault();\n      }\n    };\n    var registerReadOnlySelectionBlockers = function (editor) {\n      editor.on('ShowCaret', function (e) {\n        if (isReadOnly(editor)) {\n          e.preventDefault();\n        }\n      });\n      editor.on('ObjectSelected', function (e) {\n        if (isReadOnly(editor)) {\n          e.preventDefault();\n        }\n      });\n    };\n\n    var defaultModes = [\n      'design',\n      'readonly'\n    ];\n    var switchToMode = function (editor, activeMode, availableModes, mode) {\n      var oldMode = availableModes[activeMode.get()];\n      var newMode = availableModes[mode];\n      try {\n        newMode.activate();\n      } catch (e) {\n        domGlobals.console.error('problem while activating editor mode ' + mode + ':', e);\n        return;\n      }\n      oldMode.deactivate();\n      if (oldMode.editorReadOnly !== newMode.editorReadOnly) {\n        toggleReadOnly(editor, newMode.editorReadOnly);\n      }\n      activeMode.set(mode);\n      Events.fireSwitchMode(editor, mode);\n    };\n    var setMode = function (editor, availableModes, activeMode, mode) {\n      if (mode === activeMode.get()) {\n        return;\n      } else if (!has(availableModes, mode)) {\n        throw new Error('Editor mode \\'' + mode + '\\' is invalid');\n      }\n      if (editor.initialized) {\n        switchToMode(editor, activeMode, availableModes, mode);\n      } else {\n        editor.on('init', function () {\n          return switchToMode(editor, activeMode, availableModes, mode);\n        });\n      }\n    };\n    var registerMode = function (availableModes, mode, api) {\n      var _a;\n      if (contains(defaultModes, mode)) {\n        throw new Error('Cannot override default mode ' + mode);\n      }\n      return __assign(__assign({}, availableModes), (_a = {}, _a[mode] = __assign(__assign({}, api), {\n        deactivate: function () {\n          try {\n            api.deactivate();\n          } catch (e) {\n            domGlobals.console.error('problem while deactivating editor mode ' + mode + ':', e);\n          }\n        }\n      }), _a));\n    };\n\n    var create$4 = function (editor) {\n      var activeMode = Cell('design');\n      var availableModes = Cell({\n        design: {\n          activate: noop,\n          deactivate: noop,\n          editorReadOnly: false\n        },\n        readonly: {\n          activate: noop,\n          deactivate: noop,\n          editorReadOnly: true\n        }\n      });\n      registerReadOnlyContentFilters(editor);\n      registerReadOnlySelectionBlockers(editor);\n      return {\n        isReadOnly: function () {\n          return isReadOnly(editor);\n        },\n        set: function (mode) {\n          return setMode(editor, availableModes.get(), activeMode, mode);\n        },\n        get: function () {\n          return activeMode.get();\n        },\n        register: function (mode, api) {\n          availableModes.set(registerMode(availableModes.get(), mode, api));\n        }\n      };\n    };\n\n    var hasOnlyOneChild$1 = function (node) {\n      return node.firstChild && node.firstChild === node.lastChild;\n    };\n    var isPaddingNode = function (node) {\n      return node.name === 'br' || node.value === '\\xA0';\n    };\n    var isPaddedEmptyBlock = function (schema, node) {\n      var blockElements = schema.getBlockElements();\n      return blockElements[node.name] && hasOnlyOneChild$1(node) && isPaddingNode(node.firstChild);\n    };\n    var isEmptyFragmentElement = function (schema, node) {\n      var nonEmptyElements = schema.getNonEmptyElements();\n      return node && (node.isEmpty(nonEmptyElements) || isPaddedEmptyBlock(schema, node));\n    };\n    var isListFragment = function (schema, fragment) {\n      var firstChild = fragment.firstChild;\n      var lastChild = fragment.lastChild;\n      if (firstChild && firstChild.name === 'meta') {\n        firstChild = firstChild.next;\n      }\n      if (lastChild && lastChild.attr('id') === 'mce_marker') {\n        lastChild = lastChild.prev;\n      }\n      if (isEmptyFragmentElement(schema, lastChild)) {\n        lastChild = lastChild.prev;\n      }\n      if (!firstChild || firstChild !== lastChild) {\n        return false;\n      }\n      return firstChild.name === 'ul' || firstChild.name === 'ol';\n    };\n    var cleanupDomFragment = function (domFragment) {\n      var firstChild = domFragment.firstChild;\n      var lastChild = domFragment.lastChild;\n      if (firstChild && firstChild.nodeName === 'META') {\n        firstChild.parentNode.removeChild(firstChild);\n      }\n      if (lastChild && lastChild.id === 'mce_marker') {\n        lastChild.parentNode.removeChild(lastChild);\n      }\n      return domFragment;\n    };\n    var toDomFragment = function (dom, serializer, fragment) {\n      var html = serializer.serialize(fragment);\n      var domFragment = dom.createFragment(html);\n      return cleanupDomFragment(domFragment);\n    };\n    var listItems$1 = function (elm) {\n      return Tools.grep(elm.childNodes, function (child) {\n        return child.nodeName === 'LI';\n      });\n    };\n    var isPadding = function (node) {\n      return node.data === '\\xA0' || NodeType.isBr(node);\n    };\n    var isListItemPadded = function (node) {\n      return node && node.firstChild && node.firstChild === node.lastChild && isPadding(node.firstChild);\n    };\n    var isEmptyOrPadded = function (elm) {\n      return !elm.firstChild || isListItemPadded(elm);\n    };\n    var trimListItems = function (elms) {\n      return elms.length > 0 && isEmptyOrPadded(elms[elms.length - 1]) ? elms.slice(0, -1) : elms;\n    };\n    var getParentLi = function (dom, node) {\n      var parentBlock = dom.getParent(node, dom.isBlock);\n      return parentBlock && parentBlock.nodeName === 'LI' ? parentBlock : null;\n    };\n    var isParentBlockLi = function (dom, node) {\n      return !!getParentLi(dom, node);\n    };\n    var getSplit = function (parentNode, rng) {\n      var beforeRng = rng.cloneRange();\n      var afterRng = rng.cloneRange();\n      beforeRng.setStartBefore(parentNode);\n      afterRng.setEndAfter(parentNode);\n      return [\n        beforeRng.cloneContents(),\n        afterRng.cloneContents()\n      ];\n    };\n    var findFirstIn = function (node, rootNode) {\n      var caretPos = CaretPosition$1.before(node);\n      var caretWalker = CaretWalker(rootNode);\n      var newCaretPos = caretWalker.next(caretPos);\n      return newCaretPos ? newCaretPos.toRange() : null;\n    };\n    var findLastOf = function (node, rootNode) {\n      var caretPos = CaretPosition$1.after(node);\n      var caretWalker = CaretWalker(rootNode);\n      var newCaretPos = caretWalker.prev(caretPos);\n      return newCaretPos ? newCaretPos.toRange() : null;\n    };\n    var insertMiddle = function (target, elms, rootNode, rng) {\n      var parts = getSplit(target, rng);\n      var parentElm = target.parentNode;\n      parentElm.insertBefore(parts[0], target);\n      Tools.each(elms, function (li) {\n        parentElm.insertBefore(li, target);\n      });\n      parentElm.insertBefore(parts[1], target);\n      parentElm.removeChild(target);\n      return findLastOf(elms[elms.length - 1], rootNode);\n    };\n    var insertBefore$1 = function (target, elms, rootNode) {\n      var parentElm = target.parentNode;\n      Tools.each(elms, function (elm) {\n        parentElm.insertBefore(elm, target);\n      });\n      return findFirstIn(target, rootNode);\n    };\n    var insertAfter$1 = function (target, elms, rootNode, dom) {\n      dom.insertAfter(elms.reverse(), target);\n      return findLastOf(elms[0], rootNode);\n    };\n    var insertAtCaret = function (serializer, dom, rng, fragment) {\n      var domFragment = toDomFragment(dom, serializer, fragment);\n      var liTarget = getParentLi(dom, rng.startContainer);\n      var liElms = trimListItems(listItems$1(domFragment.firstChild));\n      var BEGINNING = 1, END = 2;\n      var rootNode = dom.getRoot();\n      var isAt = function (location) {\n        var caretPos = CaretPosition$1.fromRangeStart(rng);\n        var caretWalker = CaretWalker(dom.getRoot());\n        var newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos);\n        return newPos ? getParentLi(dom, newPos.getNode()) !== liTarget : true;\n      };\n      if (isAt(BEGINNING)) {\n        return insertBefore$1(liTarget, liElms, rootNode);\n      } else if (isAt(END)) {\n        return insertAfter$1(liTarget, liElms, rootNode, dom);\n      }\n      return insertMiddle(liTarget, liElms, rootNode, rng);\n    };\n    var InsertList = {\n      isListFragment: isListFragment,\n      insertAtCaret: insertAtCaret,\n      isParentBlockLi: isParentBlockLi,\n      trimListItems: trimListItems,\n      listItems: listItems$1\n    };\n\n    var isAfterNbsp = function (container, offset) {\n      return NodeType.isText(container) && container.nodeValue[offset - 1] === '\\xA0';\n    };\n    var trimOrPadLeftRight = function (rng, html) {\n      var container, offset;\n      container = rng.startContainer;\n      offset = rng.startOffset;\n      var hasSiblingText = function (siblingName) {\n        return container[siblingName] && container[siblingName].nodeType === 3;\n      };\n      if (container.nodeType === 3) {\n        if (offset > 0) {\n          html = html.replace(/^&nbsp;/, ' ');\n        } else if (!hasSiblingText('previousSibling')) {\n          html = html.replace(/^ /, '&nbsp;');\n        }\n        if (offset < container.length) {\n          html = html.replace(/&nbsp;(<br>|)$/, ' ');\n        } else if (!hasSiblingText('nextSibling')) {\n          html = html.replace(/(&nbsp;| )(<br>|)$/, '&nbsp;');\n        }\n      }\n      return html;\n    };\n    var trimNbspAfterDeleteAndPadValue = function (rng, value) {\n      var container, offset;\n      container = rng.startContainer;\n      offset = rng.startOffset;\n      if (container.nodeType === 3 && rng.collapsed) {\n        if (container.data[offset] === '\\xA0') {\n          container.deleteData(offset, 1);\n          if (!/[\\u00a0| ]$/.test(value)) {\n            value += ' ';\n          }\n        } else if (container.data[offset - 1] === '\\xA0') {\n          container.deleteData(offset - 1, 1);\n          if (!/[\\u00a0| ]$/.test(value)) {\n            value = ' ' + value;\n          }\n        }\n      }\n      return value;\n    };\n\n    var isTableCell$5 = NodeType.matchNodeNames([\n      'td',\n      'th'\n    ]);\n    var selectionSetContent = function (editor, content) {\n      var rng = editor.selection.getRng();\n      var container = rng.startContainer;\n      var offset = rng.startOffset;\n      if (rng.collapsed && isAfterNbsp(container, offset) && NodeType.isText(container)) {\n        container.insertData(offset - 1, ' ');\n        container.deleteData(offset, 1);\n        rng.setStart(container, offset);\n        rng.setEnd(container, offset);\n        editor.selection.setRng(rng);\n      }\n      editor.selection.setContent(content);\n    };\n    var validInsertion = function (editor, value, parentNode) {\n      if (parentNode.getAttribute('data-mce-bogus') === 'all') {\n        parentNode.parentNode.insertBefore(editor.dom.createFragment(value), parentNode);\n      } else {\n        var node = parentNode.firstChild;\n        var node2 = parentNode.lastChild;\n        if (!node || node === node2 && node.nodeName === 'BR') {\n          editor.dom.setHTML(parentNode, value);\n        } else {\n          selectionSetContent(editor, value);\n        }\n      }\n    };\n    var trimBrsFromTableCell = function (dom, elm) {\n      Option.from(dom.getParent(elm, 'td,th')).map(Element.fromDom).each(PaddingBr.trimBlockTrailingBr);\n    };\n    var reduceInlineTextElements = function (editor, merge) {\n      var textInlineElements = editor.schema.getTextInlineElements();\n      var dom = editor.dom;\n      if (merge) {\n        var root_1 = editor.getBody(), elementUtils_1 = new ElementUtils(dom);\n        Tools.each(dom.select('*[data-mce-fragment]'), function (node) {\n          for (var testNode = node.parentNode; testNode && testNode !== root_1; testNode = testNode.parentNode) {\n            if (textInlineElements[node.nodeName.toLowerCase()] && elementUtils_1.compare(testNode, node)) {\n              dom.remove(node, true);\n            }\n          }\n        });\n      }\n    };\n    var markFragmentElements = function (fragment) {\n      var node = fragment;\n      while (node = node.walk()) {\n        if (node.type === 1) {\n          node.attr('data-mce-fragment', '1');\n        }\n      }\n    };\n    var umarkFragmentElements = function (elm) {\n      Tools.each(elm.getElementsByTagName('*'), function (elm) {\n        elm.removeAttribute('data-mce-fragment');\n      });\n    };\n    var isPartOfFragment = function (node) {\n      return !!node.getAttribute('data-mce-fragment');\n    };\n    var canHaveChildren = function (editor, node) {\n      return node && !editor.schema.getShortEndedElements()[node.nodeName];\n    };\n    var moveSelectionToMarker = function (editor, marker) {\n      var parentEditableFalseElm, parentBlock, nextRng;\n      var dom = editor.dom, selection = editor.selection;\n      var node, node2;\n      var getContentEditableFalseParent = function (node) {\n        var root = editor.getBody();\n        for (; node && node !== root; node = node.parentNode) {\n          if (editor.dom.getContentEditable(node) === 'false') {\n            return node;\n          }\n        }\n        return null;\n      };\n      if (!marker) {\n        return;\n      }\n      editor.selection.scrollIntoView(marker);\n      parentEditableFalseElm = getContentEditableFalseParent(marker);\n      if (parentEditableFalseElm) {\n        dom.remove(marker);\n        selection.select(parentEditableFalseElm);\n        return;\n      }\n      var rng = dom.createRng();\n      node = marker.previousSibling;\n      if (node && node.nodeType === 3) {\n        rng.setStart(node, node.nodeValue.length);\n        if (!Env.ie) {\n          node2 = marker.nextSibling;\n          if (node2 && node2.nodeType === 3) {\n            node.appendData(node2.data);\n            node2.parentNode.removeChild(node2);\n          }\n        }\n      } else {\n        rng.setStartBefore(marker);\n        rng.setEndBefore(marker);\n      }\n      var findNextCaretRng = function (rng) {\n        var caretPos = CaretPosition$1.fromRangeStart(rng);\n        var caretWalker = CaretWalker(editor.getBody());\n        caretPos = caretWalker.next(caretPos);\n        if (caretPos) {\n          return caretPos.toRange();\n        }\n      };\n      parentBlock = dom.getParent(marker, dom.isBlock);\n      dom.remove(marker);\n      if (parentBlock && dom.isEmpty(parentBlock)) {\n        editor.$(parentBlock).empty();\n        rng.setStart(parentBlock, 0);\n        rng.setEnd(parentBlock, 0);\n        if (!isTableCell$5(parentBlock) && !isPartOfFragment(parentBlock) && (nextRng = findNextCaretRng(rng))) {\n          rng = nextRng;\n          dom.remove(parentBlock);\n        } else {\n          dom.add(parentBlock, dom.create('br', { 'data-mce-bogus': '1' }));\n        }\n      }\n      selection.setRng(rng);\n    };\n    var insertHtmlAtCaret = function (editor, value, details) {\n      var parser, serializer, parentNode, rootNode, fragment, args;\n      var marker, rng, node, bookmarkHtml, merge;\n      var selection = editor.selection, dom = editor.dom;\n      if (/^ | $/.test(value)) {\n        value = trimOrPadLeftRight(selection.getRng(), value);\n      }\n      parser = editor.parser;\n      merge = details.merge;\n      serializer = Serializer({ validate: editor.settings.validate }, editor.schema);\n      bookmarkHtml = '<span id=\"mce_marker\" data-mce-type=\"bookmark\">&#xFEFF;&#x200B;</span>';\n      args = {\n        content: value,\n        format: 'html',\n        selection: true,\n        paste: details.paste\n      };\n      args = editor.fire('BeforeSetContent', args);\n      if (args.isDefaultPrevented()) {\n        editor.fire('SetContent', {\n          content: args.content,\n          format: 'html',\n          selection: true,\n          paste: details.paste\n        });\n        return;\n      }\n      value = args.content;\n      if (value.indexOf('{$caret}') === -1) {\n        value += '{$caret}';\n      }\n      value = value.replace(/\\{\\$caret\\}/, bookmarkHtml);\n      rng = selection.getRng();\n      var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null);\n      var body = editor.getBody();\n      if (caretElement === body && selection.isCollapsed()) {\n        if (dom.isBlock(body.firstChild) && canHaveChildren(editor, body.firstChild) && dom.isEmpty(body.firstChild)) {\n          rng = dom.createRng();\n          rng.setStart(body.firstChild, 0);\n          rng.setEnd(body.firstChild, 0);\n          selection.setRng(rng);\n        }\n      }\n      if (!selection.isCollapsed()) {\n        editor.selection.setRng(RangeNormalizer.normalize(editor.selection.getRng()));\n        editor.getDoc().execCommand('Delete', false, null);\n        value = trimNbspAfterDeleteAndPadValue(editor.selection.getRng(), value);\n      }\n      parentNode = selection.getNode();\n      var parserArgs = {\n        context: parentNode.nodeName.toLowerCase(),\n        data: details.data,\n        insert: true\n      };\n      fragment = parser.parse(value, parserArgs);\n      if (details.paste === true && InsertList.isListFragment(editor.schema, fragment) && InsertList.isParentBlockLi(dom, parentNode)) {\n        rng = InsertList.insertAtCaret(serializer, dom, editor.selection.getRng(), fragment);\n        editor.selection.setRng(rng);\n        editor.fire('SetContent', args);\n        return;\n      }\n      markFragmentElements(fragment);\n      node = fragment.lastChild;\n      if (node.attr('id') === 'mce_marker') {\n        marker = node;\n        for (node = node.prev; node; node = node.walk(true)) {\n          if (node.type === 3 || !dom.isBlock(node.name)) {\n            if (editor.schema.isValidChild(node.parent.name, 'span')) {\n              node.parent.insert(marker, node, node.name === 'br');\n            }\n            break;\n          }\n        }\n      }\n      editor._selectionOverrides.showBlockCaretContainer(parentNode);\n      if (!parserArgs.invalid) {\n        value = serializer.serialize(fragment);\n        validInsertion(editor, value, parentNode);\n      } else {\n        selectionSetContent(editor, bookmarkHtml);\n        parentNode = selection.getNode();\n        rootNode = editor.getBody();\n        if (parentNode.nodeType === 9) {\n          parentNode = node = rootNode;\n        } else {\n          node = parentNode;\n        }\n        while (node !== rootNode) {\n          parentNode = node;\n          node = node.parentNode;\n        }\n        value = parentNode === rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode);\n        value = serializer.serialize(parser.parse(value.replace(/<span (id=\"mce_marker\"|id=mce_marker).+?<\\/span>/i, function () {\n          return serializer.serialize(fragment);\n        })));\n        if (parentNode === rootNode) {\n          dom.setHTML(rootNode, value);\n        } else {\n          dom.setOuterHTML(parentNode, value);\n        }\n      }\n      reduceInlineTextElements(editor, merge);\n      moveSelectionToMarker(editor, dom.get('mce_marker'));\n      umarkFragmentElements(editor.getBody());\n      trimBrsFromTableCell(editor.dom, editor.selection.getStart());\n      editor.fire('SetContent', args);\n      editor.addVisual();\n    };\n    var processValue = function (value) {\n      var details;\n      if (typeof value !== 'string') {\n        details = Tools.extend({\n          paste: value.paste,\n          data: { paste: value.paste }\n        }, value);\n        return {\n          content: value.content,\n          details: details\n        };\n      }\n      return {\n        content: value,\n        details: {}\n      };\n    };\n    var insertAtCaret$1 = function (editor, value) {\n      var result = processValue(value);\n      insertHtmlAtCaret(editor, result.content, result.details);\n    };\n    var InsertContent = { insertAtCaret: insertAtCaret$1 };\n\n    var nativeCommand = function (editor, command) {\n      editor.getDoc().execCommand(command, false, null);\n    };\n    var deleteCommand = function (editor) {\n      if (Outdent.backspaceDelete(editor, false)) {\n        return;\n      } else if (CefDelete.backspaceDelete(editor, false)) {\n        return;\n      } else if (CefBoundaryDelete.backspaceDelete(editor, false)) {\n        return;\n      } else if (BoundaryDelete.backspaceDelete(editor, false)) {\n        return;\n      } else if (BlockBoundaryDelete.backspaceDelete(editor, false)) {\n        return;\n      } else if (TableDelete.backspaceDelete(editor)) {\n        return;\n      } else if (BlockRangeDelete.backspaceDelete(editor, false)) {\n        return;\n      } else if (InlineFormatDelete.backspaceDelete(editor, false)) {\n        return;\n      } else {\n        nativeCommand(editor, 'Delete');\n        DeleteUtils.paddEmptyBody(editor);\n      }\n    };\n    var forwardDeleteCommand = function (editor) {\n      if (CefDelete.backspaceDelete(editor, true)) {\n        return;\n      } else if (CefBoundaryDelete.backspaceDelete(editor, true)) {\n        return;\n      } else if (BoundaryDelete.backspaceDelete(editor, true)) {\n        return;\n      } else if (BlockBoundaryDelete.backspaceDelete(editor, true)) {\n        return;\n      } else if (TableDelete.backspaceDelete(editor)) {\n        return;\n      } else if (BlockRangeDelete.backspaceDelete(editor, true)) {\n        return;\n      } else if (InlineFormatDelete.backspaceDelete(editor, true)) {\n        return;\n      } else {\n        nativeCommand(editor, 'ForwardDelete');\n      }\n    };\n    var DeleteCommands = {\n      deleteCommand: deleteCommand,\n      forwardDeleteCommand: forwardDeleteCommand\n    };\n\n    var getSpecifiedFontProp = function (propName, rootElm, elm) {\n      var getProperty = function (elm) {\n        return getRaw(elm, propName);\n      };\n      var isRoot = function (elm) {\n        return eq(Element.fromDom(rootElm), elm);\n      };\n      return closest(Element.fromDom(elm), function (elm) {\n        return getProperty(elm).isSome();\n      }, isRoot).bind(getProperty);\n    };\n    var round$1 = function (number, precision) {\n      var factor = Math.pow(10, precision);\n      return Math.round(number * factor) / factor;\n    };\n    var toPt = function (fontSize, precision) {\n      if (/[0-9.]+px$/.test(fontSize)) {\n        return round$1(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt';\n      }\n      return fontSize;\n    };\n    var normalizeFontFamily = function (fontFamily) {\n      return fontFamily.replace(/[\\'\\\"\\\\]/g, '').replace(/,\\s+/g, ',');\n    };\n    var getComputedFontProp = function (propName, elm) {\n      return Option.from(DOMUtils$1.DOM.getStyle(elm, propName, true));\n    };\n    var getFontProp = function (propName) {\n      return function (rootElm, elm) {\n        return Option.from(elm).map(Element.fromDom).filter(isElement$1).bind(function (element) {\n          return getSpecifiedFontProp(propName, rootElm, element.dom()).or(getComputedFontProp(propName, element.dom()));\n        }).getOr('');\n      };\n    };\n    var FontInfo = {\n      getFontSize: getFontProp('font-size'),\n      getFontFamily: compose(normalizeFontFamily, getFontProp('font-family')),\n      toPt: toPt\n    };\n\n    var findFirstCaretElement = function (editor) {\n      return CaretFinder.firstPositionIn(editor.getBody()).map(function (caret) {\n        var container = caret.container();\n        return NodeType.isText(container) ? container.parentNode : container;\n      });\n    };\n    var isRangeAtStartOfNode = function (rng, root) {\n      return rng.startContainer === root && rng.startOffset === 0;\n    };\n    var getCaretElement = function (editor) {\n      return Option.from(editor.selection.getRng()).bind(function (rng) {\n        var root = editor.getBody();\n        return isRangeAtStartOfNode(rng, root) ? Option.none() : Option.from(editor.selection.getStart(true));\n      });\n    };\n    var fromFontSizeNumber = function (editor, value) {\n      if (/^[0-9\\.]+$/.test(value)) {\n        var fontSizeNumber = parseInt(value, 10);\n        if (fontSizeNumber >= 1 && fontSizeNumber <= 7) {\n          var fontSizes = Settings.getFontStyleValues(editor);\n          var fontClasses = Settings.getFontSizeClasses(editor);\n          if (fontClasses) {\n            return fontClasses[fontSizeNumber - 1] || value;\n          } else {\n            return fontSizes[fontSizeNumber - 1] || value;\n          }\n        } else {\n          return value;\n        }\n      } else {\n        return value;\n      }\n    };\n    var normalizeFontNames = function (font) {\n      var fonts = font.split(/\\s*,\\s*/);\n      return map(fonts, function (font) {\n        if (font.indexOf(' ') !== -1 && !(startsWith(font, '\"') || startsWith(font, '\\''))) {\n          return '\\'' + font + '\\'';\n        } else {\n          return font;\n        }\n      }).join(',');\n    };\n    var fontNameAction = function (editor, value) {\n      var font = fromFontSizeNumber(editor, value);\n      editor.formatter.toggle('fontname', { value: normalizeFontNames(font) });\n      editor.nodeChanged();\n    };\n    var fontNameQuery = function (editor) {\n      return getCaretElement(editor).fold(function () {\n        return findFirstCaretElement(editor).map(function (caretElement) {\n          return FontInfo.getFontFamily(editor.getBody(), caretElement);\n        }).getOr('');\n      }, function (caretElement) {\n        return FontInfo.getFontFamily(editor.getBody(), caretElement);\n      });\n    };\n    var fontSizeAction = function (editor, value) {\n      editor.formatter.toggle('fontsize', { value: fromFontSizeNumber(editor, value) });\n      editor.nodeChanged();\n    };\n    var fontSizeQuery = function (editor) {\n      return getCaretElement(editor).fold(function () {\n        return findFirstCaretElement(editor).map(function (caretElement) {\n          return FontInfo.getFontSize(editor.getBody(), caretElement);\n        }).getOr('');\n      }, function (caretElement) {\n        return FontInfo.getFontSize(editor.getBody(), caretElement);\n      });\n    };\n\n    var each$g = Tools.each;\n    var map$3 = Tools.map, inArray$2 = Tools.inArray;\n    var EditorCommands = function () {\n      function EditorCommands(editor) {\n        this.commands = {\n          state: {},\n          exec: {},\n          value: {}\n        };\n        this.editor = editor;\n        this.setupCommands(editor);\n      }\n      EditorCommands.prototype.execCommand = function (command, ui, value, args) {\n        var func, customCommand, state = false;\n        var self = this;\n        if (self.editor.removed) {\n          return;\n        }\n        if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) {\n          self.editor.focus();\n        } else {\n          SelectionBookmark.restore(self.editor);\n        }\n        args = self.editor.fire('BeforeExecCommand', {\n          command: command,\n          ui: ui,\n          value: value\n        });\n        if (args.isDefaultPrevented()) {\n          return false;\n        }\n        customCommand = command.toLowerCase();\n        if (func = self.commands.exec[customCommand]) {\n          func(customCommand, ui, value);\n          self.editor.fire('ExecCommand', {\n            command: command,\n            ui: ui,\n            value: value\n          });\n          return true;\n        }\n        each$g(this.editor.plugins, function (p) {\n          if (p.execCommand && p.execCommand(command, ui, value)) {\n            self.editor.fire('ExecCommand', {\n              command: command,\n              ui: ui,\n              value: value\n            });\n            state = true;\n            return false;\n          }\n        });\n        if (state) {\n          return state;\n        }\n        if (self.editor.theme && self.editor.theme.execCommand && self.editor.theme.execCommand(command, ui, value)) {\n          self.editor.fire('ExecCommand', {\n            command: command,\n            ui: ui,\n            value: value\n          });\n          return true;\n        }\n        try {\n          state = self.editor.getDoc().execCommand(command, ui, value);\n        } catch (ex) {\n        }\n        if (state) {\n          self.editor.fire('ExecCommand', {\n            command: command,\n            ui: ui,\n            value: value\n          });\n          return true;\n        }\n        return false;\n      };\n      EditorCommands.prototype.queryCommandState = function (command) {\n        var func;\n        if (this.editor.quirks.isHidden() || this.editor.removed) {\n          return;\n        }\n        command = command.toLowerCase();\n        if (func = this.commands.state[command]) {\n          return func(command);\n        }\n        try {\n          return this.editor.getDoc().queryCommandState(command);\n        } catch (ex) {\n        }\n        return false;\n      };\n      EditorCommands.prototype.queryCommandValue = function (command) {\n        var func;\n        if (this.editor.quirks.isHidden() || this.editor.removed) {\n          return;\n        }\n        command = command.toLowerCase();\n        if (func = this.commands.value[command]) {\n          return func(command);\n        }\n        try {\n          return this.editor.getDoc().queryCommandValue(command);\n        } catch (ex) {\n        }\n      };\n      EditorCommands.prototype.addCommands = function (commandList, type) {\n        var self = this;\n        type = type || 'exec';\n        each$g(commandList, function (callback, command) {\n          each$g(command.toLowerCase().split(','), function (command) {\n            self.commands[type][command] = callback;\n          });\n        });\n      };\n      EditorCommands.prototype.addCommand = function (command, callback, scope) {\n        var _this = this;\n        command = command.toLowerCase();\n        this.commands.exec[command] = function (command, ui, value, args) {\n          return callback.call(scope || _this.editor, ui, value, args);\n        };\n      };\n      EditorCommands.prototype.queryCommandSupported = function (command) {\n        command = command.toLowerCase();\n        if (this.commands.exec[command]) {\n          return true;\n        }\n        try {\n          return this.editor.getDoc().queryCommandSupported(command);\n        } catch (ex) {\n        }\n        return false;\n      };\n      EditorCommands.prototype.addQueryStateHandler = function (command, callback, scope) {\n        var _this = this;\n        command = command.toLowerCase();\n        this.commands.state[command] = function () {\n          return callback.call(scope || _this.editor);\n        };\n      };\n      EditorCommands.prototype.addQueryValueHandler = function (command, callback, scope) {\n        var _this = this;\n        command = command.toLowerCase();\n        this.commands.value[command] = function () {\n          return callback.call(scope || _this.editor);\n        };\n      };\n      EditorCommands.prototype.hasCustomCommand = function (command) {\n        command = command.toLowerCase();\n        return !!this.commands.exec[command];\n      };\n      EditorCommands.prototype.execNativeCommand = function (command, ui, value) {\n        if (ui === undefined) {\n          ui = false;\n        }\n        if (value === undefined) {\n          value = null;\n        }\n        return this.editor.getDoc().execCommand(command, ui, value);\n      };\n      EditorCommands.prototype.isFormatMatch = function (name) {\n        return this.editor.formatter.match(name);\n      };\n      EditorCommands.prototype.toggleFormat = function (name, value) {\n        this.editor.formatter.toggle(name, value ? { value: value } : undefined);\n        this.editor.nodeChanged();\n      };\n      EditorCommands.prototype.storeSelection = function (type) {\n        this.selectionBookmark = this.editor.selection.getBookmark(type);\n      };\n      EditorCommands.prototype.restoreSelection = function () {\n        this.editor.selection.moveToBookmark(this.selectionBookmark);\n      };\n      EditorCommands.prototype.setupCommands = function (editor) {\n        var self = this;\n        this.addCommands({\n          'mceResetDesignMode,mceBeginUndoLevel': function () {\n          },\n          'mceEndUndoLevel,mceAddUndoLevel': function () {\n            editor.undoManager.add();\n          },\n          'Cut,Copy,Paste': function (command) {\n            var doc = editor.getDoc();\n            var failed;\n            try {\n              self.execNativeCommand(command);\n            } catch (ex) {\n              failed = true;\n            }\n            if (command === 'paste' && !doc.queryCommandEnabled(command)) {\n              failed = true;\n            }\n            if (failed || !doc.queryCommandSupported(command)) {\n              var msg = editor.translate('Your browser doesn\\'t support direct access to the clipboard. ' + 'Please use the Ctrl+X/C/V keyboard shortcuts instead.');\n              if (Env.mac) {\n                msg = msg.replace(/Ctrl\\+/g, '\\u2318+');\n              }\n              editor.notificationManager.open({\n                text: msg,\n                type: 'error'\n              });\n            }\n          },\n          'unlink': function () {\n            if (editor.selection.isCollapsed()) {\n              var elm = editor.dom.getParent(editor.selection.getStart(), 'a');\n              if (elm) {\n                editor.dom.remove(elm, true);\n              }\n              return;\n            }\n            editor.formatter.remove('link');\n          },\n          'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function (command) {\n            var align = command.substring(7);\n            if (align === 'full') {\n              align = 'justify';\n            }\n            each$g('left,center,right,justify'.split(','), function (name) {\n              if (align !== name) {\n                editor.formatter.remove('align' + name);\n              }\n            });\n            if (align !== 'none') {\n              self.toggleFormat('align' + align);\n            }\n          },\n          'InsertUnorderedList,InsertOrderedList': function (command) {\n            var listElm, listParent;\n            self.execNativeCommand(command);\n            listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');\n            if (listElm) {\n              listParent = listElm.parentNode;\n              if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) {\n                self.storeSelection();\n                editor.dom.split(listParent, listElm);\n                self.restoreSelection();\n              }\n            }\n          },\n          'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {\n            self.toggleFormat(command);\n          },\n          'ForeColor,HiliteColor': function (command, ui, value) {\n            self.toggleFormat(command, value);\n          },\n          'FontName': function (command, ui, value) {\n            fontNameAction(editor, value);\n          },\n          'FontSize': function (command, ui, value) {\n            fontSizeAction(editor, value);\n          },\n          'RemoveFormat': function (command) {\n            editor.formatter.remove(command);\n          },\n          'mceBlockQuote': function () {\n            self.toggleFormat('blockquote');\n          },\n          'FormatBlock': function (command, ui, value) {\n            return self.toggleFormat(value || 'p');\n          },\n          'mceCleanup': function () {\n            var bookmark = editor.selection.getBookmark();\n            editor.setContent(editor.getContent());\n            editor.selection.moveToBookmark(bookmark);\n          },\n          'mceRemoveNode': function (command, ui, value) {\n            var node = value || editor.selection.getNode();\n            if (node !== editor.getBody()) {\n              self.storeSelection();\n              editor.dom.remove(node, true);\n              self.restoreSelection();\n            }\n          },\n          'mceSelectNodeDepth': function (command, ui, value) {\n            var counter = 0;\n            editor.dom.getParent(editor.selection.getNode(), function (node) {\n              if (node.nodeType === 1 && counter++ === value) {\n                editor.selection.select(node);\n                return false;\n              }\n            }, editor.getBody());\n          },\n          'mceSelectNode': function (command, ui, value) {\n            editor.selection.select(value);\n          },\n          'mceInsertContent': function (command, ui, value) {\n            InsertContent.insertAtCaret(editor, value);\n          },\n          'mceInsertRawHTML': function (command, ui, value) {\n            editor.selection.setContent('tiny_mce_marker');\n            var content = editor.getContent();\n            editor.setContent(content.replace(/tiny_mce_marker/g, function () {\n              return value;\n            }));\n          },\n          'mceInsertNewLine': function (command, ui, value) {\n            InsertNewLine.insert(editor, value);\n          },\n          'mceToggleFormat': function (command, ui, value) {\n            self.toggleFormat(value);\n          },\n          'mceSetContent': function (command, ui, value) {\n            editor.setContent(value);\n          },\n          'Indent,Outdent': function (command) {\n            handle(editor, command);\n          },\n          'mceRepaint': function () {\n          },\n          'InsertHorizontalRule': function () {\n            editor.execCommand('mceInsertContent', false, '<hr />');\n          },\n          'mceToggleVisualAid': function () {\n            editor.hasVisual = !editor.hasVisual;\n            editor.addVisual();\n          },\n          'mceReplaceContent': function (command, ui, value) {\n            editor.execCommand('mceInsertContent', false, value.replace(/\\{\\$selection\\}/g, editor.selection.getContent({ format: 'text' })));\n          },\n          'mceInsertLink': function (command, ui, value) {\n            var anchor;\n            if (typeof value === 'string') {\n              value = { href: value };\n            }\n            anchor = editor.dom.getParent(editor.selection.getNode(), 'a');\n            value.href = value.href.replace(/ /g, '%20');\n            if (!anchor || !value.href) {\n              editor.formatter.remove('link');\n            }\n            if (value.href) {\n              editor.formatter.apply('link', value, anchor);\n            }\n          },\n          'selectAll': function () {\n            var editingHost = editor.dom.getParent(editor.selection.getStart(), NodeType.isContentEditableTrue);\n            if (editingHost) {\n              var rng = editor.dom.createRng();\n              rng.selectNodeContents(editingHost);\n              editor.selection.setRng(rng);\n            }\n          },\n          'delete': function () {\n            DeleteCommands.deleteCommand(editor);\n          },\n          'forwardDelete': function () {\n            DeleteCommands.forwardDeleteCommand(editor);\n          },\n          'mceNewDocument': function () {\n            editor.setContent('');\n          },\n          'InsertLineBreak': function (command, ui, value) {\n            InsertBr.insert(editor, value);\n            return true;\n          }\n        });\n        var alignStates = function (name) {\n          return function () {\n            var nodes = editor.selection.isCollapsed() ? [editor.dom.getParent(editor.selection.getNode(), editor.dom.isBlock)] : editor.selection.getSelectedBlocks();\n            var matches = map$3(nodes, function (node) {\n              return !!editor.formatter.matchNode(node, name);\n            });\n            return inArray$2(matches, true) !== -1;\n          };\n        };\n        self.addCommands({\n          'JustifyLeft': alignStates('alignleft'),\n          'JustifyCenter': alignStates('aligncenter'),\n          'JustifyRight': alignStates('alignright'),\n          'JustifyFull': alignStates('alignjustify'),\n          'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {\n            return self.isFormatMatch(command);\n          },\n          'mceBlockQuote': function () {\n            return self.isFormatMatch('blockquote');\n          },\n          'Outdent': function () {\n            return canOutdent(editor);\n          },\n          'InsertUnorderedList,InsertOrderedList': function (command) {\n            var list = editor.dom.getParent(editor.selection.getNode(), 'ul,ol');\n            return list && (command === 'insertunorderedlist' && list.tagName === 'UL' || command === 'insertorderedlist' && list.tagName === 'OL');\n          }\n        }, 'state');\n        self.addCommands({\n          Undo: function () {\n            editor.undoManager.undo();\n          },\n          Redo: function () {\n            editor.undoManager.redo();\n          }\n        });\n        self.addQueryValueHandler('FontName', function () {\n          return fontNameQuery(editor);\n        }, this);\n        self.addQueryValueHandler('FontSize', function () {\n          return fontSizeQuery(editor);\n        }, this);\n      };\n      return EditorCommands;\n    }();\n\n    var nativeEvents = Tools.makeMap('focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange ' + 'mouseout mouseenter mouseleave wheel keydown keypress keyup input beforeinput contextmenu dragstart dragend dragover ' + 'draggesture dragdrop drop drag submit ' + 'compositionstart compositionend compositionupdate touchstart touchmove touchend touchcancel', ' ');\n    var EventDispatcher = function () {\n      function EventDispatcher(settings) {\n        this.bindings = {};\n        this.settings = settings || {};\n        this.scope = this.settings.scope || this;\n        this.toggleEvent = this.settings.toggleEvent || never;\n      }\n      EventDispatcher.isNative = function (name) {\n        return !!nativeEvents[name.toLowerCase()];\n      };\n      EventDispatcher.prototype.fire = function (name, args) {\n        var handlers, i, l, callback;\n        name = name.toLowerCase();\n        args = args || {};\n        args.type = name;\n        if (!args.target) {\n          args.target = this.scope;\n        }\n        if (!args.preventDefault) {\n          args.preventDefault = function () {\n            args.isDefaultPrevented = always;\n          };\n          args.stopPropagation = function () {\n            args.isPropagationStopped = always;\n          };\n          args.stopImmediatePropagation = function () {\n            args.isImmediatePropagationStopped = always;\n          };\n          args.isDefaultPrevented = never;\n          args.isPropagationStopped = never;\n          args.isImmediatePropagationStopped = never;\n        }\n        if (this.settings.beforeFire) {\n          this.settings.beforeFire(args);\n        }\n        handlers = this.bindings[name];\n        if (handlers) {\n          for (i = 0, l = handlers.length; i < l; i++) {\n            callback = handlers[i];\n            if (callback.once) {\n              this.off(name, callback.func);\n            }\n            if (args.isImmediatePropagationStopped()) {\n              args.stopPropagation();\n              return args;\n            }\n            if (callback.func.call(this.scope, args) === false) {\n              args.preventDefault();\n              return args;\n            }\n          }\n        }\n        return args;\n      };\n      EventDispatcher.prototype.on = function (name, callback, prepend, extra) {\n        var handlers, names, i;\n        if (callback === false) {\n          callback = never;\n        }\n        if (callback) {\n          var wrappedCallback = { func: callback };\n          if (extra) {\n            Tools.extend(wrappedCallback, extra);\n          }\n          names = name.toLowerCase().split(' ');\n          i = names.length;\n          while (i--) {\n            name = names[i];\n            handlers = this.bindings[name];\n            if (!handlers) {\n              handlers = this.bindings[name] = [];\n              this.toggleEvent(name, true);\n            }\n            if (prepend) {\n              handlers.unshift(wrappedCallback);\n            } else {\n              handlers.push(wrappedCallback);\n            }\n          }\n        }\n        return this;\n      };\n      EventDispatcher.prototype.off = function (name, callback) {\n        var i, handlers, bindingName, names, hi;\n        if (name) {\n          names = name.toLowerCase().split(' ');\n          i = names.length;\n          while (i--) {\n            name = names[i];\n            handlers = this.bindings[name];\n            if (!name) {\n              for (bindingName in this.bindings) {\n                this.toggleEvent(bindingName, false);\n                delete this.bindings[bindingName];\n              }\n              return this;\n            }\n            if (handlers) {\n              if (!callback) {\n                handlers.length = 0;\n              } else {\n                hi = handlers.length;\n                while (hi--) {\n                  if (handlers[hi].func === callback) {\n                    handlers = handlers.slice(0, hi).concat(handlers.slice(hi + 1));\n                    this.bindings[name] = handlers;\n                  }\n                }\n              }\n              if (!handlers.length) {\n                this.toggleEvent(name, false);\n                delete this.bindings[name];\n              }\n            }\n          }\n        } else {\n          for (name in this.bindings) {\n            this.toggleEvent(name, false);\n          }\n          this.bindings = {};\n        }\n        return this;\n      };\n      EventDispatcher.prototype.once = function (name, callback, prepend) {\n        return this.on(name, callback, prepend, { once: true });\n      };\n      EventDispatcher.prototype.has = function (name) {\n        name = name.toLowerCase();\n        return !(!this.bindings[name] || this.bindings[name].length === 0);\n      };\n      return EventDispatcher;\n    }();\n\n    var getEventDispatcher = function (obj) {\n      if (!obj._eventDispatcher) {\n        obj._eventDispatcher = new EventDispatcher({\n          scope: obj,\n          toggleEvent: function (name, state) {\n            if (EventDispatcher.isNative(name) && obj.toggleNativeEvent) {\n              obj.toggleNativeEvent(name, state);\n            }\n          }\n        });\n      }\n      return obj._eventDispatcher;\n    };\n    var Observable = {\n      fire: function (name, args, bubble) {\n        var self = this;\n        if (self.removed && name !== 'remove' && name !== 'detach') {\n          return args;\n        }\n        var dispatcherArgs = getEventDispatcher(self).fire(name, args);\n        if (bubble !== false && self.parent) {\n          var parent = self.parent();\n          while (parent && !dispatcherArgs.isPropagationStopped()) {\n            parent.fire(name, dispatcherArgs, false);\n            parent = parent.parent();\n          }\n        }\n        return dispatcherArgs;\n      },\n      on: function (name, callback, prepend) {\n        return getEventDispatcher(this).on(name, callback, prepend);\n      },\n      off: function (name, callback) {\n        return getEventDispatcher(this).off(name, callback);\n      },\n      once: function (name, callback) {\n        return getEventDispatcher(this).once(name, callback);\n      },\n      hasEventListeners: function (name) {\n        return getEventDispatcher(this).has(name);\n      }\n    };\n\n    var DOM$7 = DOMUtils$1.DOM;\n    var customEventRootDelegates;\n    var getEventTarget = function (editor, eventName) {\n      if (eventName === 'selectionchange') {\n        return editor.getDoc();\n      }\n      if (!editor.inline && /^mouse|touch|click|contextmenu|drop|dragover|dragend/.test(eventName)) {\n        return editor.getDoc().documentElement;\n      }\n      if (editor.settings.event_root) {\n        if (!editor.eventRoot) {\n          editor.eventRoot = DOM$7.select(editor.settings.event_root)[0];\n        }\n        return editor.eventRoot;\n      }\n      return editor.getBody();\n    };\n    var isListening = function (editor) {\n      return !editor.hidden && !isReadOnly(editor);\n    };\n    var fireEvent = function (editor, eventName, e) {\n      if (isListening(editor)) {\n        editor.fire(eventName, e);\n      } else if (isReadOnly(editor)) {\n        preventReadOnlyEvents(e);\n      }\n    };\n    var bindEventDelegate = function (editor, eventName) {\n      var eventRootElm, delegate;\n      if (!editor.delegates) {\n        editor.delegates = {};\n      }\n      if (editor.delegates[eventName] || editor.removed) {\n        return;\n      }\n      eventRootElm = getEventTarget(editor, eventName);\n      if (editor.settings.event_root) {\n        if (!customEventRootDelegates) {\n          customEventRootDelegates = {};\n          editor.editorManager.on('removeEditor', function () {\n            var name;\n            if (!editor.editorManager.activeEditor) {\n              if (customEventRootDelegates) {\n                for (name in customEventRootDelegates) {\n                  editor.dom.unbind(getEventTarget(editor, name));\n                }\n                customEventRootDelegates = null;\n              }\n            }\n          });\n        }\n        if (customEventRootDelegates[eventName]) {\n          return;\n        }\n        delegate = function (e) {\n          var target = e.target;\n          var editors = editor.editorManager.get();\n          var i = editors.length;\n          while (i--) {\n            var body = editors[i].getBody();\n            if (body === target || DOM$7.isChildOf(target, body)) {\n              fireEvent(editors[i], eventName, e);\n            }\n          }\n        };\n        customEventRootDelegates[eventName] = delegate;\n        DOM$7.bind(eventRootElm, eventName, delegate);\n      } else {\n        delegate = function (e) {\n          fireEvent(editor, eventName, e);\n        };\n        DOM$7.bind(eventRootElm, eventName, delegate);\n        editor.delegates[eventName] = delegate;\n      }\n    };\n    var EditorObservable = __assign(__assign({}, Observable), {\n      bindPendingEventDelegates: function () {\n        var self = this;\n        Tools.each(self._pendingNativeEvents, function (name) {\n          bindEventDelegate(self, name);\n        });\n      },\n      toggleNativeEvent: function (name, state) {\n        var self = this;\n        if (name === 'focus' || name === 'blur') {\n          return;\n        }\n        if (state) {\n          if (self.initialized) {\n            bindEventDelegate(self, name);\n          } else {\n            if (!self._pendingNativeEvents) {\n              self._pendingNativeEvents = [name];\n            } else {\n              self._pendingNativeEvents.push(name);\n            }\n          }\n        } else if (self.initialized) {\n          self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);\n          delete self.delegates[name];\n        }\n      },\n      unbindAllNativeEvents: function () {\n        var self = this;\n        var body = self.getBody();\n        var dom = self.dom;\n        var name;\n        if (self.delegates) {\n          for (name in self.delegates) {\n            self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);\n          }\n          delete self.delegates;\n        }\n        if (!self.inline && body && dom) {\n          body.onload = null;\n          dom.unbind(self.getWin());\n          dom.unbind(self.getDoc());\n        }\n        if (dom) {\n          dom.unbind(body);\n          dom.unbind(self.getContainer());\n        }\n      }\n    });\n\n    var each$h = Tools.each, explode$3 = Tools.explode;\n    var keyCodeLookup = {\n      f1: 112,\n      f2: 113,\n      f3: 114,\n      f4: 115,\n      f5: 116,\n      f6: 117,\n      f7: 118,\n      f8: 119,\n      f9: 120,\n      f10: 121,\n      f11: 122,\n      f12: 123\n    };\n    var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access');\n    var Shortcuts = function () {\n      function Shortcuts(editor) {\n        this.shortcuts = {};\n        this.pendingPatterns = [];\n        this.editor = editor;\n        var self = this;\n        editor.on('keyup keypress keydown', function (e) {\n          if ((self.hasModifier(e) || self.isFunctionKey(e)) && !e.isDefaultPrevented()) {\n            each$h(self.shortcuts, function (shortcut) {\n              if (self.matchShortcut(e, shortcut)) {\n                self.pendingPatterns = shortcut.subpatterns.slice(0);\n                if (e.type === 'keydown') {\n                  self.executeShortcutAction(shortcut);\n                }\n                return true;\n              }\n            });\n            if (self.matchShortcut(e, self.pendingPatterns[0])) {\n              if (self.pendingPatterns.length === 1) {\n                if (e.type === 'keydown') {\n                  self.executeShortcutAction(self.pendingPatterns[0]);\n                }\n              }\n              self.pendingPatterns.shift();\n            }\n          }\n        });\n      }\n      Shortcuts.prototype.add = function (pattern, desc, cmdFunc, scope) {\n        var self = this;\n        var cmd;\n        cmd = cmdFunc;\n        if (typeof cmdFunc === 'string') {\n          cmdFunc = function () {\n            self.editor.execCommand(cmd, false, null);\n          };\n        } else if (Tools.isArray(cmd)) {\n          cmdFunc = function () {\n            self.editor.execCommand(cmd[0], cmd[1], cmd[2]);\n          };\n        }\n        each$h(explode$3(Tools.trim(pattern)), function (pattern) {\n          var shortcut = self.createShortcut(pattern, desc, cmdFunc, scope);\n          self.shortcuts[shortcut.id] = shortcut;\n        });\n        return true;\n      };\n      Shortcuts.prototype.remove = function (pattern) {\n        var shortcut = this.createShortcut(pattern);\n        if (this.shortcuts[shortcut.id]) {\n          delete this.shortcuts[shortcut.id];\n          return true;\n        }\n        return false;\n      };\n      Shortcuts.prototype.parseShortcut = function (pattern) {\n        var id, key;\n        var shortcut = {};\n        each$h(explode$3(pattern.toLowerCase(), '+'), function (value) {\n          if (value in modifierNames) {\n            shortcut[value] = true;\n          } else {\n            if (/^[0-9]{2,}$/.test(value)) {\n              shortcut.keyCode = parseInt(value, 10);\n            } else {\n              shortcut.charCode = value.charCodeAt(0);\n              shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);\n            }\n          }\n        });\n        id = [shortcut.keyCode];\n        for (key in modifierNames) {\n          if (shortcut[key]) {\n            id.push(key);\n          } else {\n            shortcut[key] = false;\n          }\n        }\n        shortcut.id = id.join(',');\n        if (shortcut.access) {\n          shortcut.alt = true;\n          if (Env.mac) {\n            shortcut.ctrl = true;\n          } else {\n            shortcut.shift = true;\n          }\n        }\n        if (shortcut.meta) {\n          if (Env.mac) {\n            shortcut.meta = true;\n          } else {\n            shortcut.ctrl = true;\n            shortcut.meta = false;\n          }\n        }\n        return shortcut;\n      };\n      Shortcuts.prototype.createShortcut = function (pattern, desc, cmdFunc, scope) {\n        var shortcuts;\n        shortcuts = Tools.map(explode$3(pattern, '>'), this.parseShortcut);\n        shortcuts[shortcuts.length - 1] = Tools.extend(shortcuts[shortcuts.length - 1], {\n          func: cmdFunc,\n          scope: scope || this.editor\n        });\n        return Tools.extend(shortcuts[0], {\n          desc: this.editor.translate(desc),\n          subpatterns: shortcuts.slice(1)\n        });\n      };\n      Shortcuts.prototype.hasModifier = function (e) {\n        return e.altKey || e.ctrlKey || e.metaKey;\n      };\n      Shortcuts.prototype.isFunctionKey = function (e) {\n        return e.type === 'keydown' && e.keyCode >= 112 && e.keyCode <= 123;\n      };\n      Shortcuts.prototype.matchShortcut = function (e, shortcut) {\n        if (!shortcut) {\n          return false;\n        }\n        if (shortcut.ctrl !== e.ctrlKey || shortcut.meta !== e.metaKey) {\n          return false;\n        }\n        if (shortcut.alt !== e.altKey || shortcut.shift !== e.shiftKey) {\n          return false;\n        }\n        if (e.keyCode === shortcut.keyCode || e.charCode && e.charCode === shortcut.charCode) {\n          e.preventDefault();\n          return true;\n        }\n        return false;\n      };\n      Shortcuts.prototype.executeShortcutAction = function (shortcut) {\n        return shortcut.func ? shortcut.func.call(shortcut.scope) : null;\n      };\n      return Shortcuts;\n    }();\n\n    var each$i = Tools.each, trim$4 = Tools.trim;\n    var queryParts = 'source protocol authority userInfo user password host port relative path directory file query anchor'.split(' ');\n    var DEFAULT_PORTS = {\n      ftp: 21,\n      http: 80,\n      https: 443,\n      mailto: 25\n    };\n    var URI = function () {\n      function URI(url, settings) {\n        url = trim$4(url);\n        this.settings = settings || {};\n        var baseUri = this.settings.base_uri;\n        var self = this;\n        if (/^([\\w\\-]+):([^\\/]{2})/i.test(url) || /^\\s*#/.test(url)) {\n          self.source = url;\n          return;\n        }\n        var isProtocolRelative = url.indexOf('//') === 0;\n        if (url.indexOf('/') === 0 && !isProtocolRelative) {\n          url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url;\n        }\n        if (!/^[\\w\\-]*:?\\/\\//.test(url)) {\n          var baseUrl = this.settings.base_uri ? this.settings.base_uri.path : new URI(domGlobals.document.location.href).directory;\n          if (this.settings.base_uri && this.settings.base_uri.protocol == '') {\n            url = '//mce_host' + self.toAbsPath(baseUrl, url);\n          } else {\n            var match = /([^#?]*)([#?]?.*)/.exec(url);\n            url = (baseUri && baseUri.protocol || 'http') + '://mce_host' + self.toAbsPath(baseUrl, match[1]) + match[2];\n          }\n        }\n        url = url.replace(/@@/g, '(mce_at)');\n        var urlMatch = /^(?:(?![^:@]+:[^:@\\/]*@)([^:\\/?#.]+):)?(?:\\/\\/)?((?:(([^:@\\/]*):?([^:@\\/]*))?@)?([^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/.exec(url);\n        each$i(queryParts, function (v, i) {\n          var part = urlMatch[i];\n          if (part) {\n            part = part.replace(/\\(mce_at\\)/g, '@@');\n          }\n          self[v] = part;\n        });\n        if (baseUri) {\n          if (!self.protocol) {\n            self.protocol = baseUri.protocol;\n          }\n          if (!self.userInfo) {\n            self.userInfo = baseUri.userInfo;\n          }\n          if (!self.port && self.host === 'mce_host') {\n            self.port = baseUri.port;\n          }\n          if (!self.host || self.host === 'mce_host') {\n            self.host = baseUri.host;\n          }\n          self.source = '';\n        }\n        if (isProtocolRelative) {\n          self.protocol = '';\n        }\n      }\n      URI.parseDataUri = function (uri) {\n        var type;\n        var uriComponents = decodeURIComponent(uri).split(',');\n        var matches = /data:([^;]+)/.exec(uriComponents[0]);\n        if (matches) {\n          type = matches[1];\n        }\n        return {\n          type: type,\n          data: uriComponents[1]\n        };\n      };\n      URI.getDocumentBaseUrl = function (loc) {\n        var baseUrl;\n        if (loc.protocol.indexOf('http') !== 0 && loc.protocol !== 'file:') {\n          baseUrl = loc.href;\n        } else {\n          baseUrl = loc.protocol + '//' + loc.host + loc.pathname;\n        }\n        if (/^[^:]+:\\/\\/\\/?[^\\/]+\\//.test(baseUrl)) {\n          baseUrl = baseUrl.replace(/[\\?#].*$/, '').replace(/[\\/\\\\][^\\/]+$/, '');\n          if (!/[\\/\\\\]$/.test(baseUrl)) {\n            baseUrl += '/';\n          }\n        }\n        return baseUrl;\n      };\n      URI.prototype.setPath = function (path) {\n        var pathMatch = /^(.*?)\\/?(\\w+)?$/.exec(path);\n        this.path = pathMatch[0];\n        this.directory = pathMatch[1];\n        this.file = pathMatch[2];\n        this.source = '';\n        this.getURI();\n      };\n      URI.prototype.toRelative = function (uri) {\n        var output;\n        if (uri === './') {\n          return uri;\n        }\n        var relativeUri = new URI(uri, { base_uri: this });\n        if (relativeUri.host !== 'mce_host' && this.host !== relativeUri.host && relativeUri.host || this.port !== relativeUri.port || this.protocol !== relativeUri.protocol && relativeUri.protocol !== '') {\n          return relativeUri.getURI();\n        }\n        var tu = this.getURI(), uu = relativeUri.getURI();\n        if (tu === uu || tu.charAt(tu.length - 1) === '/' && tu.substr(0, tu.length - 1) === uu) {\n          return tu;\n        }\n        output = this.toRelPath(this.path, relativeUri.path);\n        if (relativeUri.query) {\n          output += '?' + relativeUri.query;\n        }\n        if (relativeUri.anchor) {\n          output += '#' + relativeUri.anchor;\n        }\n        return output;\n      };\n      URI.prototype.toAbsolute = function (uri, noHost) {\n        var absoluteUri = new URI(uri, { base_uri: this });\n        return absoluteUri.getURI(noHost && this.isSameOrigin(absoluteUri));\n      };\n      URI.prototype.isSameOrigin = function (uri) {\n        if (this.host == uri.host && this.protocol == uri.protocol) {\n          if (this.port == uri.port) {\n            return true;\n          }\n          var defaultPort = DEFAULT_PORTS[this.protocol];\n          if (defaultPort && (this.port || defaultPort) == (uri.port || defaultPort)) {\n            return true;\n          }\n        }\n        return false;\n      };\n      URI.prototype.toRelPath = function (base, path) {\n        var items, breakPoint = 0, out = '', i, l;\n        var normalizedBase = base.substring(0, base.lastIndexOf('/')).split('/');\n        items = path.split('/');\n        if (normalizedBase.length >= items.length) {\n          for (i = 0, l = normalizedBase.length; i < l; i++) {\n            if (i >= items.length || normalizedBase[i] !== items[i]) {\n              breakPoint = i + 1;\n              break;\n            }\n          }\n        }\n        if (normalizedBase.length < items.length) {\n          for (i = 0, l = items.length; i < l; i++) {\n            if (i >= normalizedBase.length || normalizedBase[i] !== items[i]) {\n              breakPoint = i + 1;\n              break;\n            }\n          }\n        }\n        if (breakPoint === 1) {\n          return path;\n        }\n        for (i = 0, l = normalizedBase.length - (breakPoint - 1); i < l; i++) {\n          out += '../';\n        }\n        for (i = breakPoint - 1, l = items.length; i < l; i++) {\n          if (i !== breakPoint - 1) {\n            out += '/' + items[i];\n          } else {\n            out += items[i];\n          }\n        }\n        return out;\n      };\n      URI.prototype.toAbsPath = function (base, path) {\n        var i, nb = 0, o = [], tr, outPath;\n        tr = /\\/$/.test(path) ? '/' : '';\n        var normalizedBase = base.split('/');\n        var normalizedPath = path.split('/');\n        each$i(normalizedBase, function (k) {\n          if (k) {\n            o.push(k);\n          }\n        });\n        normalizedBase = o;\n        for (i = normalizedPath.length - 1, o = []; i >= 0; i--) {\n          if (normalizedPath[i].length === 0 || normalizedPath[i] === '.') {\n            continue;\n          }\n          if (normalizedPath[i] === '..') {\n            nb++;\n            continue;\n          }\n          if (nb > 0) {\n            nb--;\n            continue;\n          }\n          o.push(normalizedPath[i]);\n        }\n        i = normalizedBase.length - nb;\n        if (i <= 0) {\n          outPath = o.reverse().join('/');\n        } else {\n          outPath = normalizedBase.slice(0, i).join('/') + '/' + o.reverse().join('/');\n        }\n        if (outPath.indexOf('/') !== 0) {\n          outPath = '/' + outPath;\n        }\n        if (tr && outPath.lastIndexOf('/') !== outPath.length - 1) {\n          outPath += tr;\n        }\n        return outPath;\n      };\n      URI.prototype.getURI = function (noProtoHost) {\n        if (noProtoHost === void 0) {\n          noProtoHost = false;\n        }\n        var s;\n        if (!this.source || noProtoHost) {\n          s = '';\n          if (!noProtoHost) {\n            if (this.protocol) {\n              s += this.protocol + '://';\n            } else {\n              s += '//';\n            }\n            if (this.userInfo) {\n              s += this.userInfo + '@';\n            }\n            if (this.host) {\n              s += this.host;\n            }\n            if (this.port) {\n              s += ':' + this.port;\n            }\n          }\n          if (this.path) {\n            s += this.path;\n          }\n          if (this.query) {\n            s += '?' + this.query;\n          }\n          if (this.anchor) {\n            s += '#' + this.anchor;\n          }\n          this.source = s;\n        }\n        return this.source;\n      };\n      return URI;\n    }();\n\n    var create$5 = function () {\n      var buttons = {};\n      var menuItems = {};\n      var popups = {};\n      var icons = {};\n      var contextMenus = {};\n      var contextToolbars = {};\n      var sidebars = {};\n      var add = function (collection, type) {\n        return function (name, spec) {\n          return collection[name.toLowerCase()] = __assign(__assign({}, spec), { type: type });\n        };\n      };\n      var addIcon = function (name, svgData) {\n        return icons[name.toLowerCase()] = svgData;\n      };\n      return {\n        addButton: add(buttons, 'button'),\n        addToggleButton: add(buttons, 'togglebutton'),\n        addMenuButton: add(buttons, 'menubutton'),\n        addSplitButton: add(buttons, 'splitbutton'),\n        addMenuItem: add(menuItems, 'menuitem'),\n        addNestedMenuItem: add(menuItems, 'nestedmenuitem'),\n        addToggleMenuItem: add(menuItems, 'togglemenuitem'),\n        addAutocompleter: add(popups, 'autocompleter'),\n        addContextMenu: add(contextMenus, 'contextmenu'),\n        addContextToolbar: add(contextToolbars, 'contexttoolbar'),\n        addContextForm: add(contextToolbars, 'contextform'),\n        addSidebar: add(sidebars, 'sidebar'),\n        addIcon: addIcon,\n        getAll: function () {\n          return {\n            buttons: buttons,\n            menuItems: menuItems,\n            icons: icons,\n            popups: popups,\n            contextMenus: contextMenus,\n            contextToolbars: contextToolbars,\n            sidebars: sidebars\n          };\n        }\n      };\n    };\n\n    var registry = function () {\n      var bridge = create$5();\n      return {\n        addAutocompleter: bridge.addAutocompleter,\n        addButton: bridge.addButton,\n        addContextForm: bridge.addContextForm,\n        addContextMenu: bridge.addContextMenu,\n        addContextToolbar: bridge.addContextToolbar,\n        addIcon: bridge.addIcon,\n        addMenuButton: bridge.addMenuButton,\n        addMenuItem: bridge.addMenuItem,\n        addNestedMenuItem: bridge.addNestedMenuItem,\n        addSidebar: bridge.addSidebar,\n        addSplitButton: bridge.addSplitButton,\n        addToggleButton: bridge.addToggleButton,\n        addToggleMenuItem: bridge.addToggleMenuItem,\n        getAll: bridge.getAll\n      };\n    };\n\n    var DOM$8 = DOMUtils$1.DOM;\n    var extend$3 = Tools.extend, each$j = Tools.each;\n    var resolve$3 = Tools.resolve;\n    var ie$1 = Env.ie;\n    var Editor = function () {\n      function Editor(id, settings, editorManager) {\n        var _this = this;\n        this.plugins = {};\n        this.contentCSS = [];\n        this.contentStyles = [];\n        this.loadedCSS = {};\n        this.isNotDirty = false;\n        this.editorManager = editorManager;\n        this.documentBaseUrl = editorManager.documentBaseURL;\n        extend$3(this, EditorObservable);\n        this.settings = getEditorSettings(this, id, this.documentBaseUrl, editorManager.defaultSettings, settings);\n        if (this.settings.suffix) {\n          editorManager.suffix = this.settings.suffix;\n        }\n        this.suffix = editorManager.suffix;\n        if (this.settings.base_url) {\n          editorManager._setBaseUrl(this.settings.base_url);\n        }\n        this.baseUri = editorManager.baseURI;\n        if (this.settings.referrer_policy) {\n          ScriptLoader.ScriptLoader._setReferrerPolicy(this.settings.referrer_policy);\n          DOMUtils$1.DOM.styleSheetLoader._setReferrerPolicy(this.settings.referrer_policy);\n        }\n        AddOnManager$1.languageLoad = this.settings.language_load;\n        AddOnManager$1.baseURL = editorManager.baseURL;\n        this.id = id;\n        this.setDirty(false);\n        this.documentBaseURI = new URI(this.settings.document_base_url, { base_uri: this.baseUri });\n        this.baseURI = this.baseUri;\n        this.inline = !!this.settings.inline;\n        this.shortcuts = new Shortcuts(this);\n        this.editorCommands = new EditorCommands(this);\n        if (this.settings.cache_suffix) {\n          Env.cacheSuffix = this.settings.cache_suffix.replace(/^[\\?\\&]+/, '');\n        }\n        this.ui = { registry: registry() };\n        var self = this;\n        var modeInstance = create$4(self);\n        this.mode = modeInstance;\n        this.setMode = modeInstance.set;\n        editorManager.fire('SetupEditor', { editor: this });\n        this.execCallback('setup', this);\n        this.$ = DomQuery.overrideDefaults(function () {\n          return {\n            context: _this.inline ? _this.getBody() : _this.getDoc(),\n            element: _this.getBody()\n          };\n        });\n      }\n      Editor.prototype.render = function () {\n        Render.render(this);\n      };\n      Editor.prototype.focus = function (skipFocus) {\n        EditorFocus.focus(this, skipFocus);\n      };\n      Editor.prototype.hasFocus = function () {\n        return EditorFocus.hasFocus(this);\n      };\n      Editor.prototype.execCallback = function (name) {\n        var x = [];\n        for (var _i = 1; _i < arguments.length; _i++) {\n          x[_i - 1] = arguments[_i];\n        }\n        var self = this;\n        var callback = self.settings[name], scope;\n        if (!callback) {\n          return;\n        }\n        if (self.callbackLookup && (scope = self.callbackLookup[name])) {\n          callback = scope.func;\n          scope = scope.scope;\n        }\n        if (typeof callback === 'string') {\n          scope = callback.replace(/\\.\\w+$/, '');\n          scope = scope ? resolve$3(scope) : 0;\n          callback = resolve$3(callback);\n          self.callbackLookup = self.callbackLookup || {};\n          self.callbackLookup[name] = {\n            func: callback,\n            scope: scope\n          };\n        }\n        return callback.apply(scope || self, Array.prototype.slice.call(arguments, 1));\n      };\n      Editor.prototype.translate = function (text) {\n        return I18n.translate(text);\n      };\n      Editor.prototype.getParam = function (name, defaultVal, type) {\n        return getParam(this, name, defaultVal, type);\n      };\n      Editor.prototype.nodeChanged = function (args) {\n        this._nodeChangeDispatcher.nodeChanged(args);\n      };\n      Editor.prototype.addCommand = function (name, callback, scope) {\n        this.editorCommands.addCommand(name, callback, scope);\n      };\n      Editor.prototype.addQueryStateHandler = function (name, callback, scope) {\n        this.editorCommands.addQueryStateHandler(name, callback, scope);\n      };\n      Editor.prototype.addQueryValueHandler = function (name, callback, scope) {\n        this.editorCommands.addQueryValueHandler(name, callback, scope);\n      };\n      Editor.prototype.addShortcut = function (pattern, desc, cmdFunc, scope) {\n        this.shortcuts.add(pattern, desc, cmdFunc, scope);\n      };\n      Editor.prototype.execCommand = function (cmd, ui, value, args) {\n        return this.editorCommands.execCommand(cmd, ui, value, args);\n      };\n      Editor.prototype.queryCommandState = function (cmd) {\n        return this.editorCommands.queryCommandState(cmd);\n      };\n      Editor.prototype.queryCommandValue = function (cmd) {\n        return this.editorCommands.queryCommandValue(cmd);\n      };\n      Editor.prototype.queryCommandSupported = function (cmd) {\n        return this.editorCommands.queryCommandSupported(cmd);\n      };\n      Editor.prototype.show = function () {\n        var self = this;\n        if (self.hidden) {\n          self.hidden = false;\n          if (self.inline) {\n            self.getBody().contentEditable = 'true';\n          } else {\n            DOM$8.show(self.getContainer());\n            DOM$8.hide(self.id);\n          }\n          self.load();\n          self.fire('show');\n        }\n      };\n      Editor.prototype.hide = function () {\n        var self = this, doc = self.getDoc();\n        if (!self.hidden) {\n          if (ie$1 && doc && !self.inline) {\n            doc.execCommand('SelectAll');\n          }\n          self.save();\n          if (self.inline) {\n            self.getBody().contentEditable = 'false';\n            if (self === self.editorManager.focusedEditor) {\n              self.editorManager.focusedEditor = null;\n            }\n          } else {\n            DOM$8.hide(self.getContainer());\n            DOM$8.setStyle(self.id, 'display', self.orgDisplay);\n          }\n          self.hidden = true;\n          self.fire('hide');\n        }\n      };\n      Editor.prototype.isHidden = function () {\n        return !!this.hidden;\n      };\n      Editor.prototype.setProgressState = function (state, time) {\n        this.fire('ProgressState', {\n          state: state,\n          time: time\n        });\n      };\n      Editor.prototype.load = function (args) {\n        var self = this;\n        var elm = self.getElement(), html;\n        if (self.removed) {\n          return '';\n        }\n        if (elm) {\n          args = args || {};\n          args.load = true;\n          var value = NodeType.isTextareaOrInput(elm) ? elm.value : elm.innerHTML;\n          html = self.setContent(value, args);\n          args.element = elm;\n          if (!args.no_events) {\n            self.fire('LoadContent', args);\n          }\n          args.element = elm = null;\n          return html;\n        }\n      };\n      Editor.prototype.save = function (args) {\n        var self = this;\n        var elm = self.getElement(), html, form;\n        if (!elm || !self.initialized || self.removed) {\n          return;\n        }\n        args = args || {};\n        args.save = true;\n        args.element = elm;\n        html = args.content = self.getContent(args);\n        if (!args.no_events) {\n          self.fire('SaveContent', args);\n        }\n        if (args.format === 'raw') {\n          self.fire('RawSaveContent', args);\n        }\n        html = args.content;\n        if (!NodeType.isTextareaOrInput(elm)) {\n          if (args.is_removing || !self.inline) {\n            elm.innerHTML = html;\n          }\n          if (form = DOM$8.getParent(self.id, 'form')) {\n            each$j(form.elements, function (elm) {\n              if (elm.name === self.id) {\n                elm.value = html;\n                return false;\n              }\n            });\n          }\n        } else {\n          elm.value = html;\n        }\n        args.element = elm = null;\n        if (args.set_dirty !== false) {\n          self.setDirty(false);\n        }\n        return html;\n      };\n      Editor.prototype.setContent = function (content, args) {\n        return setContent(this, content, args);\n      };\n      Editor.prototype.getContent = function (args) {\n        return getContent(this, args);\n      };\n      Editor.prototype.insertContent = function (content, args) {\n        if (args) {\n          content = extend$3({ content: content }, args);\n        }\n        this.execCommand('mceInsertContent', false, content);\n      };\n      Editor.prototype.resetContent = function (initialContent) {\n        if (initialContent === undefined) {\n          setContent(this, this.startContent, { format: 'raw' });\n        } else {\n          setContent(this, initialContent);\n        }\n        this.undoManager.reset();\n        this.setDirty(false);\n        this.nodeChanged();\n      };\n      Editor.prototype.isDirty = function () {\n        return !this.isNotDirty;\n      };\n      Editor.prototype.setDirty = function (state) {\n        var oldState = !this.isNotDirty;\n        this.isNotDirty = !state;\n        if (state && state !== oldState) {\n          this.fire('dirty');\n        }\n      };\n      Editor.prototype.getContainer = function () {\n        var self = this;\n        if (!self.container) {\n          self.container = DOM$8.get(self.editorContainer || self.id + '_parent');\n        }\n        return self.container;\n      };\n      Editor.prototype.getContentAreaContainer = function () {\n        return this.contentAreaContainer;\n      };\n      Editor.prototype.getElement = function () {\n        if (!this.targetElm) {\n          this.targetElm = DOM$8.get(this.id);\n        }\n        return this.targetElm;\n      };\n      Editor.prototype.getWin = function () {\n        var self = this;\n        var elm;\n        if (!self.contentWindow) {\n          elm = self.iframeElement;\n          if (elm) {\n            self.contentWindow = elm.contentWindow;\n          }\n        }\n        return self.contentWindow;\n      };\n      Editor.prototype.getDoc = function () {\n        var self = this;\n        var win;\n        if (!self.contentDocument) {\n          win = self.getWin();\n          if (win) {\n            self.contentDocument = win.document;\n          }\n        }\n        return self.contentDocument;\n      };\n      Editor.prototype.getBody = function () {\n        var doc = this.getDoc();\n        return this.bodyElement || (doc ? doc.body : null);\n      };\n      Editor.prototype.convertURL = function (url, name, elm) {\n        var self = this, settings = self.settings;\n        if (settings.urlconverter_callback) {\n          return self.execCallback('urlconverter_callback', url, elm, true, name);\n        }\n        if (!settings.convert_urls || elm && elm.nodeName === 'LINK' || url.indexOf('file:') === 0 || url.length === 0) {\n          return url;\n        }\n        if (settings.relative_urls) {\n          return self.documentBaseURI.toRelative(url);\n        }\n        url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host);\n        return url;\n      };\n      Editor.prototype.addVisual = function (elm) {\n        var self = this;\n        var settings = self.settings;\n        var dom = self.dom;\n        var cls;\n        elm = elm || self.getBody();\n        if (self.hasVisual === undefined) {\n          self.hasVisual = settings.visual;\n        }\n        each$j(dom.select('table,a', elm), function (elm) {\n          var value;\n          switch (elm.nodeName) {\n          case 'TABLE':\n            cls = settings.visual_table_class || 'mce-item-table';\n            value = dom.getAttrib(elm, 'border');\n            if ((!value || value === '0') && self.hasVisual) {\n              dom.addClass(elm, cls);\n            } else {\n              dom.removeClass(elm, cls);\n            }\n            return;\n          case 'A':\n            if (!dom.getAttrib(elm, 'href')) {\n              value = dom.getAttrib(elm, 'name') || elm.id;\n              cls = settings.visual_anchor_class || 'mce-item-anchor';\n              if (value && self.hasVisual) {\n                dom.addClass(elm, cls);\n              } else {\n                dom.removeClass(elm, cls);\n              }\n            }\n            return;\n          }\n        });\n        self.fire('VisualAid', {\n          element: elm,\n          hasVisual: self.hasVisual\n        });\n      };\n      Editor.prototype.remove = function () {\n        remove$6(this);\n      };\n      Editor.prototype.destroy = function (automatic) {\n        destroy(this, automatic);\n      };\n      Editor.prototype.uploadImages = function (callback) {\n        return this.editorUpload.uploadImages(callback);\n      };\n      Editor.prototype._scanForImages = function () {\n        return this.editorUpload.scanForImages();\n      };\n      Editor.prototype.addButton = function () {\n        throw new Error('editor.addButton has been removed in tinymce 5x, use editor.ui.registry.addButton or editor.ui.registry.addToggleButton or editor.ui.registry.addSplitButton instead');\n      };\n      Editor.prototype.addSidebar = function () {\n        throw new Error('editor.addSidebar has been removed in tinymce 5x, use editor.ui.registry.addSidebar instead');\n      };\n      Editor.prototype.addMenuItem = function () {\n        throw new Error('editor.addMenuItem has been removed in tinymce 5x, use editor.ui.registry.addMenuItem instead');\n      };\n      Editor.prototype.addContextToolbar = function () {\n        throw new Error('editor.addContextToolbar has been removed in tinymce 5x, use editor.ui.registry.addContextToolbar instead');\n      };\n      return Editor;\n    }();\n\n    var DOM$9 = DOMUtils$1.DOM;\n    var explode$4 = Tools.explode, each$k = Tools.each, extend$4 = Tools.extend;\n    var instanceCounter = 0, boundGlobalEvents = false;\n    var beforeUnloadDelegate;\n    var legacyEditors = [];\n    var editors = [];\n    var isValidLegacyKey = function (id) {\n      return id !== 'length';\n    };\n    var globalEventDelegate = function (e) {\n      var type = e.type;\n      each$k(EditorManager.get(), function (editor) {\n        switch (type) {\n        case 'scroll':\n          editor.fire('ScrollWindow', e);\n          break;\n        case 'resize':\n          editor.fire('ResizeWindow', e);\n          break;\n        }\n      });\n    };\n    var toggleGlobalEvents = function (state) {\n      if (state !== boundGlobalEvents) {\n        if (state) {\n          DomQuery(window).on('resize scroll', globalEventDelegate);\n        } else {\n          DomQuery(window).off('resize scroll', globalEventDelegate);\n        }\n        boundGlobalEvents = state;\n      }\n    };\n    var removeEditorFromList = function (targetEditor) {\n      var oldEditors = editors;\n      delete legacyEditors[targetEditor.id];\n      for (var i = 0; i < legacyEditors.length; i++) {\n        if (legacyEditors[i] === targetEditor) {\n          legacyEditors.splice(i, 1);\n          break;\n        }\n      }\n      editors = filter(editors, function (editor) {\n        return targetEditor !== editor;\n      });\n      if (EditorManager.activeEditor === targetEditor) {\n        EditorManager.activeEditor = editors.length > 0 ? editors[0] : null;\n      }\n      if (EditorManager.focusedEditor === targetEditor) {\n        EditorManager.focusedEditor = null;\n      }\n      return oldEditors.length !== editors.length;\n    };\n    var purgeDestroyedEditor = function (editor) {\n      if (editor && editor.initialized && !(editor.getContainer() || editor.getBody()).parentNode) {\n        removeEditorFromList(editor);\n        editor.unbindAllNativeEvents();\n        editor.destroy(true);\n        editor.removed = true;\n        editor = null;\n      }\n      return editor;\n    };\n    var isQuirksMode = domGlobals.document.compatMode !== 'CSS1Compat';\n    var EditorManager = __assign(__assign({}, Observable), {\n      baseURI: null,\n      baseURL: null,\n      defaultSettings: {},\n      documentBaseURL: null,\n      suffix: null,\n      $: DomQuery,\n      majorVersion: '5',\n      minorVersion: '1.5',\n      releaseDate: '2019-12-19',\n      editors: legacyEditors,\n      i18n: I18n,\n      activeEditor: null,\n      focusedEditor: null,\n      settings: {},\n      setup: function () {\n        var self = this;\n        var baseURL, documentBaseURL, suffix = '';\n        documentBaseURL = URI.getDocumentBaseUrl(domGlobals.document.location);\n        if (/^[^:]+:\\/\\/\\/?[^\\/]+\\//.test(documentBaseURL)) {\n          documentBaseURL = documentBaseURL.replace(/[\\?#].*$/, '').replace(/[\\/\\\\][^\\/]+$/, '');\n          if (!/[\\/\\\\]$/.test(documentBaseURL)) {\n            documentBaseURL += '/';\n          }\n        }\n        var preInit = window.tinymce || window.tinyMCEPreInit;\n        if (preInit) {\n          baseURL = preInit.base || preInit.baseURL;\n          suffix = preInit.suffix;\n        } else {\n          var scripts = domGlobals.document.getElementsByTagName('script');\n          for (var i = 0; i < scripts.length; i++) {\n            var src = scripts[i].src || '';\n            if (src === '') {\n              continue;\n            }\n            var srcScript = src.substring(src.lastIndexOf('/'));\n            if (/tinymce(\\.full|\\.jquery|)(\\.min|\\.dev|)\\.js/.test(src)) {\n              if (srcScript.indexOf('.min') !== -1) {\n                suffix = '.min';\n              }\n              baseURL = src.substring(0, src.lastIndexOf('/'));\n              break;\n            }\n          }\n          if (!baseURL && domGlobals.document.currentScript) {\n            var src = domGlobals.document.currentScript.src;\n            if (src.indexOf('.min') !== -1) {\n              suffix = '.min';\n            }\n            baseURL = src.substring(0, src.lastIndexOf('/'));\n          }\n        }\n        self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL);\n        self.documentBaseURL = documentBaseURL;\n        self.baseURI = new URI(self.baseURL);\n        self.suffix = suffix;\n        FocusController.setup(self);\n      },\n      overrideDefaults: function (defaultSettings) {\n        var baseUrl, suffix;\n        baseUrl = defaultSettings.base_url;\n        if (baseUrl) {\n          this._setBaseUrl(baseUrl);\n        }\n        suffix = defaultSettings.suffix;\n        if (defaultSettings.suffix) {\n          this.suffix = suffix;\n        }\n        this.defaultSettings = defaultSettings;\n        var pluginBaseUrls = defaultSettings.plugin_base_urls;\n        for (var name in pluginBaseUrls) {\n          AddOnManager$1.PluginManager.urls[name] = pluginBaseUrls[name];\n        }\n      },\n      init: function (settings) {\n        var self = this;\n        var result, invalidInlineTargets;\n        invalidInlineTargets = Tools.makeMap('area base basefont br col frame hr img input isindex link meta param embed source wbr track ' + 'colgroup option table tbody tfoot thead tr th td script noscript style textarea video audio iframe object menu', ' ');\n        var isInvalidInlineTarget = function (settings, elm) {\n          return settings.inline && elm.tagName.toLowerCase() in invalidInlineTargets;\n        };\n        var createId = function (elm) {\n          var id = elm.id;\n          if (!id) {\n            id = elm.name;\n            if (id && !DOM$9.get(id)) {\n              id = elm.name;\n            } else {\n              id = DOM$9.uniqueId();\n            }\n            elm.setAttribute('id', id);\n          }\n          return id;\n        };\n        var execCallback = function (name) {\n          var callback = settings[name];\n          if (!callback) {\n            return;\n          }\n          return callback.apply(self, Array.prototype.slice.call(arguments, 2));\n        };\n        var hasClass = function (elm, className) {\n          return className.constructor === RegExp ? className.test(elm.className) : DOM$9.hasClass(elm, className);\n        };\n        var findTargets = function (settings) {\n          var l, targets = [];\n          if (Env.browser.isIE() && Env.browser.version.major < 11) {\n            ErrorReporter.initError('TinyMCE does not support the browser you are using. For a list of supported' + ' browsers please see: https://www.tinymce.com/docs/get-started/system-requirements/');\n            return [];\n          } else if (isQuirksMode) {\n            ErrorReporter.initError('Failed to initialize the editor as the document is not in standards mode. ' + 'TinyMCE requires standards mode.');\n            return [];\n          }\n          if (settings.types) {\n            each$k(settings.types, function (type) {\n              targets = targets.concat(DOM$9.select(type.selector));\n            });\n            return targets;\n          } else if (settings.selector) {\n            return DOM$9.select(settings.selector);\n          } else if (settings.target) {\n            return [settings.target];\n          }\n          switch (settings.mode) {\n          case 'exact':\n            l = settings.elements || '';\n            if (l.length > 0) {\n              each$k(explode$4(l), function (id) {\n                var elm;\n                if (elm = DOM$9.get(id)) {\n                  targets.push(elm);\n                } else {\n                  each$k(domGlobals.document.forms, function (f) {\n                    each$k(f.elements, function (e) {\n                      if (e.name === id) {\n                        id = 'mce_editor_' + instanceCounter++;\n                        DOM$9.setAttrib(e, 'id', id);\n                        targets.push(e);\n                      }\n                    });\n                  });\n                }\n              });\n            }\n            break;\n          case 'textareas':\n          case 'specific_textareas':\n            each$k(DOM$9.select('textarea'), function (elm) {\n              if (settings.editor_deselector && hasClass(elm, settings.editor_deselector)) {\n                return;\n              }\n              if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) {\n                targets.push(elm);\n              }\n            });\n            break;\n          }\n          return targets;\n        };\n        var provideResults = function (editors) {\n          result = editors;\n        };\n        var initEditors = function () {\n          var initCount = 0;\n          var editors = [];\n          var targets;\n          var createEditor = function (id, settings, targetElm) {\n            var editor = new Editor(id, settings, self);\n            editors.push(editor);\n            editor.on('init', function () {\n              if (++initCount === targets.length) {\n                provideResults(editors);\n              }\n            });\n            editor.targetElm = editor.targetElm || targetElm;\n            editor.render();\n          };\n          DOM$9.unbind(window, 'ready', initEditors);\n          execCallback('onpageload');\n          targets = DomQuery.unique(findTargets(settings));\n          if (settings.types) {\n            each$k(settings.types, function (type) {\n              Tools.each(targets, function (elm) {\n                if (DOM$9.is(elm, type.selector)) {\n                  createEditor(createId(elm), extend$4({}, settings, type), elm);\n                  return false;\n                }\n                return true;\n              });\n            });\n            return;\n          }\n          Tools.each(targets, function (elm) {\n            purgeDestroyedEditor(self.get(elm.id));\n          });\n          targets = Tools.grep(targets, function (elm) {\n            return !self.get(elm.id);\n          });\n          if (targets.length === 0) {\n            provideResults([]);\n          } else {\n            each$k(targets, function (elm) {\n              if (isInvalidInlineTarget(settings, elm)) {\n                ErrorReporter.initError('Could not initialize inline editor on invalid inline target element', elm);\n              } else {\n                createEditor(createId(elm), settings, elm);\n              }\n            });\n          }\n        };\n        self.settings = settings;\n        DOM$9.bind(window, 'ready', initEditors);\n        return new promiseObj(function (resolve) {\n          if (result) {\n            resolve(result);\n          } else {\n            provideResults = function (editors) {\n              resolve(editors);\n            };\n          }\n        });\n      },\n      get: function (id) {\n        if (arguments.length === 0) {\n          return editors.slice(0);\n        } else if (isString(id)) {\n          return find(editors, function (editor) {\n            return editor.id === id;\n          }).getOr(null);\n        } else if (isNumber(id)) {\n          return editors[id] ? editors[id] : null;\n        } else {\n          return null;\n        }\n      },\n      add: function (editor) {\n        var self = this;\n        var existingEditor;\n        existingEditor = legacyEditors[editor.id];\n        if (existingEditor === editor) {\n          return editor;\n        }\n        if (self.get(editor.id) === null) {\n          if (isValidLegacyKey(editor.id)) {\n            legacyEditors[editor.id] = editor;\n          }\n          legacyEditors.push(editor);\n          editors.push(editor);\n        }\n        toggleGlobalEvents(true);\n        self.activeEditor = editor;\n        self.fire('AddEditor', { editor: editor });\n        if (!beforeUnloadDelegate) {\n          beforeUnloadDelegate = function (e) {\n            var event = self.fire('BeforeUnload');\n            if (event.returnValue) {\n              e.preventDefault();\n              e.returnValue = event.returnValue;\n              return event.returnValue;\n            }\n          };\n          window.addEventListener('beforeunload', beforeUnloadDelegate);\n        }\n        return editor;\n      },\n      createEditor: function (id, settings) {\n        return this.add(new Editor(id, settings, this));\n      },\n      remove: function (selector) {\n        var self = this;\n        var i, editor;\n        if (!selector) {\n          for (i = editors.length - 1; i >= 0; i--) {\n            self.remove(editors[i]);\n          }\n          return;\n        }\n        if (isString(selector)) {\n          each$k(DOM$9.select(selector), function (elm) {\n            editor = self.get(elm.id);\n            if (editor) {\n              self.remove(editor);\n            }\n          });\n          return;\n        }\n        editor = selector;\n        if (isNull(self.get(editor.id))) {\n          return null;\n        }\n        if (removeEditorFromList(editor)) {\n          self.fire('RemoveEditor', { editor: editor });\n        }\n        if (editors.length === 0) {\n          window.removeEventListener('beforeunload', beforeUnloadDelegate);\n        }\n        editor.remove();\n        toggleGlobalEvents(editors.length > 0);\n        return editor;\n      },\n      execCommand: function (cmd, ui, value) {\n        var self = this, editor = self.get(value);\n        switch (cmd) {\n        case 'mceAddEditor':\n          if (!self.get(value)) {\n            new Editor(value, self.settings, self).render();\n          }\n          return true;\n        case 'mceRemoveEditor':\n          if (editor) {\n            editor.remove();\n          }\n          return true;\n        case 'mceToggleEditor':\n          if (!editor) {\n            self.execCommand('mceAddEditor', 0, value);\n            return true;\n          }\n          if (editor.isHidden()) {\n            editor.show();\n          } else {\n            editor.hide();\n          }\n          return true;\n        }\n        if (self.activeEditor) {\n          return self.activeEditor.execCommand(cmd, ui, value);\n        }\n        return false;\n      },\n      triggerSave: function () {\n        each$k(editors, function (editor) {\n          editor.save();\n        });\n      },\n      addI18n: function (code, items) {\n        I18n.add(code, items);\n      },\n      translate: function (text) {\n        return I18n.translate(text);\n      },\n      setActive: function (editor) {\n        var activeEditor = this.activeEditor;\n        if (this.activeEditor !== editor) {\n          if (activeEditor) {\n            activeEditor.fire('deactivate', { relatedTarget: editor });\n          }\n          editor.fire('activate', { relatedTarget: activeEditor });\n        }\n        this.activeEditor = editor;\n      },\n      _setBaseUrl: function (baseUrl) {\n        this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\\/+$/, ''));\n        this.baseURI = new URI(this.baseURL);\n      }\n    });\n    EditorManager.setup();\n\n    function RangeUtils(dom) {\n      var walk = function (rng, callback) {\n        return RangeWalk.walk(dom, rng, callback);\n      };\n      var split = split$1;\n      var normalize = function (rng) {\n        return NormalizeRange.normalize(dom, rng).fold(constant(false), function (normalizedRng) {\n          rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset);\n          rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset);\n          return true;\n        });\n      };\n      return {\n        walk: walk,\n        split: split,\n        normalize: normalize\n      };\n    }\n    (function (RangeUtils) {\n      RangeUtils.compareRanges = RangeCompare.isEq;\n      RangeUtils.getCaretRangeFromPoint = CaretRangeFromPoint.fromPoint;\n      RangeUtils.getSelectedNode = getSelectedNode;\n      RangeUtils.getNode = getNode;\n    }(RangeUtils || (RangeUtils = {})));\n    var RangeUtils$1 = RangeUtils;\n\n    var awaiter = function (resolveCb, rejectCb, timeout) {\n      if (timeout === void 0) {\n        timeout = 1000;\n      }\n      var done = false;\n      var timer = null;\n      var complete = function (completer) {\n        return function () {\n          var args = [];\n          for (var _i = 0; _i < arguments.length; _i++) {\n            args[_i] = arguments[_i];\n          }\n          if (!done) {\n            done = true;\n            if (timer !== null) {\n              domGlobals.clearTimeout(timer);\n              timer = null;\n            }\n            completer.apply(null, args);\n          }\n        };\n      };\n      var resolve = complete(resolveCb);\n      var reject = complete(rejectCb);\n      var start = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n          args[_i] = arguments[_i];\n        }\n        if (!done && timer === null) {\n          timer = domGlobals.setTimeout(function () {\n            return reject.apply(null, args);\n          }, timeout);\n        }\n      };\n      return {\n        start: start,\n        resolve: resolve,\n        reject: reject\n      };\n    };\n    var create$6 = function () {\n      var tasks = {};\n      var resultFns = {};\n      var load = function (id, url) {\n        var loadErrMsg = 'Script at URL \"' + url + '\" failed to load';\n        var runErrMsg = 'Script at URL \"' + url + '\" did not call `tinymce.Resource.add(\\'' + id + '\\', data)` within 1 second';\n        if (tasks[id] !== undefined) {\n          return tasks[id];\n        } else {\n          var task = new promiseObj(function (resolve, reject) {\n            var waiter = awaiter(resolve, reject);\n            resultFns[id] = waiter.resolve;\n            ScriptLoader.ScriptLoader.loadScript(url, function () {\n              return waiter.start(runErrMsg);\n            }, function () {\n              return waiter.reject(loadErrMsg);\n            });\n          });\n          tasks[id] = task;\n          return task;\n        }\n      };\n      var add = function (id, data) {\n        if (resultFns[id] !== undefined) {\n          resultFns[id](data);\n          delete resultFns[id];\n        }\n        tasks[id] = promiseObj.resolve(data);\n      };\n      return {\n        load: load,\n        add: add\n      };\n    };\n    var Resource = create$6();\n\n    var min = Math.min, max = Math.max, round$2 = Math.round;\n    var relativePosition = function (rect, targetRect, rel) {\n      var x, y, w, h, targetW, targetH;\n      x = targetRect.x;\n      y = targetRect.y;\n      w = rect.w;\n      h = rect.h;\n      targetW = targetRect.w;\n      targetH = targetRect.h;\n      rel = (rel || '').split('');\n      if (rel[0] === 'b') {\n        y += targetH;\n      }\n      if (rel[1] === 'r') {\n        x += targetW;\n      }\n      if (rel[0] === 'c') {\n        y += round$2(targetH / 2);\n      }\n      if (rel[1] === 'c') {\n        x += round$2(targetW / 2);\n      }\n      if (rel[3] === 'b') {\n        y -= h;\n      }\n      if (rel[4] === 'r') {\n        x -= w;\n      }\n      if (rel[3] === 'c') {\n        y -= round$2(h / 2);\n      }\n      if (rel[4] === 'c') {\n        x -= round$2(w / 2);\n      }\n      return create$7(x, y, w, h);\n    };\n    var findBestRelativePosition = function (rect, targetRect, constrainRect, rels) {\n      var pos, i;\n      for (i = 0; i < rels.length; i++) {\n        pos = relativePosition(rect, targetRect, rels[i]);\n        if (pos.x >= constrainRect.x && pos.x + pos.w <= constrainRect.w + constrainRect.x && pos.y >= constrainRect.y && pos.y + pos.h <= constrainRect.h + constrainRect.y) {\n          return rels[i];\n        }\n      }\n      return null;\n    };\n    var inflate = function (rect, w, h) {\n      return create$7(rect.x - w, rect.y - h, rect.w + w * 2, rect.h + h * 2);\n    };\n    var intersect = function (rect, cropRect) {\n      var x1, y1, x2, y2;\n      x1 = max(rect.x, cropRect.x);\n      y1 = max(rect.y, cropRect.y);\n      x2 = min(rect.x + rect.w, cropRect.x + cropRect.w);\n      y2 = min(rect.y + rect.h, cropRect.y + cropRect.h);\n      if (x2 - x1 < 0 || y2 - y1 < 0) {\n        return null;\n      }\n      return create$7(x1, y1, x2 - x1, y2 - y1);\n    };\n    var clamp$1 = function (rect, clampRect, fixedSize) {\n      var underflowX1, underflowY1, overflowX2, overflowY2, x1, y1, x2, y2, cx2, cy2;\n      x1 = rect.x;\n      y1 = rect.y;\n      x2 = rect.x + rect.w;\n      y2 = rect.y + rect.h;\n      cx2 = clampRect.x + clampRect.w;\n      cy2 = clampRect.y + clampRect.h;\n      underflowX1 = max(0, clampRect.x - x1);\n      underflowY1 = max(0, clampRect.y - y1);\n      overflowX2 = max(0, x2 - cx2);\n      overflowY2 = max(0, y2 - cy2);\n      x1 += underflowX1;\n      y1 += underflowY1;\n      if (fixedSize) {\n        x2 += underflowX1;\n        y2 += underflowY1;\n        x1 -= overflowX2;\n        y1 -= overflowY2;\n      }\n      x2 -= overflowX2;\n      y2 -= overflowY2;\n      return create$7(x1, y1, x2 - x1, y2 - y1);\n    };\n    var create$7 = function (x, y, w, h) {\n      return {\n        x: x,\n        y: y,\n        w: w,\n        h: h\n      };\n    };\n    var fromClientRect = function (clientRect) {\n      return create$7(clientRect.left, clientRect.top, clientRect.width, clientRect.height);\n    };\n    var Rect = {\n      inflate: inflate,\n      relativePosition: relativePosition,\n      findBestRelativePosition: findBestRelativePosition,\n      intersect: intersect,\n      clamp: clamp$1,\n      create: create$7,\n      fromClientRect: fromClientRect\n    };\n\n    var each$l = Tools.each, extend$5 = Tools.extend;\n    var extendClass, initializing;\n    var Class = function () {\n    };\n    Class.extend = extendClass = function (prop) {\n      var self = this;\n      var _super = self.prototype;\n      var prototype, name, member;\n      var Class = function () {\n        var i, mixins, mixin;\n        var self = this;\n        if (!initializing) {\n          if (self.init) {\n            self.init.apply(self, arguments);\n          }\n          mixins = self.Mixins;\n          if (mixins) {\n            i = mixins.length;\n            while (i--) {\n              mixin = mixins[i];\n              if (mixin.init) {\n                mixin.init.apply(self, arguments);\n              }\n            }\n          }\n        }\n      };\n      var dummy = function () {\n        return this;\n      };\n      var createMethod = function (name, fn) {\n        return function () {\n          var self = this;\n          var tmp = self._super;\n          var ret;\n          self._super = _super[name];\n          ret = fn.apply(self, arguments);\n          self._super = tmp;\n          return ret;\n        };\n      };\n      initializing = true;\n      prototype = new self();\n      initializing = false;\n      if (prop.Mixins) {\n        each$l(prop.Mixins, function (mixin) {\n          for (var name_1 in mixin) {\n            if (name_1 !== 'init') {\n              prop[name_1] = mixin[name_1];\n            }\n          }\n        });\n        if (_super.Mixins) {\n          prop.Mixins = _super.Mixins.concat(prop.Mixins);\n        }\n      }\n      if (prop.Methods) {\n        each$l(prop.Methods.split(','), function (name) {\n          prop[name] = dummy;\n        });\n      }\n      if (prop.Properties) {\n        each$l(prop.Properties.split(','), function (name) {\n          var fieldName = '_' + name;\n          prop[name] = function (value) {\n            var self = this;\n            if (value !== undefined) {\n              self[fieldName] = value;\n              return self;\n            }\n            return self[fieldName];\n          };\n        });\n      }\n      if (prop.Statics) {\n        each$l(prop.Statics, function (func, name) {\n          Class[name] = func;\n        });\n      }\n      if (prop.Defaults && _super.Defaults) {\n        prop.Defaults = extend$5({}, _super.Defaults, prop.Defaults);\n      }\n      for (name in prop) {\n        member = prop[name];\n        if (typeof member === 'function' && _super[name]) {\n          prototype[name] = createMethod(name, member);\n        } else {\n          prototype[name] = member;\n        }\n      }\n      Class.prototype = prototype;\n      Class.constructor = Class;\n      Class.extend = extendClass;\n      return Class;\n    };\n\n    var min$1 = Math.min, max$1 = Math.max, round$3 = Math.round;\n    var Color = function (value) {\n      var self = {};\n      var r = 0, g = 0, b = 0;\n      var rgb2hsv = function (r, g, b) {\n        var h, s, v, d, minRGB, maxRGB;\n        h = 0;\n        s = 0;\n        v = 0;\n        r = r / 255;\n        g = g / 255;\n        b = b / 255;\n        minRGB = min$1(r, min$1(g, b));\n        maxRGB = max$1(r, max$1(g, b));\n        if (minRGB === maxRGB) {\n          v = minRGB;\n          return {\n            h: 0,\n            s: 0,\n            v: v * 100\n          };\n        }\n        d = r === minRGB ? g - b : b === minRGB ? r - g : b - r;\n        h = r === minRGB ? 3 : b === minRGB ? 1 : 5;\n        h = 60 * (h - d / (maxRGB - minRGB));\n        s = (maxRGB - minRGB) / maxRGB;\n        v = maxRGB;\n        return {\n          h: round$3(h),\n          s: round$3(s * 100),\n          v: round$3(v * 100)\n        };\n      };\n      var hsvToRgb = function (hue, saturation, brightness) {\n        var side, chroma, x, match;\n        hue = (parseInt(hue, 10) || 0) % 360;\n        saturation = parseInt(saturation, 10) / 100;\n        brightness = parseInt(brightness, 10) / 100;\n        saturation = max$1(0, min$1(saturation, 1));\n        brightness = max$1(0, min$1(brightness, 1));\n        if (saturation === 0) {\n          r = g = b = round$3(255 * brightness);\n          return;\n        }\n        side = hue / 60;\n        chroma = brightness * saturation;\n        x = chroma * (1 - Math.abs(side % 2 - 1));\n        match = brightness - chroma;\n        switch (Math.floor(side)) {\n        case 0:\n          r = chroma;\n          g = x;\n          b = 0;\n          break;\n        case 1:\n          r = x;\n          g = chroma;\n          b = 0;\n          break;\n        case 2:\n          r = 0;\n          g = chroma;\n          b = x;\n          break;\n        case 3:\n          r = 0;\n          g = x;\n          b = chroma;\n          break;\n        case 4:\n          r = x;\n          g = 0;\n          b = chroma;\n          break;\n        case 5:\n          r = chroma;\n          g = 0;\n          b = x;\n          break;\n        default:\n          r = g = b = 0;\n        }\n        r = round$3(255 * (r + match));\n        g = round$3(255 * (g + match));\n        b = round$3(255 * (b + match));\n      };\n      var toHex = function () {\n        var hex = function (val) {\n          val = parseInt(val, 10).toString(16);\n          return val.length > 1 ? val : '0' + val;\n        };\n        return '#' + hex(r) + hex(g) + hex(b);\n      };\n      var toRgb = function () {\n        return {\n          r: r,\n          g: g,\n          b: b\n        };\n      };\n      var toHsv = function () {\n        return rgb2hsv(r, g, b);\n      };\n      var parse = function (value) {\n        var matches;\n        if (typeof value === 'object') {\n          if ('r' in value) {\n            r = value.r;\n            g = value.g;\n            b = value.b;\n          } else if ('v' in value) {\n            hsvToRgb(value.h, value.s, value.v);\n          }\n        } else {\n          if (matches = /rgb\\s*\\(\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)[^\\)]*\\)/gi.exec(value)) {\n            r = parseInt(matches[1], 10);\n            g = parseInt(matches[2], 10);\n            b = parseInt(matches[3], 10);\n          } else if (matches = /#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(value)) {\n            r = parseInt(matches[1], 16);\n            g = parseInt(matches[2], 16);\n            b = parseInt(matches[3], 16);\n          } else if (matches = /#([0-F])([0-F])([0-F])/gi.exec(value)) {\n            r = parseInt(matches[1] + matches[1], 16);\n            g = parseInt(matches[2] + matches[2], 16);\n            b = parseInt(matches[3] + matches[3], 16);\n          }\n        }\n        r = r < 0 ? 0 : r > 255 ? 255 : r;\n        g = g < 0 ? 0 : g > 255 ? 255 : g;\n        b = b < 0 ? 0 : b > 255 ? 255 : b;\n        return self;\n      };\n      if (value) {\n        parse(value);\n      }\n      self.toRgb = toRgb;\n      self.toHsv = toHsv;\n      self.toHex = toHex;\n      self.parse = parse;\n      return self;\n    };\n\n    var serialize = function (obj) {\n      var data = JSON.stringify(obj);\n      if (!isString(data)) {\n        return data;\n      }\n      return data.replace(/[\\u0080-\\uFFFF]/g, function (match) {\n        var hexCode = match.charCodeAt(0).toString(16);\n        return '\\\\u' + '0000'.substring(hexCode.length) + hexCode;\n      });\n    };\n    var JSONUtils = {\n      serialize: serialize,\n      parse: function (text) {\n        try {\n          return JSON.parse(text);\n        } catch (ex) {\n        }\n      }\n    };\n\n    var JSONP = {\n      callbacks: {},\n      count: 0,\n      send: function (settings) {\n        var self = this, dom = DOMUtils$1.DOM, count = settings.count !== undefined ? settings.count : self.count;\n        var id = 'tinymce_jsonp_' + count;\n        self.callbacks[count] = function (json) {\n          dom.remove(id);\n          delete self.callbacks[count];\n          settings.callback(json);\n        };\n        dom.add(dom.doc.body, 'script', {\n          id: id,\n          src: settings.url,\n          type: 'text/javascript'\n        });\n        self.count++;\n      }\n    };\n\n    var XHR = __assign(__assign({}, Observable), {\n      send: function (settings) {\n        var xhr, count = 0;\n        var ready = function () {\n          if (!settings.async || xhr.readyState === 4 || count++ > 10000) {\n            if (settings.success && count < 10000 && xhr.status === 200) {\n              settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings);\n            } else if (settings.error) {\n              settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings);\n            }\n            xhr = null;\n          } else {\n            Delay.setTimeout(ready, 10);\n          }\n        };\n        settings.scope = settings.scope || this;\n        settings.success_scope = settings.success_scope || settings.scope;\n        settings.error_scope = settings.error_scope || settings.scope;\n        settings.async = settings.async !== false;\n        settings.data = settings.data || '';\n        XHR.fire('beforeInitialize', { settings: settings });\n        xhr = new domGlobals.XMLHttpRequest();\n        if (xhr) {\n          if (xhr.overrideMimeType) {\n            xhr.overrideMimeType(settings.content_type);\n          }\n          xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async);\n          if (settings.crossDomain) {\n            xhr.withCredentials = true;\n          }\n          if (settings.content_type) {\n            xhr.setRequestHeader('Content-Type', settings.content_type);\n          }\n          if (settings.requestheaders) {\n            Tools.each(settings.requestheaders, function (header) {\n              xhr.setRequestHeader(header.key, header.value);\n            });\n          }\n          xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n          xhr = XHR.fire('beforeSend', {\n            xhr: xhr,\n            settings: settings\n          }).xhr;\n          xhr.send(settings.data);\n          if (!settings.async) {\n            return ready();\n          }\n          Delay.setTimeout(ready, 10);\n        }\n      }\n    });\n\n    var extend$6 = Tools.extend;\n    var JSONRequest = function () {\n      function JSONRequest(settings) {\n        this.settings = extend$6({}, settings);\n        this.count = 0;\n      }\n      JSONRequest.sendRPC = function (o) {\n        return new JSONRequest().send(o);\n      };\n      JSONRequest.prototype.send = function (args) {\n        var ecb = args.error, scb = args.success;\n        var xhrArgs = extend$6(this.settings, args);\n        xhrArgs.success = function (c, x) {\n          c = JSONUtils.parse(c);\n          if (typeof c === 'undefined') {\n            c = { error: 'JSON Parse error.' };\n          }\n          if (c.error) {\n            ecb.call(xhrArgs.error_scope || xhrArgs.scope, c.error, x);\n          } else {\n            scb.call(xhrArgs.success_scope || xhrArgs.scope, c.result);\n          }\n        };\n        xhrArgs.error = function (ty, x) {\n          if (ecb) {\n            ecb.call(xhrArgs.error_scope || xhrArgs.scope, ty, x);\n          }\n        };\n        xhrArgs.data = JSONUtils.serialize({\n          id: args.id || 'c' + this.count++,\n          method: args.method,\n          params: args.params\n        });\n        xhrArgs.content_type = 'application/json';\n        XHR.send(xhrArgs);\n      };\n      return JSONRequest;\n    }();\n\n    var create$8 = function () {\n      return function () {\n        var data = {};\n        var keys = [];\n        var storage = {\n          getItem: function (key) {\n            var item = data[key];\n            return item ? item : null;\n          },\n          setItem: function (key, value) {\n            keys.push(key);\n            data[key] = String(value);\n          },\n          key: function (index) {\n            return keys[index];\n          },\n          removeItem: function (key) {\n            keys = keys.filter(function (k) {\n              return k === key;\n            });\n            delete data[key];\n          },\n          clear: function () {\n            keys = [];\n            data = {};\n          },\n          length: 0\n        };\n        Object.defineProperty(storage, 'length', {\n          get: function () {\n            return keys.length;\n          },\n          configurable: false,\n          enumerable: false\n        });\n        return storage;\n      }();\n    };\n\n    var localStorage;\n    try {\n      localStorage = domGlobals.window.localStorage;\n    } catch (e) {\n      localStorage = create$8();\n    }\n    var LocalStorage = localStorage;\n\n    var publicApi = {\n      geom: { Rect: Rect },\n      util: {\n        Promise: promiseObj,\n        Delay: Delay,\n        Tools: Tools,\n        VK: VK,\n        URI: URI,\n        Class: Class,\n        EventDispatcher: EventDispatcher,\n        Observable: Observable,\n        I18n: I18n,\n        XHR: XHR,\n        JSON: JSONUtils,\n        JSONRequest: JSONRequest,\n        JSONP: JSONP,\n        LocalStorage: LocalStorage,\n        Color: Color\n      },\n      dom: {\n        EventUtils: EventUtils,\n        Sizzle: Sizzle,\n        DomQuery: DomQuery,\n        TreeWalker: TreeWalker,\n        DOMUtils: DOMUtils$1,\n        ScriptLoader: ScriptLoader,\n        RangeUtils: RangeUtils$1,\n        Serializer: Serializer$1,\n        ControlSelection: ControlSelection,\n        BookmarkManager: BookmarkManager$1,\n        Selection: Selection$1,\n        Event: EventUtils.Event\n      },\n      html: {\n        Styles: Styles,\n        Entities: Entities,\n        Node: Node$1,\n        Schema: Schema,\n        SaxParser: SaxParser$1,\n        DomParser: DomParser,\n        Writer: Writer,\n        Serializer: Serializer\n      },\n      Env: Env,\n      AddOnManager: AddOnManager$1,\n      Annotator: Annotator,\n      Formatter: Formatter,\n      UndoManager: UndoManager,\n      EditorCommands: EditorCommands,\n      WindowManager: WindowManager,\n      NotificationManager: NotificationManager,\n      EditorObservable: EditorObservable,\n      Shortcuts: Shortcuts,\n      Editor: Editor,\n      FocusManager: FocusManager,\n      EditorManager: EditorManager,\n      DOM: DOMUtils$1.DOM,\n      ScriptLoader: ScriptLoader.ScriptLoader,\n      PluginManager: AddOnManager$1.PluginManager,\n      ThemeManager: AddOnManager$1.ThemeManager,\n      IconManager: IconManager,\n      Resource: Resource,\n      trim: Tools.trim,\n      isArray: Tools.isArray,\n      is: Tools.is,\n      toArray: Tools.toArray,\n      makeMap: Tools.makeMap,\n      each: Tools.each,\n      map: Tools.map,\n      grep: Tools.grep,\n      inArray: Tools.inArray,\n      extend: Tools.extend,\n      create: Tools.create,\n      walk: Tools.walk,\n      createNS: Tools.createNS,\n      resolve: Tools.resolve,\n      explode: Tools.explode,\n      _addCacheSuffix: Tools._addCacheSuffix,\n      isOpera: Env.opera,\n      isWebKit: Env.webkit,\n      isIE: Env.ie,\n      isGecko: Env.gecko,\n      isMac: Env.mac\n    };\n    var tinymce = Tools.extend(EditorManager, publicApi);\n\n    var exportToModuleLoaders = function (tinymce) {\n      if (true) {\n        try {\n          module.exports = tinymce;\n        } catch (_) {\n        }\n      }\n    };\n    var exportToWindowGlobal = function (tinymce) {\n      window.tinymce = tinymce;\n      window.tinyMCE = tinymce;\n    };\n    exportToWindowGlobal(tinymce);\n    exportToModuleLoaders(tinymce);\n\n}(window));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack:///./node_modules/tinymce/tinymce.js?");

/***/ }),

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

eval("var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n//# sourceURL=webpack:///(webpack)/buildin/global.js?");

/***/ }),

/***/ "./webpack/vendors/custom/tinymce.js":
/*!*******************************************!*\
  !*** ./webpack/vendors/custom/tinymce.js ***!
  \*******************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\r\n\r\n/**\r\n * Define the output of this file. The output of CSS and JS file will be auto detected.\r\n *\r\n * @output plugins/custom/tinymce/tinymce.bundle\r\n */\r\n\r\n// Tinymce\r\nwindow.tinymce = __webpack_require__(/*! tinymce */ \"./node_modules/tinymce/tinymce.js\");\r\n__webpack_require__(/*! tinymce/themes/silver/theme */ \"./node_modules/tinymce/themes/silver/theme.js\");\r\n__webpack_require__(/*! tinymce/themes/mobile/theme */ \"./node_modules/tinymce/themes/mobile/theme.js\");\r\n\n\n//# sourceURL=webpack:///./webpack/vendors/custom/tinymce.js?");

/***/ })

/******/ });