[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/vendor/tinymce/plugins/table/ -> plugin.js (source)

   1  /**
   2   * Copyright (c) Tiny Technologies, Inc. All rights reserved.
   3   * Licensed under the LGPL or a commercial license.
   4   * For LGPL see License.txt in the project root for license information.
   5   * For commercial licenses see https://www.tiny.cloud/
   6   *
   7   * Version: 5.10.5 (2022-05-25)
   8   */
   9  (function () {
  10      'use strict';
  11  
  12      var typeOf = function (x) {
  13        var t = typeof x;
  14        if (x === null) {
  15          return 'null';
  16        } else if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
  17          return 'array';
  18        } else if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
  19          return 'string';
  20        } else {
  21          return t;
  22        }
  23      };
  24      var isType$1 = function (type) {
  25        return function (value) {
  26          return typeOf(value) === type;
  27        };
  28      };
  29      var isSimpleType = function (type) {
  30        return function (value) {
  31          return typeof value === type;
  32        };
  33      };
  34      var eq$2 = function (t) {
  35        return function (a) {
  36          return t === a;
  37        };
  38      };
  39      var isString = isType$1('string');
  40      var isObject = isType$1('object');
  41      var isArray = isType$1('array');
  42      var isNull = eq$2(null);
  43      var isBoolean = isSimpleType('boolean');
  44      var isUndefined = eq$2(undefined);
  45      var isNullable = function (a) {
  46        return a === null || a === undefined;
  47      };
  48      var isNonNullable = function (a) {
  49        return !isNullable(a);
  50      };
  51      var isFunction = isSimpleType('function');
  52      var isNumber = isSimpleType('number');
  53  
  54      var noop = function () {
  55      };
  56      var compose = function (fa, fb) {
  57        return function () {
  58          var args = [];
  59          for (var _i = 0; _i < arguments.length; _i++) {
  60            args[_i] = arguments[_i];
  61          }
  62          return fa(fb.apply(null, args));
  63        };
  64      };
  65      var compose1 = function (fbc, fab) {
  66        return function (a) {
  67          return fbc(fab(a));
  68        };
  69      };
  70      var constant = function (value) {
  71        return function () {
  72          return value;
  73        };
  74      };
  75      var identity = function (x) {
  76        return x;
  77      };
  78      var tripleEquals = function (a, b) {
  79        return a === b;
  80      };
  81      function curry(fn) {
  82        var initialArgs = [];
  83        for (var _i = 1; _i < arguments.length; _i++) {
  84          initialArgs[_i - 1] = arguments[_i];
  85        }
  86        return function () {
  87          var restArgs = [];
  88          for (var _i = 0; _i < arguments.length; _i++) {
  89            restArgs[_i] = arguments[_i];
  90          }
  91          var all = initialArgs.concat(restArgs);
  92          return fn.apply(null, all);
  93        };
  94      }
  95      var not = function (f) {
  96        return function (t) {
  97          return !f(t);
  98        };
  99      };
 100      var die = function (msg) {
 101        return function () {
 102          throw new Error(msg);
 103        };
 104      };
 105      var never = constant(false);
 106      var always = constant(true);
 107  
 108      var none$2 = function () {
 109        return NONE;
 110      };
 111      var NONE = function () {
 112        var call = function (thunk) {
 113          return thunk();
 114        };
 115        var id = identity;
 116        var me = {
 117          fold: function (n, _s) {
 118            return n();
 119          },
 120          isSome: never,
 121          isNone: always,
 122          getOr: id,
 123          getOrThunk: call,
 124          getOrDie: function (msg) {
 125            throw new Error(msg || 'error: getOrDie called on none.');
 126          },
 127          getOrNull: constant(null),
 128          getOrUndefined: constant(undefined),
 129          or: id,
 130          orThunk: call,
 131          map: none$2,
 132          each: noop,
 133          bind: none$2,
 134          exists: never,
 135          forall: always,
 136          filter: function () {
 137            return none$2();
 138          },
 139          toArray: function () {
 140            return [];
 141          },
 142          toString: constant('none()')
 143        };
 144        return me;
 145      }();
 146      var some = function (a) {
 147        var constant_a = constant(a);
 148        var self = function () {
 149          return me;
 150        };
 151        var bind = function (f) {
 152          return f(a);
 153        };
 154        var me = {
 155          fold: function (n, s) {
 156            return s(a);
 157          },
 158          isSome: always,
 159          isNone: never,
 160          getOr: constant_a,
 161          getOrThunk: constant_a,
 162          getOrDie: constant_a,
 163          getOrNull: constant_a,
 164          getOrUndefined: constant_a,
 165          or: self,
 166          orThunk: self,
 167          map: function (f) {
 168            return some(f(a));
 169          },
 170          each: function (f) {
 171            f(a);
 172          },
 173          bind: bind,
 174          exists: bind,
 175          forall: bind,
 176          filter: function (f) {
 177            return f(a) ? me : NONE;
 178          },
 179          toArray: function () {
 180            return [a];
 181          },
 182          toString: function () {
 183            return 'some(' + a + ')';
 184          }
 185        };
 186        return me;
 187      };
 188      var from$1 = function (value) {
 189        return value === null || value === undefined ? NONE : some(value);
 190      };
 191      var Optional = {
 192        some: some,
 193        none: none$2,
 194        from: from$1
 195      };
 196  
 197      var nativeSlice = Array.prototype.slice;
 198      var nativeIndexOf = Array.prototype.indexOf;
 199      var nativePush = Array.prototype.push;
 200      var rawIndexOf = function (ts, t) {
 201        return nativeIndexOf.call(ts, t);
 202      };
 203      var contains$2 = function (xs, x) {
 204        return rawIndexOf(xs, x) > -1;
 205      };
 206      var exists = function (xs, pred) {
 207        for (var i = 0, len = xs.length; i < len; i++) {
 208          var x = xs[i];
 209          if (pred(x, i)) {
 210            return true;
 211          }
 212        }
 213        return false;
 214      };
 215      var range$1 = function (num, f) {
 216        var r = [];
 217        for (var i = 0; i < num; i++) {
 218          r.push(f(i));
 219        }
 220        return r;
 221      };
 222      var map$1 = function (xs, f) {
 223        var len = xs.length;
 224        var r = new Array(len);
 225        for (var i = 0; i < len; i++) {
 226          var x = xs[i];
 227          r[i] = f(x, i);
 228        }
 229        return r;
 230      };
 231      var each$2 = function (xs, f) {
 232        for (var i = 0, len = xs.length; i < len; i++) {
 233          var x = xs[i];
 234          f(x, i);
 235        }
 236      };
 237      var eachr = function (xs, f) {
 238        for (var i = xs.length - 1; i >= 0; i--) {
 239          var x = xs[i];
 240          f(x, i);
 241        }
 242      };
 243      var partition = function (xs, pred) {
 244        var pass = [];
 245        var fail = [];
 246        for (var i = 0, len = xs.length; i < len; i++) {
 247          var x = xs[i];
 248          var arr = pred(x, i) ? pass : fail;
 249          arr.push(x);
 250        }
 251        return {
 252          pass: pass,
 253          fail: fail
 254        };
 255      };
 256      var filter$2 = function (xs, pred) {
 257        var r = [];
 258        for (var i = 0, len = xs.length; i < len; i++) {
 259          var x = xs[i];
 260          if (pred(x, i)) {
 261            r.push(x);
 262          }
 263        }
 264        return r;
 265      };
 266      var foldr = function (xs, f, acc) {
 267        eachr(xs, function (x, i) {
 268          acc = f(acc, x, i);
 269        });
 270        return acc;
 271      };
 272      var foldl = function (xs, f, acc) {
 273        each$2(xs, function (x, i) {
 274          acc = f(acc, x, i);
 275        });
 276        return acc;
 277      };
 278      var findUntil = function (xs, pred, until) {
 279        for (var i = 0, len = xs.length; i < len; i++) {
 280          var x = xs[i];
 281          if (pred(x, i)) {
 282            return Optional.some(x);
 283          } else if (until(x, i)) {
 284            break;
 285          }
 286        }
 287        return Optional.none();
 288      };
 289      var find$1 = function (xs, pred) {
 290        return findUntil(xs, pred, never);
 291      };
 292      var findIndex = function (xs, pred) {
 293        for (var i = 0, len = xs.length; i < len; i++) {
 294          var x = xs[i];
 295          if (pred(x, i)) {
 296            return Optional.some(i);
 297          }
 298        }
 299        return Optional.none();
 300      };
 301      var flatten$1 = function (xs) {
 302        var r = [];
 303        for (var i = 0, len = xs.length; i < len; ++i) {
 304          if (!isArray(xs[i])) {
 305            throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
 306          }
 307          nativePush.apply(r, xs[i]);
 308        }
 309        return r;
 310      };
 311      var bind$2 = function (xs, f) {
 312        return flatten$1(map$1(xs, f));
 313      };
 314      var forall = function (xs, pred) {
 315        for (var i = 0, len = xs.length; i < len; ++i) {
 316          var x = xs[i];
 317          if (pred(x, i) !== true) {
 318            return false;
 319          }
 320        }
 321        return true;
 322      };
 323      var reverse = function (xs) {
 324        var r = nativeSlice.call(xs, 0);
 325        r.reverse();
 326        return r;
 327      };
 328      var mapToObject = function (xs, f) {
 329        var r = {};
 330        for (var i = 0, len = xs.length; i < len; i++) {
 331          var x = xs[i];
 332          r[String(x)] = f(x, i);
 333        }
 334        return r;
 335      };
 336      var pure = function (x) {
 337        return [x];
 338      };
 339      var sort$1 = function (xs, comparator) {
 340        var copy = nativeSlice.call(xs, 0);
 341        copy.sort(comparator);
 342        return copy;
 343      };
 344      var get$d = function (xs, i) {
 345        return i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();
 346      };
 347      var head = function (xs) {
 348        return get$d(xs, 0);
 349      };
 350      var last$2 = function (xs) {
 351        return get$d(xs, xs.length - 1);
 352      };
 353      var findMap = function (arr, f) {
 354        for (var i = 0; i < arr.length; i++) {
 355          var r = f(arr[i], i);
 356          if (r.isSome()) {
 357            return r;
 358          }
 359        }
 360        return Optional.none();
 361      };
 362  
 363      var __assign = function () {
 364        __assign = Object.assign || function __assign(t) {
 365          for (var s, i = 1, n = arguments.length; i < n; i++) {
 366            s = arguments[i];
 367            for (var p in s)
 368              if (Object.prototype.hasOwnProperty.call(s, p))
 369                t[p] = s[p];
 370          }
 371          return t;
 372        };
 373        return __assign.apply(this, arguments);
 374      };
 375      function __spreadArray(to, from, pack) {
 376        if (pack || arguments.length === 2)
 377          for (var i = 0, l = from.length, ar; i < l; i++) {
 378            if (ar || !(i in from)) {
 379              if (!ar)
 380                ar = Array.prototype.slice.call(from, 0, i);
 381              ar[i] = from[i];
 382            }
 383          }
 384        return to.concat(ar || Array.prototype.slice.call(from));
 385      }
 386  
 387      var cached = function (f) {
 388        var called = false;
 389        var r;
 390        return function () {
 391          var args = [];
 392          for (var _i = 0; _i < arguments.length; _i++) {
 393            args[_i] = arguments[_i];
 394          }
 395          if (!called) {
 396            called = true;
 397            r = f.apply(null, args);
 398          }
 399          return r;
 400        };
 401      };
 402  
 403      var DeviceType = function (os, browser, userAgent, mediaMatch) {
 404        var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
 405        var isiPhone = os.isiOS() && !isiPad;
 406        var isMobile = os.isiOS() || os.isAndroid();
 407        var isTouch = isMobile || mediaMatch('(pointer:coarse)');
 408        var isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');
 409        var isPhone = isiPhone || isMobile && !isTablet;
 410        var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
 411        var isDesktop = !isPhone && !isTablet && !iOSwebview;
 412        return {
 413          isiPad: constant(isiPad),
 414          isiPhone: constant(isiPhone),
 415          isTablet: constant(isTablet),
 416          isPhone: constant(isPhone),
 417          isTouch: constant(isTouch),
 418          isAndroid: os.isAndroid,
 419          isiOS: os.isiOS,
 420          isWebView: constant(iOSwebview),
 421          isDesktop: constant(isDesktop)
 422        };
 423      };
 424  
 425      var firstMatch = function (regexes, s) {
 426        for (var i = 0; i < regexes.length; i++) {
 427          var x = regexes[i];
 428          if (x.test(s)) {
 429            return x;
 430          }
 431        }
 432        return undefined;
 433      };
 434      var find = function (regexes, agent) {
 435        var r = firstMatch(regexes, agent);
 436        if (!r) {
 437          return {
 438            major: 0,
 439            minor: 0
 440          };
 441        }
 442        var group = function (i) {
 443          return Number(agent.replace(r, '$' + i));
 444        };
 445        return nu$2(group(1), group(2));
 446      };
 447      var detect$6 = function (versionRegexes, agent) {
 448        var cleanedAgent = String(agent).toLowerCase();
 449        if (versionRegexes.length === 0) {
 450          return unknown$2();
 451        }
 452        return find(versionRegexes, cleanedAgent);
 453      };
 454      var unknown$2 = function () {
 455        return nu$2(0, 0);
 456      };
 457      var nu$2 = function (major, minor) {
 458        return {
 459          major: major,
 460          minor: minor
 461        };
 462      };
 463      var Version = {
 464        nu: nu$2,
 465        detect: detect$6,
 466        unknown: unknown$2
 467      };
 468  
 469      var detectBrowser$1 = function (browsers, userAgentData) {
 470        return findMap(userAgentData.brands, function (uaBrand) {
 471          var lcBrand = uaBrand.brand.toLowerCase();
 472          return find$1(browsers, function (browser) {
 473            var _a;
 474            return lcBrand === ((_a = browser.brand) === null || _a === void 0 ? void 0 : _a.toLowerCase());
 475          }).map(function (info) {
 476            return {
 477              current: info.name,
 478              version: Version.nu(parseInt(uaBrand.version, 10), 0)
 479            };
 480          });
 481        });
 482      };
 483  
 484      var detect$5 = function (candidates, userAgent) {
 485        var agent = String(userAgent).toLowerCase();
 486        return find$1(candidates, function (candidate) {
 487          return candidate.search(agent);
 488        });
 489      };
 490      var detectBrowser = function (browsers, userAgent) {
 491        return detect$5(browsers, userAgent).map(function (browser) {
 492          var version = Version.detect(browser.versionRegexes, userAgent);
 493          return {
 494            current: browser.name,
 495            version: version
 496          };
 497        });
 498      };
 499      var detectOs = function (oses, userAgent) {
 500        return detect$5(oses, userAgent).map(function (os) {
 501          var version = Version.detect(os.versionRegexes, userAgent);
 502          return {
 503            current: os.name,
 504            version: version
 505          };
 506        });
 507      };
 508  
 509      var removeFromStart = function (str, numChars) {
 510        return str.substring(numChars);
 511      };
 512  
 513      var checkRange = function (str, substr, start) {
 514        return substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
 515      };
 516      var removeLeading = function (str, prefix) {
 517        return startsWith(str, prefix) ? removeFromStart(str, prefix.length) : str;
 518      };
 519      var contains$1 = function (str, substr) {
 520        return str.indexOf(substr) !== -1;
 521      };
 522      var startsWith = function (str, prefix) {
 523        return checkRange(str, prefix, 0);
 524      };
 525      var endsWith = function (str, suffix) {
 526        return checkRange(str, suffix, str.length - suffix.length);
 527      };
 528      var blank = function (r) {
 529        return function (s) {
 530          return s.replace(r, '');
 531        };
 532      };
 533      var trim = blank(/^\s+|\s+$/g);
 534      var isNotEmpty = function (s) {
 535        return s.length > 0;
 536      };
 537      var isEmpty$1 = function (s) {
 538        return !isNotEmpty(s);
 539      };
 540      var toFloat = function (value) {
 541        var num = parseFloat(value);
 542        return isNaN(num) ? Optional.none() : Optional.some(num);
 543      };
 544  
 545      var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
 546      var checkContains = function (target) {
 547        return function (uastring) {
 548          return contains$1(uastring, target);
 549        };
 550      };
 551      var browsers = [
 552        {
 553          name: 'Edge',
 554          versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
 555          search: function (uastring) {
 556            return contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit');
 557          }
 558        },
 559        {
 560          name: 'Chrome',
 561          brand: 'Chromium',
 562          versionRegexes: [
 563            /.*?chrome\/([0-9]+)\.([0-9]+).*/,
 564            normalVersionRegex
 565          ],
 566          search: function (uastring) {
 567            return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe');
 568          }
 569        },
 570        {
 571          name: 'IE',
 572          versionRegexes: [
 573            /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
 574            /.*?rv:([0-9]+)\.([0-9]+).*/
 575          ],
 576          search: function (uastring) {
 577            return contains$1(uastring, 'msie') || contains$1(uastring, 'trident');
 578          }
 579        },
 580        {
 581          name: 'Opera',
 582          versionRegexes: [
 583            normalVersionRegex,
 584            /.*?opera\/([0-9]+)\.([0-9]+).*/
 585          ],
 586          search: checkContains('opera')
 587        },
 588        {
 589          name: 'Firefox',
 590          versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
 591          search: checkContains('firefox')
 592        },
 593        {
 594          name: 'Safari',
 595          versionRegexes: [
 596            normalVersionRegex,
 597            /.*?cpu os ([0-9]+)_([0-9]+).*/
 598          ],
 599          search: function (uastring) {
 600            return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit');
 601          }
 602        }
 603      ];
 604      var oses = [
 605        {
 606          name: 'Windows',
 607          search: checkContains('win'),
 608          versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
 609        },
 610        {
 611          name: 'iOS',
 612          search: function (uastring) {
 613            return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad');
 614          },
 615          versionRegexes: [
 616            /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
 617            /.*cpu os ([0-9]+)_([0-9]+).*/,
 618            /.*cpu iphone os ([0-9]+)_([0-9]+).*/
 619          ]
 620        },
 621        {
 622          name: 'Android',
 623          search: checkContains('android'),
 624          versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
 625        },
 626        {
 627          name: 'OSX',
 628          search: checkContains('mac os x'),
 629          versionRegexes: [/.*?mac\ os\ x\ ?([0-9]+)_([0-9]+).*/]
 630        },
 631        {
 632          name: 'Linux',
 633          search: checkContains('linux'),
 634          versionRegexes: []
 635        },
 636        {
 637          name: 'Solaris',
 638          search: checkContains('sunos'),
 639          versionRegexes: []
 640        },
 641        {
 642          name: 'FreeBSD',
 643          search: checkContains('freebsd'),
 644          versionRegexes: []
 645        },
 646        {
 647          name: 'ChromeOS',
 648          search: checkContains('cros'),
 649          versionRegexes: [/.*?chrome\/([0-9]+)\.([0-9]+).*/]
 650        }
 651      ];
 652      var PlatformInfo = {
 653        browsers: constant(browsers),
 654        oses: constant(oses)
 655      };
 656  
 657      var edge = 'Edge';
 658      var chrome = 'Chrome';
 659      var ie = 'IE';
 660      var opera = 'Opera';
 661      var firefox = 'Firefox';
 662      var safari = 'Safari';
 663      var unknown$1 = function () {
 664        return nu$1({
 665          current: undefined,
 666          version: Version.unknown()
 667        });
 668      };
 669      var nu$1 = function (info) {
 670        var current = info.current;
 671        var version = info.version;
 672        var isBrowser = function (name) {
 673          return function () {
 674            return current === name;
 675          };
 676        };
 677        return {
 678          current: current,
 679          version: version,
 680          isEdge: isBrowser(edge),
 681          isChrome: isBrowser(chrome),
 682          isIE: isBrowser(ie),
 683          isOpera: isBrowser(opera),
 684          isFirefox: isBrowser(firefox),
 685          isSafari: isBrowser(safari)
 686        };
 687      };
 688      var Browser = {
 689        unknown: unknown$1,
 690        nu: nu$1,
 691        edge: constant(edge),
 692        chrome: constant(chrome),
 693        ie: constant(ie),
 694        opera: constant(opera),
 695        firefox: constant(firefox),
 696        safari: constant(safari)
 697      };
 698  
 699      var windows = 'Windows';
 700      var ios = 'iOS';
 701      var android = 'Android';
 702      var linux = 'Linux';
 703      var osx = 'OSX';
 704      var solaris = 'Solaris';
 705      var freebsd = 'FreeBSD';
 706      var chromeos = 'ChromeOS';
 707      var unknown = function () {
 708        return nu({
 709          current: undefined,
 710          version: Version.unknown()
 711        });
 712      };
 713      var nu = function (info) {
 714        var current = info.current;
 715        var version = info.version;
 716        var isOS = function (name) {
 717          return function () {
 718            return current === name;
 719          };
 720        };
 721        return {
 722          current: current,
 723          version: version,
 724          isWindows: isOS(windows),
 725          isiOS: isOS(ios),
 726          isAndroid: isOS(android),
 727          isOSX: isOS(osx),
 728          isLinux: isOS(linux),
 729          isSolaris: isOS(solaris),
 730          isFreeBSD: isOS(freebsd),
 731          isChromeOS: isOS(chromeos)
 732        };
 733      };
 734      var OperatingSystem = {
 735        unknown: unknown,
 736        nu: nu,
 737        windows: constant(windows),
 738        ios: constant(ios),
 739        android: constant(android),
 740        linux: constant(linux),
 741        osx: constant(osx),
 742        solaris: constant(solaris),
 743        freebsd: constant(freebsd),
 744        chromeos: constant(chromeos)
 745      };
 746  
 747      var detect$4 = function (userAgent, userAgentDataOpt, mediaMatch) {
 748        var browsers = PlatformInfo.browsers();
 749        var oses = PlatformInfo.oses();
 750        var browser = userAgentDataOpt.bind(function (userAgentData) {
 751          return detectBrowser$1(browsers, userAgentData);
 752        }).orThunk(function () {
 753          return detectBrowser(browsers, userAgent);
 754        }).fold(Browser.unknown, Browser.nu);
 755        var os = detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
 756        var deviceType = DeviceType(os, browser, userAgent, mediaMatch);
 757        return {
 758          browser: browser,
 759          os: os,
 760          deviceType: deviceType
 761        };
 762      };
 763      var PlatformDetection = { detect: detect$4 };
 764  
 765      var mediaMatch = function (query) {
 766        return window.matchMedia(query).matches;
 767      };
 768      var platform = cached(function () {
 769        return PlatformDetection.detect(navigator.userAgent, Optional.from(navigator.userAgentData), mediaMatch);
 770      });
 771      var detect$3 = function () {
 772        return platform();
 773      };
 774  
 775      var compareDocumentPosition = function (a, b, match) {
 776        return (a.compareDocumentPosition(b) & match) !== 0;
 777      };
 778      var documentPositionContainedBy = function (a, b) {
 779        return compareDocumentPosition(a, b, Node.DOCUMENT_POSITION_CONTAINED_BY);
 780      };
 781  
 782      var COMMENT = 8;
 783      var DOCUMENT = 9;
 784      var DOCUMENT_FRAGMENT = 11;
 785      var ELEMENT = 1;
 786      var TEXT = 3;
 787  
 788      var fromHtml$1 = function (html, scope) {
 789        var doc = scope || document;
 790        var div = doc.createElement('div');
 791        div.innerHTML = html;
 792        if (!div.hasChildNodes() || div.childNodes.length > 1) {
 793          console.error('HTML does not have a single root node', html);
 794          throw new Error('HTML must have a single root node');
 795        }
 796        return fromDom$1(div.childNodes[0]);
 797      };
 798      var fromTag = function (tag, scope) {
 799        var doc = scope || document;
 800        var node = doc.createElement(tag);
 801        return fromDom$1(node);
 802      };
 803      var fromText = function (text, scope) {
 804        var doc = scope || document;
 805        var node = doc.createTextNode(text);
 806        return fromDom$1(node);
 807      };
 808      var fromDom$1 = function (node) {
 809        if (node === null || node === undefined) {
 810          throw new Error('Node cannot be null or undefined');
 811        }
 812        return { dom: node };
 813      };
 814      var fromPoint$1 = function (docElm, x, y) {
 815        return Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom$1);
 816      };
 817      var SugarElement = {
 818        fromHtml: fromHtml$1,
 819        fromTag: fromTag,
 820        fromText: fromText,
 821        fromDom: fromDom$1,
 822        fromPoint: fromPoint$1
 823      };
 824  
 825      var is$2 = function (element, selector) {
 826        var dom = element.dom;
 827        if (dom.nodeType !== ELEMENT) {
 828          return false;
 829        } else {
 830          var elem = dom;
 831          if (elem.matches !== undefined) {
 832            return elem.matches(selector);
 833          } else if (elem.msMatchesSelector !== undefined) {
 834            return elem.msMatchesSelector(selector);
 835          } else if (elem.webkitMatchesSelector !== undefined) {
 836            return elem.webkitMatchesSelector(selector);
 837          } else if (elem.mozMatchesSelector !== undefined) {
 838            return elem.mozMatchesSelector(selector);
 839          } else {
 840            throw new Error('Browser lacks native selectors');
 841          }
 842        }
 843      };
 844      var bypassSelector = function (dom) {
 845        return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT && dom.nodeType !== DOCUMENT_FRAGMENT || dom.childElementCount === 0;
 846      };
 847      var all$1 = function (selector, scope) {
 848        var base = scope === undefined ? document : scope.dom;
 849        return bypassSelector(base) ? [] : map$1(base.querySelectorAll(selector), SugarElement.fromDom);
 850      };
 851      var one = function (selector, scope) {
 852        var base = scope === undefined ? document : scope.dom;
 853        return bypassSelector(base) ? Optional.none() : Optional.from(base.querySelector(selector)).map(SugarElement.fromDom);
 854      };
 855  
 856      var eq$1 = function (e1, e2) {
 857        return e1.dom === e2.dom;
 858      };
 859      var regularContains = function (e1, e2) {
 860        var d1 = e1.dom;
 861        var d2 = e2.dom;
 862        return d1 === d2 ? false : d1.contains(d2);
 863      };
 864      var ieContains = function (e1, e2) {
 865        return documentPositionContainedBy(e1.dom, e2.dom);
 866      };
 867      var contains = function (e1, e2) {
 868        return detect$3().browser.isIE() ? ieContains(e1, e2) : regularContains(e1, e2);
 869      };
 870      var is$1 = is$2;
 871  
 872      var keys = Object.keys;
 873      var hasOwnProperty = Object.hasOwnProperty;
 874      var each$1 = function (obj, f) {
 875        var props = keys(obj);
 876        for (var k = 0, len = props.length; k < len; k++) {
 877          var i = props[k];
 878          var x = obj[i];
 879          f(x, i);
 880        }
 881      };
 882      var map = function (obj, f) {
 883        return tupleMap(obj, function (x, i) {
 884          return {
 885            k: i,
 886            v: f(x, i)
 887          };
 888        });
 889      };
 890      var tupleMap = function (obj, f) {
 891        var r = {};
 892        each$1(obj, function (x, i) {
 893          var tuple = f(x, i);
 894          r[tuple.k] = tuple.v;
 895        });
 896        return r;
 897      };
 898      var objAcc = function (r) {
 899        return function (x, i) {
 900          r[i] = x;
 901        };
 902      };
 903      var internalFilter = function (obj, pred, onTrue, onFalse) {
 904        var r = {};
 905        each$1(obj, function (x, i) {
 906          (pred(x, i) ? onTrue : onFalse)(x, i);
 907        });
 908        return r;
 909      };
 910      var filter$1 = function (obj, pred) {
 911        var t = {};
 912        internalFilter(obj, pred, objAcc(t), noop);
 913        return t;
 914      };
 915      var mapToArray = function (obj, f) {
 916        var r = [];
 917        each$1(obj, function (value, name) {
 918          r.push(f(value, name));
 919        });
 920        return r;
 921      };
 922      var values = function (obj) {
 923        return mapToArray(obj, identity);
 924      };
 925      var size = function (obj) {
 926        return keys(obj).length;
 927      };
 928      var get$c = function (obj, key) {
 929        return has$1(obj, key) ? Optional.from(obj[key]) : Optional.none();
 930      };
 931      var has$1 = function (obj, key) {
 932        return hasOwnProperty.call(obj, key);
 933      };
 934      var hasNonNullableKey = function (obj, key) {
 935        return has$1(obj, key) && obj[key] !== undefined && obj[key] !== null;
 936      };
 937      var isEmpty = function (r) {
 938        for (var x in r) {
 939          if (hasOwnProperty.call(r, x)) {
 940            return false;
 941          }
 942        }
 943        return true;
 944      };
 945  
 946      var validSectionList = [
 947        'tfoot',
 948        'thead',
 949        'tbody',
 950        'colgroup'
 951      ];
 952      var isValidSection = function (parentName) {
 953        return contains$2(validSectionList, parentName);
 954      };
 955      var grid = function (rows, columns) {
 956        return {
 957          rows: rows,
 958          columns: columns
 959        };
 960      };
 961      var address = function (row, column) {
 962        return {
 963          row: row,
 964          column: column
 965        };
 966      };
 967      var detail = function (element, rowspan, colspan) {
 968        return {
 969          element: element,
 970          rowspan: rowspan,
 971          colspan: colspan
 972        };
 973      };
 974      var detailnew = function (element, rowspan, colspan, isNew) {
 975        return {
 976          element: element,
 977          rowspan: rowspan,
 978          colspan: colspan,
 979          isNew: isNew
 980        };
 981      };
 982      var extended = function (element, rowspan, colspan, row, column, isLocked) {
 983        return {
 984          element: element,
 985          rowspan: rowspan,
 986          colspan: colspan,
 987          row: row,
 988          column: column,
 989          isLocked: isLocked
 990        };
 991      };
 992      var rowdetail = function (element, cells, section) {
 993        return {
 994          element: element,
 995          cells: cells,
 996          section: section
 997        };
 998      };
 999      var rowdetailnew = function (element, cells, section, isNew) {
1000        return {
1001          element: element,
1002          cells: cells,
1003          section: section,
1004          isNew: isNew
1005        };
1006      };
1007      var elementnew = function (element, isNew, isLocked) {
1008        return {
1009          element: element,
1010          isNew: isNew,
1011          isLocked: isLocked
1012        };
1013      };
1014      var rowcells = function (element, cells, section, isNew) {
1015        return {
1016          element: element,
1017          cells: cells,
1018          section: section,
1019          isNew: isNew
1020        };
1021      };
1022      var bounds = function (startRow, startCol, finishRow, finishCol) {
1023        return {
1024          startRow: startRow,
1025          startCol: startCol,
1026          finishRow: finishRow,
1027          finishCol: finishCol
1028        };
1029      };
1030      var columnext = function (element, colspan, column) {
1031        return {
1032          element: element,
1033          colspan: colspan,
1034          column: column
1035        };
1036      };
1037      var colgroup = function (element, columns) {
1038        return {
1039          element: element,
1040          columns: columns
1041        };
1042      };
1043  
1044      typeof window !== 'undefined' ? window : Function('return this;')();
1045  
1046      var name = function (element) {
1047        var r = element.dom.nodeName;
1048        return r.toLowerCase();
1049      };
1050      var type$1 = function (element) {
1051        return element.dom.nodeType;
1052      };
1053      var isType = function (t) {
1054        return function (element) {
1055          return type$1(element) === t;
1056        };
1057      };
1058      var isComment = function (element) {
1059        return type$1(element) === COMMENT || name(element) === '#comment';
1060      };
1061      var isElement = isType(ELEMENT);
1062      var isText = isType(TEXT);
1063      var isDocument = isType(DOCUMENT);
1064      var isDocumentFragment = isType(DOCUMENT_FRAGMENT);
1065      var isTag = function (tag) {
1066        return function (e) {
1067          return isElement(e) && name(e) === tag;
1068        };
1069      };
1070  
1071      var owner = function (element) {
1072        return SugarElement.fromDom(element.dom.ownerDocument);
1073      };
1074      var documentOrOwner = function (dos) {
1075        return isDocument(dos) ? dos : owner(dos);
1076      };
1077      var defaultView = function (element) {
1078        return SugarElement.fromDom(documentOrOwner(element).dom.defaultView);
1079      };
1080      var parent = function (element) {
1081        return Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
1082      };
1083      var parentElement = function (element) {
1084        return Optional.from(element.dom.parentElement).map(SugarElement.fromDom);
1085      };
1086      var parents = function (element, isRoot) {
1087        var stop = isFunction(isRoot) ? isRoot : never;
1088        var dom = element.dom;
1089        var ret = [];
1090        while (dom.parentNode !== null && dom.parentNode !== undefined) {
1091          var rawParent = dom.parentNode;
1092          var p = SugarElement.fromDom(rawParent);
1093          ret.push(p);
1094          if (stop(p) === true) {
1095            break;
1096          } else {
1097            dom = rawParent;
1098          }
1099        }
1100        return ret;
1101      };
1102      var prevSibling = function (element) {
1103        return Optional.from(element.dom.previousSibling).map(SugarElement.fromDom);
1104      };
1105      var nextSibling = function (element) {
1106        return Optional.from(element.dom.nextSibling).map(SugarElement.fromDom);
1107      };
1108      var children$3 = function (element) {
1109        return map$1(element.dom.childNodes, SugarElement.fromDom);
1110      };
1111      var child$3 = function (element, index) {
1112        var cs = element.dom.childNodes;
1113        return Optional.from(cs[index]).map(SugarElement.fromDom);
1114      };
1115      var firstChild = function (element) {
1116        return child$3(element, 0);
1117      };
1118  
1119      var isShadowRoot = function (dos) {
1120        return isDocumentFragment(dos) && isNonNullable(dos.dom.host);
1121      };
1122      var supported = isFunction(Element.prototype.attachShadow) && isFunction(Node.prototype.getRootNode);
1123      var isSupported$1 = constant(supported);
1124      var getRootNode = supported ? function (e) {
1125        return SugarElement.fromDom(e.dom.getRootNode());
1126      } : documentOrOwner;
1127      var getShadowRoot = function (e) {
1128        var r = getRootNode(e);
1129        return isShadowRoot(r) ? Optional.some(r) : Optional.none();
1130      };
1131      var getShadowHost = function (e) {
1132        return SugarElement.fromDom(e.dom.host);
1133      };
1134      var getOriginalEventTarget = function (event) {
1135        if (isSupported$1() && isNonNullable(event.target)) {
1136          var el = SugarElement.fromDom(event.target);
1137          if (isElement(el) && isOpenShadowHost(el)) {
1138            if (event.composed && event.composedPath) {
1139              var composedPath = event.composedPath();
1140              if (composedPath) {
1141                return head(composedPath);
1142              }
1143            }
1144          }
1145        }
1146        return Optional.from(event.target);
1147      };
1148      var isOpenShadowHost = function (element) {
1149        return isNonNullable(element.dom.shadowRoot);
1150      };
1151  
1152      var inBody = function (element) {
1153        var dom = isText(element) ? element.dom.parentNode : element.dom;
1154        if (dom === undefined || dom === null || dom.ownerDocument === null) {
1155          return false;
1156        }
1157        var doc = dom.ownerDocument;
1158        return getShadowRoot(SugarElement.fromDom(dom)).fold(function () {
1159          return doc.body.contains(dom);
1160        }, compose1(inBody, getShadowHost));
1161      };
1162      var body$1 = function () {
1163        return getBody$1(SugarElement.fromDom(document));
1164      };
1165      var getBody$1 = function (doc) {
1166        var b = doc.dom.body;
1167        if (b === null || b === undefined) {
1168          throw new Error('Body is not available yet');
1169        }
1170        return SugarElement.fromDom(b);
1171      };
1172  
1173      var ancestors$4 = function (scope, predicate, isRoot) {
1174        return filter$2(parents(scope, isRoot), predicate);
1175      };
1176      var children$2 = function (scope, predicate) {
1177        return filter$2(children$3(scope), predicate);
1178      };
1179      var descendants$1 = function (scope, predicate) {
1180        var result = [];
1181        each$2(children$3(scope), function (x) {
1182          if (predicate(x)) {
1183            result = result.concat([x]);
1184          }
1185          result = result.concat(descendants$1(x, predicate));
1186        });
1187        return result;
1188      };
1189  
1190      var ancestors$3 = function (scope, selector, isRoot) {
1191        return ancestors$4(scope, function (e) {
1192          return is$2(e, selector);
1193        }, isRoot);
1194      };
1195      var children$1 = function (scope, selector) {
1196        return children$2(scope, function (e) {
1197          return is$2(e, selector);
1198        });
1199      };
1200      var descendants = function (scope, selector) {
1201        return all$1(selector, scope);
1202      };
1203  
1204      function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {
1205        if (is(scope, a)) {
1206          return Optional.some(scope);
1207        } else if (isFunction(isRoot) && isRoot(scope)) {
1208          return Optional.none();
1209        } else {
1210          return ancestor(scope, a, isRoot);
1211        }
1212      }
1213  
1214      var ancestor$2 = function (scope, predicate, isRoot) {
1215        var element = scope.dom;
1216        var stop = isFunction(isRoot) ? isRoot : never;
1217        while (element.parentNode) {
1218          element = element.parentNode;
1219          var el = SugarElement.fromDom(element);
1220          if (predicate(el)) {
1221            return Optional.some(el);
1222          } else if (stop(el)) {
1223            break;
1224          }
1225        }
1226        return Optional.none();
1227      };
1228      var closest$2 = function (scope, predicate, isRoot) {
1229        var is = function (s, test) {
1230          return test(s);
1231        };
1232        return ClosestOrAncestor(is, ancestor$2, scope, predicate, isRoot);
1233      };
1234      var child$2 = function (scope, predicate) {
1235        var pred = function (node) {
1236          return predicate(SugarElement.fromDom(node));
1237        };
1238        var result = find$1(scope.dom.childNodes, pred);
1239        return result.map(SugarElement.fromDom);
1240      };
1241      var descendant$1 = function (scope, predicate) {
1242        var descend = function (node) {
1243          for (var i = 0; i < node.childNodes.length; i++) {
1244            var child_1 = SugarElement.fromDom(node.childNodes[i]);
1245            if (predicate(child_1)) {
1246              return Optional.some(child_1);
1247            }
1248            var res = descend(node.childNodes[i]);
1249            if (res.isSome()) {
1250              return res;
1251            }
1252          }
1253          return Optional.none();
1254        };
1255        return descend(scope.dom);
1256      };
1257  
1258      var ancestor$1 = function (scope, selector, isRoot) {
1259        return ancestor$2(scope, function (e) {
1260          return is$2(e, selector);
1261        }, isRoot);
1262      };
1263      var child$1 = function (scope, selector) {
1264        return child$2(scope, function (e) {
1265          return is$2(e, selector);
1266        });
1267      };
1268      var descendant = function (scope, selector) {
1269        return one(selector, scope);
1270      };
1271      var closest$1 = function (scope, selector, isRoot) {
1272        var is = function (element, selector) {
1273          return is$2(element, selector);
1274        };
1275        return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot);
1276      };
1277  
1278      var rawSet = function (dom, key, value) {
1279        if (isString(value) || isBoolean(value) || isNumber(value)) {
1280          dom.setAttribute(key, value + '');
1281        } else {
1282          console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
1283          throw new Error('Attribute value was not simple');
1284        }
1285      };
1286      var set$2 = function (element, key, value) {
1287        rawSet(element.dom, key, value);
1288      };
1289      var setAll$1 = function (element, attrs) {
1290        var dom = element.dom;
1291        each$1(attrs, function (v, k) {
1292          rawSet(dom, k, v);
1293        });
1294      };
1295      var setOptions = function (element, attrs) {
1296        each$1(attrs, function (v, k) {
1297          v.fold(function () {
1298            remove$7(element, k);
1299          }, function (value) {
1300            rawSet(element.dom, k, value);
1301          });
1302        });
1303      };
1304      var get$b = function (element, key) {
1305        var v = element.dom.getAttribute(key);
1306        return v === null ? undefined : v;
1307      };
1308      var getOpt = function (element, key) {
1309        return Optional.from(get$b(element, key));
1310      };
1311      var remove$7 = function (element, key) {
1312        element.dom.removeAttribute(key);
1313      };
1314      var clone$2 = function (element) {
1315        return foldl(element.dom.attributes, function (acc, attr) {
1316          acc[attr.name] = attr.value;
1317          return acc;
1318        }, {});
1319      };
1320  
1321      var is = function (lhs, rhs, comparator) {
1322        if (comparator === void 0) {
1323          comparator = tripleEquals;
1324        }
1325        return lhs.exists(function (left) {
1326          return comparator(left, rhs);
1327        });
1328      };
1329      var cat = function (arr) {
1330        var r = [];
1331        var push = function (x) {
1332          r.push(x);
1333        };
1334        for (var i = 0; i < arr.length; i++) {
1335          arr[i].each(push);
1336        }
1337        return r;
1338      };
1339      var lift2 = function (oa, ob, f) {
1340        return oa.isSome() && ob.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie())) : Optional.none();
1341      };
1342      var bindFrom = function (a, f) {
1343        return a !== undefined && a !== null ? f(a) : Optional.none();
1344      };
1345      var flatten = function (oot) {
1346        return oot.bind(identity);
1347      };
1348      var someIf = function (b, a) {
1349        return b ? Optional.some(a) : Optional.none();
1350      };
1351  
1352      var isSupported = function (dom) {
1353        return dom.style !== undefined && isFunction(dom.style.getPropertyValue);
1354      };
1355  
1356      var internalSet = function (dom, property, value) {
1357        if (!isString(value)) {
1358          console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
1359          throw new Error('CSS value must be a string: ' + value);
1360        }
1361        if (isSupported(dom)) {
1362          dom.style.setProperty(property, value);
1363        }
1364      };
1365      var internalRemove = function (dom, property) {
1366        if (isSupported(dom)) {
1367          dom.style.removeProperty(property);
1368        }
1369      };
1370      var set$1 = function (element, property, value) {
1371        var dom = element.dom;
1372        internalSet(dom, property, value);
1373      };
1374      var setAll = function (element, css) {
1375        var dom = element.dom;
1376        each$1(css, function (v, k) {
1377          internalSet(dom, k, v);
1378        });
1379      };
1380      var get$a = function (element, property) {
1381        var dom = element.dom;
1382        var styles = window.getComputedStyle(dom);
1383        var r = styles.getPropertyValue(property);
1384        return r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
1385      };
1386      var getUnsafeProperty = function (dom, property) {
1387        return isSupported(dom) ? dom.style.getPropertyValue(property) : '';
1388      };
1389      var getRaw$2 = function (element, property) {
1390        var dom = element.dom;
1391        var raw = getUnsafeProperty(dom, property);
1392        return Optional.from(raw).filter(function (r) {
1393          return r.length > 0;
1394        });
1395      };
1396      var remove$6 = function (element, property) {
1397        var dom = element.dom;
1398        internalRemove(dom, property);
1399        if (is(getOpt(element, 'style').map(trim), '')) {
1400          remove$7(element, 'style');
1401        }
1402      };
1403      var copy$2 = function (source, target) {
1404        var sourceDom = source.dom;
1405        var targetDom = target.dom;
1406        if (isSupported(sourceDom) && isSupported(targetDom)) {
1407          targetDom.style.cssText = sourceDom.style.cssText;
1408        }
1409      };
1410  
1411      var getAttrValue = function (cell, name, fallback) {
1412        if (fallback === void 0) {
1413          fallback = 0;
1414        }
1415        return getOpt(cell, name).map(function (value) {
1416          return parseInt(value, 10);
1417        }).getOr(fallback);
1418      };
1419      var getSpan = function (cell, type) {
1420        return getAttrValue(cell, type, 1);
1421      };
1422      var hasColspan = function (cellOrCol) {
1423        if (isTag('col')(cellOrCol)) {
1424          return getAttrValue(cellOrCol, 'span', 1) > 1;
1425        } else {
1426          return getSpan(cellOrCol, 'colspan') > 1;
1427        }
1428      };
1429      var hasRowspan = function (cell) {
1430        return getSpan(cell, 'rowspan') > 1;
1431      };
1432      var getCssValue = function (element, property) {
1433        return parseInt(get$a(element, property), 10);
1434      };
1435      var minWidth = constant(10);
1436      var minHeight = constant(10);
1437  
1438      var firstLayer = function (scope, selector) {
1439        return filterFirstLayer(scope, selector, always);
1440      };
1441      var filterFirstLayer = function (scope, selector, predicate) {
1442        return bind$2(children$3(scope), function (x) {
1443          if (is$2(x, selector)) {
1444            return predicate(x) ? [x] : [];
1445          } else {
1446            return filterFirstLayer(x, selector, predicate);
1447          }
1448        });
1449      };
1450  
1451      var lookup = function (tags, element, isRoot) {
1452        if (isRoot === void 0) {
1453          isRoot = never;
1454        }
1455        if (isRoot(element)) {
1456          return Optional.none();
1457        }
1458        if (contains$2(tags, name(element))) {
1459          return Optional.some(element);
1460        }
1461        var isRootOrUpperTable = function (elm) {
1462          return is$2(elm, 'table') || isRoot(elm);
1463        };
1464        return ancestor$1(element, tags.join(','), isRootOrUpperTable);
1465      };
1466      var cell = function (element, isRoot) {
1467        return lookup([
1468          'td',
1469          'th'
1470        ], element, isRoot);
1471      };
1472      var cells$1 = function (ancestor) {
1473        return firstLayer(ancestor, 'th,td');
1474      };
1475      var columns$1 = function (ancestor) {
1476        if (is$2(ancestor, 'colgroup')) {
1477          return children$1(ancestor, 'col');
1478        } else {
1479          return bind$2(columnGroups(ancestor), function (columnGroup) {
1480            return children$1(columnGroup, 'col');
1481          });
1482        }
1483      };
1484      var table = function (element, isRoot) {
1485        return closest$1(element, 'table', isRoot);
1486      };
1487      var rows$1 = function (ancestor) {
1488        return firstLayer(ancestor, 'tr');
1489      };
1490      var columnGroups = function (ancestor) {
1491        return table(ancestor).fold(constant([]), function (table) {
1492          return children$1(table, 'colgroup');
1493        });
1494      };
1495  
1496      var fromRowsOrColGroups = function (elems, getSection) {
1497        return map$1(elems, function (row) {
1498          if (name(row) === 'colgroup') {
1499            var cells = map$1(columns$1(row), function (column) {
1500              var colspan = getAttrValue(column, 'span', 1);
1501              return detail(column, 1, colspan);
1502            });
1503            return rowdetail(row, cells, 'colgroup');
1504          } else {
1505            var cells = map$1(cells$1(row), function (cell) {
1506              var rowspan = getAttrValue(cell, 'rowspan', 1);
1507              var colspan = getAttrValue(cell, 'colspan', 1);
1508              return detail(cell, rowspan, colspan);
1509            });
1510            return rowdetail(row, cells, getSection(row));
1511          }
1512        });
1513      };
1514      var getParentSection = function (group) {
1515        return parent(group).map(function (parent) {
1516          var parentName = name(parent);
1517          return isValidSection(parentName) ? parentName : 'tbody';
1518        }).getOr('tbody');
1519      };
1520      var fromTable$1 = function (table) {
1521        var rows = rows$1(table);
1522        var columnGroups$1 = columnGroups(table);
1523        var elems = __spreadArray(__spreadArray([], columnGroups$1, true), rows, true);
1524        return fromRowsOrColGroups(elems, getParentSection);
1525      };
1526      var fromPastedRows = function (elems, section) {
1527        return fromRowsOrColGroups(elems, function () {
1528          return section;
1529        });
1530      };
1531  
1532      var addCells = function (gridRow, index, cells) {
1533        var existingCells = gridRow.cells;
1534        var before = existingCells.slice(0, index);
1535        var after = existingCells.slice(index);
1536        var newCells = before.concat(cells).concat(after);
1537        return setCells(gridRow, newCells);
1538      };
1539      var addCell = function (gridRow, index, cell) {
1540        return addCells(gridRow, index, [cell]);
1541      };
1542      var mutateCell = function (gridRow, index, cell) {
1543        var cells = gridRow.cells;
1544        cells[index] = cell;
1545      };
1546      var setCells = function (gridRow, cells) {
1547        return rowcells(gridRow.element, cells, gridRow.section, gridRow.isNew);
1548      };
1549      var mapCells = function (gridRow, f) {
1550        var cells = gridRow.cells;
1551        var r = map$1(cells, f);
1552        return rowcells(gridRow.element, r, gridRow.section, gridRow.isNew);
1553      };
1554      var getCell = function (gridRow, index) {
1555        return gridRow.cells[index];
1556      };
1557      var getCellElement = function (gridRow, index) {
1558        return getCell(gridRow, index).element;
1559      };
1560      var cellLength = function (gridRow) {
1561        return gridRow.cells.length;
1562      };
1563      var extractGridDetails = function (grid) {
1564        var result = partition(grid, function (row) {
1565          return row.section === 'colgroup';
1566        });
1567        return {
1568          rows: result.fail,
1569          cols: result.pass
1570        };
1571      };
1572      var clone$1 = function (gridRow, cloneRow, cloneCell) {
1573        var newCells = map$1(gridRow.cells, cloneCell);
1574        return rowcells(cloneRow(gridRow.element), newCells, gridRow.section, true);
1575      };
1576  
1577      var LOCKED_COL_ATTR = 'data-snooker-locked-cols';
1578      var getLockedColumnsFromTable = function (table) {
1579        return getOpt(table, LOCKED_COL_ATTR).bind(function (lockedColStr) {
1580          return Optional.from(lockedColStr.match(/\d+/g));
1581        }).map(function (lockedCols) {
1582          return mapToObject(lockedCols, always);
1583        });
1584      };
1585      var getLockedColumnsFromGrid = function (grid) {
1586        var locked = foldl(extractGridDetails(grid).rows, function (acc, row) {
1587          each$2(row.cells, function (cell, idx) {
1588            if (cell.isLocked) {
1589              acc[idx] = true;
1590            }
1591          });
1592          return acc;
1593        }, {});
1594        var lockedArr = mapToArray(locked, function (_val, key) {
1595          return parseInt(key, 10);
1596        });
1597        return sort$1(lockedArr);
1598      };
1599  
1600      var key = function (row, column) {
1601        return row + ',' + column;
1602      };
1603      var getAt = function (warehouse, row, column) {
1604        return Optional.from(warehouse.access[key(row, column)]);
1605      };
1606      var findItem = function (warehouse, item, comparator) {
1607        var filtered = filterItems(warehouse, function (detail) {
1608          return comparator(item, detail.element);
1609        });
1610        return filtered.length > 0 ? Optional.some(filtered[0]) : Optional.none();
1611      };
1612      var filterItems = function (warehouse, predicate) {
1613        var all = bind$2(warehouse.all, function (r) {
1614          return r.cells;
1615        });
1616        return filter$2(all, predicate);
1617      };
1618      var generateColumns = function (rowData) {
1619        var columnsGroup = {};
1620        var index = 0;
1621        each$2(rowData.cells, function (column) {
1622          var colspan = column.colspan;
1623          range$1(colspan, function (columnIndex) {
1624            var colIndex = index + columnIndex;
1625            columnsGroup[colIndex] = columnext(column.element, colspan, colIndex);
1626          });
1627          index += colspan;
1628        });
1629        return columnsGroup;
1630      };
1631      var generate$1 = function (list) {
1632        var access = {};
1633        var cells = [];
1634        var tableOpt = head(list).map(function (rowData) {
1635          return rowData.element;
1636        }).bind(table);
1637        var lockedColumns = tableOpt.bind(getLockedColumnsFromTable).getOr({});
1638        var maxRows = 0;
1639        var maxColumns = 0;
1640        var rowCount = 0;
1641        var _a = partition(list, function (rowData) {
1642            return rowData.section === 'colgroup';
1643          }), colgroupRows = _a.pass, rows = _a.fail;
1644        each$2(rows, function (rowData) {
1645          var currentRow = [];
1646          each$2(rowData.cells, function (rowCell) {
1647            var start = 0;
1648            while (access[key(rowCount, start)] !== undefined) {
1649              start++;
1650            }
1651            var isLocked = hasNonNullableKey(lockedColumns, start.toString());
1652            var current = extended(rowCell.element, rowCell.rowspan, rowCell.colspan, rowCount, start, isLocked);
1653            for (var occupiedColumnPosition = 0; occupiedColumnPosition < rowCell.colspan; occupiedColumnPosition++) {
1654              for (var occupiedRowPosition = 0; occupiedRowPosition < rowCell.rowspan; occupiedRowPosition++) {
1655                var rowPosition = rowCount + occupiedRowPosition;
1656                var columnPosition = start + occupiedColumnPosition;
1657                var newpos = key(rowPosition, columnPosition);
1658                access[newpos] = current;
1659                maxColumns = Math.max(maxColumns, columnPosition + 1);
1660              }
1661            }
1662            currentRow.push(current);
1663          });
1664          maxRows++;
1665          cells.push(rowdetail(rowData.element, currentRow, rowData.section));
1666          rowCount++;
1667        });
1668        var _b = last$2(colgroupRows).map(function (rowData) {
1669            var columns = generateColumns(rowData);
1670            var colgroup$1 = colgroup(rowData.element, values(columns));
1671            return {
1672              colgroups: [colgroup$1],
1673              columns: columns
1674            };
1675          }).getOrThunk(function () {
1676            return {
1677              colgroups: [],
1678              columns: {}
1679            };
1680          }), columns = _b.columns, colgroups = _b.colgroups;
1681        var grid$1 = grid(maxRows, maxColumns);
1682        return {
1683          grid: grid$1,
1684          access: access,
1685          all: cells,
1686          columns: columns,
1687          colgroups: colgroups
1688        };
1689      };
1690      var fromTable = function (table) {
1691        var list = fromTable$1(table);
1692        return generate$1(list);
1693      };
1694      var justCells = function (warehouse) {
1695        return bind$2(warehouse.all, function (w) {
1696          return w.cells;
1697        });
1698      };
1699      var justColumns = function (warehouse) {
1700        return values(warehouse.columns);
1701      };
1702      var hasColumns = function (warehouse) {
1703        return keys(warehouse.columns).length > 0;
1704      };
1705      var getColumnAt = function (warehouse, columnIndex) {
1706        return Optional.from(warehouse.columns[columnIndex]);
1707      };
1708      var Warehouse = {
1709        fromTable: fromTable,
1710        generate: generate$1,
1711        getAt: getAt,
1712        findItem: findItem,
1713        filterItems: filterItems,
1714        justCells: justCells,
1715        justColumns: justColumns,
1716        hasColumns: hasColumns,
1717        getColumnAt: getColumnAt
1718      };
1719  
1720      var inSelection = function (bounds, detail) {
1721        var leftEdge = detail.column;
1722        var rightEdge = detail.column + detail.colspan - 1;
1723        var topEdge = detail.row;
1724        var bottomEdge = detail.row + detail.rowspan - 1;
1725        return leftEdge <= bounds.finishCol && rightEdge >= bounds.startCol && (topEdge <= bounds.finishRow && bottomEdge >= bounds.startRow);
1726      };
1727      var isWithin = function (bounds, detail) {
1728        return detail.column >= bounds.startCol && detail.column + detail.colspan - 1 <= bounds.finishCol && detail.row >= bounds.startRow && detail.row + detail.rowspan - 1 <= bounds.finishRow;
1729      };
1730      var isRectangular = function (warehouse, bounds) {
1731        var isRect = true;
1732        var detailIsWithin = curry(isWithin, bounds);
1733        for (var i = bounds.startRow; i <= bounds.finishRow; i++) {
1734          for (var j = bounds.startCol; j <= bounds.finishCol; j++) {
1735            isRect = isRect && Warehouse.getAt(warehouse, i, j).exists(detailIsWithin);
1736          }
1737        }
1738        return isRect ? Optional.some(bounds) : Optional.none();
1739      };
1740  
1741      var getBounds = function (detailA, detailB) {
1742        return bounds(Math.min(detailA.row, detailB.row), Math.min(detailA.column, detailB.column), Math.max(detailA.row + detailA.rowspan - 1, detailB.row + detailB.rowspan - 1), Math.max(detailA.column + detailA.colspan - 1, detailB.column + detailB.colspan - 1));
1743      };
1744      var getAnyBox = function (warehouse, startCell, finishCell) {
1745        var startCoords = Warehouse.findItem(warehouse, startCell, eq$1);
1746        var finishCoords = Warehouse.findItem(warehouse, finishCell, eq$1);
1747        return startCoords.bind(function (sc) {
1748          return finishCoords.map(function (fc) {
1749            return getBounds(sc, fc);
1750          });
1751        });
1752      };
1753      var getBox$1 = function (warehouse, startCell, finishCell) {
1754        return getAnyBox(warehouse, startCell, finishCell).bind(function (bounds) {
1755          return isRectangular(warehouse, bounds);
1756        });
1757      };
1758  
1759      var moveBy$1 = function (warehouse, cell, row, column) {
1760        return Warehouse.findItem(warehouse, cell, eq$1).bind(function (detail) {
1761          var startRow = row > 0 ? detail.row + detail.rowspan - 1 : detail.row;
1762          var startCol = column > 0 ? detail.column + detail.colspan - 1 : detail.column;
1763          var dest = Warehouse.getAt(warehouse, startRow + row, startCol + column);
1764          return dest.map(function (d) {
1765            return d.element;
1766          });
1767        });
1768      };
1769      var intercepts$1 = function (warehouse, start, finish) {
1770        return getAnyBox(warehouse, start, finish).map(function (bounds) {
1771          var inside = Warehouse.filterItems(warehouse, curry(inSelection, bounds));
1772          return map$1(inside, function (detail) {
1773            return detail.element;
1774          });
1775        });
1776      };
1777      var parentCell = function (warehouse, innerCell) {
1778        var isContainedBy = function (c1, c2) {
1779          return contains(c2, c1);
1780        };
1781        return Warehouse.findItem(warehouse, innerCell, isContainedBy).map(function (detail) {
1782          return detail.element;
1783        });
1784      };
1785  
1786      var moveBy = function (cell, deltaRow, deltaColumn) {
1787        return table(cell).bind(function (table) {
1788          var warehouse = getWarehouse(table);
1789          return moveBy$1(warehouse, cell, deltaRow, deltaColumn);
1790        });
1791      };
1792      var intercepts = function (table, first, last) {
1793        var warehouse = getWarehouse(table);
1794        return intercepts$1(warehouse, first, last);
1795      };
1796      var nestedIntercepts = function (table, first, firstTable, last, lastTable) {
1797        var warehouse = getWarehouse(table);
1798        var optStartCell = eq$1(table, firstTable) ? Optional.some(first) : parentCell(warehouse, first);
1799        var optLastCell = eq$1(table, lastTable) ? Optional.some(last) : parentCell(warehouse, last);
1800        return optStartCell.bind(function (startCell) {
1801          return optLastCell.bind(function (lastCell) {
1802            return intercepts$1(warehouse, startCell, lastCell);
1803          });
1804        });
1805      };
1806      var getBox = function (table, first, last) {
1807        var warehouse = getWarehouse(table);
1808        return getBox$1(warehouse, first, last);
1809      };
1810      var getWarehouse = Warehouse.fromTable;
1811  
1812      var before$4 = function (marker, element) {
1813        var parent$1 = parent(marker);
1814        parent$1.each(function (v) {
1815          v.dom.insertBefore(element.dom, marker.dom);
1816        });
1817      };
1818      var after$5 = function (marker, element) {
1819        var sibling = nextSibling(marker);
1820        sibling.fold(function () {
1821          var parent$1 = parent(marker);
1822          parent$1.each(function (v) {
1823            append$1(v, element);
1824          });
1825        }, function (v) {
1826          before$4(v, element);
1827        });
1828      };
1829      var prepend = function (parent, element) {
1830        var firstChild$1 = firstChild(parent);
1831        firstChild$1.fold(function () {
1832          append$1(parent, element);
1833        }, function (v) {
1834          parent.dom.insertBefore(element.dom, v.dom);
1835        });
1836      };
1837      var append$1 = function (parent, element) {
1838        parent.dom.appendChild(element.dom);
1839      };
1840      var appendAt = function (parent, element, index) {
1841        child$3(parent, index).fold(function () {
1842          append$1(parent, element);
1843        }, function (v) {
1844          before$4(v, element);
1845        });
1846      };
1847      var wrap = function (element, wrapper) {
1848        before$4(element, wrapper);
1849        append$1(wrapper, element);
1850      };
1851  
1852      var before$3 = function (marker, elements) {
1853        each$2(elements, function (x) {
1854          before$4(marker, x);
1855        });
1856      };
1857      var after$4 = function (marker, elements) {
1858        each$2(elements, function (x, i) {
1859          var e = i === 0 ? marker : elements[i - 1];
1860          after$5(e, x);
1861        });
1862      };
1863      var append = function (parent, elements) {
1864        each$2(elements, function (x) {
1865          append$1(parent, x);
1866        });
1867      };
1868  
1869      var empty = function (element) {
1870        element.dom.textContent = '';
1871        each$2(children$3(element), function (rogue) {
1872          remove$5(rogue);
1873        });
1874      };
1875      var remove$5 = function (element) {
1876        var dom = element.dom;
1877        if (dom.parentNode !== null) {
1878          dom.parentNode.removeChild(dom);
1879        }
1880      };
1881      var unwrap = function (wrapper) {
1882        var children = children$3(wrapper);
1883        if (children.length > 0) {
1884          before$3(wrapper, children);
1885        }
1886        remove$5(wrapper);
1887      };
1888  
1889      var NodeValue = function (is, name) {
1890        var get = function (element) {
1891          if (!is(element)) {
1892            throw new Error('Can only get ' + name + ' value of a ' + name + ' node');
1893          }
1894          return getOption(element).getOr('');
1895        };
1896        var getOption = function (element) {
1897          return is(element) ? Optional.from(element.dom.nodeValue) : Optional.none();
1898        };
1899        var set = function (element, value) {
1900          if (!is(element)) {
1901            throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');
1902          }
1903          element.dom.nodeValue = value;
1904        };
1905        return {
1906          get: get,
1907          getOption: getOption,
1908          set: set
1909        };
1910      };
1911  
1912      var api$2 = NodeValue(isText, 'text');
1913      var get$9 = function (element) {
1914        return api$2.get(element);
1915      };
1916      var getOption = function (element) {
1917        return api$2.getOption(element);
1918      };
1919      var set = function (element, value) {
1920        return api$2.set(element, value);
1921      };
1922  
1923      var TagBoundaries = [
1924        'body',
1925        'p',
1926        'div',
1927        'article',
1928        'aside',
1929        'figcaption',
1930        'figure',
1931        'footer',
1932        'header',
1933        'nav',
1934        'section',
1935        'ol',
1936        'ul',
1937        'li',
1938        'table',
1939        'thead',
1940        'tbody',
1941        'tfoot',
1942        'caption',
1943        'tr',
1944        'td',
1945        'th',
1946        'h1',
1947        'h2',
1948        'h3',
1949        'h4',
1950        'h5',
1951        'h6',
1952        'blockquote',
1953        'pre',
1954        'address'
1955      ];
1956  
1957      function DomUniverse () {
1958        var clone = function (element) {
1959          return SugarElement.fromDom(element.dom.cloneNode(false));
1960        };
1961        var document = function (element) {
1962          return documentOrOwner(element).dom;
1963        };
1964        var isBoundary = function (element) {
1965          if (!isElement(element)) {
1966            return false;
1967          }
1968          if (name(element) === 'body') {
1969            return true;
1970          }
1971          return contains$2(TagBoundaries, name(element));
1972        };
1973        var isEmptyTag = function (element) {
1974          if (!isElement(element)) {
1975            return false;
1976          }
1977          return contains$2([
1978            'br',
1979            'img',
1980            'hr',
1981            'input'
1982          ], name(element));
1983        };
1984        var isNonEditable = function (element) {
1985          return isElement(element) && get$b(element, 'contenteditable') === 'false';
1986        };
1987        var comparePosition = function (element, other) {
1988          return element.dom.compareDocumentPosition(other.dom);
1989        };
1990        var copyAttributesTo = function (source, destination) {
1991          var as = clone$2(source);
1992          setAll$1(destination, as);
1993        };
1994        var isSpecial = function (element) {
1995          var tag = name(element);
1996          return contains$2([
1997            'script',
1998            'noscript',
1999            'iframe',
2000            'noframes',
2001            'noembed',
2002            'title',
2003            'style',
2004            'textarea',
2005            'xmp'
2006          ], tag);
2007        };
2008        var getLanguage = function (element) {
2009          return isElement(element) ? getOpt(element, 'lang') : Optional.none();
2010        };
2011        return {
2012          up: constant({
2013            selector: ancestor$1,
2014            closest: closest$1,
2015            predicate: ancestor$2,
2016            all: parents
2017          }),
2018          down: constant({
2019            selector: descendants,
2020            predicate: descendants$1
2021          }),
2022          styles: constant({
2023            get: get$a,
2024            getRaw: getRaw$2,
2025            set: set$1,
2026            remove: remove$6
2027          }),
2028          attrs: constant({
2029            get: get$b,
2030            set: set$2,
2031            remove: remove$7,
2032            copyTo: copyAttributesTo
2033          }),
2034          insert: constant({
2035            before: before$4,
2036            after: after$5,
2037            afterAll: after$4,
2038            append: append$1,
2039            appendAll: append,
2040            prepend: prepend,
2041            wrap: wrap
2042          }),
2043          remove: constant({
2044            unwrap: unwrap,
2045            remove: remove$5
2046          }),
2047          create: constant({
2048            nu: SugarElement.fromTag,
2049            clone: clone,
2050            text: SugarElement.fromText
2051          }),
2052          query: constant({
2053            comparePosition: comparePosition,
2054            prevSibling: prevSibling,
2055            nextSibling: nextSibling
2056          }),
2057          property: constant({
2058            children: children$3,
2059            name: name,
2060            parent: parent,
2061            document: document,
2062            isText: isText,
2063            isComment: isComment,
2064            isElement: isElement,
2065            isSpecial: isSpecial,
2066            getLanguage: getLanguage,
2067            getText: get$9,
2068            setText: set,
2069            isBoundary: isBoundary,
2070            isEmptyTag: isEmptyTag,
2071            isNonEditable: isNonEditable
2072          }),
2073          eq: eq$1,
2074          is: is$1
2075        };
2076      }
2077  
2078      var all = function (universe, look, elements, f) {
2079        var head = elements[0];
2080        var tail = elements.slice(1);
2081        return f(universe, look, head, tail);
2082      };
2083      var oneAll = function (universe, look, elements) {
2084        return elements.length > 0 ? all(universe, look, elements, unsafeOne) : Optional.none();
2085      };
2086      var unsafeOne = function (universe, look, head, tail) {
2087        var start = look(universe, head);
2088        return foldr(tail, function (b, a) {
2089          var current = look(universe, a);
2090          return commonElement(universe, b, current);
2091        }, start);
2092      };
2093      var commonElement = function (universe, start, end) {
2094        return start.bind(function (s) {
2095          return end.filter(curry(universe.eq, s));
2096        });
2097      };
2098  
2099      var eq = function (universe, item) {
2100        return curry(universe.eq, item);
2101      };
2102      var ancestors$2 = function (universe, start, end, isRoot) {
2103        if (isRoot === void 0) {
2104          isRoot = never;
2105        }
2106        var ps1 = [start].concat(universe.up().all(start));
2107        var ps2 = [end].concat(universe.up().all(end));
2108        var prune = function (path) {
2109          var index = findIndex(path, isRoot);
2110          return index.fold(function () {
2111            return path;
2112          }, function (ind) {
2113            return path.slice(0, ind + 1);
2114          });
2115        };
2116        var pruned1 = prune(ps1);
2117        var pruned2 = prune(ps2);
2118        var shared = find$1(pruned1, function (x) {
2119          return exists(pruned2, eq(universe, x));
2120        });
2121        return {
2122          firstpath: pruned1,
2123          secondpath: pruned2,
2124          shared: shared
2125        };
2126      };
2127  
2128      var sharedOne$1 = oneAll;
2129      var ancestors$1 = ancestors$2;
2130  
2131      var universe$3 = DomUniverse();
2132      var sharedOne = function (look, elements) {
2133        return sharedOne$1(universe$3, function (_universe, element) {
2134          return look(element);
2135        }, elements);
2136      };
2137      var ancestors = function (start, finish, isRoot) {
2138        return ancestors$1(universe$3, start, finish, isRoot);
2139      };
2140  
2141      var lookupTable = function (container) {
2142        return ancestor$1(container, 'table');
2143      };
2144      var identify = function (start, finish, isRoot) {
2145        var getIsRoot = function (rootTable) {
2146          return function (element) {
2147            return isRoot !== undefined && isRoot(element) || eq$1(element, rootTable);
2148          };
2149        };
2150        if (eq$1(start, finish)) {
2151          return Optional.some({
2152            boxes: Optional.some([start]),
2153            start: start,
2154            finish: finish
2155          });
2156        } else {
2157          return lookupTable(start).bind(function (startTable) {
2158            return lookupTable(finish).bind(function (finishTable) {
2159              if (eq$1(startTable, finishTable)) {
2160                return Optional.some({
2161                  boxes: intercepts(startTable, start, finish),
2162                  start: start,
2163                  finish: finish
2164                });
2165              } else if (contains(startTable, finishTable)) {
2166                var ancestorCells = ancestors$3(finish, 'td,th', getIsRoot(startTable));
2167                var finishCell = ancestorCells.length > 0 ? ancestorCells[ancestorCells.length - 1] : finish;
2168                return Optional.some({
2169                  boxes: nestedIntercepts(startTable, start, startTable, finish, finishTable),
2170                  start: start,
2171                  finish: finishCell
2172                });
2173              } else if (contains(finishTable, startTable)) {
2174                var ancestorCells = ancestors$3(start, 'td,th', getIsRoot(finishTable));
2175                var startCell = ancestorCells.length > 0 ? ancestorCells[ancestorCells.length - 1] : start;
2176                return Optional.some({
2177                  boxes: nestedIntercepts(finishTable, start, startTable, finish, finishTable),
2178                  start: start,
2179                  finish: startCell
2180                });
2181              } else {
2182                return ancestors(start, finish).shared.bind(function (lca) {
2183                  return closest$1(lca, 'table', isRoot).bind(function (lcaTable) {
2184                    var finishAncestorCells = ancestors$3(finish, 'td,th', getIsRoot(lcaTable));
2185                    var finishCell = finishAncestorCells.length > 0 ? finishAncestorCells[finishAncestorCells.length - 1] : finish;
2186                    var startAncestorCells = ancestors$3(start, 'td,th', getIsRoot(lcaTable));
2187                    var startCell = startAncestorCells.length > 0 ? startAncestorCells[startAncestorCells.length - 1] : start;
2188                    return Optional.some({
2189                      boxes: nestedIntercepts(lcaTable, start, startTable, finish, finishTable),
2190                      start: startCell,
2191                      finish: finishCell
2192                    });
2193                  });
2194                });
2195              }
2196            });
2197          });
2198        }
2199      };
2200      var retrieve$1 = function (container, selector) {
2201        var sels = descendants(container, selector);
2202        return sels.length > 0 ? Optional.some(sels) : Optional.none();
2203      };
2204      var getLast = function (boxes, lastSelectedSelector) {
2205        return find$1(boxes, function (box) {
2206          return is$2(box, lastSelectedSelector);
2207        });
2208      };
2209      var getEdges = function (container, firstSelectedSelector, lastSelectedSelector) {
2210        return descendant(container, firstSelectedSelector).bind(function (first) {
2211          return descendant(container, lastSelectedSelector).bind(function (last) {
2212            return sharedOne(lookupTable, [
2213              first,
2214              last
2215            ]).map(function (table) {
2216              return {
2217                first: first,
2218                last: last,
2219                table: table
2220              };
2221            });
2222          });
2223        });
2224      };
2225      var expandTo = function (finish, firstSelectedSelector) {
2226        return ancestor$1(finish, 'table').bind(function (table) {
2227          return descendant(table, firstSelectedSelector).bind(function (start) {
2228            return identify(start, finish).bind(function (identified) {
2229              return identified.boxes.map(function (boxes) {
2230                return {
2231                  boxes: boxes,
2232                  start: identified.start,
2233                  finish: identified.finish
2234                };
2235              });
2236            });
2237          });
2238        });
2239      };
2240      var shiftSelection = function (boxes, deltaRow, deltaColumn, firstSelectedSelector, lastSelectedSelector) {
2241        return getLast(boxes, lastSelectedSelector).bind(function (last) {
2242          return moveBy(last, deltaRow, deltaColumn).bind(function (finish) {
2243            return expandTo(finish, firstSelectedSelector);
2244          });
2245        });
2246      };
2247  
2248      var retrieve = function (container, selector) {
2249        return retrieve$1(container, selector);
2250      };
2251      var retrieveBox = function (container, firstSelectedSelector, lastSelectedSelector) {
2252        return getEdges(container, firstSelectedSelector, lastSelectedSelector).bind(function (edges) {
2253          var isRoot = function (ancestor) {
2254            return eq$1(container, ancestor);
2255          };
2256          var sectionSelector = 'thead,tfoot,tbody,table';
2257          var firstAncestor = ancestor$1(edges.first, sectionSelector, isRoot);
2258          var lastAncestor = ancestor$1(edges.last, sectionSelector, isRoot);
2259          return firstAncestor.bind(function (fA) {
2260            return lastAncestor.bind(function (lA) {
2261              return eq$1(fA, lA) ? getBox(edges.table, edges.first, edges.last) : Optional.none();
2262            });
2263          });
2264        });
2265      };
2266  
2267      var generate = function (cases) {
2268        if (!isArray(cases)) {
2269          throw new Error('cases must be an array');
2270        }
2271        if (cases.length === 0) {
2272          throw new Error('there must be at least one case');
2273        }
2274        var constructors = [];
2275        var adt = {};
2276        each$2(cases, function (acase, count) {
2277          var keys$1 = keys(acase);
2278          if (keys$1.length !== 1) {
2279            throw new Error('one and only one name per case');
2280          }
2281          var key = keys$1[0];
2282          var value = acase[key];
2283          if (adt[key] !== undefined) {
2284            throw new Error('duplicate key detected:' + key);
2285          } else if (key === 'cata') {
2286            throw new Error('cannot have a case named cata (sorry)');
2287          } else if (!isArray(value)) {
2288            throw new Error('case arguments must be an array');
2289          }
2290          constructors.push(key);
2291          adt[key] = function () {
2292            var args = [];
2293            for (var _i = 0; _i < arguments.length; _i++) {
2294              args[_i] = arguments[_i];
2295            }
2296            var argLength = args.length;
2297            if (argLength !== value.length) {
2298              throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);
2299            }
2300            var match = function (branches) {
2301              var branchKeys = keys(branches);
2302              if (constructors.length !== branchKeys.length) {
2303                throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(','));
2304              }
2305              var allReqd = forall(constructors, function (reqKey) {
2306                return contains$2(branchKeys, reqKey);
2307              });
2308              if (!allReqd) {
2309                throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', '));
2310              }
2311              return branches[key].apply(null, args);
2312            };
2313            return {
2314              fold: function () {
2315                var foldArgs = [];
2316                for (var _i = 0; _i < arguments.length; _i++) {
2317                  foldArgs[_i] = arguments[_i];
2318                }
2319                if (foldArgs.length !== cases.length) {
2320                  throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + foldArgs.length);
2321                }
2322                var target = foldArgs[count];
2323                return target.apply(null, args);
2324              },
2325              match: match,
2326              log: function (label) {
2327                console.log(label, {
2328                  constructors: constructors,
2329                  constructor: key,
2330                  params: args
2331                });
2332              }
2333            };
2334          };
2335        });
2336        return adt;
2337      };
2338      var Adt = { generate: generate };
2339  
2340      var type = Adt.generate([
2341        { none: [] },
2342        { multiple: ['elements'] },
2343        { single: ['element'] }
2344      ]);
2345      var cata$2 = function (subject, onNone, onMultiple, onSingle) {
2346        return subject.fold(onNone, onMultiple, onSingle);
2347      };
2348      var none$1 = type.none;
2349      var multiple = type.multiple;
2350      var single = type.single;
2351  
2352      var Selections = function (lazyRoot, getStart, selectedSelector) {
2353        var get = function () {
2354          return retrieve(lazyRoot(), selectedSelector).fold(function () {
2355            return getStart().fold(none$1, single);
2356          }, function (cells) {
2357            return multiple(cells);
2358          });
2359        };
2360        return { get: get };
2361      };
2362  
2363      var global$3 = tinymce.util.Tools.resolve('tinymce.PluginManager');
2364  
2365      var clone = function (original, isDeep) {
2366        return SugarElement.fromDom(original.dom.cloneNode(isDeep));
2367      };
2368      var shallow = function (original) {
2369        return clone(original, false);
2370      };
2371      var deep = function (original) {
2372        return clone(original, true);
2373      };
2374      var shallowAs = function (original, tag) {
2375        var nu = SugarElement.fromTag(tag);
2376        var attributes = clone$2(original);
2377        setAll$1(nu, attributes);
2378        return nu;
2379      };
2380      var copy$1 = function (original, tag) {
2381        var nu = shallowAs(original, tag);
2382        var cloneChildren = children$3(deep(original));
2383        append(nu, cloneChildren);
2384        return nu;
2385      };
2386      var mutate$1 = function (original, tag) {
2387        var nu = shallowAs(original, tag);
2388        before$4(original, nu);
2389        var children = children$3(original);
2390        append(nu, children);
2391        remove$5(original);
2392        return nu;
2393      };
2394  
2395      var Dimension = function (name, getOffset) {
2396        var set = function (element, h) {
2397          if (!isNumber(h) && !h.match(/^[0-9]+$/)) {
2398            throw new Error(name + '.set accepts only positive integer values. Value was ' + h);
2399          }
2400          var dom = element.dom;
2401          if (isSupported(dom)) {
2402            dom.style[name] = h + 'px';
2403          }
2404        };
2405        var get = function (element) {
2406          var r = getOffset(element);
2407          if (r <= 0 || r === null) {
2408            var css = get$a(element, name);
2409            return parseFloat(css) || 0;
2410          }
2411          return r;
2412        };
2413        var getOuter = get;
2414        var aggregate = function (element, properties) {
2415          return foldl(properties, function (acc, property) {
2416            var val = get$a(element, property);
2417            var value = val === undefined ? 0 : parseInt(val, 10);
2418            return isNaN(value) ? acc : acc + value;
2419          }, 0);
2420        };
2421        var max = function (element, value, properties) {
2422          var cumulativeInclusions = aggregate(element, properties);
2423          var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;
2424          return absoluteMax;
2425        };
2426        return {
2427          set: set,
2428          get: get,
2429          getOuter: getOuter,
2430          aggregate: aggregate,
2431          max: max
2432        };
2433      };
2434  
2435      var needManualCalc = function () {
2436        var browser = detect$3().browser;
2437        return browser.isIE() || browser.isEdge();
2438      };
2439      var toNumber = function (px, fallback) {
2440        return toFloat(px).getOr(fallback);
2441      };
2442      var getProp = function (element, name, fallback) {
2443        return toNumber(get$a(element, name), fallback);
2444      };
2445      var getBoxSizing = function (element) {
2446        return get$a(element, 'box-sizing');
2447      };
2448      var calcContentBoxSize = function (element, size, upper, lower) {
2449        var paddingUpper = getProp(element, 'padding-' + upper, 0);
2450        var paddingLower = getProp(element, 'padding-' + lower, 0);
2451        var borderUpper = getProp(element, 'border-' + upper + '-width', 0);
2452        var borderLower = getProp(element, 'border-' + lower + '-width', 0);
2453        return size - paddingUpper - paddingLower - borderUpper - borderLower;
2454      };
2455      var getCalculatedHeight = function (element, boxSizing) {
2456        var dom = element.dom;
2457        var height = dom.getBoundingClientRect().height || dom.offsetHeight;
2458        return boxSizing === 'border-box' ? height : calcContentBoxSize(element, height, 'top', 'bottom');
2459      };
2460      var getCalculatedWidth = function (element, boxSizing) {
2461        var dom = element.dom;
2462        var width = dom.getBoundingClientRect().width || dom.offsetWidth;
2463        return boxSizing === 'border-box' ? width : calcContentBoxSize(element, width, 'left', 'right');
2464      };
2465      var getHeight$1 = function (element) {
2466        return needManualCalc() ? getCalculatedHeight(element, getBoxSizing(element)) : getProp(element, 'height', element.dom.offsetHeight);
2467      };
2468      var getWidth = function (element) {
2469        return needManualCalc() ? getCalculatedWidth(element, getBoxSizing(element)) : getProp(element, 'width', element.dom.offsetWidth);
2470      };
2471      var getInnerWidth = function (element) {
2472        return getCalculatedWidth(element, 'content-box');
2473      };
2474  
2475      var api$1 = Dimension('width', function (element) {
2476        return element.dom.offsetWidth;
2477      });
2478      var get$8 = function (element) {
2479        return api$1.get(element);
2480      };
2481      var getOuter$2 = function (element) {
2482        return api$1.getOuter(element);
2483      };
2484      var getInner = getInnerWidth;
2485      var getRuntime$1 = getWidth;
2486  
2487      var columns = function (warehouse, isValidCell) {
2488        if (isValidCell === void 0) {
2489          isValidCell = always;
2490        }
2491        var grid = warehouse.grid;
2492        var cols = range$1(grid.columns, identity);
2493        var rowsArr = range$1(grid.rows, identity);
2494        return map$1(cols, function (col) {
2495          var getBlock = function () {
2496            return bind$2(rowsArr, function (r) {
2497              return Warehouse.getAt(warehouse, r, col).filter(function (detail) {
2498                return detail.column === col;
2499              }).toArray();
2500            });
2501          };
2502          var isValid = function (detail) {
2503            return detail.colspan === 1 && isValidCell(detail.element);
2504          };
2505          var getFallback = function () {
2506            return Warehouse.getAt(warehouse, 0, col);
2507          };
2508          return decide(getBlock, isValid, getFallback);
2509        });
2510      };
2511      var decide = function (getBlock, isValid, getFallback) {
2512        var inBlock = getBlock();
2513        var validInBlock = find$1(inBlock, isValid);
2514        var detailOption = validInBlock.orThunk(function () {
2515          return Optional.from(inBlock[0]).orThunk(getFallback);
2516        });
2517        return detailOption.map(function (detail) {
2518          return detail.element;
2519        });
2520      };
2521      var rows = function (warehouse) {
2522        var grid = warehouse.grid;
2523        var rowsArr = range$1(grid.rows, identity);
2524        var cols = range$1(grid.columns, identity);
2525        return map$1(rowsArr, function (row) {
2526          var getBlock = function () {
2527            return bind$2(cols, function (c) {
2528              return Warehouse.getAt(warehouse, row, c).filter(function (detail) {
2529                return detail.row === row;
2530              }).fold(constant([]), function (detail) {
2531                return [detail];
2532              });
2533            });
2534          };
2535          var isSingle = function (detail) {
2536            return detail.rowspan === 1;
2537          };
2538          var getFallback = function () {
2539            return Warehouse.getAt(warehouse, row, 0);
2540          };
2541          return decide(getBlock, isSingle, getFallback);
2542        });
2543      };
2544  
2545      var deduce = function (xs, index) {
2546        if (index < 0 || index >= xs.length - 1) {
2547          return Optional.none();
2548        }
2549        var current = xs[index].fold(function () {
2550          var rest = reverse(xs.slice(0, index));
2551          return findMap(rest, function (a, i) {
2552            return a.map(function (aa) {
2553              return {
2554                value: aa,
2555                delta: i + 1
2556              };
2557            });
2558          });
2559        }, function (c) {
2560          return Optional.some({
2561            value: c,
2562            delta: 0
2563          });
2564        });
2565        var next = xs[index + 1].fold(function () {
2566          var rest = xs.slice(index + 1);
2567          return findMap(rest, function (a, i) {
2568            return a.map(function (aa) {
2569              return {
2570                value: aa,
2571                delta: i + 1
2572              };
2573            });
2574          });
2575        }, function (n) {
2576          return Optional.some({
2577            value: n,
2578            delta: 1
2579          });
2580        });
2581        return current.bind(function (c) {
2582          return next.map(function (n) {
2583            var extras = n.delta + c.delta;
2584            return Math.abs(n.value - c.value) / extras;
2585          });
2586        });
2587      };
2588  
2589      var onDirection = function (isLtr, isRtl) {
2590        return function (element) {
2591          return getDirection(element) === 'rtl' ? isRtl : isLtr;
2592        };
2593      };
2594      var getDirection = function (element) {
2595        return get$a(element, 'direction') === 'rtl' ? 'rtl' : 'ltr';
2596      };
2597  
2598      var api = Dimension('height', function (element) {
2599        var dom = element.dom;
2600        return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;
2601      });
2602      var get$7 = function (element) {
2603        return api.get(element);
2604      };
2605      var getOuter$1 = function (element) {
2606        return api.getOuter(element);
2607      };
2608      var getRuntime = getHeight$1;
2609  
2610      var r = function (left, top) {
2611        var translate = function (x, y) {
2612          return r(left + x, top + y);
2613        };
2614        return {
2615          left: left,
2616          top: top,
2617          translate: translate
2618        };
2619      };
2620      var SugarPosition = r;
2621  
2622      var boxPosition = function (dom) {
2623        var box = dom.getBoundingClientRect();
2624        return SugarPosition(box.left, box.top);
2625      };
2626      var firstDefinedOrZero = function (a, b) {
2627        if (a !== undefined) {
2628          return a;
2629        } else {
2630          return b !== undefined ? b : 0;
2631        }
2632      };
2633      var absolute = function (element) {
2634        var doc = element.dom.ownerDocument;
2635        var body = doc.body;
2636        var win = doc.defaultView;
2637        var html = doc.documentElement;
2638        if (body === element.dom) {
2639          return SugarPosition(body.offsetLeft, body.offsetTop);
2640        }
2641        var scrollTop = firstDefinedOrZero(win === null || win === void 0 ? void 0 : win.pageYOffset, html.scrollTop);
2642        var scrollLeft = firstDefinedOrZero(win === null || win === void 0 ? void 0 : win.pageXOffset, html.scrollLeft);
2643        var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);
2644        var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);
2645        return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);
2646      };
2647      var viewport = function (element) {
2648        var dom = element.dom;
2649        var doc = dom.ownerDocument;
2650        var body = doc.body;
2651        if (body === dom) {
2652          return SugarPosition(body.offsetLeft, body.offsetTop);
2653        }
2654        if (!inBody(element)) {
2655          return SugarPosition(0, 0);
2656        }
2657        return boxPosition(dom);
2658      };
2659  
2660      var rowInfo = function (row, y) {
2661        return {
2662          row: row,
2663          y: y
2664        };
2665      };
2666      var colInfo = function (col, x) {
2667        return {
2668          col: col,
2669          x: x
2670        };
2671      };
2672      var rtlEdge = function (cell) {
2673        var pos = absolute(cell);
2674        return pos.left + getOuter$2(cell);
2675      };
2676      var ltrEdge = function (cell) {
2677        return absolute(cell).left;
2678      };
2679      var getLeftEdge = function (index, cell) {
2680        return colInfo(index, ltrEdge(cell));
2681      };
2682      var getRightEdge = function (index, cell) {
2683        return colInfo(index, rtlEdge(cell));
2684      };
2685      var getTop$1 = function (cell) {
2686        return absolute(cell).top;
2687      };
2688      var getTopEdge = function (index, cell) {
2689        return rowInfo(index, getTop$1(cell));
2690      };
2691      var getBottomEdge = function (index, cell) {
2692        return rowInfo(index, getTop$1(cell) + getOuter$1(cell));
2693      };
2694      var findPositions = function (getInnerEdge, getOuterEdge, array) {
2695        if (array.length === 0) {
2696          return [];
2697        }
2698        var lines = map$1(array.slice(1), function (cellOption, index) {
2699          return cellOption.map(function (cell) {
2700            return getInnerEdge(index, cell);
2701          });
2702        });
2703        var lastLine = array[array.length - 1].map(function (cell) {
2704          return getOuterEdge(array.length - 1, cell);
2705        });
2706        return lines.concat([lastLine]);
2707      };
2708      var negate = function (step) {
2709        return -step;
2710      };
2711      var height = {
2712        delta: identity,
2713        positions: function (optElements) {
2714          return findPositions(getTopEdge, getBottomEdge, optElements);
2715        },
2716        edge: getTop$1
2717      };
2718      var ltr$1 = {
2719        delta: identity,
2720        edge: ltrEdge,
2721        positions: function (optElements) {
2722          return findPositions(getLeftEdge, getRightEdge, optElements);
2723        }
2724      };
2725      var rtl$1 = {
2726        delta: negate,
2727        edge: rtlEdge,
2728        positions: function (optElements) {
2729          return findPositions(getRightEdge, getLeftEdge, optElements);
2730        }
2731      };
2732      var detect$2 = onDirection(ltr$1, rtl$1);
2733      var width = {
2734        delta: function (amount, table) {
2735          return detect$2(table).delta(amount, table);
2736        },
2737        positions: function (cols, table) {
2738          return detect$2(table).positions(cols, table);
2739        },
2740        edge: function (cell) {
2741          return detect$2(cell).edge(cell);
2742        }
2743      };
2744  
2745      var units = {
2746        unsupportedLength: [
2747          'em',
2748          'ex',
2749          'cap',
2750          'ch',
2751          'ic',
2752          'rem',
2753          'lh',
2754          'rlh',
2755          'vw',
2756          'vh',
2757          'vi',
2758          'vb',
2759          'vmin',
2760          'vmax',
2761          'cm',
2762          'mm',
2763          'Q',
2764          'in',
2765          'pc',
2766          'pt',
2767          'px'
2768        ],
2769        fixed: [
2770          'px',
2771          'pt'
2772        ],
2773        relative: ['%'],
2774        empty: ['']
2775      };
2776      var pattern = function () {
2777        var decimalDigits = '[0-9]+';
2778        var signedInteger = '[+-]?' + decimalDigits;
2779        var exponentPart = '[eE]' + signedInteger;
2780        var dot = '\\.';
2781        var opt = function (input) {
2782          return '(?:' + input + ')?';
2783        };
2784        var unsignedDecimalLiteral = [
2785          'Infinity',
2786          decimalDigits + dot + opt(decimalDigits) + opt(exponentPart),
2787          dot + decimalDigits + opt(exponentPart),
2788          decimalDigits + opt(exponentPart)
2789        ].join('|');
2790        var float = '[+-]?(?:' + unsignedDecimalLiteral + ')';
2791        return new RegExp('^(' + float + ')(.*)$');
2792      }();
2793      var isUnit = function (unit, accepted) {
2794        return exists(accepted, function (acc) {
2795          return exists(units[acc], function (check) {
2796            return unit === check;
2797          });
2798        });
2799      };
2800      var parse = function (input, accepted) {
2801        var match = Optional.from(pattern.exec(input));
2802        return match.bind(function (array) {
2803          var value = Number(array[1]);
2804          var unitRaw = array[2];
2805          if (isUnit(unitRaw, accepted)) {
2806            return Optional.some({
2807              value: value,
2808              unit: unitRaw
2809            });
2810          } else {
2811            return Optional.none();
2812          }
2813        });
2814      };
2815  
2816      var rPercentageBasedSizeRegex = /(\d+(\.\d+)?)%/;
2817      var rPixelBasedSizeRegex = /(\d+(\.\d+)?)px|em/;
2818      var isCol$2 = isTag('col');
2819      var getPercentSize = function (elm, outerGetter, innerGetter) {
2820        var relativeParent = parentElement(elm).getOrThunk(function () {
2821          return getBody$1(owner(elm));
2822        });
2823        return outerGetter(elm) / innerGetter(relativeParent) * 100;
2824      };
2825      var setPixelWidth = function (cell, amount) {
2826        set$1(cell, 'width', amount + 'px');
2827      };
2828      var setPercentageWidth = function (cell, amount) {
2829        set$1(cell, 'width', amount + '%');
2830      };
2831      var setHeight = function (cell, amount) {
2832        set$1(cell, 'height', amount + 'px');
2833      };
2834      var getHeightValue = function (cell) {
2835        return getRuntime(cell) + 'px';
2836      };
2837      var convert = function (cell, number, getter, setter) {
2838        var newSize = table(cell).map(function (table) {
2839          var total = getter(table);
2840          return Math.floor(number / 100 * total);
2841        }).getOr(number);
2842        setter(cell, newSize);
2843        return newSize;
2844      };
2845      var normalizePixelSize = function (value, cell, getter, setter) {
2846        var number = parseFloat(value);
2847        return endsWith(value, '%') && name(cell) !== 'table' ? convert(cell, number, getter, setter) : number;
2848      };
2849      var getTotalHeight = function (cell) {
2850        var value = getHeightValue(cell);
2851        if (!value) {
2852          return get$7(cell);
2853        }
2854        return normalizePixelSize(value, cell, get$7, setHeight);
2855      };
2856      var get$6 = function (cell, type, f) {
2857        var v = f(cell);
2858        var span = getSpan(cell, type);
2859        return v / span;
2860      };
2861      var getRaw$1 = function (element, prop) {
2862        return getRaw$2(element, prop).orThunk(function () {
2863          return getOpt(element, prop).map(function (val) {
2864            return val + 'px';
2865          });
2866        });
2867      };
2868      var getRawWidth$1 = function (element) {
2869        return getRaw$1(element, 'width');
2870      };
2871      var getRawHeight = function (element) {
2872        return getRaw$1(element, 'height');
2873      };
2874      var getPercentageWidth = function (cell) {
2875        return getPercentSize(cell, get$8, getInner);
2876      };
2877      var getPixelWidth$1 = function (cell) {
2878        return isCol$2(cell) ? get$8(cell) : getRuntime$1(cell);
2879      };
2880      var getHeight = function (cell) {
2881        return get$6(cell, 'rowspan', getTotalHeight);
2882      };
2883      var getGenericWidth = function (cell) {
2884        var width = getRawWidth$1(cell);
2885        return width.bind(function (w) {
2886          return parse(w, [
2887            'fixed',
2888            'relative',
2889            'empty'
2890          ]);
2891        });
2892      };
2893      var setGenericWidth = function (cell, amount, unit) {
2894        set$1(cell, 'width', amount + unit);
2895      };
2896      var getPixelTableWidth = function (table) {
2897        return get$8(table) + 'px';
2898      };
2899      var getPercentTableWidth = function (table) {
2900        return getPercentSize(table, get$8, getInner) + '%';
2901      };
2902      var isPercentSizing$1 = function (table) {
2903        return getRawWidth$1(table).exists(function (size) {
2904          return rPercentageBasedSizeRegex.test(size);
2905        });
2906      };
2907      var isPixelSizing$1 = function (table) {
2908        return getRawWidth$1(table).exists(function (size) {
2909          return rPixelBasedSizeRegex.test(size);
2910        });
2911      };
2912      var isNoneSizing$1 = function (table) {
2913        return getRawWidth$1(table).isNone();
2914      };
2915      var percentageBasedSizeRegex = constant(rPercentageBasedSizeRegex);
2916  
2917      var isCol$1 = isTag('col');
2918      var getRawW = function (cell) {
2919        return getRawWidth$1(cell).getOrThunk(function () {
2920          return getPixelWidth$1(cell) + 'px';
2921        });
2922      };
2923      var getRawH = function (cell) {
2924        return getRawHeight(cell).getOrThunk(function () {
2925          return getHeight(cell) + 'px';
2926        });
2927      };
2928      var justCols = function (warehouse) {
2929        return map$1(Warehouse.justColumns(warehouse), function (column) {
2930          return Optional.from(column.element);
2931        });
2932      };
2933      var isValidColumn = function (cell) {
2934        var browser = detect$3().browser;
2935        var supportsColWidths = browser.isChrome() || browser.isFirefox();
2936        return isCol$1(cell) ? supportsColWidths : true;
2937      };
2938      var getDimension = function (cellOpt, index, backups, filter, getter, fallback) {
2939        return cellOpt.filter(filter).fold(function () {
2940          return fallback(deduce(backups, index));
2941        }, function (cell) {
2942          return getter(cell);
2943        });
2944      };
2945      var getWidthFrom = function (warehouse, table, getWidth, fallback) {
2946        var columnCells = columns(warehouse);
2947        var columns$1 = Warehouse.hasColumns(warehouse) ? justCols(warehouse) : columnCells;
2948        var backups = [Optional.some(width.edge(table))].concat(map$1(width.positions(columnCells, table), function (pos) {
2949          return pos.map(function (p) {
2950            return p.x;
2951          });
2952        }));
2953        var colFilter = not(hasColspan);
2954        return map$1(columns$1, function (cellOption, c) {
2955          return getDimension(cellOption, c, backups, colFilter, function (column) {
2956            if (isValidColumn(column)) {
2957              return getWidth(column);
2958            } else {
2959              var cell = bindFrom(columnCells[c], identity);
2960              return getDimension(cell, c, backups, colFilter, function (cell) {
2961                return fallback(Optional.some(get$8(cell)));
2962              }, fallback);
2963            }
2964          }, fallback);
2965        });
2966      };
2967      var getDeduced = function (deduced) {
2968        return deduced.map(function (d) {
2969          return d + 'px';
2970        }).getOr('');
2971      };
2972      var getRawWidths = function (warehouse, table) {
2973        return getWidthFrom(warehouse, table, getRawW, getDeduced);
2974      };
2975      var getPercentageWidths = function (warehouse, table, tableSize) {
2976        return getWidthFrom(warehouse, table, getPercentageWidth, function (deduced) {
2977          return deduced.fold(function () {
2978            return tableSize.minCellWidth();
2979          }, function (cellWidth) {
2980            return cellWidth / tableSize.pixelWidth() * 100;
2981          });
2982        });
2983      };
2984      var getPixelWidths = function (warehouse, table, tableSize) {
2985        return getWidthFrom(warehouse, table, getPixelWidth$1, function (deduced) {
2986          return deduced.getOrThunk(tableSize.minCellWidth);
2987        });
2988      };
2989      var getHeightFrom = function (warehouse, table, direction, getHeight, fallback) {
2990        var rows$1 = rows(warehouse);
2991        var backups = [Optional.some(direction.edge(table))].concat(map$1(direction.positions(rows$1, table), function (pos) {
2992          return pos.map(function (p) {
2993            return p.y;
2994          });
2995        }));
2996        return map$1(rows$1, function (cellOption, c) {
2997          return getDimension(cellOption, c, backups, not(hasRowspan), getHeight, fallback);
2998        });
2999      };
3000      var getPixelHeights = function (warehouse, table, direction) {
3001        return getHeightFrom(warehouse, table, direction, getHeight, function (deduced) {
3002          return deduced.getOrThunk(minHeight);
3003        });
3004      };
3005      var getRawHeights = function (warehouse, table, direction) {
3006        return getHeightFrom(warehouse, table, direction, getRawH, getDeduced);
3007      };
3008  
3009      var widthLookup = function (table, getter) {
3010        return function () {
3011          if (inBody(table)) {
3012            return getter(table);
3013          } else {
3014            return parseFloat(getRaw$2(table, 'width').getOr('0'));
3015          }
3016        };
3017      };
3018      var noneSize = function (table) {
3019        var getWidth = widthLookup(table, get$8);
3020        var zero = constant(0);
3021        var getWidths = function (warehouse, tableSize) {
3022          return getPixelWidths(warehouse, table, tableSize);
3023        };
3024        return {
3025          width: getWidth,
3026          pixelWidth: getWidth,
3027          getWidths: getWidths,
3028          getCellDelta: zero,
3029          singleColumnWidth: constant([0]),
3030          minCellWidth: zero,
3031          setElementWidth: noop,
3032          adjustTableWidth: noop,
3033          isRelative: true,
3034          label: 'none'
3035        };
3036      };
3037      var percentageSize = function (table) {
3038        var getFloatWidth = widthLookup(table, function (elem) {
3039          return parseFloat(getPercentTableWidth(elem));
3040        });
3041        var getWidth = widthLookup(table, get$8);
3042        var getCellDelta = function (delta) {
3043          return delta / getWidth() * 100;
3044        };
3045        var singleColumnWidth = function (w, _delta) {
3046          return [100 - w];
3047        };
3048        var minCellWidth = function () {
3049          return minWidth() / getWidth() * 100;
3050        };
3051        var adjustTableWidth = function (delta) {
3052          var currentWidth = getFloatWidth();
3053          var change = delta / 100 * currentWidth;
3054          var newWidth = currentWidth + change;
3055          setPercentageWidth(table, newWidth);
3056        };
3057        var getWidths = function (warehouse, tableSize) {
3058          return getPercentageWidths(warehouse, table, tableSize);
3059        };
3060        return {
3061          width: getFloatWidth,
3062          pixelWidth: getWidth,
3063          getWidths: getWidths,
3064          getCellDelta: getCellDelta,
3065          singleColumnWidth: singleColumnWidth,
3066          minCellWidth: minCellWidth,
3067          setElementWidth: setPercentageWidth,
3068          adjustTableWidth: adjustTableWidth,
3069          isRelative: true,
3070          label: 'percent'
3071        };
3072      };
3073      var pixelSize = function (table) {
3074        var getWidth = widthLookup(table, get$8);
3075        var getCellDelta = identity;
3076        var singleColumnWidth = function (w, delta) {
3077          var newNext = Math.max(minWidth(), w + delta);
3078          return [newNext - w];
3079        };
3080        var adjustTableWidth = function (delta) {
3081          var newWidth = getWidth() + delta;
3082          setPixelWidth(table, newWidth);
3083        };
3084        var getWidths = function (warehouse, tableSize) {
3085          return getPixelWidths(warehouse, table, tableSize);
3086        };
3087        return {
3088          width: getWidth,
3089          pixelWidth: getWidth,
3090          getWidths: getWidths,
3091          getCellDelta: getCellDelta,
3092          singleColumnWidth: singleColumnWidth,
3093          minCellWidth: minWidth,
3094          setElementWidth: setPixelWidth,
3095          adjustTableWidth: adjustTableWidth,
3096          isRelative: false,
3097          label: 'pixel'
3098        };
3099      };
3100      var chooseSize = function (element, width) {
3101        var percentMatch = percentageBasedSizeRegex().exec(width);
3102        if (percentMatch !== null) {
3103          return percentageSize(element);
3104        } else {
3105          return pixelSize(element);
3106        }
3107      };
3108      var getTableSize = function (table) {
3109        var width = getRawWidth$1(table);
3110        return width.fold(function () {
3111          return noneSize(table);
3112        }, function (w) {
3113          return chooseSize(table, w);
3114        });
3115      };
3116      var TableSize = {
3117        getTableSize: getTableSize,
3118        pixelSize: pixelSize,
3119        percentageSize: percentageSize,
3120        noneSize: noneSize
3121      };
3122  
3123      var statsStruct = function (minRow, minCol, maxRow, maxCol, allCells, selectedCells) {
3124        return {
3125          minRow: minRow,
3126          minCol: minCol,
3127          maxRow: maxRow,
3128          maxCol: maxCol,
3129          allCells: allCells,
3130          selectedCells: selectedCells
3131        };
3132      };
3133      var findSelectedStats = function (house, isSelected) {
3134        var totalColumns = house.grid.columns;
3135        var totalRows = house.grid.rows;
3136        var minRow = totalRows;
3137        var minCol = totalColumns;
3138        var maxRow = 0;
3139        var maxCol = 0;
3140        var allCells = [];
3141        var selectedCells = [];
3142        each$1(house.access, function (detail) {
3143          allCells.push(detail);
3144          if (isSelected(detail)) {
3145            selectedCells.push(detail);
3146            var startRow = detail.row;
3147            var endRow = startRow + detail.rowspan - 1;
3148            var startCol = detail.column;
3149            var endCol = startCol + detail.colspan - 1;
3150            if (startRow < minRow) {
3151              minRow = startRow;
3152            } else if (endRow > maxRow) {
3153              maxRow = endRow;
3154            }
3155            if (startCol < minCol) {
3156              minCol = startCol;
3157            } else if (endCol > maxCol) {
3158              maxCol = endCol;
3159            }
3160          }
3161        });
3162        return statsStruct(minRow, minCol, maxRow, maxCol, allCells, selectedCells);
3163      };
3164      var makeCell = function (list, seenSelected, rowIndex) {
3165        var row = list[rowIndex].element;
3166        var td = SugarElement.fromTag('td');
3167        append$1(td, SugarElement.fromTag('br'));
3168        var f = seenSelected ? append$1 : prepend;
3169        f(row, td);
3170      };
3171      var fillInGaps = function (list, house, stats, isSelected) {
3172        var totalColumns = house.grid.columns;
3173        var totalRows = house.grid.rows;
3174        for (var i = 0; i < totalRows; i++) {
3175          var seenSelected = false;
3176          for (var j = 0; j < totalColumns; j++) {
3177            if (!(i < stats.minRow || i > stats.maxRow || j < stats.minCol || j > stats.maxCol)) {
3178              var needCell = Warehouse.getAt(house, i, j).filter(isSelected).isNone();
3179              if (needCell) {
3180                makeCell(list, seenSelected, i);
3181              } else {
3182                seenSelected = true;
3183              }
3184            }
3185          }
3186        }
3187      };
3188      var clean = function (replica, stats, house, widthDelta) {
3189        each$1(house.columns, function (col) {
3190          if (col.column < stats.minCol || col.column > stats.maxCol) {
3191            remove$5(col.element);
3192          }
3193        });
3194        var emptyRows = filter$2(firstLayer(replica, 'tr'), function (row) {
3195          return row.dom.childElementCount === 0;
3196        });
3197        each$2(emptyRows, remove$5);
3198        if (stats.minCol === stats.maxCol || stats.minRow === stats.maxRow) {
3199          each$2(firstLayer(replica, 'th,td'), function (cell) {
3200            remove$7(cell, 'rowspan');
3201            remove$7(cell, 'colspan');
3202          });
3203        }
3204        remove$7(replica, LOCKED_COL_ATTR);
3205        remove$7(replica, 'data-snooker-col-series');
3206        var tableSize = TableSize.getTableSize(replica);
3207        tableSize.adjustTableWidth(widthDelta);
3208      };
3209      var getTableWidthDelta = function (table, warehouse, tableSize, stats) {
3210        if (stats.minCol === 0 && warehouse.grid.columns === stats.maxCol + 1) {
3211          return 0;
3212        }
3213        var colWidths = getPixelWidths(warehouse, table, tableSize);
3214        var allColsWidth = foldl(colWidths, function (acc, width) {
3215          return acc + width;
3216        }, 0);
3217        var selectedColsWidth = foldl(colWidths.slice(stats.minCol, stats.maxCol + 1), function (acc, width) {
3218          return acc + width;
3219        }, 0);
3220        var newWidth = selectedColsWidth / allColsWidth * tableSize.pixelWidth();
3221        var delta = newWidth - tableSize.pixelWidth();
3222        return tableSize.getCellDelta(delta);
3223      };
3224      var extract$1 = function (table, selectedSelector) {
3225        var isSelected = function (detail) {
3226          return is$2(detail.element, selectedSelector);
3227        };
3228        var replica = deep(table);
3229        var list = fromTable$1(replica);
3230        var tableSize = TableSize.getTableSize(table);
3231        var replicaHouse = Warehouse.generate(list);
3232        var replicaStats = findSelectedStats(replicaHouse, isSelected);
3233        var selector = 'th:not(' + selectedSelector + ')' + ',td:not(' + selectedSelector + ')';
3234        var unselectedCells = filterFirstLayer(replica, 'th,td', function (cell) {
3235          return is$2(cell, selector);
3236        });
3237        each$2(unselectedCells, remove$5);
3238        fillInGaps(list, replicaHouse, replicaStats, isSelected);
3239        var house = Warehouse.fromTable(table);
3240        var widthDelta = getTableWidthDelta(table, house, tableSize, replicaStats);
3241        clean(replica, replicaStats, replicaHouse, widthDelta);
3242        return replica;
3243      };
3244  
3245      var nbsp = '\xA0';
3246  
3247      var getEnd = function (element) {
3248        return name(element) === 'img' ? 1 : getOption(element).fold(function () {
3249          return children$3(element).length;
3250        }, function (v) {
3251          return v.length;
3252        });
3253      };
3254      var isTextNodeWithCursorPosition = function (el) {
3255        return getOption(el).filter(function (text) {
3256          return text.trim().length !== 0 || text.indexOf(nbsp) > -1;
3257        }).isSome();
3258      };
3259      var elementsWithCursorPosition = [
3260        'img',
3261        'br'
3262      ];
3263      var isCursorPosition = function (elem) {
3264        var hasCursorPosition = isTextNodeWithCursorPosition(elem);
3265        return hasCursorPosition || contains$2(elementsWithCursorPosition, name(elem));
3266      };
3267  
3268      var first = function (element) {
3269        return descendant$1(element, isCursorPosition);
3270      };
3271      var last$1 = function (element) {
3272        return descendantRtl(element, isCursorPosition);
3273      };
3274      var descendantRtl = function (scope, predicate) {
3275        var descend = function (element) {
3276          var children = children$3(element);
3277          for (var i = children.length - 1; i >= 0; i--) {
3278            var child = children[i];
3279            if (predicate(child)) {
3280              return Optional.some(child);
3281            }
3282            var res = descend(child);
3283            if (res.isSome()) {
3284              return res;
3285            }
3286          }
3287          return Optional.none();
3288        };
3289        return descend(scope);
3290      };
3291  
3292      var transferableAttributes = {
3293        scope: [
3294          'row',
3295          'col'
3296        ]
3297      };
3298      var createCell = function (doc) {
3299        return function () {
3300          var td = SugarElement.fromTag('td', doc.dom);
3301          append$1(td, SugarElement.fromTag('br', doc.dom));
3302          return td;
3303        };
3304      };
3305      var createCol = function (doc) {
3306        return function () {
3307          return SugarElement.fromTag('col', doc.dom);
3308        };
3309      };
3310      var createColgroup = function (doc) {
3311        return function () {
3312          return SugarElement.fromTag('colgroup', doc.dom);
3313        };
3314      };
3315      var createRow$1 = function (doc) {
3316        return function () {
3317          return SugarElement.fromTag('tr', doc.dom);
3318        };
3319      };
3320      var replace$1 = function (cell, tag, attrs) {
3321        var replica = copy$1(cell, tag);
3322        each$1(attrs, function (v, k) {
3323          if (v === null) {
3324            remove$7(replica, k);
3325          } else {
3326            set$2(replica, k, v);
3327          }
3328        });
3329        return replica;
3330      };
3331      var pasteReplace = function (cell) {
3332        return cell;
3333      };
3334      var cloneFormats = function (oldCell, newCell, formats) {
3335        var first$1 = first(oldCell);
3336        return first$1.map(function (firstText) {
3337          var formatSelector = formats.join(',');
3338          var parents = ancestors$3(firstText, formatSelector, function (element) {
3339            return eq$1(element, oldCell);
3340          });
3341          return foldr(parents, function (last, parent) {
3342            var clonedFormat = shallow(parent);
3343            remove$7(clonedFormat, 'contenteditable');
3344            append$1(last, clonedFormat);
3345            return clonedFormat;
3346          }, newCell);
3347        }).getOr(newCell);
3348      };
3349      var cloneAppropriateAttributes = function (original, clone) {
3350        each$1(transferableAttributes, function (validAttributes, attributeName) {
3351          return getOpt(original, attributeName).filter(function (attribute) {
3352            return contains$2(validAttributes, attribute);
3353          }).each(function (attribute) {
3354            return set$2(clone, attributeName, attribute);
3355          });
3356        });
3357      };
3358      var cellOperations = function (mutate, doc, formatsToClone) {
3359        var cloneCss = function (prev, clone) {
3360          copy$2(prev.element, clone);
3361          remove$6(clone, 'height');
3362          if (prev.colspan !== 1) {
3363            remove$6(clone, 'width');
3364          }
3365        };
3366        var newCell = function (prev) {
3367          var td = SugarElement.fromTag(name(prev.element), doc.dom);
3368          var formats = formatsToClone.getOr([
3369            'strong',
3370            'em',
3371            'b',
3372            'i',
3373            'span',
3374            'font',
3375            'h1',
3376            'h2',
3377            'h3',
3378            'h4',
3379            'h5',
3380            'h6',
3381            'p',
3382            'div'
3383          ]);
3384          var lastNode = formats.length > 0 ? cloneFormats(prev.element, td, formats) : td;
3385          append$1(lastNode, SugarElement.fromTag('br'));
3386          cloneCss(prev, td);
3387          cloneAppropriateAttributes(prev.element, td);
3388          mutate(prev.element, td);
3389          return td;
3390        };
3391        var newCol = function (prev) {
3392          var col = SugarElement.fromTag(name(prev.element), doc.dom);
3393          cloneCss(prev, col);
3394          mutate(prev.element, col);
3395          return col;
3396        };
3397        return {
3398          col: newCol,
3399          colgroup: createColgroup(doc),
3400          row: createRow$1(doc),
3401          cell: newCell,
3402          replace: replace$1,
3403          colGap: createCol(doc),
3404          gap: createCell(doc)
3405        };
3406      };
3407      var paste$1 = function (doc) {
3408        return {
3409          col: createCol(doc),
3410          colgroup: createColgroup(doc),
3411          row: createRow$1(doc),
3412          cell: createCell(doc),
3413          replace: pasteReplace,
3414          colGap: createCol(doc),
3415          gap: createCell(doc)
3416        };
3417      };
3418  
3419      var fromHtml = function (html, scope) {
3420        var doc = scope || document;
3421        var div = doc.createElement('div');
3422        div.innerHTML = html;
3423        return children$3(SugarElement.fromDom(div));
3424      };
3425      var fromDom = function (nodes) {
3426        return map$1(nodes, SugarElement.fromDom);
3427      };
3428  
3429      var getNodeName = function (elm) {
3430        return elm.nodeName.toLowerCase();
3431      };
3432      var getBody = function (editor) {
3433        return SugarElement.fromDom(editor.getBody());
3434      };
3435      var getPixelWidth = function (elm) {
3436        return elm.getBoundingClientRect().width;
3437      };
3438      var getPixelHeight = function (elm) {
3439        return elm.getBoundingClientRect().height;
3440      };
3441      var getIsRoot = function (editor) {
3442        return function (element) {
3443          return eq$1(element, getBody(editor));
3444        };
3445      };
3446      var removePxSuffix = function (size) {
3447        return size ? size.replace(/px$/, '') : '';
3448      };
3449      var addPxSuffix = function (size) {
3450        return /^\d+(\.\d+)?$/.test(size) ? size + 'px' : size;
3451      };
3452      var removeDataStyle = function (table) {
3453        remove$7(table, 'data-mce-style');
3454        var removeStyleAttribute = function (element) {
3455          return remove$7(element, 'data-mce-style');
3456        };
3457        each$2(cells$1(table), removeStyleAttribute);
3458        each$2(columns$1(table), removeStyleAttribute);
3459        each$2(rows$1(table), removeStyleAttribute);
3460      };
3461      var getRawWidth = function (editor, elm) {
3462        var raw = editor.dom.getStyle(elm, 'width') || editor.dom.getAttrib(elm, 'width');
3463        return Optional.from(raw).filter(isNotEmpty);
3464      };
3465      var isPercentage$1 = function (value) {
3466        return /^(\d+(\.\d+)?)%$/.test(value);
3467      };
3468      var isPixel = function (value) {
3469        return /^(\d+(\.\d+)?)px$/.test(value);
3470      };
3471      var getSelectionStart = function (editor) {
3472        return SugarElement.fromDom(editor.selection.getStart());
3473      };
3474      var getSelectionEnd = function (editor) {
3475        return SugarElement.fromDom(editor.selection.getEnd());
3476      };
3477  
3478      var selection = function (selections) {
3479        return cata$2(selections.get(), constant([]), identity, pure);
3480      };
3481      var unmergable = function (selections) {
3482        var hasSpan = function (elem, type) {
3483          return getOpt(elem, type).exists(function (span) {
3484            return parseInt(span, 10) > 1;
3485          });
3486        };
3487        var hasRowOrColSpan = function (elem) {
3488          return hasSpan(elem, 'rowspan') || hasSpan(elem, 'colspan');
3489        };
3490        var candidates = selection(selections);
3491        return candidates.length > 0 && forall(candidates, hasRowOrColSpan) ? Optional.some(candidates) : Optional.none();
3492      };
3493      var mergable = function (table, selections, ephemera) {
3494        return cata$2(selections.get(), Optional.none, function (cells) {
3495          if (cells.length <= 1) {
3496            return Optional.none();
3497          } else {
3498            return retrieveBox(table, ephemera.firstSelectedSelector, ephemera.lastSelectedSelector).map(function (bounds) {
3499              return {
3500                bounds: bounds,
3501                cells: cells
3502              };
3503            });
3504          }
3505        }, Optional.none);
3506      };
3507  
3508      var strSelected = 'data-mce-selected';
3509      var strSelectedSelector = 'td[' + strSelected + '],th[' + strSelected + ']';
3510      var strAttributeSelector = '[' + strSelected + ']';
3511      var strFirstSelected = 'data-mce-first-selected';
3512      var strFirstSelectedSelector = 'td[' + strFirstSelected + '],th[' + strFirstSelected + ']';
3513      var strLastSelected = 'data-mce-last-selected';
3514      var strLastSelectedSelector = 'td[' + strLastSelected + '],th[' + strLastSelected + ']';
3515      var attributeSelector = strAttributeSelector;
3516      var ephemera = {
3517        selected: strSelected,
3518        selectedSelector: strSelectedSelector,
3519        firstSelected: strFirstSelected,
3520        firstSelectedSelector: strFirstSelectedSelector,
3521        lastSelected: strLastSelected,
3522        lastSelectedSelector: strLastSelectedSelector
3523      };
3524  
3525      var noMenu = function (cell) {
3526        return {
3527          element: cell,
3528          mergable: Optional.none(),
3529          unmergable: Optional.none(),
3530          selection: [cell]
3531        };
3532      };
3533      var forMenu = function (selections, table, cell) {
3534        return {
3535          element: cell,
3536          mergable: mergable(table, selections, ephemera),
3537          unmergable: unmergable(selections),
3538          selection: selection(selections)
3539        };
3540      };
3541      var paste = function (element, clipboard, generators) {
3542        return {
3543          element: element,
3544          clipboard: clipboard,
3545          generators: generators
3546        };
3547      };
3548      var pasteRows = function (selections, cell, clipboard, generators) {
3549        return {
3550          selection: selection(selections),
3551          clipboard: clipboard,
3552          generators: generators
3553        };
3554      };
3555  
3556      var getSelectionCellFallback = function (element) {
3557        return table(element).bind(function (table) {
3558          return retrieve(table, ephemera.firstSelectedSelector);
3559        }).fold(constant(element), function (cells) {
3560          return cells[0];
3561        });
3562      };
3563      var getSelectionFromSelector = function (selector) {
3564        return function (initCell, isRoot) {
3565          var cellName = name(initCell);
3566          var cell = cellName === 'col' || cellName === 'colgroup' ? getSelectionCellFallback(initCell) : initCell;
3567          return closest$1(cell, selector, isRoot);
3568        };
3569      };
3570      var getSelectionCellOrCaption = getSelectionFromSelector('th,td,caption');
3571      var getSelectionCell = getSelectionFromSelector('th,td');
3572      var getCellsFromSelection = function (selections) {
3573        return selection(selections);
3574      };
3575      var getRowsFromSelection = function (selected, selector) {
3576        var cellOpt = getSelectionCell(selected);
3577        var rowsOpt = cellOpt.bind(function (cell) {
3578          return table(cell);
3579        }).map(function (table) {
3580          return rows$1(table);
3581        });
3582        return lift2(cellOpt, rowsOpt, function (cell, rows) {
3583          return filter$2(rows, function (row) {
3584            return exists(fromDom(row.dom.cells), function (rowCell) {
3585              return get$b(rowCell, selector) === '1' || eq$1(rowCell, cell);
3586            });
3587          });
3588        }).getOr([]);
3589      };
3590  
3591      var extractSelected = function (cells) {
3592        return table(cells[0]).map(function (table) {
3593          var replica = extract$1(table, attributeSelector);
3594          removeDataStyle(replica);
3595          return [replica];
3596        });
3597      };
3598      var serializeElements = function (editor, elements) {
3599        return map$1(elements, function (elm) {
3600          return editor.selection.serializer.serialize(elm.dom, {});
3601        }).join('');
3602      };
3603      var getTextContent = function (elements) {
3604        return map$1(elements, function (element) {
3605          return element.dom.innerText;
3606        }).join('');
3607      };
3608      var registerEvents = function (editor, selections, actions) {
3609        editor.on('BeforeGetContent', function (e) {
3610          var multiCellContext = function (cells) {
3611            e.preventDefault();
3612            extractSelected(cells).each(function (elements) {
3613              e.content = e.format === 'text' ? getTextContent(elements) : serializeElements(editor, elements);
3614            });
3615          };
3616          if (e.selection === true) {
3617            cata$2(selections.get(), noop, multiCellContext, noop);
3618          }
3619        });
3620        editor.on('BeforeSetContent', function (e) {
3621          if (e.selection === true && e.paste === true) {
3622            var selectedCells = getCellsFromSelection(selections);
3623            head(selectedCells).each(function (cell) {
3624              table(cell).each(function (table) {
3625                var elements = filter$2(fromHtml(e.content), function (content) {
3626                  return name(content) !== 'meta';
3627                });
3628                var isTable = isTag('table');
3629                if (elements.length === 1 && isTable(elements[0])) {
3630                  e.preventDefault();
3631                  var doc = SugarElement.fromDom(editor.getDoc());
3632                  var generators = paste$1(doc);
3633                  var targets = paste(cell, elements[0], generators);
3634                  actions.pasteCells(table, targets).each(function () {
3635                    editor.focus();
3636                  });
3637                }
3638              });
3639            });
3640          }
3641        });
3642      };
3643  
3644      var adt$7 = Adt.generate([
3645        { none: [] },
3646        { only: ['index'] },
3647        {
3648          left: [
3649            'index',
3650            'next'
3651          ]
3652        },
3653        {
3654          middle: [
3655            'prev',
3656            'index',
3657            'next'
3658          ]
3659        },
3660        {
3661          right: [
3662            'prev',
3663            'index'
3664          ]
3665        }
3666      ]);
3667      var ColumnContext = __assign({}, adt$7);
3668  
3669      var neighbours = function (input, index) {
3670        if (input.length === 0) {
3671          return ColumnContext.none();
3672        }
3673        if (input.length === 1) {
3674          return ColumnContext.only(0);
3675        }
3676        if (index === 0) {
3677          return ColumnContext.left(0, 1);
3678        }
3679        if (index === input.length - 1) {
3680          return ColumnContext.right(index - 1, index);
3681        }
3682        if (index > 0 && index < input.length - 1) {
3683          return ColumnContext.middle(index - 1, index, index + 1);
3684        }
3685        return ColumnContext.none();
3686      };
3687      var determine = function (input, column, step, tableSize, resize) {
3688        var result = input.slice(0);
3689        var context = neighbours(input, column);
3690        var onNone = constant(map$1(result, constant(0)));
3691        var onOnly = function (index) {
3692          return tableSize.singleColumnWidth(result[index], step);
3693        };
3694        var onLeft = function (index, next) {
3695          return resize.calcLeftEdgeDeltas(result, index, next, step, tableSize.minCellWidth(), tableSize.isRelative);
3696        };
3697        var onMiddle = function (prev, index, next) {
3698          return resize.calcMiddleDeltas(result, prev, index, next, step, tableSize.minCellWidth(), tableSize.isRelative);
3699        };
3700        var onRight = function (prev, index) {
3701          return resize.calcRightEdgeDeltas(result, prev, index, step, tableSize.minCellWidth(), tableSize.isRelative);
3702        };
3703        return context.fold(onNone, onOnly, onLeft, onMiddle, onRight);
3704      };
3705  
3706      var total = function (start, end, measures) {
3707        var r = 0;
3708        for (var i = start; i < end; i++) {
3709          r += measures[i] !== undefined ? measures[i] : 0;
3710        }
3711        return r;
3712      };
3713      var recalculateWidthForCells = function (warehouse, widths) {
3714        var all = Warehouse.justCells(warehouse);
3715        return map$1(all, function (cell) {
3716          var width = total(cell.column, cell.column + cell.colspan, widths);
3717          return {
3718            element: cell.element,
3719            width: width,
3720            colspan: cell.colspan
3721          };
3722        });
3723      };
3724      var recalculateWidthForColumns = function (warehouse, widths) {
3725        var groups = Warehouse.justColumns(warehouse);
3726        return map$1(groups, function (column, index) {
3727          return {
3728            element: column.element,
3729            width: widths[index],
3730            colspan: column.colspan
3731          };
3732        });
3733      };
3734      var recalculateHeightForCells = function (warehouse, heights) {
3735        var all = Warehouse.justCells(warehouse);
3736        return map$1(all, function (cell) {
3737          var height = total(cell.row, cell.row + cell.rowspan, heights);
3738          return {
3739            element: cell.element,
3740            height: height,
3741            rowspan: cell.rowspan
3742          };
3743        });
3744      };
3745      var matchRowHeight = function (warehouse, heights) {
3746        return map$1(warehouse.all, function (row, i) {
3747          return {
3748            element: row.element,
3749            height: heights[i]
3750          };
3751        });
3752      };
3753  
3754      var sumUp = function (newSize) {
3755        return foldr(newSize, function (b, a) {
3756          return b + a;
3757        }, 0);
3758      };
3759      var recalculate = function (warehouse, widths) {
3760        if (Warehouse.hasColumns(warehouse)) {
3761          return recalculateWidthForColumns(warehouse, widths);
3762        } else {
3763          return recalculateWidthForCells(warehouse, widths);
3764        }
3765      };
3766      var recalculateAndApply = function (warehouse, widths, tableSize) {
3767        var newSizes = recalculate(warehouse, widths);
3768        each$2(newSizes, function (cell) {
3769          tableSize.setElementWidth(cell.element, cell.width);
3770        });
3771      };
3772      var adjustWidth = function (table, delta, index, resizing, tableSize) {
3773        var warehouse = Warehouse.fromTable(table);
3774        var step = tableSize.getCellDelta(delta);
3775        var widths = tableSize.getWidths(warehouse, tableSize);
3776        var isLastColumn = index === warehouse.grid.columns - 1;
3777        var clampedStep = resizing.clampTableDelta(widths, index, step, tableSize.minCellWidth(), isLastColumn);
3778        var deltas = determine(widths, index, clampedStep, tableSize, resizing);
3779        var newWidths = map$1(deltas, function (dx, i) {
3780          return dx + widths[i];
3781        });
3782        recalculateAndApply(warehouse, newWidths, tableSize);
3783        resizing.resizeTable(tableSize.adjustTableWidth, clampedStep, isLastColumn);
3784      };
3785      var adjustHeight = function (table, delta, index, direction) {
3786        var warehouse = Warehouse.fromTable(table);
3787        var heights = getPixelHeights(warehouse, table, direction);
3788        var newHeights = map$1(heights, function (dy, i) {
3789          return index === i ? Math.max(delta + dy, minHeight()) : dy;
3790        });
3791        var newCellSizes = recalculateHeightForCells(warehouse, newHeights);
3792        var newRowSizes = matchRowHeight(warehouse, newHeights);
3793        each$2(newRowSizes, function (row) {
3794          setHeight(row.element, row.height);
3795        });
3796        each$2(newCellSizes, function (cell) {
3797          setHeight(cell.element, cell.height);
3798        });
3799        var total = sumUp(newHeights);
3800        setHeight(table, total);
3801      };
3802      var adjustAndRedistributeWidths$1 = function (_table, list, details, tableSize, resizeBehaviour) {
3803        var warehouse = Warehouse.generate(list);
3804        var sizes = tableSize.getWidths(warehouse, tableSize);
3805        var tablePixelWidth = tableSize.pixelWidth();
3806        var _a = resizeBehaviour.calcRedestributedWidths(sizes, tablePixelWidth, details.pixelDelta, tableSize.isRelative), newSizes = _a.newSizes, delta = _a.delta;
3807        recalculateAndApply(warehouse, newSizes, tableSize);
3808        tableSize.adjustTableWidth(delta);
3809      };
3810      var adjustWidthTo = function (_table, list, _info, tableSize) {
3811        var warehouse = Warehouse.generate(list);
3812        var widths = tableSize.getWidths(warehouse, tableSize);
3813        recalculateAndApply(warehouse, widths, tableSize);
3814      };
3815  
3816      var zero = function (array) {
3817        return map$1(array, constant(0));
3818      };
3819      var surround = function (sizes, startIndex, endIndex, results, f) {
3820        return f(sizes.slice(0, startIndex)).concat(results).concat(f(sizes.slice(endIndex)));
3821      };
3822      var clampDeltaHelper = function (predicate) {
3823        return function (sizes, index, delta, minCellSize) {
3824          if (!predicate(delta)) {
3825            return delta;
3826          } else {
3827            var newSize = Math.max(minCellSize, sizes[index] - Math.abs(delta));
3828            var diff = Math.abs(newSize - sizes[index]);
3829            return delta >= 0 ? diff : -diff;
3830          }
3831        };
3832      };
3833      var clampNegativeDelta = clampDeltaHelper(function (delta) {
3834        return delta < 0;
3835      });
3836      var clampDelta = clampDeltaHelper(always);
3837      var resizeTable = function () {
3838        var calcFixedDeltas = function (sizes, index, next, delta, minCellSize) {
3839          var clampedDelta = clampNegativeDelta(sizes, index, delta, minCellSize);
3840          return surround(sizes, index, next + 1, [
3841            clampedDelta,
3842            0
3843          ], zero);
3844        };
3845        var calcRelativeDeltas = function (sizes, index, delta, minCellSize) {
3846          var ratio = (100 + delta) / 100;
3847          var newThis = Math.max(minCellSize, (sizes[index] + delta) / ratio);
3848          return map$1(sizes, function (size, idx) {
3849            var newSize = idx === index ? newThis : size / ratio;
3850            return newSize - size;
3851          });
3852        };
3853        var calcLeftEdgeDeltas = function (sizes, index, next, delta, minCellSize, isRelative) {
3854          if (isRelative) {
3855            return calcRelativeDeltas(sizes, index, delta, minCellSize);
3856          } else {
3857            return calcFixedDeltas(sizes, index, next, delta, minCellSize);
3858          }
3859        };
3860        var calcMiddleDeltas = function (sizes, _prev, index, next, delta, minCellSize, isRelative) {
3861          return calcLeftEdgeDeltas(sizes, index, next, delta, minCellSize, isRelative);
3862        };
3863        var resizeTable = function (resizer, delta) {
3864          return resizer(delta);
3865        };
3866        var calcRightEdgeDeltas = function (sizes, _prev, index, delta, minCellSize, isRelative) {
3867          if (isRelative) {
3868            return calcRelativeDeltas(sizes, index, delta, minCellSize);
3869          } else {
3870            var clampedDelta = clampNegativeDelta(sizes, index, delta, minCellSize);
3871            return zero(sizes.slice(0, index)).concat([clampedDelta]);
3872          }
3873        };
3874        var calcRedestributedWidths = function (sizes, totalWidth, pixelDelta, isRelative) {
3875          if (isRelative) {
3876            var tableWidth = totalWidth + pixelDelta;
3877            var ratio_1 = tableWidth / totalWidth;
3878            var newSizes = map$1(sizes, function (size) {
3879              return size / ratio_1;
3880            });
3881            return {
3882              delta: ratio_1 * 100 - 100,
3883              newSizes: newSizes
3884            };
3885          } else {
3886            return {
3887              delta: pixelDelta,
3888              newSizes: sizes
3889            };
3890          }
3891        };
3892        return {
3893          resizeTable: resizeTable,
3894          clampTableDelta: clampNegativeDelta,
3895          calcLeftEdgeDeltas: calcLeftEdgeDeltas,
3896          calcMiddleDeltas: calcMiddleDeltas,
3897          calcRightEdgeDeltas: calcRightEdgeDeltas,
3898          calcRedestributedWidths: calcRedestributedWidths
3899        };
3900      };
3901      var preserveTable = function () {
3902        var calcLeftEdgeDeltas = function (sizes, index, next, delta, minCellSize) {
3903          var idx = delta >= 0 ? next : index;
3904          var clampedDelta = clampDelta(sizes, idx, delta, minCellSize);
3905          return surround(sizes, index, next + 1, [
3906            clampedDelta,
3907            -clampedDelta
3908          ], zero);
3909        };
3910        var calcMiddleDeltas = function (sizes, _prev, index, next, delta, minCellSize) {
3911          return calcLeftEdgeDeltas(sizes, index, next, delta, minCellSize);
3912        };
3913        var resizeTable = function (resizer, delta, isLastColumn) {
3914          if (isLastColumn) {
3915            resizer(delta);
3916          }
3917        };
3918        var calcRightEdgeDeltas = function (sizes, _prev, _index, delta, _minCellSize, isRelative) {
3919          if (isRelative) {
3920            return zero(sizes);
3921          } else {
3922            var diff = delta / sizes.length;
3923            return map$1(sizes, constant(diff));
3924          }
3925        };
3926        var clampTableDelta = function (sizes, index, delta, minCellSize, isLastColumn) {
3927          if (isLastColumn) {
3928            if (delta >= 0) {
3929              return delta;
3930            } else {
3931              var maxDelta = foldl(sizes, function (a, b) {
3932                return a + b - minCellSize;
3933              }, 0);
3934              return Math.max(-maxDelta, delta);
3935            }
3936          } else {
3937            return clampNegativeDelta(sizes, index, delta, minCellSize);
3938          }
3939        };
3940        var calcRedestributedWidths = function (sizes, _totalWidth, _pixelDelta, _isRelative) {
3941          return {
3942            delta: 0,
3943            newSizes: sizes
3944          };
3945        };
3946        return {
3947          resizeTable: resizeTable,
3948          clampTableDelta: clampTableDelta,
3949          calcLeftEdgeDeltas: calcLeftEdgeDeltas,
3950          calcMiddleDeltas: calcMiddleDeltas,
3951          calcRightEdgeDeltas: calcRightEdgeDeltas,
3952          calcRedestributedWidths: calcRedestributedWidths
3953        };
3954      };
3955  
3956      var only = function (element, isResizable) {
3957        var parent = Optional.from(element.dom.documentElement).map(SugarElement.fromDom).getOr(element);
3958        return {
3959          parent: constant(parent),
3960          view: constant(element),
3961          origin: constant(SugarPosition(0, 0)),
3962          isResizable: isResizable
3963        };
3964      };
3965      var detached = function (editable, chrome, isResizable) {
3966        var origin = function () {
3967          return absolute(chrome);
3968        };
3969        return {
3970          parent: constant(chrome),
3971          view: constant(editable),
3972          origin: origin,
3973          isResizable: isResizable
3974        };
3975      };
3976      var body = function (editable, chrome, isResizable) {
3977        return {
3978          parent: constant(chrome),
3979          view: constant(editable),
3980          origin: constant(SugarPosition(0, 0)),
3981          isResizable: isResizable
3982        };
3983      };
3984      var ResizeWire = {
3985        only: only,
3986        detached: detached,
3987        body: body
3988      };
3989  
3990      var adt$6 = Adt.generate([
3991        { invalid: ['raw'] },
3992        { pixels: ['value'] },
3993        { percent: ['value'] }
3994      ]);
3995      var validateFor = function (suffix, type, value) {
3996        var rawAmount = value.substring(0, value.length - suffix.length);
3997        var amount = parseFloat(rawAmount);
3998        return rawAmount === amount.toString() ? type(amount) : adt$6.invalid(value);
3999      };
4000      var from = function (value) {
4001        if (endsWith(value, '%')) {
4002          return validateFor('%', adt$6.percent, value);
4003        }
4004        if (endsWith(value, 'px')) {
4005          return validateFor('px', adt$6.pixels, value);
4006        }
4007        return adt$6.invalid(value);
4008      };
4009      var Size = __assign(__assign({}, adt$6), { from: from });
4010  
4011      var redistributeToPercent = function (widths, totalWidth) {
4012        return map$1(widths, function (w) {
4013          var colType = Size.from(w);
4014          return colType.fold(function () {
4015            return w;
4016          }, function (px) {
4017            var ratio = px / totalWidth * 100;
4018            return ratio + '%';
4019          }, function (pc) {
4020            return pc + '%';
4021          });
4022        });
4023      };
4024      var redistributeToPx = function (widths, totalWidth, newTotalWidth) {
4025        var scale = newTotalWidth / totalWidth;
4026        return map$1(widths, function (w) {
4027          var colType = Size.from(w);
4028          return colType.fold(function () {
4029            return w;
4030          }, function (px) {
4031            return px * scale + 'px';
4032          }, function (pc) {
4033            return pc / 100 * newTotalWidth + 'px';
4034          });
4035        });
4036      };
4037      var redistributeEmpty = function (newWidthType, columns) {
4038        var f = newWidthType.fold(function () {
4039          return constant('');
4040        }, function (pixels) {
4041          var num = pixels / columns;
4042          return constant(num + 'px');
4043        }, function () {
4044          var num = 100 / columns;
4045          return constant(num + '%');
4046        });
4047        return range$1(columns, f);
4048      };
4049      var redistributeValues = function (newWidthType, widths, totalWidth) {
4050        return newWidthType.fold(function () {
4051          return widths;
4052        }, function (px) {
4053          return redistributeToPx(widths, totalWidth, px);
4054        }, function (_pc) {
4055          return redistributeToPercent(widths, totalWidth);
4056        });
4057      };
4058      var redistribute$1 = function (widths, totalWidth, newWidth) {
4059        var newType = Size.from(newWidth);
4060        var floats = forall(widths, function (s) {
4061          return s === '0px';
4062        }) ? redistributeEmpty(newType, widths.length) : redistributeValues(newType, widths, totalWidth);
4063        return normalize(floats);
4064      };
4065      var sum = function (values, fallback) {
4066        if (values.length === 0) {
4067          return fallback;
4068        }
4069        return foldr(values, function (rest, v) {
4070          return Size.from(v).fold(constant(0), identity, identity) + rest;
4071        }, 0);
4072      };
4073      var roundDown = function (num, unit) {
4074        var floored = Math.floor(num);
4075        return {
4076          value: floored + unit,
4077          remainder: num - floored
4078        };
4079      };
4080      var add$3 = function (value, amount) {
4081        return Size.from(value).fold(constant(value), function (px) {
4082          return px + amount + 'px';
4083        }, function (pc) {
4084          return pc + amount + '%';
4085        });
4086      };
4087      var normalize = function (values) {
4088        if (values.length === 0) {
4089          return values;
4090        }
4091        var scan = foldr(values, function (rest, value) {
4092          var info = Size.from(value).fold(function () {
4093            return {
4094              value: value,
4095              remainder: 0
4096            };
4097          }, function (num) {
4098            return roundDown(num, 'px');
4099          }, function (num) {
4100            return {
4101              value: num + '%',
4102              remainder: 0
4103            };
4104          });
4105          return {
4106            output: [info.value].concat(rest.output),
4107            remainder: rest.remainder + info.remainder
4108          };
4109        }, {
4110          output: [],
4111          remainder: 0
4112        });
4113        var r = scan.output;
4114        return r.slice(0, r.length - 1).concat([add$3(r[r.length - 1], Math.round(scan.remainder))]);
4115      };
4116      var validate = Size.from;
4117  
4118      var redistributeToW = function (newWidths, cells, unit) {
4119        each$2(cells, function (cell) {
4120          var widths = newWidths.slice(cell.column, cell.colspan + cell.column);
4121          var w = sum(widths, minWidth());
4122          set$1(cell.element, 'width', w + unit);
4123        });
4124      };
4125      var redistributeToColumns = function (newWidths, columns, unit) {
4126        each$2(columns, function (column, index) {
4127          var width = sum([newWidths[index]], minWidth());
4128          set$1(column.element, 'width', width + unit);
4129        });
4130      };
4131      var redistributeToH = function (newHeights, rows, cells, unit) {
4132        each$2(cells, function (cell) {
4133          var heights = newHeights.slice(cell.row, cell.rowspan + cell.row);
4134          var h = sum(heights, minHeight());
4135          set$1(cell.element, 'height', h + unit);
4136        });
4137        each$2(rows, function (row, i) {
4138          set$1(row.element, 'height', newHeights[i]);
4139        });
4140      };
4141      var getUnit = function (newSize) {
4142        return validate(newSize).fold(constant('px'), constant('px'), constant('%'));
4143      };
4144      var redistribute = function (table, optWidth, optHeight) {
4145        var warehouse = Warehouse.fromTable(table);
4146        var rows = warehouse.all;
4147        var cells = Warehouse.justCells(warehouse);
4148        var columns = Warehouse.justColumns(warehouse);
4149        optWidth.each(function (newWidth) {
4150          var widthUnit = getUnit(newWidth);
4151          var totalWidth = get$8(table);
4152          var oldWidths = getRawWidths(warehouse, table);
4153          var nuWidths = redistribute$1(oldWidths, totalWidth, newWidth);
4154          if (Warehouse.hasColumns(warehouse)) {
4155            redistributeToColumns(nuWidths, columns, widthUnit);
4156          } else {
4157            redistributeToW(nuWidths, cells, widthUnit);
4158          }
4159          set$1(table, 'width', newWidth);
4160        });
4161        optHeight.each(function (newHeight) {
4162          var hUnit = getUnit(newHeight);
4163          var totalHeight = get$7(table);
4164          var oldHeights = getRawHeights(warehouse, table, height);
4165          var nuHeights = redistribute$1(oldHeights, totalHeight, newHeight);
4166          redistributeToH(nuHeights, rows, cells, hUnit);
4167          set$1(table, 'height', newHeight);
4168        });
4169      };
4170      var isPercentSizing = isPercentSizing$1;
4171      var isPixelSizing = isPixelSizing$1;
4172      var isNoneSizing = isNoneSizing$1;
4173  
4174      var getGridSize = function (table) {
4175        var warehouse = Warehouse.fromTable(table);
4176        return warehouse.grid;
4177      };
4178  
4179      var Event = function (fields) {
4180        var handlers = [];
4181        var bind = function (handler) {
4182          if (handler === undefined) {
4183            throw new Error('Event bind error: undefined handler');
4184          }
4185          handlers.push(handler);
4186        };
4187        var unbind = function (handler) {
4188          handlers = filter$2(handlers, function (h) {
4189            return h !== handler;
4190          });
4191        };
4192        var trigger = function () {
4193          var args = [];
4194          for (var _i = 0; _i < arguments.length; _i++) {
4195            args[_i] = arguments[_i];
4196          }
4197          var event = {};
4198          each$2(fields, function (name, i) {
4199            event[name] = args[i];
4200          });
4201          each$2(handlers, function (handler) {
4202            handler(event);
4203          });
4204        };
4205        return {
4206          bind: bind,
4207          unbind: unbind,
4208          trigger: trigger
4209        };
4210      };
4211  
4212      var create$4 = function (typeDefs) {
4213        var registry = map(typeDefs, function (event) {
4214          return {
4215            bind: event.bind,
4216            unbind: event.unbind
4217          };
4218        });
4219        var trigger = map(typeDefs, function (event) {
4220          return event.trigger;
4221        });
4222        return {
4223          registry: registry,
4224          trigger: trigger
4225        };
4226      };
4227  
4228      var last = function (fn, rate) {
4229        var timer = null;
4230        var cancel = function () {
4231          if (!isNull(timer)) {
4232            clearTimeout(timer);
4233            timer = null;
4234          }
4235        };
4236        var throttle = function () {
4237          var args = [];
4238          for (var _i = 0; _i < arguments.length; _i++) {
4239            args[_i] = arguments[_i];
4240          }
4241          cancel();
4242          timer = setTimeout(function () {
4243            timer = null;
4244            fn.apply(null, args);
4245          }, rate);
4246        };
4247        return {
4248          cancel: cancel,
4249          throttle: throttle
4250        };
4251      };
4252  
4253      var sort = function (arr) {
4254        return arr.slice(0).sort();
4255      };
4256      var reqMessage = function (required, keys) {
4257        throw new Error('All required keys (' + sort(required).join(', ') + ') were not specified. Specified keys were: ' + sort(keys).join(', ') + '.');
4258      };
4259      var unsuppMessage = function (unsupported) {
4260        throw new Error('Unsupported keys for object: ' + sort(unsupported).join(', '));
4261      };
4262      var validateStrArr = function (label, array) {
4263        if (!isArray(array)) {
4264          throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.');
4265        }
4266        each$2(array, function (a) {
4267          if (!isString(a)) {
4268            throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.');
4269          }
4270        });
4271      };
4272      var invalidTypeMessage = function (incorrect, type) {
4273        throw new Error('All values need to be of type: ' + type + '. Keys (' + sort(incorrect).join(', ') + ') were not.');
4274      };
4275      var checkDupes = function (everything) {
4276        var sorted = sort(everything);
4277        var dupe = find$1(sorted, function (s, i) {
4278          return i < sorted.length - 1 && s === sorted[i + 1];
4279        });
4280        dupe.each(function (d) {
4281          throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].');
4282        });
4283      };
4284  
4285      var base = function (handleUnsupported, required) {
4286        return baseWith(handleUnsupported, required, {
4287          validate: isFunction,
4288          label: 'function'
4289        });
4290      };
4291      var baseWith = function (handleUnsupported, required, pred) {
4292        if (required.length === 0) {
4293          throw new Error('You must specify at least one required field.');
4294        }
4295        validateStrArr('required', required);
4296        checkDupes(required);
4297        return function (obj) {
4298          var keys$1 = keys(obj);
4299          var allReqd = forall(required, function (req) {
4300            return contains$2(keys$1, req);
4301          });
4302          if (!allReqd) {
4303            reqMessage(required, keys$1);
4304          }
4305          handleUnsupported(required, keys$1);
4306          var invalidKeys = filter$2(required, function (key) {
4307            return !pred.validate(obj[key], key);
4308          });
4309          if (invalidKeys.length > 0) {
4310            invalidTypeMessage(invalidKeys, pred.label);
4311          }
4312          return obj;
4313        };
4314      };
4315      var handleExact = function (required, keys) {
4316        var unsupported = filter$2(keys, function (key) {
4317          return !contains$2(required, key);
4318        });
4319        if (unsupported.length > 0) {
4320          unsuppMessage(unsupported);
4321        }
4322      };
4323      var exactly = function (required) {
4324        return base(handleExact, required);
4325      };
4326  
4327      var DragMode = exactly([
4328        'compare',
4329        'extract',
4330        'mutate',
4331        'sink'
4332      ]);
4333      var DragSink = exactly([
4334        'element',
4335        'start',
4336        'stop',
4337        'destroy'
4338      ]);
4339      var DragApi = exactly([
4340        'forceDrop',
4341        'drop',
4342        'move',
4343        'delayDrop'
4344      ]);
4345  
4346      var InDrag = function () {
4347        var previous = Optional.none();
4348        var reset = function () {
4349          previous = Optional.none();
4350        };
4351        var update = function (mode, nu) {
4352          var result = previous.map(function (old) {
4353            return mode.compare(old, nu);
4354          });
4355          previous = Optional.some(nu);
4356          return result;
4357        };
4358        var onEvent = function (event, mode) {
4359          var dataOption = mode.extract(event);
4360          dataOption.each(function (data) {
4361            var offset = update(mode, data);
4362            offset.each(function (d) {
4363              events.trigger.move(d);
4364            });
4365          });
4366        };
4367        var events = create$4({ move: Event(['info']) });
4368        return {
4369          onEvent: onEvent,
4370          reset: reset,
4371          events: events.registry
4372        };
4373      };
4374  
4375      var NoDrag = function () {
4376        var events = create$4({ move: Event(['info']) });
4377        return {
4378          onEvent: noop,
4379          reset: noop,
4380          events: events.registry
4381        };
4382      };
4383  
4384      var Movement = function () {
4385        var noDragState = NoDrag();
4386        var inDragState = InDrag();
4387        var dragState = noDragState;
4388        var on = function () {
4389          dragState.reset();
4390          dragState = inDragState;
4391        };
4392        var off = function () {
4393          dragState.reset();
4394          dragState = noDragState;
4395        };
4396        var onEvent = function (event, mode) {
4397          dragState.onEvent(event, mode);
4398        };
4399        var isOn = function () {
4400          return dragState === inDragState;
4401        };
4402        return {
4403          on: on,
4404          off: off,
4405          isOn: isOn,
4406          onEvent: onEvent,
4407          events: inDragState.events
4408        };
4409      };
4410  
4411      var setup = function (mutation, mode, settings) {
4412        var active = false;
4413        var events = create$4({
4414          start: Event([]),
4415          stop: Event([])
4416        });
4417        var movement = Movement();
4418        var drop = function () {
4419          sink.stop();
4420          if (movement.isOn()) {
4421            movement.off();
4422            events.trigger.stop();
4423          }
4424        };
4425        var throttledDrop = last(drop, 200);
4426        var go = function (parent) {
4427          sink.start(parent);
4428          movement.on();
4429          events.trigger.start();
4430        };
4431        var mousemove = function (event) {
4432          throttledDrop.cancel();
4433          movement.onEvent(event, mode);
4434        };
4435        movement.events.move.bind(function (event) {
4436          mode.mutate(mutation, event.info);
4437        });
4438        var on = function () {
4439          active = true;
4440        };
4441        var off = function () {
4442          active = false;
4443        };
4444        var runIfActive = function (f) {
4445          return function () {
4446            var args = [];
4447            for (var _i = 0; _i < arguments.length; _i++) {
4448              args[_i] = arguments[_i];
4449            }
4450            if (active) {
4451              f.apply(null, args);
4452            }
4453          };
4454        };
4455        var sink = mode.sink(DragApi({
4456          forceDrop: drop,
4457          drop: runIfActive(drop),
4458          move: runIfActive(mousemove),
4459          delayDrop: runIfActive(throttledDrop.throttle)
4460        }), settings);
4461        var destroy = function () {
4462          sink.destroy();
4463        };
4464        return {
4465          element: sink.element,
4466          go: go,
4467          on: on,
4468          off: off,
4469          destroy: destroy,
4470          events: events.registry
4471        };
4472      };
4473  
4474      var mkEvent = function (target, x, y, stop, prevent, kill, raw) {
4475        return {
4476          target: target,
4477          x: x,
4478          y: y,
4479          stop: stop,
4480          prevent: prevent,
4481          kill: kill,
4482          raw: raw
4483        };
4484      };
4485      var fromRawEvent$1 = function (rawEvent) {
4486        var target = SugarElement.fromDom(getOriginalEventTarget(rawEvent).getOr(rawEvent.target));
4487        var stop = function () {
4488          return rawEvent.stopPropagation();
4489        };
4490        var prevent = function () {
4491          return rawEvent.preventDefault();
4492        };
4493        var kill = compose(prevent, stop);
4494        return mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent);
4495      };
4496      var handle$2 = function (filter, handler) {
4497        return function (rawEvent) {
4498          if (filter(rawEvent)) {
4499            handler(fromRawEvent$1(rawEvent));
4500          }
4501        };
4502      };
4503      var binder = function (element, event, filter, handler, useCapture) {
4504        var wrapped = handle$2(filter, handler);
4505        element.dom.addEventListener(event, wrapped, useCapture);
4506        return { unbind: curry(unbind, element, event, wrapped, useCapture) };
4507      };
4508      var bind$1 = function (element, event, filter, handler) {
4509        return binder(element, event, filter, handler, false);
4510      };
4511      var unbind = function (element, event, handler, useCapture) {
4512        element.dom.removeEventListener(event, handler, useCapture);
4513      };
4514  
4515      var filter = always;
4516      var bind = function (element, event, handler) {
4517        return bind$1(element, event, filter, handler);
4518      };
4519      var fromRawEvent = fromRawEvent$1;
4520  
4521      var read = function (element, attr) {
4522        var value = get$b(element, attr);
4523        return value === undefined || value === '' ? [] : value.split(' ');
4524      };
4525      var add$2 = function (element, attr, id) {
4526        var old = read(element, attr);
4527        var nu = old.concat([id]);
4528        set$2(element, attr, nu.join(' '));
4529        return true;
4530      };
4531      var remove$4 = function (element, attr, id) {
4532        var nu = filter$2(read(element, attr), function (v) {
4533          return v !== id;
4534        });
4535        if (nu.length > 0) {
4536          set$2(element, attr, nu.join(' '));
4537        } else {
4538          remove$7(element, attr);
4539        }
4540        return false;
4541      };
4542  
4543      var supports = function (element) {
4544        return element.dom.classList !== undefined;
4545      };
4546      var get$5 = function (element) {
4547        return read(element, 'class');
4548      };
4549      var add$1 = function (element, clazz) {
4550        return add$2(element, 'class', clazz);
4551      };
4552      var remove$3 = function (element, clazz) {
4553        return remove$4(element, 'class', clazz);
4554      };
4555  
4556      var add = function (element, clazz) {
4557        if (supports(element)) {
4558          element.dom.classList.add(clazz);
4559        } else {
4560          add$1(element, clazz);
4561        }
4562      };
4563      var cleanClass = function (element) {
4564        var classList = supports(element) ? element.dom.classList : get$5(element);
4565        if (classList.length === 0) {
4566          remove$7(element, 'class');
4567        }
4568      };
4569      var remove$2 = function (element, clazz) {
4570        if (supports(element)) {
4571          var classList = element.dom.classList;
4572          classList.remove(clazz);
4573        } else {
4574          remove$3(element, clazz);
4575        }
4576        cleanClass(element);
4577      };
4578      var has = function (element, clazz) {
4579        return supports(element) && element.dom.classList.contains(clazz);
4580      };
4581  
4582      var css = function (namespace) {
4583        var dashNamespace = namespace.replace(/\./g, '-');
4584        var resolve = function (str) {
4585          return dashNamespace + '-' + str;
4586        };
4587        return { resolve: resolve };
4588      };
4589  
4590      var styles$1 = css('ephox-dragster');
4591      var resolve$1 = styles$1.resolve;
4592  
4593      var Blocker = function (options) {
4594        var settings = __assign({ layerClass: resolve$1('blocker') }, options);
4595        var div = SugarElement.fromTag('div');
4596        set$2(div, 'role', 'presentation');
4597        setAll(div, {
4598          position: 'fixed',
4599          left: '0px',
4600          top: '0px',
4601          width: '100%',
4602          height: '100%'
4603        });
4604        add(div, resolve$1('blocker'));
4605        add(div, settings.layerClass);
4606        var element = constant(div);
4607        var destroy = function () {
4608          remove$5(div);
4609        };
4610        return {
4611          element: element,
4612          destroy: destroy
4613        };
4614      };
4615  
4616      var compare = function (old, nu) {
4617        return SugarPosition(nu.left - old.left, nu.top - old.top);
4618      };
4619      var extract = function (event) {
4620        return Optional.some(SugarPosition(event.x, event.y));
4621      };
4622      var mutate = function (mutation, info) {
4623        mutation.mutate(info.left, info.top);
4624      };
4625      var sink = function (dragApi, settings) {
4626        var blocker = Blocker(settings);
4627        var mdown = bind(blocker.element(), 'mousedown', dragApi.forceDrop);
4628        var mup = bind(blocker.element(), 'mouseup', dragApi.drop);
4629        var mmove = bind(blocker.element(), 'mousemove', dragApi.move);
4630        var mout = bind(blocker.element(), 'mouseout', dragApi.delayDrop);
4631        var destroy = function () {
4632          blocker.destroy();
4633          mup.unbind();
4634          mmove.unbind();
4635          mout.unbind();
4636          mdown.unbind();
4637        };
4638        var start = function (parent) {
4639          append$1(parent, blocker.element());
4640        };
4641        var stop = function () {
4642          remove$5(blocker.element());
4643        };
4644        return DragSink({
4645          element: blocker.element,
4646          start: start,
4647          stop: stop,
4648          destroy: destroy
4649        });
4650      };
4651      var MouseDrag = DragMode({
4652        compare: compare,
4653        extract: extract,
4654        sink: sink,
4655        mutate: mutate
4656      });
4657  
4658      var transform$1 = function (mutation, settings) {
4659        if (settings === void 0) {
4660          settings = {};
4661        }
4662        var mode = settings.mode !== undefined ? settings.mode : MouseDrag;
4663        return setup(mutation, mode, settings);
4664      };
4665  
4666      var closest = function (target) {
4667        return closest$1(target, '[contenteditable]');
4668      };
4669      var isEditable$1 = function (element, assumeEditable) {
4670        if (assumeEditable === void 0) {
4671          assumeEditable = false;
4672        }
4673        if (!detect$3().browser.isIE() && inBody(element)) {
4674          return element.dom.isContentEditable;
4675        } else {
4676          return closest(element).fold(constant(assumeEditable), function (editable) {
4677            return getRaw(editable) === 'true';
4678          });
4679        }
4680      };
4681      var getRaw = function (element) {
4682        return element.dom.contentEditable;
4683      };
4684  
4685      var styles = css('ephox-snooker');
4686      var resolve = styles.resolve;
4687  
4688      var Mutation = function () {
4689        var events = create$4({
4690          drag: Event([
4691            'xDelta',
4692            'yDelta'
4693          ])
4694        });
4695        var mutate = function (x, y) {
4696          events.trigger.drag(x, y);
4697        };
4698        return {
4699          mutate: mutate,
4700          events: events.registry
4701        };
4702      };
4703  
4704      var BarMutation = function () {
4705        var events = create$4({
4706          drag: Event([
4707            'xDelta',
4708            'yDelta',
4709            'target'
4710          ])
4711        });
4712        var target = Optional.none();
4713        var delegate = Mutation();
4714        delegate.events.drag.bind(function (event) {
4715          target.each(function (t) {
4716            events.trigger.drag(event.xDelta, event.yDelta, t);
4717          });
4718        });
4719        var assign = function (t) {
4720          target = Optional.some(t);
4721        };
4722        var get = function () {
4723          return target;
4724        };
4725        return {
4726          assign: assign,
4727          get: get,
4728          mutate: delegate.mutate,
4729          events: events.registry
4730        };
4731      };
4732  
4733      var col = function (column, x, y, w, h) {
4734        var bar = SugarElement.fromTag('div');
4735        setAll(bar, {
4736          position: 'absolute',
4737          left: x - w / 2 + 'px',
4738          top: y + 'px',
4739          height: h + 'px',
4740          width: w + 'px'
4741        });
4742        setAll$1(bar, {
4743          'data-column': column,
4744          'role': 'presentation'
4745        });
4746        return bar;
4747      };
4748      var row = function (r, x, y, w, h) {
4749        var bar = SugarElement.fromTag('div');
4750        setAll(bar, {
4751          position: 'absolute',
4752          left: x + 'px',
4753          top: y - h / 2 + 'px',
4754          height: h + 'px',
4755          width: w + 'px'
4756        });
4757        setAll$1(bar, {
4758          'data-row': r,
4759          'role': 'presentation'
4760        });
4761        return bar;
4762      };
4763  
4764      var resizeBar = resolve('resizer-bar');
4765      var resizeRowBar = resolve('resizer-rows');
4766      var resizeColBar = resolve('resizer-cols');
4767      var BAR_THICKNESS = 7;
4768      var resizableRows = function (warehouse, isResizable) {
4769        return bind$2(warehouse.all, function (row, i) {
4770          return isResizable(row.element) ? [i] : [];
4771        });
4772      };
4773      var resizableColumns = function (warehouse, isResizable) {
4774        var resizableCols = [];
4775        range$1(warehouse.grid.columns, function (index) {
4776          var colElmOpt = Warehouse.getColumnAt(warehouse, index).map(function (col) {
4777            return col.element;
4778          });
4779          if (colElmOpt.forall(isResizable)) {
4780            resizableCols.push(index);
4781          }
4782        });
4783        return filter$2(resizableCols, function (colIndex) {
4784          var columnCells = Warehouse.filterItems(warehouse, function (cell) {
4785            return cell.column === colIndex;
4786          });
4787          return forall(columnCells, function (cell) {
4788            return isResizable(cell.element);
4789          });
4790        });
4791      };
4792      var destroy = function (wire) {
4793        var previous = descendants(wire.parent(), '.' + resizeBar);
4794        each$2(previous, remove$5);
4795      };
4796      var drawBar = function (wire, positions, create) {
4797        var origin = wire.origin();
4798        each$2(positions, function (cpOption) {
4799          cpOption.each(function (cp) {
4800            var bar = create(origin, cp);
4801            add(bar, resizeBar);
4802            append$1(wire.parent(), bar);
4803          });
4804        });
4805      };
4806      var refreshCol = function (wire, colPositions, position, tableHeight) {
4807        drawBar(wire, colPositions, function (origin, cp) {
4808          var colBar = col(cp.col, cp.x - origin.left, position.top - origin.top, BAR_THICKNESS, tableHeight);
4809          add(colBar, resizeColBar);
4810          return colBar;
4811        });
4812      };
4813      var refreshRow = function (wire, rowPositions, position, tableWidth) {
4814        drawBar(wire, rowPositions, function (origin, cp) {
4815          var rowBar = row(cp.row, position.left - origin.left, cp.y - origin.top, tableWidth, BAR_THICKNESS);
4816          add(rowBar, resizeRowBar);
4817          return rowBar;
4818        });
4819      };
4820      var refreshGrid = function (warhouse, wire, table, rows, cols) {
4821        var position = absolute(table);
4822        var isResizable = wire.isResizable;
4823        var rowPositions = rows.length > 0 ? height.positions(rows, table) : [];
4824        var resizableRowBars = rowPositions.length > 0 ? resizableRows(warhouse, isResizable) : [];
4825        var resizableRowPositions = filter$2(rowPositions, function (_pos, i) {
4826          return exists(resizableRowBars, function (barIndex) {
4827            return i === barIndex;
4828          });
4829        });
4830        refreshRow(wire, resizableRowPositions, position, getOuter$2(table));
4831        var colPositions = cols.length > 0 ? width.positions(cols, table) : [];
4832        var resizableColBars = colPositions.length > 0 ? resizableColumns(warhouse, isResizable) : [];
4833        var resizableColPositions = filter$2(colPositions, function (_pos, i) {
4834          return exists(resizableColBars, function (barIndex) {
4835            return i === barIndex;
4836          });
4837        });
4838        refreshCol(wire, resizableColPositions, position, getOuter$1(table));
4839      };
4840      var refresh = function (wire, table) {
4841        destroy(wire);
4842        if (wire.isResizable(table)) {
4843          var warehouse = Warehouse.fromTable(table);
4844          var rows$1 = rows(warehouse);
4845          var cols = columns(warehouse);
4846          refreshGrid(warehouse, wire, table, rows$1, cols);
4847        }
4848      };
4849      var each = function (wire, f) {
4850        var bars = descendants(wire.parent(), '.' + resizeBar);
4851        each$2(bars, f);
4852      };
4853      var hide = function (wire) {
4854        each(wire, function (bar) {
4855          set$1(bar, 'display', 'none');
4856        });
4857      };
4858      var show = function (wire) {
4859        each(wire, function (bar) {
4860          set$1(bar, 'display', 'block');
4861        });
4862      };
4863      var isRowBar = function (element) {
4864        return has(element, resizeRowBar);
4865      };
4866      var isColBar = function (element) {
4867        return has(element, resizeColBar);
4868      };
4869  
4870      var resizeBarDragging = resolve('resizer-bar-dragging');
4871      var BarManager = function (wire) {
4872        var mutation = BarMutation();
4873        var resizing = transform$1(mutation, {});
4874        var hoverTable = Optional.none();
4875        var getResizer = function (element, type) {
4876          return Optional.from(get$b(element, type));
4877        };
4878        mutation.events.drag.bind(function (event) {
4879          getResizer(event.target, 'data-row').each(function (_dataRow) {
4880            var currentRow = getCssValue(event.target, 'top');
4881            set$1(event.target, 'top', currentRow + event.yDelta + 'px');
4882          });
4883          getResizer(event.target, 'data-column').each(function (_dataCol) {
4884            var currentCol = getCssValue(event.target, 'left');
4885            set$1(event.target, 'left', currentCol + event.xDelta + 'px');
4886          });
4887        });
4888        var getDelta = function (target, dir) {
4889          var newX = getCssValue(target, dir);
4890          var oldX = getAttrValue(target, 'data-initial-' + dir, 0);
4891          return newX - oldX;
4892        };
4893        resizing.events.stop.bind(function () {
4894          mutation.get().each(function (target) {
4895            hoverTable.each(function (table) {
4896              getResizer(target, 'data-row').each(function (row) {
4897                var delta = getDelta(target, 'top');
4898                remove$7(target, 'data-initial-top');
4899                events.trigger.adjustHeight(table, delta, parseInt(row, 10));
4900              });
4901              getResizer(target, 'data-column').each(function (column) {
4902                var delta = getDelta(target, 'left');
4903                remove$7(target, 'data-initial-left');
4904                events.trigger.adjustWidth(table, delta, parseInt(column, 10));
4905              });
4906              refresh(wire, table);
4907            });
4908          });
4909        });
4910        var handler = function (target, dir) {
4911          events.trigger.startAdjust();
4912          mutation.assign(target);
4913          set$2(target, 'data-initial-' + dir, getCssValue(target, dir));
4914          add(target, resizeBarDragging);
4915          set$1(target, 'opacity', '0.2');
4916          resizing.go(wire.parent());
4917        };
4918        var mousedown = bind(wire.parent(), 'mousedown', function (event) {
4919          if (isRowBar(event.target)) {
4920            handler(event.target, 'top');
4921          }
4922          if (isColBar(event.target)) {
4923            handler(event.target, 'left');
4924          }
4925        });
4926        var isRoot = function (e) {
4927          return eq$1(e, wire.view());
4928        };
4929        var findClosestEditableTable = function (target) {
4930          return closest$1(target, 'table', isRoot).filter(isEditable$1);
4931        };
4932        var mouseover = bind(wire.view(), 'mouseover', function (event) {
4933          findClosestEditableTable(event.target).fold(function () {
4934            if (inBody(event.target)) {
4935              destroy(wire);
4936            }
4937          }, function (table) {
4938            hoverTable = Optional.some(table);
4939            refresh(wire, table);
4940          });
4941        });
4942        var destroy$1 = function () {
4943          mousedown.unbind();
4944          mouseover.unbind();
4945          resizing.destroy();
4946          destroy(wire);
4947        };
4948        var refresh$1 = function (tbl) {
4949          refresh(wire, tbl);
4950        };
4951        var events = create$4({
4952          adjustHeight: Event([
4953            'table',
4954            'delta',
4955            'row'
4956          ]),
4957          adjustWidth: Event([
4958            'table',
4959            'delta',
4960            'column'
4961          ]),
4962          startAdjust: Event([])
4963        });
4964        return {
4965          destroy: destroy$1,
4966          refresh: refresh$1,
4967          on: resizing.on,
4968          off: resizing.off,
4969          hideBars: curry(hide, wire),
4970          showBars: curry(show, wire),
4971          events: events.registry
4972        };
4973      };
4974  
4975      var create$3 = function (wire, resizing, lazySizing) {
4976        var hdirection = height;
4977        var vdirection = width;
4978        var manager = BarManager(wire);
4979        var events = create$4({
4980          beforeResize: Event([
4981            'table',
4982            'type'
4983          ]),
4984          afterResize: Event([
4985            'table',
4986            'type'
4987          ]),
4988          startDrag: Event([])
4989        });
4990        manager.events.adjustHeight.bind(function (event) {
4991          var table = event.table;
4992          events.trigger.beforeResize(table, 'row');
4993          var delta = hdirection.delta(event.delta, table);
4994          adjustHeight(table, delta, event.row, hdirection);
4995          events.trigger.afterResize(table, 'row');
4996        });
4997        manager.events.startAdjust.bind(function (_event) {
4998          events.trigger.startDrag();
4999        });
5000        manager.events.adjustWidth.bind(function (event) {
5001          var table = event.table;
5002          events.trigger.beforeResize(table, 'col');
5003          var delta = vdirection.delta(event.delta, table);
5004          var tableSize = lazySizing(table);
5005          adjustWidth(table, delta, event.column, resizing, tableSize);
5006          events.trigger.afterResize(table, 'col');
5007        });
5008        return {
5009          on: manager.on,
5010          off: manager.off,
5011          hideBars: manager.hideBars,
5012          showBars: manager.showBars,
5013          destroy: manager.destroy,
5014          events: events.registry
5015        };
5016      };
5017      var TableResize = { create: create$3 };
5018  
5019      var fireNewRow = function (editor, row) {
5020        return editor.fire('newrow', { node: row });
5021      };
5022      var fireNewCell = function (editor, cell) {
5023        return editor.fire('newcell', { node: cell });
5024      };
5025      var fireObjectResizeStart = function (editor, target, width, height, origin) {
5026        editor.fire('ObjectResizeStart', {
5027          target: target,
5028          width: width,
5029          height: height,
5030          origin: origin
5031        });
5032      };
5033      var fireObjectResized = function (editor, target, width, height, origin) {
5034        editor.fire('ObjectResized', {
5035          target: target,
5036          width: width,
5037          height: height,
5038          origin: origin
5039        });
5040      };
5041      var fireTableSelectionChange = function (editor, cells, start, finish, otherCells) {
5042        editor.fire('TableSelectionChange', {
5043          cells: cells,
5044          start: start,
5045          finish: finish,
5046          otherCells: otherCells
5047        });
5048      };
5049      var fireTableSelectionClear = function (editor) {
5050        editor.fire('TableSelectionClear');
5051      };
5052      var fireTableModified = function (editor, table, data) {
5053        editor.fire('TableModified', __assign(__assign({}, data), { table: table }));
5054      };
5055      var styleModified = {
5056        structure: false,
5057        style: true
5058      };
5059      var structureModified = {
5060        structure: true,
5061        style: false
5062      };
5063      var styleAndStructureModified = {
5064        structure: true,
5065        style: true
5066      };
5067  
5068      var defaultTableToolbar = 'tableprops tabledelete | tableinsertrowbefore tableinsertrowafter tabledeleterow | tableinsertcolbefore tableinsertcolafter tabledeletecol';
5069      var defaultStyles = {
5070        'border-collapse': 'collapse',
5071        'width': '100%'
5072      };
5073      var defaultCellBorderWidths = range$1(5, function (i) {
5074        var size = i + 1 + 'px';
5075        return {
5076          title: size,
5077          value: size
5078        };
5079      });
5080      var defaultCellBorderStyles = map$1([
5081        'Solid',
5082        'Dotted',
5083        'Dashed',
5084        'Double',
5085        'Groove',
5086        'Ridge',
5087        'Inset',
5088        'Outset',
5089        'None',
5090        'Hidden'
5091      ], function (type) {
5092        return {
5093          title: type,
5094          value: type.toLowerCase()
5095        };
5096      });
5097      var determineDefaultStyles = function (editor) {
5098        var _a;
5099        if (isPixelsForced(editor)) {
5100          var dom = editor.dom;
5101          var parentBlock = (_a = dom.getParent(editor.selection.getStart(), dom.isBlock)) !== null && _a !== void 0 ? _a : editor.getBody();
5102          var contentWidth = getInner(SugarElement.fromDom(parentBlock));
5103          return __assign(__assign({}, defaultStyles), { width: contentWidth + 'px' });
5104        } else if (isResponsiveForced(editor)) {
5105          return filter$1(defaultStyles, function (_value, key) {
5106            return key !== 'width';
5107          });
5108        } else {
5109          return defaultStyles;
5110        }
5111      };
5112      var defaultAttributes = { border: '1' };
5113      var defaultColumnResizingBehaviour = 'preservetable';
5114      var getTableSizingMode = function (editor) {
5115        return editor.getParam('table_sizing_mode', 'auto');
5116      };
5117      var getTableResponseWidth = function (editor) {
5118        return editor.getParam('table_responsive_width');
5119      };
5120      var getTableBorderWidths = function (editor) {
5121        return editor.getParam('table_border_widths', defaultCellBorderWidths, 'array');
5122      };
5123      var getTableBorderStyles = function (editor) {
5124        return editor.getParam('table_border_styles', defaultCellBorderStyles, 'array');
5125      };
5126      var getDefaultAttributes = function (editor) {
5127        return editor.getParam('table_default_attributes', defaultAttributes, 'object');
5128      };
5129      var getDefaultStyles = function (editor) {
5130        return editor.getParam('table_default_styles', determineDefaultStyles(editor), 'object');
5131      };
5132      var hasTableResizeBars = function (editor) {
5133        return editor.getParam('table_resize_bars', true, 'boolean');
5134      };
5135      var hasTabNavigation = function (editor) {
5136        return editor.getParam('table_tab_navigation', true, 'boolean');
5137      };
5138      var hasAdvancedCellTab = function (editor) {
5139        return editor.getParam('table_cell_advtab', true, 'boolean');
5140      };
5141      var hasAdvancedRowTab = function (editor) {
5142        return editor.getParam('table_row_advtab', true, 'boolean');
5143      };
5144      var hasAdvancedTableTab = function (editor) {
5145        return editor.getParam('table_advtab', true, 'boolean');
5146      };
5147      var hasAppearanceOptions = function (editor) {
5148        return editor.getParam('table_appearance_options', true, 'boolean');
5149      };
5150      var hasTableGrid = function (editor) {
5151        return editor.getParam('table_grid', true, 'boolean');
5152      };
5153      var shouldStyleWithCss = function (editor) {
5154        return editor.getParam('table_style_by_css', false, 'boolean');
5155      };
5156      var getCellClassList = function (editor) {
5157        return editor.getParam('table_cell_class_list', [], 'array');
5158      };
5159      var getRowClassList = function (editor) {
5160        return editor.getParam('table_row_class_list', [], 'array');
5161      };
5162      var getTableClassList = function (editor) {
5163        return editor.getParam('table_class_list', [], 'array');
5164      };
5165      var isPercentagesForced = function (editor) {
5166        return getTableSizingMode(editor) === 'relative' || getTableResponseWidth(editor) === true;
5167      };
5168      var isPixelsForced = function (editor) {
5169        return getTableSizingMode(editor) === 'fixed' || getTableResponseWidth(editor) === false;
5170      };
5171      var isResponsiveForced = function (editor) {
5172        return getTableSizingMode(editor) === 'responsive';
5173      };
5174      var getToolbar = function (editor) {
5175        return editor.getParam('table_toolbar', defaultTableToolbar);
5176      };
5177      var useColumnGroup = function (editor) {
5178        return editor.getParam('table_use_colgroups', false, 'boolean');
5179      };
5180      var getTableHeaderType = function (editor) {
5181        var defaultValue = 'section';
5182        var value = editor.getParam('table_header_type', defaultValue, 'string');
5183        var validValues = [
5184          'section',
5185          'cells',
5186          'sectionCells',
5187          'auto'
5188        ];
5189        if (!contains$2(validValues, value)) {
5190          return defaultValue;
5191        } else {
5192          return value;
5193        }
5194      };
5195      var getColumnResizingBehaviour = function (editor) {
5196        var validModes = [
5197          'preservetable',
5198          'resizetable'
5199        ];
5200        var givenMode = editor.getParam('table_column_resizing', defaultColumnResizingBehaviour, 'string');
5201        return find$1(validModes, function (mode) {
5202          return mode === givenMode;
5203        }).getOr(defaultColumnResizingBehaviour);
5204      };
5205      var isPreserveTableColumnResizing = function (editor) {
5206        return getColumnResizingBehaviour(editor) === 'preservetable';
5207      };
5208      var isResizeTableColumnResizing = function (editor) {
5209        return getColumnResizingBehaviour(editor) === 'resizetable';
5210      };
5211      var getCloneElements = function (editor) {
5212        var cloneElements = editor.getParam('table_clone_elements');
5213        if (isString(cloneElements)) {
5214          return Optional.some(cloneElements.split(/[ ,]/));
5215        } else if (Array.isArray(cloneElements)) {
5216          return Optional.some(cloneElements);
5217        } else {
5218          return Optional.none();
5219        }
5220      };
5221      var hasObjectResizing = function (editor) {
5222        var objectResizing = editor.getParam('object_resizing', true);
5223        return isString(objectResizing) ? objectResizing === 'table' : objectResizing;
5224      };
5225      var getTableBackgroundColorMap = function (editor) {
5226        return editor.getParam('table_background_color_map', [], 'array');
5227      };
5228      var getTableBorderColorMap = function (editor) {
5229        return editor.getParam('table_border_color_map', [], 'array');
5230      };
5231  
5232      var get$4 = function (editor, table) {
5233        if (isPercentagesForced(editor)) {
5234          return TableSize.percentageSize(table);
5235        } else if (isPixelsForced(editor)) {
5236          return TableSize.pixelSize(table);
5237        } else {
5238          return TableSize.getTableSize(table);
5239        }
5240      };
5241  
5242      var cleanupLegacyAttributes = function (element) {
5243        remove$7(element, 'width');
5244      };
5245      var convertToPercentSize = function (table) {
5246        var newWidth = getPercentTableWidth(table);
5247        redistribute(table, Optional.some(newWidth), Optional.none());
5248        cleanupLegacyAttributes(table);
5249      };
5250      var convertToPixelSize = function (table) {
5251        var newWidth = getPixelTableWidth(table);
5252        redistribute(table, Optional.some(newWidth), Optional.none());
5253        cleanupLegacyAttributes(table);
5254      };
5255      var convertToNoneSize = function (table) {
5256        remove$6(table, 'width');
5257        var columns = columns$1(table);
5258        var rowElements = columns.length > 0 ? columns : cells$1(table);
5259        each$2(rowElements, function (cell) {
5260          remove$6(cell, 'width');
5261          cleanupLegacyAttributes(cell);
5262        });
5263        cleanupLegacyAttributes(table);
5264      };
5265  
5266      var enforcePercentage = convertToPercentSize;
5267      var enforcePixels = convertToPixelSize;
5268      var enforceNone = convertToNoneSize;
5269      var syncPixels = function (table) {
5270        var warehouse = Warehouse.fromTable(table);
5271        if (!Warehouse.hasColumns(warehouse)) {
5272          each$2(cells$1(table), function (cell) {
5273            var computedWidth = get$a(cell, 'width');
5274            set$1(cell, 'width', computedWidth);
5275            remove$7(cell, 'width');
5276          });
5277        }
5278      };
5279  
5280      var createContainer = function () {
5281        var container = SugarElement.fromTag('div');
5282        setAll(container, {
5283          position: 'static',
5284          height: '0',
5285          width: '0',
5286          padding: '0',
5287          margin: '0',
5288          border: '0'
5289        });
5290        append$1(body$1(), container);
5291        return container;
5292      };
5293      var get$3 = function (editor, isResizable) {
5294        return editor.inline ? ResizeWire.body(getBody(editor), createContainer(), isResizable) : ResizeWire.only(SugarElement.fromDom(editor.getDoc()), isResizable);
5295      };
5296      var remove$1 = function (editor, wire) {
5297        if (editor.inline) {
5298          remove$5(wire.parent());
5299        }
5300      };
5301  
5302      var barResizerPrefix = 'bar-';
5303      var isResizable = function (elm) {
5304        return get$b(elm, 'data-mce-resize') !== 'false';
5305      };
5306      var getResizeHandler = function (editor) {
5307        var selectionRng = Optional.none();
5308        var resize = Optional.none();
5309        var wire = Optional.none();
5310        var startW;
5311        var startRawW;
5312        var isTable = function (elm) {
5313          return elm.nodeName === 'TABLE';
5314        };
5315        var lazyResize = function () {
5316          return resize;
5317        };
5318        var lazyWire = function () {
5319          return wire.getOr(ResizeWire.only(SugarElement.fromDom(editor.getBody()), isResizable));
5320        };
5321        var lazySizing = function (table) {
5322          return get$4(editor, table);
5323        };
5324        var lazyResizingBehaviour = function () {
5325          return isPreserveTableColumnResizing(editor) ? preserveTable() : resizeTable();
5326        };
5327        var getNumColumns = function (table) {
5328          return getGridSize(table).columns;
5329        };
5330        var afterCornerResize = function (table, origin, width) {
5331          var isRightEdgeResize = endsWith(origin, 'e');
5332          if (startRawW === '') {
5333            enforcePercentage(table);
5334          }
5335          if (width !== startW && startRawW !== '') {
5336            set$1(table, 'width', startRawW);
5337            var resizing = lazyResizingBehaviour();
5338            var tableSize = lazySizing(table);
5339            var col = isPreserveTableColumnResizing(editor) || isRightEdgeResize ? getNumColumns(table) - 1 : 0;
5340            adjustWidth(table, width - startW, col, resizing, tableSize);
5341          } else if (isPercentage$1(startRawW)) {
5342            var percentW = parseFloat(startRawW.replace('%', ''));
5343            var targetPercentW = width * percentW / startW;
5344            set$1(table, 'width', targetPercentW + '%');
5345          }
5346          if (isPixel(startRawW)) {
5347            syncPixels(table);
5348          }
5349        };
5350        var destroy = function () {
5351          resize.each(function (sz) {
5352            sz.destroy();
5353          });
5354          wire.each(function (w) {
5355            remove$1(editor, w);
5356          });
5357        };
5358        editor.on('init', function () {
5359          var rawWire = get$3(editor, isResizable);
5360          wire = Optional.some(rawWire);
5361          if (hasObjectResizing(editor) && hasTableResizeBars(editor)) {
5362            var resizing = lazyResizingBehaviour();
5363            var sz = TableResize.create(rawWire, resizing, lazySizing);
5364            sz.on();
5365            sz.events.startDrag.bind(function (_event) {
5366              selectionRng = Optional.some(editor.selection.getRng());
5367            });
5368            sz.events.beforeResize.bind(function (event) {
5369              var rawTable = event.table.dom;
5370              fireObjectResizeStart(editor, rawTable, getPixelWidth(rawTable), getPixelHeight(rawTable), barResizerPrefix + event.type);
5371            });
5372            sz.events.afterResize.bind(function (event) {
5373              var table = event.table;
5374              var rawTable = table.dom;
5375              removeDataStyle(table);
5376              selectionRng.each(function (rng) {
5377                editor.selection.setRng(rng);
5378                editor.focus();
5379              });
5380              fireObjectResized(editor, rawTable, getPixelWidth(rawTable), getPixelHeight(rawTable), barResizerPrefix + event.type);
5381              editor.undoManager.add();
5382            });
5383            resize = Optional.some(sz);
5384          }
5385        });
5386        editor.on('ObjectResizeStart', function (e) {
5387          var targetElm = e.target;
5388          if (isTable(targetElm)) {
5389            var table = SugarElement.fromDom(targetElm);
5390            each$2(editor.dom.select('.mce-clonedresizable'), function (clone) {
5391              editor.dom.addClass(clone, 'mce-' + getColumnResizingBehaviour(editor) + '-columns');
5392            });
5393            if (!isPixelSizing(table) && isPixelsForced(editor)) {
5394              enforcePixels(table);
5395            } else if (!isPercentSizing(table) && isPercentagesForced(editor)) {
5396              enforcePercentage(table);
5397            }
5398            if (isNoneSizing(table) && startsWith(e.origin, barResizerPrefix)) {
5399              enforcePercentage(table);
5400            }
5401            startW = e.width;
5402            startRawW = isResponsiveForced(editor) ? '' : getRawWidth(editor, targetElm).getOr('');
5403          }
5404        });
5405        editor.on('ObjectResized', function (e) {
5406          var targetElm = e.target;
5407          if (isTable(targetElm)) {
5408            var table = SugarElement.fromDom(targetElm);
5409            var origin_1 = e.origin;
5410            if (startsWith(origin_1, 'corner-')) {
5411              afterCornerResize(table, origin_1, e.width);
5412            }
5413            removeDataStyle(table);
5414            fireTableModified(editor, table.dom, styleModified);
5415          }
5416        });
5417        editor.on('SwitchMode', function () {
5418          lazyResize().each(function (resize) {
5419            if (editor.mode.isReadOnly()) {
5420              resize.hideBars();
5421            } else {
5422              resize.showBars();
5423            }
5424          });
5425        });
5426        return {
5427          lazyResize: lazyResize,
5428          lazyWire: lazyWire,
5429          destroy: destroy
5430        };
5431      };
5432  
5433      var point = function (element, offset) {
5434        return {
5435          element: element,
5436          offset: offset
5437        };
5438      };
5439  
5440      var scan$1 = function (universe, element, direction) {
5441        if (universe.property().isText(element) && universe.property().getText(element).trim().length === 0 || universe.property().isComment(element)) {
5442          return direction(element).bind(function (elem) {
5443            return scan$1(universe, elem, direction).orThunk(function () {
5444              return Optional.some(elem);
5445            });
5446          });
5447        } else {
5448          return Optional.none();
5449        }
5450      };
5451      var toEnd = function (universe, element) {
5452        if (universe.property().isText(element)) {
5453          return universe.property().getText(element).length;
5454        }
5455        var children = universe.property().children(element);
5456        return children.length;
5457      };
5458      var freefallRtl$2 = function (universe, element) {
5459        var candidate = scan$1(universe, element, universe.query().prevSibling).getOr(element);
5460        if (universe.property().isText(candidate)) {
5461          return point(candidate, toEnd(universe, candidate));
5462        }
5463        var children = universe.property().children(candidate);
5464        return children.length > 0 ? freefallRtl$2(universe, children[children.length - 1]) : point(candidate, toEnd(universe, candidate));
5465      };
5466  
5467      var freefallRtl$1 = freefallRtl$2;
5468  
5469      var universe$2 = DomUniverse();
5470      var freefallRtl = function (element) {
5471        return freefallRtl$1(universe$2, element);
5472      };
5473  
5474      var halve = function (main, other) {
5475        var colspan = getSpan(main, 'colspan');
5476        if (colspan === 1) {
5477          var width = getGenericWidth(main);
5478          width.each(function (w) {
5479            var newWidth = w.value / 2;
5480            setGenericWidth(main, newWidth, w.unit);
5481            setGenericWidth(other, newWidth, w.unit);
5482          });
5483        }
5484      };
5485  
5486      var isHeaderCell = isTag('th');
5487      var isHeaderCells = function (cells) {
5488        return forall(cells, function (cell) {
5489          return isHeaderCell(cell.element);
5490        });
5491      };
5492      var getRowHeaderType = function (isHeaderRow, isHeaderCells) {
5493        if (isHeaderRow && isHeaderCells) {
5494          return 'sectionCells';
5495        } else if (isHeaderRow) {
5496          return 'section';
5497        } else {
5498          return 'cells';
5499        }
5500      };
5501      var getRowType$1 = function (row) {
5502        var isHeaderRow = row.section === 'thead';
5503        var isHeaderCells = is(findCommonCellType(row.cells), 'th');
5504        if (isHeaderRow || isHeaderCells) {
5505          return {
5506            type: 'header',
5507            subType: getRowHeaderType(isHeaderRow, isHeaderCells)
5508          };
5509        } else if (row.section === 'tfoot') {
5510          return { type: 'footer' };
5511        } else {
5512          return { type: 'body' };
5513        }
5514      };
5515      var findCommonCellType = function (cells) {
5516        var headerCells = filter$2(cells, function (cell) {
5517          return isHeaderCell(cell.element);
5518        });
5519        if (headerCells.length === 0) {
5520          return Optional.some('td');
5521        } else if (headerCells.length === cells.length) {
5522          return Optional.some('th');
5523        } else {
5524          return Optional.none();
5525        }
5526      };
5527      var findCommonRowType = function (rows) {
5528        var rowTypes = map$1(rows, function (row) {
5529          return getRowType$1(row).type;
5530        });
5531        var hasHeader = contains$2(rowTypes, 'header');
5532        var hasFooter = contains$2(rowTypes, 'footer');
5533        if (!hasHeader && !hasFooter) {
5534          return Optional.some('body');
5535        } else {
5536          var hasBody = contains$2(rowTypes, 'body');
5537          if (hasHeader && !hasBody && !hasFooter) {
5538            return Optional.some('header');
5539          } else if (!hasHeader && !hasBody && hasFooter) {
5540            return Optional.some('footer');
5541          } else {
5542            return Optional.none();
5543          }
5544        }
5545      };
5546      var findTableRowHeaderType = function (warehouse) {
5547        return findMap(warehouse.all, function (row) {
5548          var rowType = getRowType$1(row);
5549          return rowType.type === 'header' ? Optional.from(rowType.subType) : Optional.none();
5550        });
5551      };
5552  
5553      var transformCell = function (cell, comparator, substitution) {
5554        return elementnew(substitution(cell.element, comparator), true, cell.isLocked);
5555      };
5556      var transformRow = function (row, section) {
5557        return row.section !== section ? rowcells(row.element, row.cells, section, row.isNew) : row;
5558      };
5559      var section = function () {
5560        return {
5561          transformRow: transformRow,
5562          transformCell: function (cell, comparator, substitution) {
5563            var newCell = substitution(cell.element, comparator);
5564            var fixedCell = name(newCell) !== 'td' ? mutate$1(newCell, 'td') : newCell;
5565            return elementnew(fixedCell, cell.isNew, cell.isLocked);
5566          }
5567        };
5568      };
5569      var sectionCells = function () {
5570        return {
5571          transformRow: transformRow,
5572          transformCell: transformCell
5573        };
5574      };
5575      var cells = function () {
5576        return {
5577          transformRow: function (row, section) {
5578            var newSection = section === 'thead' ? 'tbody' : section;
5579            return transformRow(row, newSection);
5580          },
5581          transformCell: transformCell
5582        };
5583      };
5584      var fallback = function () {
5585        return {
5586          transformRow: identity,
5587          transformCell: transformCell
5588        };
5589      };
5590      var getTableSectionType = function (table, fallback) {
5591        var warehouse = Warehouse.fromTable(table);
5592        var type = findTableRowHeaderType(warehouse).getOr(fallback);
5593        switch (type) {
5594        case 'section':
5595          return section();
5596        case 'sectionCells':
5597          return sectionCells();
5598        case 'cells':
5599          return cells();
5600        }
5601      };
5602      var TableSection = {
5603        getTableSectionType: getTableSectionType,
5604        section: section,
5605        sectionCells: sectionCells,
5606        cells: cells,
5607        fallback: fallback
5608      };
5609  
5610      var setIfNot = function (element, property, value, ignore) {
5611        if (value === ignore) {
5612          remove$7(element, property);
5613        } else {
5614          set$2(element, property, value);
5615        }
5616      };
5617      var insert$1 = function (table, selector, element) {
5618        last$2(children$1(table, selector)).fold(function () {
5619          return prepend(table, element);
5620        }, function (child) {
5621          return after$5(child, element);
5622        });
5623      };
5624      var generateSection = function (table, sectionName) {
5625        var section = child$1(table, sectionName).getOrThunk(function () {
5626          var newSection = SugarElement.fromTag(sectionName, owner(table).dom);
5627          if (sectionName === 'thead') {
5628            insert$1(table, 'caption,colgroup', newSection);
5629          } else if (sectionName === 'colgroup') {
5630            insert$1(table, 'caption', newSection);
5631          } else {
5632            append$1(table, newSection);
5633          }
5634          return newSection;
5635        });
5636        empty(section);
5637        return section;
5638      };
5639      var render$1 = function (table, grid) {
5640        var newRows = [];
5641        var newCells = [];
5642        var syncRows = function (gridSection) {
5643          return map$1(gridSection, function (row) {
5644            if (row.isNew) {
5645              newRows.push(row.element);
5646            }
5647            var tr = row.element;
5648            empty(tr);
5649            each$2(row.cells, function (cell) {
5650              if (cell.isNew) {
5651                newCells.push(cell.element);
5652              }
5653              setIfNot(cell.element, 'colspan', cell.colspan, 1);
5654              setIfNot(cell.element, 'rowspan', cell.rowspan, 1);
5655              append$1(tr, cell.element);
5656            });
5657            return tr;
5658          });
5659        };
5660        var syncColGroup = function (gridSection) {
5661          return bind$2(gridSection, function (colGroup) {
5662            return map$1(colGroup.cells, function (col) {
5663              setIfNot(col.element, 'span', col.colspan, 1);
5664              return col.element;
5665            });
5666          });
5667        };
5668        var renderSection = function (gridSection, sectionName) {
5669          var section = generateSection(table, sectionName);
5670          var sync = sectionName === 'colgroup' ? syncColGroup : syncRows;
5671          var sectionElems = sync(gridSection);
5672          append(section, sectionElems);
5673        };
5674        var removeSection = function (sectionName) {
5675          child$1(table, sectionName).each(remove$5);
5676        };
5677        var renderOrRemoveSection = function (gridSection, sectionName) {
5678          if (gridSection.length > 0) {
5679            renderSection(gridSection, sectionName);
5680          } else {
5681            removeSection(sectionName);
5682          }
5683        };
5684        var headSection = [];
5685        var bodySection = [];
5686        var footSection = [];
5687        var columnGroupsSection = [];
5688        each$2(grid, function (row) {
5689          switch (row.section) {
5690          case 'thead':
5691            headSection.push(row);
5692            break;
5693          case 'tbody':
5694            bodySection.push(row);
5695            break;
5696          case 'tfoot':
5697            footSection.push(row);
5698            break;
5699          case 'colgroup':
5700            columnGroupsSection.push(row);
5701            break;
5702          }
5703        });
5704        renderOrRemoveSection(columnGroupsSection, 'colgroup');
5705        renderOrRemoveSection(headSection, 'thead');
5706        renderOrRemoveSection(bodySection, 'tbody');
5707        renderOrRemoveSection(footSection, 'tfoot');
5708        return {
5709          newRows: newRows,
5710          newCells: newCells
5711        };
5712      };
5713      var copy = function (grid) {
5714        return map$1(grid, function (row) {
5715          var tr = shallow(row.element);
5716          each$2(row.cells, function (cell) {
5717            var clonedCell = deep(cell.element);
5718            setIfNot(clonedCell, 'colspan', cell.colspan, 1);
5719            setIfNot(clonedCell, 'rowspan', cell.rowspan, 1);
5720            append$1(tr, clonedCell);
5721          });
5722          return tr;
5723        });
5724      };
5725  
5726      var getColumn = function (grid, index) {
5727        return map$1(grid, function (row) {
5728          return getCell(row, index);
5729        });
5730      };
5731      var getRow = function (grid, index) {
5732        return grid[index];
5733      };
5734      var findDiff = function (xs, comp) {
5735        if (xs.length === 0) {
5736          return 0;
5737        }
5738        var first = xs[0];
5739        var index = findIndex(xs, function (x) {
5740          return !comp(first.element, x.element);
5741        });
5742        return index.getOr(xs.length);
5743      };
5744      var subgrid = function (grid, row, column, comparator) {
5745        var gridRow = getRow(grid, row);
5746        var isColRow = gridRow.section === 'colgroup';
5747        var colspan = findDiff(gridRow.cells.slice(column), comparator);
5748        var rowspan = isColRow ? 1 : findDiff(getColumn(grid.slice(row), column), comparator);
5749        return {
5750          colspan: colspan,
5751          rowspan: rowspan
5752        };
5753      };
5754  
5755      var toDetails = function (grid, comparator) {
5756        var seen = map$1(grid, function (row) {
5757          return map$1(row.cells, never);
5758        });
5759        var updateSeen = function (rowIndex, columnIndex, rowspan, colspan) {
5760          for (var row = rowIndex; row < rowIndex + rowspan; row++) {
5761            for (var column = columnIndex; column < columnIndex + colspan; column++) {
5762              seen[row][column] = true;
5763            }
5764          }
5765        };
5766        return map$1(grid, function (row, rowIndex) {
5767          var details = bind$2(row.cells, function (cell, columnIndex) {
5768            if (seen[rowIndex][columnIndex] === false) {
5769              var result = subgrid(grid, rowIndex, columnIndex, comparator);
5770              updateSeen(rowIndex, columnIndex, result.rowspan, result.colspan);
5771              return [detailnew(cell.element, result.rowspan, result.colspan, cell.isNew)];
5772            } else {
5773              return [];
5774            }
5775          });
5776          return rowdetailnew(row.element, details, row.section, row.isNew);
5777        });
5778      };
5779      var toGrid = function (warehouse, generators, isNew) {
5780        var grid = [];
5781        each$2(warehouse.colgroups, function (colgroup) {
5782          var colgroupCols = [];
5783          for (var columnIndex = 0; columnIndex < warehouse.grid.columns; columnIndex++) {
5784            var element = Warehouse.getColumnAt(warehouse, columnIndex).map(function (column) {
5785              return elementnew(column.element, isNew, false);
5786            }).getOrThunk(function () {
5787              return elementnew(generators.colGap(), true, false);
5788            });
5789            colgroupCols.push(element);
5790          }
5791          grid.push(rowcells(colgroup.element, colgroupCols, 'colgroup', isNew));
5792        });
5793        for (var rowIndex = 0; rowIndex < warehouse.grid.rows; rowIndex++) {
5794          var rowCells = [];
5795          for (var columnIndex = 0; columnIndex < warehouse.grid.columns; columnIndex++) {
5796            var element = Warehouse.getAt(warehouse, rowIndex, columnIndex).map(function (item) {
5797              return elementnew(item.element, isNew, item.isLocked);
5798            }).getOrThunk(function () {
5799              return elementnew(generators.gap(), true, false);
5800            });
5801            rowCells.push(element);
5802          }
5803          var rowDetail = warehouse.all[rowIndex];
5804          var row = rowcells(rowDetail.element, rowCells, rowDetail.section, isNew);
5805          grid.push(row);
5806        }
5807        return grid;
5808      };
5809  
5810      var fromWarehouse = function (warehouse, generators) {
5811        return toGrid(warehouse, generators, false);
5812      };
5813      var toDetailList = function (grid) {
5814        return toDetails(grid, eq$1);
5815      };
5816      var findInWarehouse = function (warehouse, element) {
5817        return findMap(warehouse.all, function (r) {
5818          return find$1(r.cells, function (e) {
5819            return eq$1(element, e.element);
5820          });
5821        });
5822      };
5823      var extractCells = function (warehouse, target, predicate) {
5824        var details = map$1(target.selection, function (cell$1) {
5825          return cell(cell$1).bind(function (lc) {
5826            return findInWarehouse(warehouse, lc);
5827          }).filter(predicate);
5828        });
5829        var cells = cat(details);
5830        return someIf(cells.length > 0, cells);
5831      };
5832      var run = function (operation, extract, adjustment, postAction, genWrappers) {
5833        return function (wire, table, target, generators, behaviours) {
5834          var warehouse = Warehouse.fromTable(table);
5835          var tableSection = Optional.from(behaviours === null || behaviours === void 0 ? void 0 : behaviours.section).getOrThunk(TableSection.fallback);
5836          var output = extract(warehouse, target).map(function (info) {
5837            var model = fromWarehouse(warehouse, generators);
5838            var result = operation(model, info, eq$1, genWrappers(generators), tableSection);
5839            var lockedColumns = getLockedColumnsFromGrid(result.grid);
5840            var grid = toDetailList(result.grid);
5841            return {
5842              info: info,
5843              grid: grid,
5844              cursor: result.cursor,
5845              lockedColumns: lockedColumns
5846            };
5847          });
5848          return output.bind(function (out) {
5849            var newElements = render$1(table, out.grid);
5850            var tableSizing = Optional.from(behaviours === null || behaviours === void 0 ? void 0 : behaviours.sizing).getOrThunk(function () {
5851              return TableSize.getTableSize(table);
5852            });
5853            var resizing = Optional.from(behaviours === null || behaviours === void 0 ? void 0 : behaviours.resize).getOrThunk(preserveTable);
5854            adjustment(table, out.grid, out.info, {
5855              sizing: tableSizing,
5856              resize: resizing,
5857              section: tableSection
5858            });
5859            postAction(table);
5860            refresh(wire, table);
5861            remove$7(table, LOCKED_COL_ATTR);
5862            if (out.lockedColumns.length > 0) {
5863              set$2(table, LOCKED_COL_ATTR, out.lockedColumns.join(','));
5864            }
5865            return Optional.some({
5866              cursor: out.cursor,
5867              newRows: newElements.newRows,
5868              newCells: newElements.newCells
5869            });
5870          });
5871        };
5872      };
5873      var onPaste = function (warehouse, target) {
5874        return cell(target.element).bind(function (cell) {
5875          return findInWarehouse(warehouse, cell).map(function (details) {
5876            var value = __assign(__assign({}, details), {
5877              generators: target.generators,
5878              clipboard: target.clipboard
5879            });
5880            return value;
5881          });
5882        });
5883      };
5884      var onPasteByEditor = function (warehouse, target) {
5885        return extractCells(warehouse, target, always).map(function (cells) {
5886          return {
5887            cells: cells,
5888            generators: target.generators,
5889            clipboard: target.clipboard
5890          };
5891        });
5892      };
5893      var onMergable = function (_warehouse, target) {
5894        return target.mergable;
5895      };
5896      var onUnmergable = function (_warehouse, target) {
5897        return target.unmergable;
5898      };
5899      var onCells = function (warehouse, target) {
5900        return extractCells(warehouse, target, always);
5901      };
5902      var onUnlockedCells = function (warehouse, target) {
5903        return extractCells(warehouse, target, function (detail) {
5904          return !detail.isLocked;
5905        });
5906      };
5907      var isUnlockedTableCell = function (warehouse, cell) {
5908        return findInWarehouse(warehouse, cell).exists(function (detail) {
5909          return !detail.isLocked;
5910        });
5911      };
5912      var allUnlocked = function (warehouse, cells) {
5913        return forall(cells, function (cell) {
5914          return isUnlockedTableCell(warehouse, cell);
5915        });
5916      };
5917      var onUnlockedMergable = function (warehouse, target) {
5918        return onMergable(warehouse, target).filter(function (mergeable) {
5919          return allUnlocked(warehouse, mergeable.cells);
5920        });
5921      };
5922      var onUnlockedUnmergable = function (warehouse, target) {
5923        return onUnmergable(warehouse, target).filter(function (cells) {
5924          return allUnlocked(warehouse, cells);
5925        });
5926      };
5927  
5928      var merge$2 = function (grid, bounds, comparator, substitution) {
5929        var rows = extractGridDetails(grid).rows;
5930        if (rows.length === 0) {
5931          return grid;
5932        }
5933        for (var i = bounds.startRow; i <= bounds.finishRow; i++) {
5934          for (var j = bounds.startCol; j <= bounds.finishCol; j++) {
5935            var row = rows[i];
5936            var isLocked = getCell(row, j).isLocked;
5937            mutateCell(row, j, elementnew(substitution(), false, isLocked));
5938          }
5939        }
5940        return grid;
5941      };
5942      var unmerge = function (grid, target, comparator, substitution) {
5943        var rows = extractGridDetails(grid).rows;
5944        var first = true;
5945        for (var i = 0; i < rows.length; i++) {
5946          for (var j = 0; j < cellLength(rows[0]); j++) {
5947            var row = rows[i];
5948            var currentCell = getCell(row, j);
5949            var currentCellElm = currentCell.element;
5950            var isToReplace = comparator(currentCellElm, target);
5951            if (isToReplace === true && first === false) {
5952              mutateCell(row, j, elementnew(substitution(), true, currentCell.isLocked));
5953            } else if (isToReplace === true) {
5954              first = false;
5955            }
5956          }
5957        }
5958        return grid;
5959      };
5960      var uniqueCells = function (row, comparator) {
5961        return foldl(row, function (rest, cell) {
5962          return exists(rest, function (currentCell) {
5963            return comparator(currentCell.element, cell.element);
5964          }) ? rest : rest.concat([cell]);
5965        }, []);
5966      };
5967      var splitCols = function (grid, index, comparator, substitution) {
5968        if (index > 0 && index < grid[0].cells.length) {
5969          each$2(grid, function (row) {
5970            var prevCell = row.cells[index - 1];
5971            var current = row.cells[index];
5972            var isToReplace = comparator(current.element, prevCell.element);
5973            if (isToReplace) {
5974              mutateCell(row, index, elementnew(substitution(), true, current.isLocked));
5975            }
5976          });
5977        }
5978        return grid;
5979      };
5980      var splitRows = function (grid, index, comparator, substitution) {
5981        var rows = extractGridDetails(grid).rows;
5982        if (index > 0 && index < rows.length) {
5983          var rowPrevCells = rows[index - 1].cells;
5984          var cells = uniqueCells(rowPrevCells, comparator);
5985          each$2(cells, function (cell) {
5986            var replacement = Optional.none();
5987            for (var i = index; i < rows.length; i++) {
5988              var _loop_1 = function (j) {
5989                var row = rows[i];
5990                var current = getCell(row, j);
5991                var isToReplace = comparator(current.element, cell.element);
5992                if (isToReplace) {
5993                  if (replacement.isNone()) {
5994                    replacement = Optional.some(substitution());
5995                  }
5996                  replacement.each(function (sub) {
5997                    mutateCell(row, j, elementnew(sub, true, current.isLocked));
5998                  });
5999                }
6000              };
6001              for (var j = 0; j < cellLength(rows[0]); j++) {
6002                _loop_1(j);
6003              }
6004            }
6005          });
6006        }
6007        return grid;
6008      };
6009  
6010      var value$1 = function (o) {
6011        var or = function (_opt) {
6012          return value$1(o);
6013        };
6014        var orThunk = function (_f) {
6015          return value$1(o);
6016        };
6017        var map = function (f) {
6018          return value$1(f(o));
6019        };
6020        var mapError = function (_f) {
6021          return value$1(o);
6022        };
6023        var each = function (f) {
6024          f(o);
6025        };
6026        var bind = function (f) {
6027          return f(o);
6028        };
6029        var fold = function (_, onValue) {
6030          return onValue(o);
6031        };
6032        var exists = function (f) {
6033          return f(o);
6034        };
6035        var forall = function (f) {
6036          return f(o);
6037        };
6038        var toOptional = function () {
6039          return Optional.some(o);
6040        };
6041        return {
6042          isValue: always,
6043          isError: never,
6044          getOr: constant(o),
6045          getOrThunk: constant(o),
6046          getOrDie: constant(o),
6047          or: or,
6048          orThunk: orThunk,
6049          fold: fold,
6050          map: map,
6051          mapError: mapError,
6052          each: each,
6053          bind: bind,
6054          exists: exists,
6055          forall: forall,
6056          toOptional: toOptional
6057        };
6058      };
6059      var error = function (message) {
6060        var getOrThunk = function (f) {
6061          return f();
6062        };
6063        var getOrDie = function () {
6064          return die(String(message))();
6065        };
6066        var or = identity;
6067        var orThunk = function (f) {
6068          return f();
6069        };
6070        var map = function (_f) {
6071          return error(message);
6072        };
6073        var mapError = function (f) {
6074          return error(f(message));
6075        };
6076        var bind = function (_f) {
6077          return error(message);
6078        };
6079        var fold = function (onError, _) {
6080          return onError(message);
6081        };
6082        return {
6083          isValue: never,
6084          isError: always,
6085          getOr: identity,
6086          getOrThunk: getOrThunk,
6087          getOrDie: getOrDie,
6088          or: or,
6089          orThunk: orThunk,
6090          fold: fold,
6091          map: map,
6092          mapError: mapError,
6093          each: noop,
6094          bind: bind,
6095          exists: never,
6096          forall: always,
6097          toOptional: Optional.none
6098        };
6099      };
6100      var fromOption = function (opt, err) {
6101        return opt.fold(function () {
6102          return error(err);
6103        }, value$1);
6104      };
6105      var Result = {
6106        value: value$1,
6107        error: error,
6108        fromOption: fromOption
6109      };
6110  
6111      var measure = function (startAddress, gridA, gridB) {
6112        if (startAddress.row >= gridA.length || startAddress.column > cellLength(gridA[0])) {
6113          return Result.error('invalid start address out of table bounds, row: ' + startAddress.row + ', column: ' + startAddress.column);
6114        }
6115        var rowRemainder = gridA.slice(startAddress.row);
6116        var colRemainder = rowRemainder[0].cells.slice(startAddress.column);
6117        var colRequired = cellLength(gridB[0]);
6118        var rowRequired = gridB.length;
6119        return Result.value({
6120          rowDelta: rowRemainder.length - rowRequired,
6121          colDelta: colRemainder.length - colRequired
6122        });
6123      };
6124      var measureWidth = function (gridA, gridB) {
6125        var colLengthA = cellLength(gridA[0]);
6126        var colLengthB = cellLength(gridB[0]);
6127        return {
6128          rowDelta: 0,
6129          colDelta: colLengthA - colLengthB
6130        };
6131      };
6132      var measureHeight = function (gridA, gridB) {
6133        var rowLengthA = gridA.length;
6134        var rowLengthB = gridB.length;
6135        return {
6136          rowDelta: rowLengthA - rowLengthB,
6137          colDelta: 0
6138        };
6139      };
6140      var generateElements = function (amount, row, generators, isLocked) {
6141        var generator = row.section === 'colgroup' ? generators.col : generators.cell;
6142        return range$1(amount, function (idx) {
6143          return elementnew(generator(), true, isLocked(idx));
6144        });
6145      };
6146      var rowFill = function (grid, amount, generators, lockedColumns) {
6147        var exampleRow = grid[grid.length - 1];
6148        return grid.concat(range$1(amount, function () {
6149          var generator = exampleRow.section === 'colgroup' ? generators.colgroup : generators.row;
6150          var row = clone$1(exampleRow, generator, identity);
6151          var elements = generateElements(row.cells.length, row, generators, function (idx) {
6152            return has$1(lockedColumns, idx.toString());
6153          });
6154          return setCells(row, elements);
6155        }));
6156      };
6157      var colFill = function (grid, amount, generators, startIndex) {
6158        return map$1(grid, function (row) {
6159          var newChildren = generateElements(amount, row, generators, never);
6160          return addCells(row, startIndex, newChildren);
6161        });
6162      };
6163      var lockedColFill = function (grid, generators, lockedColumns) {
6164        return map$1(grid, function (row) {
6165          return foldl(lockedColumns, function (acc, colNum) {
6166            var newChild = generateElements(1, row, generators, always)[0];
6167            return addCell(acc, colNum, newChild);
6168          }, row);
6169        });
6170      };
6171      var tailor = function (gridA, delta, generators) {
6172        var fillCols = delta.colDelta < 0 ? colFill : identity;
6173        var fillRows = delta.rowDelta < 0 ? rowFill : identity;
6174        var lockedColumns = getLockedColumnsFromGrid(gridA);
6175        var gridWidth = cellLength(gridA[0]);
6176        var isLastColLocked = exists(lockedColumns, function (locked) {
6177          return locked === gridWidth - 1;
6178        });
6179        var modifiedCols = fillCols(gridA, Math.abs(delta.colDelta), generators, isLastColLocked ? gridWidth - 1 : gridWidth);
6180        var newLockedColumns = getLockedColumnsFromGrid(modifiedCols);
6181        return fillRows(modifiedCols, Math.abs(delta.rowDelta), generators, mapToObject(newLockedColumns, always));
6182      };
6183  
6184      var isSpanning = function (grid, row, col, comparator) {
6185        var candidate = getCell(grid[row], col);
6186        var matching = curry(comparator, candidate.element);
6187        var currentRow = grid[row];
6188        return grid.length > 1 && cellLength(currentRow) > 1 && (col > 0 && matching(getCellElement(currentRow, col - 1)) || col < currentRow.cells.length - 1 && matching(getCellElement(currentRow, col + 1)) || row > 0 && matching(getCellElement(grid[row - 1], col)) || row < grid.length - 1 && matching(getCellElement(grid[row + 1], col)));
6189      };
6190      var mergeTables = function (startAddress, gridA, gridB, generator, comparator, lockedColumns) {
6191        var startRow = startAddress.row;
6192        var startCol = startAddress.column;
6193        var mergeHeight = gridB.length;
6194        var mergeWidth = cellLength(gridB[0]);
6195        var endRow = startRow + mergeHeight;
6196        var endCol = startCol + mergeWidth + lockedColumns.length;
6197        var lockedColumnObj = mapToObject(lockedColumns, always);
6198        for (var r = startRow; r < endRow; r++) {
6199          var skippedCol = 0;
6200          for (var c = startCol; c < endCol; c++) {
6201            if (lockedColumnObj[c]) {
6202              skippedCol++;
6203              continue;
6204            }
6205            if (isSpanning(gridA, r, c, comparator)) {
6206              unmerge(gridA, getCellElement(gridA[r], c), comparator, generator.cell);
6207            }
6208            var gridBColIndex = c - startCol - skippedCol;
6209            var newCell = getCell(gridB[r - startRow], gridBColIndex);
6210            var newCellElm = newCell.element;
6211            var replacement = generator.replace(newCellElm);
6212            mutateCell(gridA[r], c, elementnew(replacement, true, newCell.isLocked));
6213          }
6214        }
6215        return gridA;
6216      };
6217      var getValidStartAddress = function (currentStartAddress, grid, lockedColumns) {
6218        var gridColLength = cellLength(grid[0]);
6219        var adjustedRowAddress = extractGridDetails(grid).cols.length + currentStartAddress.row;
6220        var possibleColAddresses = range$1(gridColLength - currentStartAddress.column, function (num) {
6221          return num + currentStartAddress.column;
6222        });
6223        var validColAddress = find$1(possibleColAddresses, function (num) {
6224          return forall(lockedColumns, function (col) {
6225            return col !== num;
6226          });
6227        }).getOr(gridColLength - 1);
6228        return {
6229          row: adjustedRowAddress,
6230          column: validColAddress
6231        };
6232      };
6233      var getLockedColumnsWithinBounds = function (startAddress, grid, lockedColumns) {
6234        return filter$2(lockedColumns, function (colNum) {
6235          return colNum >= startAddress.column && colNum <= cellLength(grid[0]) + startAddress.column;
6236        });
6237      };
6238      var merge$1 = function (startAddress, gridA, gridB, generator, comparator) {
6239        var lockedColumns = getLockedColumnsFromGrid(gridA);
6240        var validStartAddress = getValidStartAddress(startAddress, gridA, lockedColumns);
6241        var gridBRows = extractGridDetails(gridB).rows;
6242        var lockedColumnsWithinBounds = getLockedColumnsWithinBounds(validStartAddress, gridBRows, lockedColumns);
6243        var result = measure(validStartAddress, gridA, gridBRows);
6244        return result.map(function (diff) {
6245          var delta = __assign(__assign({}, diff), { colDelta: diff.colDelta - lockedColumnsWithinBounds.length });
6246          var fittedGrid = tailor(gridA, delta, generator);
6247          var newLockedColumns = getLockedColumnsFromGrid(fittedGrid);
6248          var newLockedColumnsWithinBounds = getLockedColumnsWithinBounds(validStartAddress, gridBRows, newLockedColumns);
6249          return mergeTables(validStartAddress, fittedGrid, gridBRows, generator, comparator, newLockedColumnsWithinBounds);
6250        });
6251      };
6252      var insertCols = function (index, gridA, gridB, generator, comparator) {
6253        splitCols(gridA, index, comparator, generator.cell);
6254        var delta = measureHeight(gridB, gridA);
6255        var fittedNewGrid = tailor(gridB, delta, generator);
6256        var secondDelta = measureHeight(gridA, fittedNewGrid);
6257        var fittedOldGrid = tailor(gridA, secondDelta, generator);
6258        return map$1(fittedOldGrid, function (gridRow, i) {
6259          return addCells(gridRow, index, fittedNewGrid[i].cells);
6260        });
6261      };
6262      var insertRows = function (index, gridA, gridB, generator, comparator) {
6263        splitRows(gridA, index, comparator, generator.cell);
6264        var locked = getLockedColumnsFromGrid(gridA);
6265        var diff = measureWidth(gridA, gridB);
6266        var delta = __assign(__assign({}, diff), { colDelta: diff.colDelta - locked.length });
6267        var fittedOldGrid = tailor(gridA, delta, generator);
6268        var _a = extractGridDetails(fittedOldGrid), oldCols = _a.cols, oldRows = _a.rows;
6269        var newLocked = getLockedColumnsFromGrid(fittedOldGrid);
6270        var secondDiff = measureWidth(gridB, gridA);
6271        var secondDelta = __assign(__assign({}, secondDiff), { colDelta: secondDiff.colDelta + newLocked.length });
6272        var fittedGridB = lockedColFill(gridB, generator, newLocked);
6273        var fittedNewGrid = tailor(fittedGridB, secondDelta, generator);
6274        return oldCols.concat(oldRows.slice(0, index)).concat(fittedNewGrid).concat(oldRows.slice(index, oldRows.length));
6275      };
6276  
6277      var cloneRow = function (row, cloneCell, comparator, substitution) {
6278        return clone$1(row, function (elem) {
6279          return substitution(elem, comparator);
6280        }, cloneCell);
6281      };
6282      var insertRowAt = function (grid, index, example, comparator, substitution) {
6283        var _a = extractGridDetails(grid), rows = _a.rows, cols = _a.cols;
6284        var before = rows.slice(0, index);
6285        var after = rows.slice(index);
6286        var newRow = cloneRow(rows[example], function (ex, c) {
6287          var withinSpan = index > 0 && index < rows.length && comparator(getCellElement(rows[index - 1], c), getCellElement(rows[index], c));
6288          var ret = withinSpan ? getCell(rows[index], c) : elementnew(substitution(ex.element, comparator), true, ex.isLocked);
6289          return ret;
6290        }, comparator, substitution);
6291        return cols.concat(before).concat([newRow]).concat(after);
6292      };
6293      var getElementFor = function (row, column, section, withinSpan, example, comparator, substitution) {
6294        if (section === 'colgroup' || !withinSpan) {
6295          var cell = getCell(row, example);
6296          return elementnew(substitution(cell.element, comparator), true, false);
6297        } else {
6298          return getCell(row, column);
6299        }
6300      };
6301      var insertColumnAt = function (grid, index, example, comparator, substitution) {
6302        return map$1(grid, function (row) {
6303          var withinSpan = index > 0 && index < cellLength(row) && comparator(getCellElement(row, index - 1), getCellElement(row, index));
6304          var sub = getElementFor(row, index, row.section, withinSpan, example, comparator, substitution);
6305          return addCell(row, index, sub);
6306        });
6307      };
6308      var deleteColumnsAt = function (grid, columns) {
6309        return bind$2(grid, function (row) {
6310          var existingCells = row.cells;
6311          var cells = foldr(columns, function (acc, column) {
6312            return column >= 0 && column < acc.length ? acc.slice(0, column).concat(acc.slice(column + 1)) : acc;
6313          }, existingCells);
6314          return cells.length > 0 ? [rowcells(row.element, cells, row.section, row.isNew)] : [];
6315        });
6316      };
6317      var deleteRowsAt = function (grid, start, finish) {
6318        var _a = extractGridDetails(grid), rows = _a.rows, cols = _a.cols;
6319        return cols.concat(rows.slice(0, start)).concat(rows.slice(finish + 1));
6320      };
6321  
6322      var notInStartRow = function (grid, rowIndex, colIndex, comparator) {
6323        return getCellElement(grid[rowIndex], colIndex) !== undefined && (rowIndex > 0 && comparator(getCellElement(grid[rowIndex - 1], colIndex), getCellElement(grid[rowIndex], colIndex)));
6324      };
6325      var notInStartColumn = function (row, index, comparator) {
6326        return index > 0 && comparator(getCellElement(row, index - 1), getCellElement(row, index));
6327      };
6328      var isDuplicatedCell = function (grid, rowIndex, colIndex, comparator) {
6329        return notInStartRow(grid, rowIndex, colIndex, comparator) || notInStartColumn(grid[rowIndex], colIndex, comparator);
6330      };
6331      var rowReplacerPredicate = function (targetRow, columnHeaders) {
6332        var entireTableIsHeader = forall(columnHeaders, identity) && isHeaderCells(targetRow.cells);
6333        return entireTableIsHeader ? always : function (cell, _rowIndex, colIndex) {
6334          var type = name(cell.element);
6335          return !(type === 'th' && columnHeaders[colIndex]);
6336        };
6337      };
6338      var columnReplacePredicate = function (targetColumn, rowHeaders) {
6339        var entireTableIsHeader = forall(rowHeaders, identity) && isHeaderCells(targetColumn);
6340        return entireTableIsHeader ? always : function (cell, rowIndex, _colIndex) {
6341          var type = name(cell.element);
6342          return !(type === 'th' && rowHeaders[rowIndex]);
6343        };
6344      };
6345      var determineScope = function (applyScope, element, newScope, isInHeader) {
6346        var hasSpan = function (scope) {
6347          return scope === 'row' ? hasRowspan(element) : hasColspan(element);
6348        };
6349        var getScope = function (scope) {
6350          return hasSpan(scope) ? scope + 'group' : scope;
6351        };
6352        if (applyScope) {
6353          return isHeaderCell(element) ? getScope(newScope) : null;
6354        } else if (isInHeader && isHeaderCell(element)) {
6355          var oppositeScope = newScope === 'row' ? 'col' : 'row';
6356          return getScope(oppositeScope);
6357        } else {
6358          return null;
6359        }
6360      };
6361      var rowScopeGenerator = function (applyScope, columnHeaders) {
6362        return function (cell, rowIndex, columnIndex) {
6363          return Optional.some(determineScope(applyScope, cell.element, 'col', columnHeaders[columnIndex]));
6364        };
6365      };
6366      var columnScopeGenerator = function (applyScope, rowHeaders) {
6367        return function (cell, rowIndex) {
6368          return Optional.some(determineScope(applyScope, cell.element, 'row', rowHeaders[rowIndex]));
6369        };
6370      };
6371      var replace = function (cell, comparator, substitute) {
6372        return elementnew(substitute(cell.element, comparator), true, cell.isLocked);
6373      };
6374      var replaceIn = function (grid, targets, comparator, substitute, replacer, genScope, shouldReplace) {
6375        var isTarget = function (cell) {
6376          return exists(targets, function (target) {
6377            return comparator(cell.element, target.element);
6378          });
6379        };
6380        return map$1(grid, function (row, rowIndex) {
6381          return mapCells(row, function (cell, colIndex) {
6382            if (isTarget(cell)) {
6383              var newCell_1 = shouldReplace(cell, rowIndex, colIndex) ? replacer(cell, comparator, substitute) : cell;
6384              genScope(newCell_1, rowIndex, colIndex).each(function (scope) {
6385                setOptions(newCell_1.element, { scope: Optional.from(scope) });
6386              });
6387              return newCell_1;
6388            } else {
6389              return cell;
6390            }
6391          });
6392        });
6393      };
6394      var getColumnCells = function (rows, columnIndex, comparator) {
6395        return bind$2(rows, function (row, i) {
6396          return isDuplicatedCell(rows, i, columnIndex, comparator) ? [] : [getCell(row, columnIndex)];
6397        });
6398      };
6399      var getRowCells = function (rows, rowIndex, comparator) {
6400        var targetRow = rows[rowIndex];
6401        return bind$2(targetRow.cells, function (item, i) {
6402          return isDuplicatedCell(rows, rowIndex, i, comparator) ? [] : [item];
6403        });
6404      };
6405      var replaceColumns = function (grid, indexes, applyScope, comparator, substitution) {
6406        var rows = extractGridDetails(grid).rows;
6407        var targets = bind$2(indexes, function (index) {
6408          return getColumnCells(rows, index, comparator);
6409        });
6410        var rowHeaders = map$1(grid, function (row) {
6411          return isHeaderCells(row.cells);
6412        });
6413        var shouldReplaceCell = columnReplacePredicate(targets, rowHeaders);
6414        var scopeGenerator = columnScopeGenerator(applyScope, rowHeaders);
6415        return replaceIn(grid, targets, comparator, substitution, replace, scopeGenerator, shouldReplaceCell);
6416      };
6417      var replaceRows = function (grid, indexes, section, applyScope, comparator, substitution, tableSection) {
6418        var _a = extractGridDetails(grid), cols = _a.cols, rows = _a.rows;
6419        var targetRow = rows[indexes[0]];
6420        var targets = bind$2(indexes, function (index) {
6421          return getRowCells(rows, index, comparator);
6422        });
6423        var columnHeaders = map$1(targetRow.cells, function (_cell, index) {
6424          return isHeaderCells(getColumnCells(rows, index, comparator));
6425        });
6426        var newRows = __spreadArray([], rows, true);
6427        each$2(indexes, function (index) {
6428          newRows[index] = tableSection.transformRow(rows[index], section);
6429        });
6430        var newGrid = cols.concat(newRows);
6431        var shouldReplaceCell = rowReplacerPredicate(targetRow, columnHeaders);
6432        var scopeGenerator = rowScopeGenerator(applyScope, columnHeaders);
6433        return replaceIn(newGrid, targets, comparator, substitution, tableSection.transformCell, scopeGenerator, shouldReplaceCell);
6434      };
6435      var replaceCells = function (grid, details, comparator, substitution) {
6436        var rows = extractGridDetails(grid).rows;
6437        var targetCells = map$1(details, function (detail) {
6438          return getCell(rows[detail.row], detail.column);
6439        });
6440        return replaceIn(grid, targetCells, comparator, substitution, replace, Optional.none, always);
6441      };
6442  
6443      var uniqueColumns = function (details) {
6444        var uniqueCheck = function (rest, detail) {
6445          var columnExists = exists(rest, function (currentDetail) {
6446            return currentDetail.column === detail.column;
6447          });
6448          return columnExists ? rest : rest.concat([detail]);
6449        };
6450        return foldl(details, uniqueCheck, []).sort(function (detailA, detailB) {
6451          return detailA.column - detailB.column;
6452        });
6453      };
6454  
6455      var isCol = isTag('col');
6456      var isColgroup = isTag('colgroup');
6457      var isRow$1 = function (element) {
6458        return name(element) === 'tr' || isColgroup(element);
6459      };
6460      var elementToData = function (element) {
6461        var colspan = getAttrValue(element, 'colspan', 1);
6462        var rowspan = getAttrValue(element, 'rowspan', 1);
6463        return {
6464          element: element,
6465          colspan: colspan,
6466          rowspan: rowspan
6467        };
6468      };
6469      var modification = function (generators, toData) {
6470        if (toData === void 0) {
6471          toData = elementToData;
6472        }
6473        var nuCell = function (data) {
6474          return isCol(data.element) ? generators.col(data) : generators.cell(data);
6475        };
6476        var nuRow = function (data) {
6477          return isColgroup(data.element) ? generators.colgroup(data) : generators.row(data);
6478        };
6479        var add = function (element) {
6480          if (isRow$1(element)) {
6481            return nuRow({ element: element });
6482          } else {
6483            var replacement = nuCell(toData(element));
6484            recent = Optional.some({
6485              item: element,
6486              replacement: replacement
6487            });
6488            return replacement;
6489          }
6490        };
6491        var recent = Optional.none();
6492        var getOrInit = function (element, comparator) {
6493          return recent.fold(function () {
6494            return add(element);
6495          }, function (p) {
6496            return comparator(element, p.item) ? p.replacement : add(element);
6497          });
6498        };
6499        return { getOrInit: getOrInit };
6500      };
6501      var transform = function (tag) {
6502        return function (generators) {
6503          var list = [];
6504          var find = function (element, comparator) {
6505            return find$1(list, function (x) {
6506              return comparator(x.item, element);
6507            });
6508          };
6509          var makeNew = function (element) {
6510            var attrs = tag === 'td' ? { scope: null } : {};
6511            var cell = generators.replace(element, tag, attrs);
6512            list.push({
6513              item: element,
6514              sub: cell
6515            });
6516            return cell;
6517          };
6518          var replaceOrInit = function (element, comparator) {
6519            if (isRow$1(element) || isCol(element)) {
6520              return element;
6521            } else {
6522              return find(element, comparator).fold(function () {
6523                return makeNew(element);
6524              }, function (p) {
6525                return comparator(element, p.item) ? p.sub : makeNew(element);
6526              });
6527            }
6528          };
6529          return { replaceOrInit: replaceOrInit };
6530        };
6531      };
6532      var getScopeAttribute = function (cell) {
6533        return getOpt(cell, 'scope').map(function (attribute) {
6534          return attribute.substr(0, 3);
6535        });
6536      };
6537      var merging = function (generators) {
6538        var unmerge = function (cell) {
6539          var scope = getScopeAttribute(cell);
6540          scope.each(function (attribute) {
6541            return set$2(cell, 'scope', attribute);
6542          });
6543          return function () {
6544            var raw = generators.cell({
6545              element: cell,
6546              colspan: 1,
6547              rowspan: 1
6548            });
6549            remove$6(raw, 'width');
6550            remove$6(cell, 'width');
6551            scope.each(function (attribute) {
6552              return set$2(raw, 'scope', attribute);
6553            });
6554            return raw;
6555          };
6556        };
6557        var merge = function (cells) {
6558          var getScopeProperty = function () {
6559            var stringAttributes = cat(map$1(cells, getScopeAttribute));
6560            if (stringAttributes.length === 0) {
6561              return Optional.none();
6562            } else {
6563              var baseScope_1 = stringAttributes[0];
6564              var scopes_1 = [
6565                'row',
6566                'col'
6567              ];
6568              var isMixed = exists(stringAttributes, function (attribute) {
6569                return attribute !== baseScope_1 && contains$2(scopes_1, attribute);
6570              });
6571              return isMixed ? Optional.none() : Optional.from(baseScope_1);
6572            }
6573          };
6574          remove$6(cells[0], 'width');
6575          getScopeProperty().fold(function () {
6576            return remove$7(cells[0], 'scope');
6577          }, function (attribute) {
6578            return set$2(cells[0], 'scope', attribute + 'group');
6579          });
6580          return constant(cells[0]);
6581        };
6582        return {
6583          unmerge: unmerge,
6584          merge: merge
6585        };
6586      };
6587      var Generators = {
6588        modification: modification,
6589        transform: transform,
6590        merging: merging
6591      };
6592  
6593      var blockList = [
6594        'body',
6595        'p',
6596        'div',
6597        'article',
6598        'aside',
6599        'figcaption',
6600        'figure',
6601        'footer',
6602        'header',
6603        'nav',
6604        'section',
6605        'ol',
6606        'ul',
6607        'table',
6608        'thead',
6609        'tfoot',
6610        'tbody',
6611        'caption',
6612        'tr',
6613        'td',
6614        'th',
6615        'h1',
6616        'h2',
6617        'h3',
6618        'h4',
6619        'h5',
6620        'h6',
6621        'blockquote',
6622        'pre',
6623        'address'
6624      ];
6625      var isList$1 = function (universe, item) {
6626        var tagName = universe.property().name(item);
6627        return contains$2([
6628          'ol',
6629          'ul'
6630        ], tagName);
6631      };
6632      var isBlock$1 = function (universe, item) {
6633        var tagName = universe.property().name(item);
6634        return contains$2(blockList, tagName);
6635      };
6636      var isEmptyTag$1 = function (universe, item) {
6637        return contains$2([
6638          'br',
6639          'img',
6640          'hr',
6641          'input'
6642        ], universe.property().name(item));
6643      };
6644  
6645      var universe$1 = DomUniverse();
6646      var isBlock = function (element) {
6647        return isBlock$1(universe$1, element);
6648      };
6649      var isList = function (element) {
6650        return isList$1(universe$1, element);
6651      };
6652      var isEmptyTag = function (element) {
6653        return isEmptyTag$1(universe$1, element);
6654      };
6655  
6656      var merge = function (cells) {
6657        var isBr = function (el) {
6658          return name(el) === 'br';
6659        };
6660        var advancedBr = function (children) {
6661          return forall(children, function (c) {
6662            return isBr(c) || isText(c) && get$9(c).trim().length === 0;
6663          });
6664        };
6665        var isListItem = function (el) {
6666          return name(el) === 'li' || ancestor$2(el, isList).isSome();
6667        };
6668        var siblingIsBlock = function (el) {
6669          return nextSibling(el).map(function (rightSibling) {
6670            if (isBlock(rightSibling)) {
6671              return true;
6672            }
6673            if (isEmptyTag(rightSibling)) {
6674              return name(rightSibling) === 'img' ? false : true;
6675            }
6676            return false;
6677          }).getOr(false);
6678        };
6679        var markCell = function (cell) {
6680          return last$1(cell).bind(function (rightEdge) {
6681            var rightSiblingIsBlock = siblingIsBlock(rightEdge);
6682            return parent(rightEdge).map(function (parent) {
6683              return rightSiblingIsBlock === true || isListItem(parent) || isBr(rightEdge) || isBlock(parent) && !eq$1(cell, parent) ? [] : [SugarElement.fromTag('br')];
6684            });
6685          }).getOr([]);
6686        };
6687        var markContent = function () {
6688          var content = bind$2(cells, function (cell) {
6689            var children = children$3(cell);
6690            return advancedBr(children) ? [] : children.concat(markCell(cell));
6691          });
6692          return content.length === 0 ? [SugarElement.fromTag('br')] : content;
6693        };
6694        var contents = markContent();
6695        empty(cells[0]);
6696        append(cells[0], contents);
6697      };
6698  
6699      var isEditable = function (elem) {
6700        return isEditable$1(elem, true);
6701      };
6702      var prune = function (table) {
6703        var cells = cells$1(table);
6704        if (cells.length === 0) {
6705          remove$5(table);
6706        }
6707      };
6708      var outcome = function (grid, cursor) {
6709        return {
6710          grid: grid,
6711          cursor: cursor
6712        };
6713      };
6714      var findEditableCursorPosition = function (rows) {
6715        return findMap(rows, function (row) {
6716          return findMap(row.cells, function (cell) {
6717            var elem = cell.element;
6718            return someIf(isEditable(elem), elem);
6719          });
6720        });
6721      };
6722      var elementFromGrid = function (grid, row, column) {
6723        var _a, _b;
6724        var rows = extractGridDetails(grid).rows;
6725        return Optional.from((_b = (_a = rows[row]) === null || _a === void 0 ? void 0 : _a.cells[column]) === null || _b === void 0 ? void 0 : _b.element).filter(isEditable).orThunk(function () {
6726          return findEditableCursorPosition(rows);
6727        });
6728      };
6729      var bundle = function (grid, row, column) {
6730        var cursorElement = elementFromGrid(grid, row, column);
6731        return outcome(grid, cursorElement);
6732      };
6733      var uniqueRows = function (details) {
6734        var rowCompilation = function (rest, detail) {
6735          var rowExists = exists(rest, function (currentDetail) {
6736            return currentDetail.row === detail.row;
6737          });
6738          return rowExists ? rest : rest.concat([detail]);
6739        };
6740        return foldl(details, rowCompilation, []).sort(function (detailA, detailB) {
6741          return detailA.row - detailB.row;
6742        });
6743      };
6744      var opInsertRowsBefore = function (grid, details, comparator, genWrappers) {
6745        var targetIndex = details[0].row;
6746        var rows = uniqueRows(details);
6747        var newGrid = foldr(rows, function (acc, row) {
6748          var newG = insertRowAt(acc.grid, targetIndex, row.row + acc.delta, comparator, genWrappers.getOrInit);
6749          return {
6750            grid: newG,
6751            delta: acc.delta + 1
6752          };
6753        }, {
6754          grid: grid,
6755          delta: 0
6756        }).grid;
6757        return bundle(newGrid, targetIndex, details[0].column);
6758      };
6759      var opInsertRowsAfter = function (grid, details, comparator, genWrappers) {
6760        var rows = uniqueRows(details);
6761        var target = rows[rows.length - 1];
6762        var targetIndex = target.row + target.rowspan;
6763        var newGrid = foldr(rows, function (newG, row) {
6764          return insertRowAt(newG, targetIndex, row.row, comparator, genWrappers.getOrInit);
6765        }, grid);
6766        return bundle(newGrid, targetIndex, details[0].column);
6767      };
6768      var opInsertColumnsBefore = function (grid, extractDetail, comparator, genWrappers) {
6769        var details = extractDetail.details;
6770        var columns = uniqueColumns(details);
6771        var targetIndex = columns[0].column;
6772        var newGrid = foldr(columns, function (acc, col) {
6773          var newG = insertColumnAt(acc.grid, targetIndex, col.column + acc.delta, comparator, genWrappers.getOrInit);
6774          return {
6775            grid: newG,
6776            delta: acc.delta + 1
6777          };
6778        }, {
6779          grid: grid,
6780          delta: 0
6781        }).grid;
6782        return bundle(newGrid, details[0].row, targetIndex);
6783      };
6784      var opInsertColumnsAfter = function (grid, extractDetail, comparator, genWrappers) {
6785        var details = extractDetail.details;
6786        var target = details[details.length - 1];
6787        var targetIndex = target.column + target.colspan;
6788        var columns = uniqueColumns(details);
6789        var newGrid = foldr(columns, function (newG, col) {
6790          return insertColumnAt(newG, targetIndex, col.column, comparator, genWrappers.getOrInit);
6791        }, grid);
6792        return bundle(newGrid, details[0].row, targetIndex);
6793      };
6794      var opMakeColumnsHeader = function (initialGrid, details, comparator, genWrappers) {
6795        var columns = uniqueColumns(details);
6796        var columnIndexes = map$1(columns, function (detail) {
6797          return detail.column;
6798        });
6799        var newGrid = replaceColumns(initialGrid, columnIndexes, true, comparator, genWrappers.replaceOrInit);
6800        return bundle(newGrid, details[0].row, details[0].column);
6801      };
6802      var opMakeCellsHeader = function (initialGrid, details, comparator, genWrappers) {
6803        var newGrid = replaceCells(initialGrid, details, comparator, genWrappers.replaceOrInit);
6804        return bundle(newGrid, details[0].row, details[0].column);
6805      };
6806      var opUnmakeColumnsHeader = function (initialGrid, details, comparator, genWrappers) {
6807        var columns = uniqueColumns(details);
6808        var columnIndexes = map$1(columns, function (detail) {
6809          return detail.column;
6810        });
6811        var newGrid = replaceColumns(initialGrid, columnIndexes, false, comparator, genWrappers.replaceOrInit);
6812        return bundle(newGrid, details[0].row, details[0].column);
6813      };
6814      var opUnmakeCellsHeader = function (initialGrid, details, comparator, genWrappers) {
6815        var newGrid = replaceCells(initialGrid, details, comparator, genWrappers.replaceOrInit);
6816        return bundle(newGrid, details[0].row, details[0].column);
6817      };
6818      var makeRowsSection = function (section, applyScope) {
6819        return function (initialGrid, details, comparator, genWrappers, tableSection) {
6820          var rows = uniqueRows(details);
6821          var rowIndexes = map$1(rows, function (detail) {
6822            return detail.row;
6823          });
6824          var newGrid = replaceRows(initialGrid, rowIndexes, section, applyScope, comparator, genWrappers.replaceOrInit, tableSection);
6825          return bundle(newGrid, details[0].row, details[0].column);
6826        };
6827      };
6828      var opMakeRowsHeader = makeRowsSection('thead', true);
6829      var opMakeRowsBody = makeRowsSection('tbody', false);
6830      var opMakeRowsFooter = makeRowsSection('tfoot', false);
6831      var opEraseColumns = function (grid, extractDetail, _comparator, _genWrappers) {
6832        var columns = uniqueColumns(extractDetail.details);
6833        var newGrid = deleteColumnsAt(grid, map$1(columns, function (column) {
6834          return column.column;
6835        }));
6836        var maxColIndex = newGrid.length > 0 ? newGrid[0].cells.length - 1 : 0;
6837        return bundle(newGrid, columns[0].row, Math.min(columns[0].column, maxColIndex));
6838      };
6839      var opEraseRows = function (grid, details, _comparator, _genWrappers) {
6840        var rows = uniqueRows(details);
6841        var newGrid = deleteRowsAt(grid, rows[0].row, rows[rows.length - 1].row);
6842        var maxRowIndex = newGrid.length > 0 ? newGrid.length - 1 : 0;
6843        return bundle(newGrid, Math.min(details[0].row, maxRowIndex), details[0].column);
6844      };
6845      var opMergeCells = function (grid, mergable, comparator, genWrappers) {
6846        var cells = mergable.cells;
6847        merge(cells);
6848        var newGrid = merge$2(grid, mergable.bounds, comparator, genWrappers.merge(cells));
6849        return outcome(newGrid, Optional.from(cells[0]));
6850      };
6851      var opUnmergeCells = function (grid, unmergable, comparator, genWrappers) {
6852        var unmerge$1 = function (b, cell) {
6853          return unmerge(b, cell, comparator, genWrappers.unmerge(cell));
6854        };
6855        var newGrid = foldr(unmergable, unmerge$1, grid);
6856        return outcome(newGrid, Optional.from(unmergable[0]));
6857      };
6858      var opPasteCells = function (grid, pasteDetails, comparator, _genWrappers) {
6859        var gridify = function (table, generators) {
6860          var wh = Warehouse.fromTable(table);
6861          return toGrid(wh, generators, true);
6862        };
6863        var gridB = gridify(pasteDetails.clipboard, pasteDetails.generators);
6864        var startAddress = address(pasteDetails.row, pasteDetails.column);
6865        var mergedGrid = merge$1(startAddress, grid, gridB, pasteDetails.generators, comparator);
6866        return mergedGrid.fold(function () {
6867          return outcome(grid, Optional.some(pasteDetails.element));
6868        }, function (newGrid) {
6869          return bundle(newGrid, pasteDetails.row, pasteDetails.column);
6870        });
6871      };
6872      var gridifyRows = function (rows, generators, context) {
6873        var pasteDetails = fromPastedRows(rows, context.section);
6874        var wh = Warehouse.generate(pasteDetails);
6875        return toGrid(wh, generators, true);
6876      };
6877      var opPasteColsBefore = function (grid, pasteDetails, comparator, _genWrappers) {
6878        var rows = extractGridDetails(grid).rows;
6879        var index = pasteDetails.cells[0].column;
6880        var context = rows[pasteDetails.cells[0].row];
6881        var gridB = gridifyRows(pasteDetails.clipboard, pasteDetails.generators, context);
6882        var mergedGrid = insertCols(index, grid, gridB, pasteDetails.generators, comparator);
6883        return bundle(mergedGrid, pasteDetails.cells[0].row, pasteDetails.cells[0].column);
6884      };
6885      var opPasteColsAfter = function (grid, pasteDetails, comparator, _genWrappers) {
6886        var rows = extractGridDetails(grid).rows;
6887        var index = pasteDetails.cells[pasteDetails.cells.length - 1].column + pasteDetails.cells[pasteDetails.cells.length - 1].colspan;
6888        var context = rows[pasteDetails.cells[0].row];
6889        var gridB = gridifyRows(pasteDetails.clipboard, pasteDetails.generators, context);
6890        var mergedGrid = insertCols(index, grid, gridB, pasteDetails.generators, comparator);
6891        return bundle(mergedGrid, pasteDetails.cells[0].row, pasteDetails.cells[0].column);
6892      };
6893      var opPasteRowsBefore = function (grid, pasteDetails, comparator, _genWrappers) {
6894        var rows = extractGridDetails(grid).rows;
6895        var index = pasteDetails.cells[0].row;
6896        var context = rows[index];
6897        var gridB = gridifyRows(pasteDetails.clipboard, pasteDetails.generators, context);
6898        var mergedGrid = insertRows(index, grid, gridB, pasteDetails.generators, comparator);
6899        return bundle(mergedGrid, pasteDetails.cells[0].row, pasteDetails.cells[0].column);
6900      };
6901      var opPasteRowsAfter = function (grid, pasteDetails, comparator, _genWrappers) {
6902        var rows = extractGridDetails(grid).rows;
6903        var index = pasteDetails.cells[pasteDetails.cells.length - 1].row + pasteDetails.cells[pasteDetails.cells.length - 1].rowspan;
6904        var context = rows[pasteDetails.cells[0].row];
6905        var gridB = gridifyRows(pasteDetails.clipboard, pasteDetails.generators, context);
6906        var mergedGrid = insertRows(index, grid, gridB, pasteDetails.generators, comparator);
6907        return bundle(mergedGrid, pasteDetails.cells[0].row, pasteDetails.cells[0].column);
6908      };
6909      var opGetColumnsType = function (table, target) {
6910        var house = Warehouse.fromTable(table);
6911        var details = onCells(house, target);
6912        return details.bind(function (selectedCells) {
6913          var lastSelectedCell = selectedCells[selectedCells.length - 1];
6914          var minColRange = selectedCells[0].column;
6915          var maxColRange = lastSelectedCell.column + lastSelectedCell.colspan;
6916          var selectedColumnCells = flatten$1(map$1(house.all, function (row) {
6917            return filter$2(row.cells, function (cell) {
6918              return cell.column >= minColRange && cell.column < maxColRange;
6919            });
6920          }));
6921          return findCommonCellType(selectedColumnCells);
6922        }).getOr('');
6923      };
6924      var opGetCellsType = function (table, target) {
6925        var house = Warehouse.fromTable(table);
6926        var details = onCells(house, target);
6927        return details.bind(findCommonCellType).getOr('');
6928      };
6929      var opGetRowsType = function (table, target) {
6930        var house = Warehouse.fromTable(table);
6931        var details = onCells(house, target);
6932        return details.bind(function (selectedCells) {
6933          var lastSelectedCell = selectedCells[selectedCells.length - 1];
6934          var minRowRange = selectedCells[0].row;
6935          var maxRowRange = lastSelectedCell.row + lastSelectedCell.rowspan;
6936          var selectedRows = house.all.slice(minRowRange, maxRowRange);
6937          return findCommonRowType(selectedRows);
6938        }).getOr('');
6939      };
6940      var resize = function (table, list, details, behaviours) {
6941        return adjustWidthTo(table, list, details, behaviours.sizing);
6942      };
6943      var adjustAndRedistributeWidths = function (table, list, details, behaviours) {
6944        return adjustAndRedistributeWidths$1(table, list, details, behaviours.sizing, behaviours.resize);
6945      };
6946      var firstColumnIsLocked = function (_warehouse, details) {
6947        return exists(details, function (detail) {
6948          return detail.column === 0 && detail.isLocked;
6949        });
6950      };
6951      var lastColumnIsLocked = function (warehouse, details) {
6952        return exists(details, function (detail) {
6953          return detail.column + detail.colspan >= warehouse.grid.columns && detail.isLocked;
6954        });
6955      };
6956      var getColumnsWidth = function (warehouse, details) {
6957        var columns$1 = columns(warehouse);
6958        var uniqueCols = uniqueColumns(details);
6959        return foldl(uniqueCols, function (acc, detail) {
6960          var column = columns$1[detail.column];
6961          var colWidth = column.map(getOuter$2).getOr(0);
6962          return acc + colWidth;
6963        }, 0);
6964      };
6965      var insertColumnsExtractor = function (before) {
6966        return function (warehouse, target) {
6967          return onCells(warehouse, target).filter(function (details) {
6968            var checkLocked = before ? firstColumnIsLocked : lastColumnIsLocked;
6969            return !checkLocked(warehouse, details);
6970          }).map(function (details) {
6971            return {
6972              details: details,
6973              pixelDelta: getColumnsWidth(warehouse, details)
6974            };
6975          });
6976        };
6977      };
6978      var eraseColumnsExtractor = function (warehouse, target) {
6979        return onUnlockedCells(warehouse, target).map(function (details) {
6980          return {
6981            details: details,
6982            pixelDelta: -getColumnsWidth(warehouse, details)
6983          };
6984        });
6985      };
6986      var pasteColumnsExtractor = function (before) {
6987        return function (warehouse, target) {
6988          return onPasteByEditor(warehouse, target).filter(function (details) {
6989            var checkLocked = before ? firstColumnIsLocked : lastColumnIsLocked;
6990            return !checkLocked(warehouse, details.cells);
6991          });
6992        };
6993      };
6994      var headerCellGenerator = Generators.transform('th');
6995      var bodyCellGenerator = Generators.transform('td');
6996      var insertRowsBefore = run(opInsertRowsBefore, onCells, noop, noop, Generators.modification);
6997      var insertRowsAfter = run(opInsertRowsAfter, onCells, noop, noop, Generators.modification);
6998      var insertColumnsBefore = run(opInsertColumnsBefore, insertColumnsExtractor(true), adjustAndRedistributeWidths, noop, Generators.modification);
6999      var insertColumnsAfter = run(opInsertColumnsAfter, insertColumnsExtractor(false), adjustAndRedistributeWidths, noop, Generators.modification);
7000      var eraseColumns = run(opEraseColumns, eraseColumnsExtractor, adjustAndRedistributeWidths, prune, Generators.modification);
7001      var eraseRows = run(opEraseRows, onCells, noop, prune, Generators.modification);
7002      var makeColumnsHeader = run(opMakeColumnsHeader, onUnlockedCells, noop, noop, headerCellGenerator);
7003      var unmakeColumnsHeader = run(opUnmakeColumnsHeader, onUnlockedCells, noop, noop, bodyCellGenerator);
7004      var makeRowsHeader = run(opMakeRowsHeader, onUnlockedCells, noop, noop, headerCellGenerator);
7005      var makeRowsBody = run(opMakeRowsBody, onUnlockedCells, noop, noop, bodyCellGenerator);
7006      var makeRowsFooter = run(opMakeRowsFooter, onUnlockedCells, noop, noop, bodyCellGenerator);
7007      var makeCellsHeader = run(opMakeCellsHeader, onUnlockedCells, noop, noop, headerCellGenerator);
7008      var unmakeCellsHeader = run(opUnmakeCellsHeader, onUnlockedCells, noop, noop, bodyCellGenerator);
7009      var mergeCells = run(opMergeCells, onUnlockedMergable, resize, noop, Generators.merging);
7010      var unmergeCells = run(opUnmergeCells, onUnlockedUnmergable, resize, noop, Generators.merging);
7011      var pasteCells = run(opPasteCells, onPaste, resize, noop, Generators.modification);
7012      var pasteColsBefore = run(opPasteColsBefore, pasteColumnsExtractor(true), noop, noop, Generators.modification);
7013      var pasteColsAfter = run(opPasteColsAfter, pasteColumnsExtractor(false), noop, noop, Generators.modification);
7014      var pasteRowsBefore = run(opPasteRowsBefore, onPasteByEditor, noop, noop, Generators.modification);
7015      var pasteRowsAfter = run(opPasteRowsAfter, onPasteByEditor, noop, noop, Generators.modification);
7016      var getColumnsType = opGetColumnsType;
7017      var getCellsType = opGetCellsType;
7018      var getRowsType = opGetRowsType;
7019  
7020      var TableActions = function (editor, cellSelection, lazyWire) {
7021        var isTableBody = function (editor) {
7022          return name(getBody(editor)) === 'table';
7023        };
7024        var lastRowGuard = function (table) {
7025          return isTableBody(editor) === false || getGridSize(table).rows > 1;
7026        };
7027        var lastColumnGuard = function (table) {
7028          return isTableBody(editor) === false || getGridSize(table).columns > 1;
7029        };
7030        var cloneFormats = getCloneElements(editor);
7031        var colMutationOp = isResizeTableColumnResizing(editor) ? noop : halve;
7032        var getTableSectionType = function (table) {
7033          switch (getTableHeaderType(editor)) {
7034          case 'section':
7035            return TableSection.section();
7036          case 'sectionCells':
7037            return TableSection.sectionCells();
7038          case 'cells':
7039            return TableSection.cells();
7040          default:
7041            return TableSection.getTableSectionType(table, 'section');
7042          }
7043        };
7044        var setSelectionFromAction = function (table, result) {
7045          return result.cursor.fold(function () {
7046            var cells = cells$1(table);
7047            return head(cells).filter(inBody).map(function (firstCell) {
7048              cellSelection.clear(table);
7049              var rng = editor.dom.createRng();
7050              rng.selectNode(firstCell.dom);
7051              editor.selection.setRng(rng);
7052              set$2(firstCell, 'data-mce-selected', '1');
7053              return rng;
7054            });
7055          }, function (cell) {
7056            var des = freefallRtl(cell);
7057            var rng = editor.dom.createRng();
7058            rng.setStart(des.element.dom, des.offset);
7059            rng.setEnd(des.element.dom, des.offset);
7060            editor.selection.setRng(rng);
7061            cellSelection.clear(table);
7062            return Optional.some(rng);
7063          });
7064        };
7065        var execute = function (operation, guard, mutate, lazyWire, effect) {
7066          return function (table, target, noEvents) {
7067            if (noEvents === void 0) {
7068              noEvents = false;
7069            }
7070            removeDataStyle(table);
7071            var wire = lazyWire();
7072            var doc = SugarElement.fromDom(editor.getDoc());
7073            var generators = cellOperations(mutate, doc, cloneFormats);
7074            var behaviours = {
7075              sizing: get$4(editor, table),
7076              resize: isResizeTableColumnResizing(editor) ? resizeTable() : preserveTable(),
7077              section: getTableSectionType(table)
7078            };
7079            return guard(table) ? operation(wire, table, target, generators, behaviours).bind(function (result) {
7080              each$2(result.newRows, function (row) {
7081                fireNewRow(editor, row.dom);
7082              });
7083              each$2(result.newCells, function (cell) {
7084                fireNewCell(editor, cell.dom);
7085              });
7086              var range = setSelectionFromAction(table, result);
7087              if (inBody(table)) {
7088                removeDataStyle(table);
7089                if (!noEvents) {
7090                  fireTableModified(editor, table.dom, effect);
7091                }
7092              }
7093              return range.map(function (rng) {
7094                return {
7095                  rng: rng,
7096                  effect: effect
7097                };
7098              });
7099            }) : Optional.none();
7100          };
7101        };
7102        var deleteRow = execute(eraseRows, lastRowGuard, noop, lazyWire, structureModified);
7103        var deleteColumn = execute(eraseColumns, lastColumnGuard, noop, lazyWire, structureModified);
7104        var insertRowsBefore$1 = execute(insertRowsBefore, always, noop, lazyWire, structureModified);
7105        var insertRowsAfter$1 = execute(insertRowsAfter, always, noop, lazyWire, structureModified);
7106        var insertColumnsBefore$1 = execute(insertColumnsBefore, always, colMutationOp, lazyWire, structureModified);
7107        var insertColumnsAfter$1 = execute(insertColumnsAfter, always, colMutationOp, lazyWire, structureModified);
7108        var mergeCells$1 = execute(mergeCells, always, noop, lazyWire, structureModified);
7109        var unmergeCells$1 = execute(unmergeCells, always, noop, lazyWire, structureModified);
7110        var pasteColsBefore$1 = execute(pasteColsBefore, always, noop, lazyWire, structureModified);
7111        var pasteColsAfter$1 = execute(pasteColsAfter, always, noop, lazyWire, structureModified);
7112        var pasteRowsBefore$1 = execute(pasteRowsBefore, always, noop, lazyWire, structureModified);
7113        var pasteRowsAfter$1 = execute(pasteRowsAfter, always, noop, lazyWire, structureModified);
7114        var pasteCells$1 = execute(pasteCells, always, noop, lazyWire, styleAndStructureModified);
7115        var makeCellsHeader$1 = execute(makeCellsHeader, always, noop, lazyWire, structureModified);
7116        var unmakeCellsHeader$1 = execute(unmakeCellsHeader, always, noop, lazyWire, structureModified);
7117        var makeColumnsHeader$1 = execute(makeColumnsHeader, always, noop, lazyWire, structureModified);
7118        var unmakeColumnsHeader$1 = execute(unmakeColumnsHeader, always, noop, lazyWire, structureModified);
7119        var makeRowsHeader$1 = execute(makeRowsHeader, always, noop, lazyWire, structureModified);
7120        var makeRowsBody$1 = execute(makeRowsBody, always, noop, lazyWire, structureModified);
7121        var makeRowsFooter$1 = execute(makeRowsFooter, always, noop, lazyWire, structureModified);
7122        var getTableCellType = getCellsType;
7123        var getTableColType = getColumnsType;
7124        var getTableRowType = getRowsType;
7125        return {
7126          deleteRow: deleteRow,
7127          deleteColumn: deleteColumn,
7128          insertRowsBefore: insertRowsBefore$1,
7129          insertRowsAfter: insertRowsAfter$1,
7130          insertColumnsBefore: insertColumnsBefore$1,
7131          insertColumnsAfter: insertColumnsAfter$1,
7132          mergeCells: mergeCells$1,
7133          unmergeCells: unmergeCells$1,
7134          pasteColsBefore: pasteColsBefore$1,
7135          pasteColsAfter: pasteColsAfter$1,
7136          pasteRowsBefore: pasteRowsBefore$1,
7137          pasteRowsAfter: pasteRowsAfter$1,
7138          pasteCells: pasteCells$1,
7139          makeCellsHeader: makeCellsHeader$1,
7140          unmakeCellsHeader: unmakeCellsHeader$1,
7141          makeColumnsHeader: makeColumnsHeader$1,
7142          unmakeColumnsHeader: unmakeColumnsHeader$1,
7143          makeRowsHeader: makeRowsHeader$1,
7144          makeRowsBody: makeRowsBody$1,
7145          makeRowsFooter: makeRowsFooter$1,
7146          getTableRowType: getTableRowType,
7147          getTableCellType: getTableCellType,
7148          getTableColType: getTableColType
7149        };
7150      };
7151  
7152      var DefaultRenderOptions = {
7153        styles: {
7154          'border-collapse': 'collapse',
7155          'width': '100%'
7156        },
7157        attributes: { border: '1' },
7158        colGroups: false
7159      };
7160      var tableHeaderCell = function () {
7161        return SugarElement.fromTag('th');
7162      };
7163      var tableCell = function () {
7164        return SugarElement.fromTag('td');
7165      };
7166      var tableColumn = function () {
7167        return SugarElement.fromTag('col');
7168      };
7169      var createRow = function (columns, rowHeaders, columnHeaders, rowIndex) {
7170        var tr = SugarElement.fromTag('tr');
7171        for (var j = 0; j < columns; j++) {
7172          var td = rowIndex < rowHeaders || j < columnHeaders ? tableHeaderCell() : tableCell();
7173          if (j < columnHeaders) {
7174            set$2(td, 'scope', 'row');
7175          }
7176          if (rowIndex < rowHeaders) {
7177            set$2(td, 'scope', 'col');
7178          }
7179          append$1(td, SugarElement.fromTag('br'));
7180          append$1(tr, td);
7181        }
7182        return tr;
7183      };
7184      var createGroupRow = function (columns) {
7185        var columnGroup = SugarElement.fromTag('colgroup');
7186        range$1(columns, function () {
7187          return append$1(columnGroup, tableColumn());
7188        });
7189        return columnGroup;
7190      };
7191      var createRows = function (rows, columns, rowHeaders, columnHeaders) {
7192        return range$1(rows, function (r) {
7193          return createRow(columns, rowHeaders, columnHeaders, r);
7194        });
7195      };
7196      var render = function (rows, columns, rowHeaders, columnHeaders, headerType, renderOpts) {
7197        if (renderOpts === void 0) {
7198          renderOpts = DefaultRenderOptions;
7199        }
7200        var table = SugarElement.fromTag('table');
7201        var rowHeadersGoInThead = headerType !== 'cells';
7202        setAll(table, renderOpts.styles);
7203        setAll$1(table, renderOpts.attributes);
7204        if (renderOpts.colGroups) {
7205          append$1(table, createGroupRow(columns));
7206        }
7207        var actualRowHeaders = Math.min(rows, rowHeaders);
7208        if (rowHeadersGoInThead && rowHeaders > 0) {
7209          var thead = SugarElement.fromTag('thead');
7210          append$1(table, thead);
7211          var theadRowHeaders = headerType === 'sectionCells' ? actualRowHeaders : 0;
7212          var theadRows = createRows(rowHeaders, columns, theadRowHeaders, columnHeaders);
7213          append(thead, theadRows);
7214        }
7215        var tbody = SugarElement.fromTag('tbody');
7216        append$1(table, tbody);
7217        var numRows = rowHeadersGoInThead ? rows - actualRowHeaders : rows;
7218        var numRowHeaders = rowHeadersGoInThead ? 0 : rowHeaders;
7219        var tbodyRows = createRows(numRows, columns, numRowHeaders, columnHeaders);
7220        append(tbody, tbodyRows);
7221        return table;
7222      };
7223  
7224      var get$2 = function (element) {
7225        return element.dom.innerHTML;
7226      };
7227      var getOuter = function (element) {
7228        var container = SugarElement.fromTag('div');
7229        var clone = SugarElement.fromDom(element.dom.cloneNode(true));
7230        append$1(container, clone);
7231        return get$2(container);
7232      };
7233  
7234      var placeCaretInCell = function (editor, cell) {
7235        editor.selection.select(cell.dom, true);
7236        editor.selection.collapse(true);
7237      };
7238      var selectFirstCellInTable = function (editor, tableElm) {
7239        descendant(tableElm, 'td,th').each(curry(placeCaretInCell, editor));
7240      };
7241      var fireEvents = function (editor, table) {
7242        each$2(descendants(table, 'tr'), function (row) {
7243          fireNewRow(editor, row.dom);
7244          each$2(descendants(row, 'th,td'), function (cell) {
7245            fireNewCell(editor, cell.dom);
7246          });
7247        });
7248      };
7249      var isPercentage = function (width) {
7250        return isString(width) && width.indexOf('%') !== -1;
7251      };
7252      var insert = function (editor, columns, rows, colHeaders, rowHeaders) {
7253        var defaultStyles = getDefaultStyles(editor);
7254        var options = {
7255          styles: defaultStyles,
7256          attributes: getDefaultAttributes(editor),
7257          colGroups: useColumnGroup(editor)
7258        };
7259        editor.undoManager.ignore(function () {
7260          var table = render(rows, columns, rowHeaders, colHeaders, getTableHeaderType(editor), options);
7261          set$2(table, 'data-mce-id', '__mce');
7262          var html = getOuter(table);
7263          editor.insertContent(html);
7264          editor.addVisual();
7265        });
7266        return descendant(getBody(editor), 'table[data-mce-id="__mce"]').map(function (table) {
7267          if (isPixelsForced(editor)) {
7268            enforcePixels(table);
7269          } else if (isResponsiveForced(editor)) {
7270            enforceNone(table);
7271          } else if (isPercentagesForced(editor) || isPercentage(defaultStyles.width)) {
7272            enforcePercentage(table);
7273          }
7274          removeDataStyle(table);
7275          remove$7(table, 'data-mce-id');
7276          fireEvents(editor, table);
7277          selectFirstCellInTable(editor, table);
7278          return table.dom;
7279        }).getOr(null);
7280      };
7281      var insertTableWithDataValidation = function (editor, rows, columns, options, errorMsg) {
7282        if (options === void 0) {
7283          options = {};
7284        }
7285        var checkInput = function (val) {
7286          return isNumber(val) && val > 0;
7287        };
7288        if (checkInput(rows) && checkInput(columns)) {
7289          var headerRows = options.headerRows || 0;
7290          var headerColumns = options.headerColumns || 0;
7291          return insert(editor, columns, rows, headerColumns, headerRows);
7292        } else {
7293          console.error(errorMsg);
7294          return null;
7295        }
7296      };
7297  
7298      var getClipboardElements = function (getClipboard) {
7299        return function () {
7300          return getClipboard().fold(function () {
7301            return [];
7302          }, function (elems) {
7303            return map$1(elems, function (e) {
7304              return e.dom;
7305            });
7306          });
7307        };
7308      };
7309      var setClipboardElements = function (setClipboard) {
7310        return function (elems) {
7311          var elmsOpt = elems.length > 0 ? Optional.some(fromDom(elems)) : Optional.none();
7312          setClipboard(elmsOpt);
7313        };
7314      };
7315      var insertTable = function (editor) {
7316        return function (columns, rows, options) {
7317          if (options === void 0) {
7318            options = {};
7319          }
7320          var table = insertTableWithDataValidation(editor, rows, columns, options, 'Invalid values for insertTable - rows and columns values are required to insert a table.');
7321          editor.undoManager.add();
7322          return table;
7323        };
7324      };
7325      var getApi = function (editor, clipboard, resizeHandler, selectionTargets) {
7326        return {
7327          insertTable: insertTable(editor),
7328          setClipboardRows: setClipboardElements(clipboard.setRows),
7329          getClipboardRows: getClipboardElements(clipboard.getRows),
7330          setClipboardCols: setClipboardElements(clipboard.setColumns),
7331          getClipboardCols: getClipboardElements(clipboard.getColumns),
7332          resizeHandler: resizeHandler,
7333          selectionTargets: selectionTargets
7334        };
7335      };
7336  
7337      var constrainSpan = function (element, property, value) {
7338        var currentColspan = getAttrValue(element, property, 1);
7339        if (value === 1 || currentColspan <= 1) {
7340          remove$7(element, property);
7341        } else {
7342          set$2(element, property, Math.min(value, currentColspan));
7343        }
7344      };
7345      var generateColGroup = function (house, minColRange, maxColRange) {
7346        if (Warehouse.hasColumns(house)) {
7347          var colsToCopy = filter$2(Warehouse.justColumns(house), function (col) {
7348            return col.column >= minColRange && col.column < maxColRange;
7349          });
7350          var copiedCols = map$1(colsToCopy, function (c) {
7351            var clonedCol = deep(c.element);
7352            constrainSpan(clonedCol, 'span', maxColRange - minColRange);
7353            return clonedCol;
7354          });
7355          var fakeColgroup = SugarElement.fromTag('colgroup');
7356          append(fakeColgroup, copiedCols);
7357          return [fakeColgroup];
7358        } else {
7359          return [];
7360        }
7361      };
7362      var generateRows = function (house, minColRange, maxColRange) {
7363        return map$1(house.all, function (row) {
7364          var cellsToCopy = filter$2(row.cells, function (cell) {
7365            return cell.column >= minColRange && cell.column < maxColRange;
7366          });
7367          var copiedCells = map$1(cellsToCopy, function (cell) {
7368            var clonedCell = deep(cell.element);
7369            constrainSpan(clonedCell, 'colspan', maxColRange - minColRange);
7370            return clonedCell;
7371          });
7372          var fakeTR = SugarElement.fromTag('tr');
7373          append(fakeTR, copiedCells);
7374          return fakeTR;
7375        });
7376      };
7377      var copyCols = function (table, target) {
7378        var house = Warehouse.fromTable(table);
7379        var details = onUnlockedCells(house, target);
7380        return details.map(function (selectedCells) {
7381          var lastSelectedCell = selectedCells[selectedCells.length - 1];
7382          var minColRange = selectedCells[0].column;
7383          var maxColRange = lastSelectedCell.column + lastSelectedCell.colspan;
7384          var fakeColGroups = generateColGroup(house, minColRange, maxColRange);
7385          var fakeRows = generateRows(house, minColRange, maxColRange);
7386          return __spreadArray(__spreadArray([], fakeColGroups, true), fakeRows, true);
7387        });
7388      };
7389  
7390      var copyRows = function (table, target, generators) {
7391        var warehouse = Warehouse.fromTable(table);
7392        var details = onCells(warehouse, target);
7393        return details.bind(function (selectedCells) {
7394          var grid = toGrid(warehouse, generators, false);
7395          var rows = extractGridDetails(grid).rows;
7396          var slicedGrid = rows.slice(selectedCells[0].row, selectedCells[selectedCells.length - 1].row + selectedCells[selectedCells.length - 1].rowspan);
7397          var filteredGrid = bind$2(slicedGrid, function (row) {
7398            var newCells = filter$2(row.cells, function (cell) {
7399              return !cell.isLocked;
7400            });
7401            return newCells.length > 0 ? [__assign(__assign({}, row), { cells: newCells })] : [];
7402          });
7403          var slicedDetails = toDetailList(filteredGrid);
7404          return someIf(slicedDetails.length > 0, slicedDetails);
7405        }).map(function (slicedDetails) {
7406          return copy(slicedDetails);
7407        });
7408      };
7409  
7410      var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools');
7411  
7412      var getTDTHOverallStyle = function (dom, elm, name) {
7413        var cells = dom.select('td,th', elm);
7414        var firstChildStyle;
7415        var checkChildren = function (firstChildStyle, elms) {
7416          for (var i = 0; i < elms.length; i++) {
7417            var currentStyle = dom.getStyle(elms[i], name);
7418            if (typeof firstChildStyle === 'undefined') {
7419              firstChildStyle = currentStyle;
7420            }
7421            if (firstChildStyle !== currentStyle) {
7422              return '';
7423            }
7424          }
7425          return firstChildStyle;
7426        };
7427        return checkChildren(firstChildStyle, cells);
7428      };
7429      var applyAlign = function (editor, elm, name) {
7430        if (name) {
7431          editor.formatter.apply('align' + name, {}, elm);
7432        }
7433      };
7434      var applyVAlign = function (editor, elm, name) {
7435        if (name) {
7436          editor.formatter.apply('valign' + name, {}, elm);
7437        }
7438      };
7439      var unApplyAlign = function (editor, elm) {
7440        global$2.each('left center right'.split(' '), function (name) {
7441          editor.formatter.remove('align' + name, {}, elm);
7442        });
7443      };
7444      var unApplyVAlign = function (editor, elm) {
7445        global$2.each('top middle bottom'.split(' '), function (name) {
7446          editor.formatter.remove('valign' + name, {}, elm);
7447        });
7448      };
7449  
7450      var verticalAlignValues = [
7451        {
7452          text: 'None',
7453          value: ''
7454        },
7455        {
7456          text: 'Top',
7457          value: 'top'
7458        },
7459        {
7460          text: 'Middle',
7461          value: 'middle'
7462        },
7463        {
7464          text: 'Bottom',
7465          value: 'bottom'
7466        }
7467      ];
7468  
7469      var hexColour = function (value) {
7470        return { value: value };
7471      };
7472      var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
7473      var longformRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
7474      var isHexString = function (hex) {
7475        return shorthandRegex.test(hex) || longformRegex.test(hex);
7476      };
7477      var normalizeHex = function (hex) {
7478        return removeLeading(hex, '#').toUpperCase();
7479      };
7480      var fromString$1 = function (hex) {
7481        return isHexString(hex) ? Optional.some({ value: normalizeHex(hex) }) : Optional.none();
7482      };
7483      var toHex = function (component) {
7484        var hex = component.toString(16);
7485        return (hex.length === 1 ? '0' + hex : hex).toUpperCase();
7486      };
7487      var fromRgba = function (rgbaColour) {
7488        var value = toHex(rgbaColour.red) + toHex(rgbaColour.green) + toHex(rgbaColour.blue);
7489        return hexColour(value);
7490      };
7491  
7492      var rgbRegex = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)/;
7493      var rgbaRegex = /^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d?(?:\.\d+)?)\)/;
7494      var rgbaColour = function (red, green, blue, alpha) {
7495        return {
7496          red: red,
7497          green: green,
7498          blue: blue,
7499          alpha: alpha
7500        };
7501      };
7502      var fromStringValues = function (red, green, blue, alpha) {
7503        var r = parseInt(red, 10);
7504        var g = parseInt(green, 10);
7505        var b = parseInt(blue, 10);
7506        var a = parseFloat(alpha);
7507        return rgbaColour(r, g, b, a);
7508      };
7509      var fromString = function (rgbaString) {
7510        if (rgbaString === 'transparent') {
7511          return Optional.some(rgbaColour(0, 0, 0, 0));
7512        }
7513        var rgbMatch = rgbRegex.exec(rgbaString);
7514        if (rgbMatch !== null) {
7515          return Optional.some(fromStringValues(rgbMatch[1], rgbMatch[2], rgbMatch[3], '1'));
7516        }
7517        var rgbaMatch = rgbaRegex.exec(rgbaString);
7518        if (rgbaMatch !== null) {
7519          return Optional.some(fromStringValues(rgbaMatch[1], rgbaMatch[2], rgbaMatch[3], rgbaMatch[4]));
7520        }
7521        return Optional.none();
7522      };
7523  
7524      var anyToHex = function (color) {
7525        return fromString$1(color).orThunk(function () {
7526          return fromString(color).map(fromRgba);
7527        }).getOrThunk(function () {
7528          var canvas = document.createElement('canvas');
7529          canvas.height = 1;
7530          canvas.width = 1;
7531          var canvasContext = canvas.getContext('2d');
7532          canvasContext.clearRect(0, 0, canvas.width, canvas.height);
7533          canvasContext.fillStyle = '#FFFFFF';
7534          canvasContext.fillStyle = color;
7535          canvasContext.fillRect(0, 0, 1, 1);
7536          var rgba = canvasContext.getImageData(0, 0, 1, 1).data;
7537          var r = rgba[0];
7538          var g = rgba[1];
7539          var b = rgba[2];
7540          var a = rgba[3];
7541          return fromRgba(rgbaColour(r, g, b, a));
7542        });
7543      };
7544  
7545      var Cell = function (initial) {
7546        var value = initial;
7547        var get = function () {
7548          return value;
7549        };
7550        var set = function (v) {
7551          value = v;
7552        };
7553        return {
7554          get: get,
7555          set: set
7556        };
7557      };
7558  
7559      var singleton = function (doRevoke) {
7560        var subject = Cell(Optional.none());
7561        var revoke = function () {
7562          return subject.get().each(doRevoke);
7563        };
7564        var clear = function () {
7565          revoke();
7566          subject.set(Optional.none());
7567        };
7568        var isSet = function () {
7569          return subject.get().isSome();
7570        };
7571        var get = function () {
7572          return subject.get();
7573        };
7574        var set = function (s) {
7575          revoke();
7576          subject.set(Optional.some(s));
7577        };
7578        return {
7579          clear: clear,
7580          isSet: isSet,
7581          get: get,
7582          set: set
7583        };
7584      };
7585      var unbindable = function () {
7586        return singleton(function (s) {
7587          return s.unbind();
7588        });
7589      };
7590      var value = function () {
7591        var subject = singleton(noop);
7592        var on = function (f) {
7593          return subject.get().each(f);
7594        };
7595        return __assign(__assign({}, subject), { on: on });
7596      };
7597  
7598      var onSetupToggle = function (editor, selections, formatName, formatValue) {
7599        return function (api) {
7600          var boundCallback = unbindable();
7601          var isNone = isEmpty$1(formatValue);
7602          var init = function () {
7603            var selectedCells = getCellsFromSelection(selections);
7604            var checkNode = function (cell) {
7605              return editor.formatter.match(formatName, { value: formatValue }, cell.dom, isNone);
7606            };
7607            if (isNone) {
7608              api.setActive(!exists(selectedCells, checkNode));
7609              boundCallback.set(editor.formatter.formatChanged(formatName, function (match) {
7610                return api.setActive(!match);
7611              }, true));
7612            } else {
7613              api.setActive(forall(selectedCells, checkNode));
7614              boundCallback.set(editor.formatter.formatChanged(formatName, api.setActive, false, { value: formatValue }));
7615            }
7616          };
7617          editor.initialized ? init() : editor.on('init', init);
7618          return boundCallback.clear;
7619        };
7620      };
7621      var isListGroup = function (item) {
7622        return hasNonNullableKey(item, 'menu');
7623      };
7624      var buildListItems = function (items) {
7625        return map$1(items, function (item) {
7626          var text = item.text || item.title;
7627          if (isListGroup(item)) {
7628            return {
7629              text: text,
7630              items: buildListItems(item.menu)
7631            };
7632          } else {
7633            return {
7634              text: text,
7635              value: item.value
7636            };
7637          }
7638        });
7639      };
7640      var buildMenuItems = function (editor, selections, items, format, onAction) {
7641        return map$1(items, function (item) {
7642          var text = item.text || item.title;
7643          if (isListGroup(item)) {
7644            return {
7645              type: 'nestedmenuitem',
7646              text: text,
7647              getSubmenuItems: function () {
7648                return buildMenuItems(editor, selections, item.menu, format, onAction);
7649              }
7650            };
7651          } else {
7652            return {
7653              text: text,
7654              type: 'togglemenuitem',
7655              onAction: function () {
7656                return onAction(item.value);
7657              },
7658              onSetup: onSetupToggle(editor, selections, format, item.value)
7659            };
7660          }
7661        });
7662      };
7663      var applyTableCellStyle = function (editor, style) {
7664        return function (value) {
7665          var _a;
7666          editor.execCommand('mceTableApplyCellStyle', false, (_a = {}, _a[style] = value, _a));
7667        };
7668      };
7669      var filterNoneItem = function (list) {
7670        return bind$2(list, function (item) {
7671          if (isListGroup(item)) {
7672            return [__assign(__assign({}, item), { menu: filterNoneItem(item.menu) })];
7673          } else {
7674            return isNotEmpty(item.value) ? [item] : [];
7675          }
7676        });
7677      };
7678      var generateMenuItemsCallback = function (editor, selections, items, format, onAction) {
7679        return function (callback) {
7680          return callback(buildMenuItems(editor, selections, items, format, onAction));
7681        };
7682      };
7683      var buildColorMenu = function (editor, colorList, style) {
7684        var colorMap = map$1(colorList, function (entry) {
7685          return {
7686            text: entry.title,
7687            value: '#' + anyToHex(entry.value).value,
7688            type: 'choiceitem'
7689          };
7690        });
7691        return [{
7692            type: 'fancymenuitem',
7693            fancytype: 'colorswatch',
7694            initData: {
7695              colors: colorMap.length > 0 ? colorMap : undefined,
7696              allowCustomColors: false
7697            },
7698            onAction: function (data) {
7699              var _a;
7700              var value = data.value === 'remove' ? '' : data.value;
7701              editor.execCommand('mceTableApplyCellStyle', false, (_a = {}, _a[style] = value, _a));
7702            }
7703          }];
7704      };
7705      var changeRowHeader = function (editor) {
7706        return function () {
7707          var currentType = editor.queryCommandValue('mceTableRowType');
7708          var newType = currentType === 'header' ? 'body' : 'header';
7709          editor.execCommand('mceTableRowType', false, { type: newType });
7710        };
7711      };
7712      var changeColumnHeader = function (editor) {
7713        return function () {
7714          var currentType = editor.queryCommandValue('mceTableColType');
7715          var newType = currentType === 'th' ? 'td' : 'th';
7716          editor.execCommand('mceTableColType', false, { type: newType });
7717        };
7718      };
7719  
7720      var getClassList$1 = function (editor) {
7721        var classes = buildListItems(getCellClassList(editor));
7722        if (classes.length > 0) {
7723          return Optional.some({
7724            name: 'class',
7725            type: 'listbox',
7726            label: 'Class',
7727            items: classes
7728          });
7729        }
7730        return Optional.none();
7731      };
7732      var children = [
7733        {
7734          name: 'width',
7735          type: 'input',
7736          label: 'Width'
7737        },
7738        {
7739          name: 'height',
7740          type: 'input',
7741          label: 'Height'
7742        },
7743        {
7744          name: 'celltype',
7745          type: 'listbox',
7746          label: 'Cell type',
7747          items: [
7748            {
7749              text: 'Cell',
7750              value: 'td'
7751            },
7752            {
7753              text: 'Header cell',
7754              value: 'th'
7755            }
7756          ]
7757        },
7758        {
7759          name: 'scope',
7760          type: 'listbox',
7761          label: 'Scope',
7762          items: [
7763            {
7764              text: 'None',
7765              value: ''
7766            },
7767            {
7768              text: 'Row',
7769              value: 'row'
7770            },
7771            {
7772              text: 'Column',
7773              value: 'col'
7774            },
7775            {
7776              text: 'Row group',
7777              value: 'rowgroup'
7778            },
7779            {
7780              text: 'Column group',
7781              value: 'colgroup'
7782            }
7783          ]
7784        },
7785        {
7786          name: 'halign',
7787          type: 'listbox',
7788          label: 'Horizontal align',
7789          items: [
7790            {
7791              text: 'None',
7792              value: ''
7793            },
7794            {
7795              text: 'Left',
7796              value: 'left'
7797            },
7798            {
7799              text: 'Center',
7800              value: 'center'
7801            },
7802            {
7803              text: 'Right',
7804              value: 'right'
7805            }
7806          ]
7807        },
7808        {
7809          name: 'valign',
7810          type: 'listbox',
7811          label: 'Vertical align',
7812          items: verticalAlignValues
7813        }
7814      ];
7815      var getItems$2 = function (editor) {
7816        return children.concat(getClassList$1(editor).toArray());
7817      };
7818  
7819      var getAdvancedTab = function (editor, dialogName) {
7820        var emptyBorderStyle = [{
7821            text: 'Select...',
7822            value: ''
7823          }];
7824        var advTabItems = [
7825          {
7826            name: 'borderstyle',
7827            type: 'listbox',
7828            label: 'Border style',
7829            items: emptyBorderStyle.concat(buildListItems(getTableBorderStyles(editor)))
7830          },
7831          {
7832            name: 'bordercolor',
7833            type: 'colorinput',
7834            label: 'Border color'
7835          },
7836          {
7837            name: 'backgroundcolor',
7838            type: 'colorinput',
7839            label: 'Background color'
7840          }
7841        ];
7842        var borderWidth = {
7843          name: 'borderwidth',
7844          type: 'input',
7845          label: 'Border width'
7846        };
7847        var items = dialogName === 'cell' ? [borderWidth].concat(advTabItems) : advTabItems;
7848        return {
7849          title: 'Advanced',
7850          name: 'advanced',
7851          items: items
7852        };
7853      };
7854  
7855      var modifiers = function (testTruthy) {
7856        return function (editor, node) {
7857          var dom = editor.dom;
7858          var setAttrib = function (attr, value) {
7859            if (!testTruthy || value) {
7860              dom.setAttrib(node, attr, value);
7861            }
7862          };
7863          var setStyle = function (prop, value) {
7864            if (!testTruthy || value) {
7865              dom.setStyle(node, prop, value);
7866            }
7867          };
7868          var setFormat = function (formatName, value) {
7869            if (!testTruthy || value) {
7870              if (value === '') {
7871                editor.formatter.remove(formatName, { value: null }, node, true);
7872              } else {
7873                editor.formatter.apply(formatName, { value: value }, node);
7874              }
7875            }
7876          };
7877          return {
7878            setAttrib: setAttrib,
7879            setStyle: setStyle,
7880            setFormat: setFormat
7881          };
7882        };
7883      };
7884      var DomModifier = {
7885        normal: modifiers(false),
7886        ifTruthy: modifiers(true)
7887      };
7888  
7889      var rgbToHex = function (dom) {
7890        return function (value) {
7891          return startsWith(value, 'rgb') ? dom.toHex(value) : value;
7892        };
7893      };
7894      var extractAdvancedStyles = function (dom, elm) {
7895        var element = SugarElement.fromDom(elm);
7896        return {
7897          borderwidth: getRaw$2(element, 'border-width').getOr(''),
7898          borderstyle: getRaw$2(element, 'border-style').getOr(''),
7899          bordercolor: getRaw$2(element, 'border-color').map(rgbToHex(dom)).getOr(''),
7900          backgroundcolor: getRaw$2(element, 'background-color').map(rgbToHex(dom)).getOr('')
7901        };
7902      };
7903      var getSharedValues = function (data) {
7904        var baseData = data[0];
7905        var comparisonData = data.slice(1);
7906        each$2(comparisonData, function (items) {
7907          each$2(keys(baseData), function (key) {
7908            each$1(items, function (itemValue, itemKey) {
7909              var comparisonValue = baseData[key];
7910              if (comparisonValue !== '' && key === itemKey) {
7911                if (comparisonValue !== itemValue) {
7912                  baseData[key] = '';
7913                }
7914              }
7915            });
7916          });
7917        });
7918        return baseData;
7919      };
7920      var getAlignment = function (formats, formatName, editor, elm) {
7921        return find$1(formats, function (name) {
7922          return !isUndefined(editor.formatter.matchNode(elm, formatName + name));
7923        }).getOr('');
7924      };
7925      var getHAlignment = curry(getAlignment, [
7926        'left',
7927        'center',
7928        'right'
7929      ], 'align');
7930      var getVAlignment = curry(getAlignment, [
7931        'top',
7932        'middle',
7933        'bottom'
7934      ], 'valign');
7935      var extractDataFromSettings = function (editor, hasAdvTableTab) {
7936        var style = getDefaultStyles(editor);
7937        var attrs = getDefaultAttributes(editor);
7938        var extractAdvancedStyleData = function (dom) {
7939          return {
7940            borderstyle: get$c(style, 'border-style').getOr(''),
7941            bordercolor: rgbToHex(dom)(get$c(style, 'border-color').getOr('')),
7942            backgroundcolor: rgbToHex(dom)(get$c(style, 'background-color').getOr(''))
7943          };
7944        };
7945        var defaultData = {
7946          height: '',
7947          width: '100%',
7948          cellspacing: '',
7949          cellpadding: '',
7950          caption: false,
7951          class: '',
7952          align: '',
7953          border: ''
7954        };
7955        var getBorder = function () {
7956          var borderWidth = style['border-width'];
7957          if (shouldStyleWithCss(editor) && borderWidth) {
7958            return { border: borderWidth };
7959          }
7960          return get$c(attrs, 'border').fold(function () {
7961            return {};
7962          }, function (border) {
7963            return { border: border };
7964          });
7965        };
7966        var advStyle = hasAdvTableTab ? extractAdvancedStyleData(editor.dom) : {};
7967        var getCellPaddingCellSpacing = function () {
7968          var spacing = get$c(style, 'border-spacing').or(get$c(attrs, 'cellspacing')).fold(function () {
7969            return {};
7970          }, function (cellspacing) {
7971            return { cellspacing: cellspacing };
7972          });
7973          var padding = get$c(style, 'border-padding').or(get$c(attrs, 'cellpadding')).fold(function () {
7974            return {};
7975          }, function (cellpadding) {
7976            return { cellpadding: cellpadding };
7977          });
7978          return __assign(__assign({}, spacing), padding);
7979        };
7980        var data = __assign(__assign(__assign(__assign(__assign(__assign({}, defaultData), style), attrs), advStyle), getBorder()), getCellPaddingCellSpacing());
7981        return data;
7982      };
7983      var getRowType = function (elm) {
7984        return table(SugarElement.fromDom(elm)).map(function (table) {
7985          var target = { selection: fromDom(elm.cells) };
7986          return getRowsType(table, target);
7987        }).getOr('');
7988      };
7989      var extractDataFromTableElement = function (editor, elm, hasAdvTableTab) {
7990        var getBorder = function (dom, elm) {
7991          var optBorderWidth = getRaw$2(SugarElement.fromDom(elm), 'border-width');
7992          if (shouldStyleWithCss(editor) && optBorderWidth.isSome()) {
7993            return optBorderWidth.getOr('');
7994          }
7995          return dom.getAttrib(elm, 'border') || getTDTHOverallStyle(editor.dom, elm, 'border-width') || getTDTHOverallStyle(editor.dom, elm, 'border');
7996        };
7997        var dom = editor.dom;
7998        var cellspacing = shouldStyleWithCss(editor) ? dom.getStyle(elm, 'border-spacing') || dom.getAttrib(elm, 'cellspacing') : dom.getAttrib(elm, 'cellspacing') || dom.getStyle(elm, 'border-spacing');
7999        var cellpadding = shouldStyleWithCss(editor) ? getTDTHOverallStyle(dom, elm, 'padding') || dom.getAttrib(elm, 'cellpadding') : dom.getAttrib(elm, 'cellpadding') || getTDTHOverallStyle(dom, elm, 'padding');
8000        return __assign({
8001          width: dom.getStyle(elm, 'width') || dom.getAttrib(elm, 'width'),
8002          height: dom.getStyle(elm, 'height') || dom.getAttrib(elm, 'height'),
8003          cellspacing: cellspacing,
8004          cellpadding: cellpadding,
8005          border: getBorder(dom, elm),
8006          caption: !!dom.select('caption', elm)[0],
8007          class: dom.getAttrib(elm, 'class', ''),
8008          align: getHAlignment(editor, elm)
8009        }, hasAdvTableTab ? extractAdvancedStyles(dom, elm) : {});
8010      };
8011      var extractDataFromRowElement = function (editor, elm, hasAdvancedRowTab) {
8012        var dom = editor.dom;
8013        return __assign({
8014          height: dom.getStyle(elm, 'height') || dom.getAttrib(elm, 'height'),
8015          class: dom.getAttrib(elm, 'class', ''),
8016          type: getRowType(elm),
8017          align: getHAlignment(editor, elm)
8018        }, hasAdvancedRowTab ? extractAdvancedStyles(dom, elm) : {});
8019      };
8020      var extractDataFromCellElement = function (editor, cell, hasAdvancedCellTab, column) {
8021        var dom = editor.dom;
8022        var colElm = column.getOr(cell);
8023        var getStyle = function (element, style) {
8024          return dom.getStyle(element, style) || dom.getAttrib(element, style);
8025        };
8026        return __assign({
8027          width: getStyle(colElm, 'width'),
8028          height: getStyle(cell, 'height'),
8029          scope: dom.getAttrib(cell, 'scope'),
8030          celltype: getNodeName(cell),
8031          class: dom.getAttrib(cell, 'class', ''),
8032          halign: getHAlignment(editor, cell),
8033          valign: getVAlignment(editor, cell)
8034        }, hasAdvancedCellTab ? extractAdvancedStyles(dom, cell) : {});
8035      };
8036  
8037      var getSelectedCells = function (table, cells) {
8038        var warehouse = Warehouse.fromTable(table);
8039        var allCells = Warehouse.justCells(warehouse);
8040        var filtered = filter$2(allCells, function (cellA) {
8041          return exists(cells, function (cellB) {
8042            return eq$1(cellA.element, cellB);
8043          });
8044        });
8045        return map$1(filtered, function (cell) {
8046          return {
8047            element: cell.element.dom,
8048            column: Warehouse.getColumnAt(warehouse, cell.column).map(function (col) {
8049              return col.element.dom;
8050            })
8051          };
8052        });
8053      };
8054      var updateSimpleProps$1 = function (modifier, colModifier, data) {
8055        modifier.setAttrib('scope', data.scope);
8056        modifier.setAttrib('class', data.class);
8057        modifier.setStyle('height', addPxSuffix(data.height));
8058        colModifier.setStyle('width', addPxSuffix(data.width));
8059      };
8060      var updateAdvancedProps$1 = function (modifier, data) {
8061        modifier.setFormat('tablecellbackgroundcolor', data.backgroundcolor);
8062        modifier.setFormat('tablecellbordercolor', data.bordercolor);
8063        modifier.setFormat('tablecellborderstyle', data.borderstyle);
8064        modifier.setFormat('tablecellborderwidth', addPxSuffix(data.borderwidth));
8065      };
8066      var applyStyleData$1 = function (editor, cells, data) {
8067        var isSingleCell = cells.length === 1;
8068        each$2(cells, function (item) {
8069          var cellElm = item.element;
8070          var modifier = isSingleCell ? DomModifier.normal(editor, cellElm) : DomModifier.ifTruthy(editor, cellElm);
8071          var colModifier = item.column.map(function (col) {
8072            return isSingleCell ? DomModifier.normal(editor, col) : DomModifier.ifTruthy(editor, col);
8073          }).getOr(modifier);
8074          updateSimpleProps$1(modifier, colModifier, data);
8075          if (hasAdvancedCellTab(editor)) {
8076            updateAdvancedProps$1(modifier, data);
8077          }
8078          if (isSingleCell) {
8079            unApplyAlign(editor, cellElm);
8080            unApplyVAlign(editor, cellElm);
8081          }
8082          if (data.halign) {
8083            applyAlign(editor, cellElm, data.halign);
8084          }
8085          if (data.valign) {
8086            applyVAlign(editor, cellElm, data.valign);
8087          }
8088        });
8089      };
8090      var applyStructureData$1 = function (editor, data) {
8091        editor.execCommand('mceTableCellType', false, {
8092          type: data.celltype,
8093          no_events: true
8094        });
8095      };
8096      var applyCellData = function (editor, cells, oldData, data) {
8097        var modifiedData = filter$1(data, function (value, key) {
8098          return oldData[key] !== value;
8099        });
8100        if (size(modifiedData) > 0 && cells.length >= 1) {
8101          table(cells[0]).each(function (table) {
8102            var selectedCells = getSelectedCells(table, cells);
8103            var styleModified = size(filter$1(modifiedData, function (_value, key) {
8104              return key !== 'scope' && key !== 'celltype';
8105            })) > 0;
8106            var structureModified = has$1(modifiedData, 'celltype');
8107            if (styleModified || has$1(modifiedData, 'scope')) {
8108              applyStyleData$1(editor, selectedCells, data);
8109            }
8110            if (structureModified) {
8111              applyStructureData$1(editor, data);
8112            }
8113            fireTableModified(editor, table.dom, {
8114              structure: structureModified,
8115              style: styleModified
8116            });
8117          });
8118        }
8119      };
8120      var onSubmitCellForm = function (editor, cells, oldData, api) {
8121        var data = api.getData();
8122        api.close();
8123        editor.undoManager.transact(function () {
8124          applyCellData(editor, cells, oldData, data);
8125          editor.focus();
8126        });
8127      };
8128      var getData = function (editor, cells) {
8129        var cellsData = table(cells[0]).map(function (table) {
8130          return map$1(getSelectedCells(table, cells), function (item) {
8131            return extractDataFromCellElement(editor, item.element, hasAdvancedCellTab(editor), item.column);
8132          });
8133        });
8134        return getSharedValues(cellsData.getOrDie());
8135      };
8136      var open$2 = function (editor, selections) {
8137        var cells = getCellsFromSelection(selections);
8138        if (cells.length === 0) {
8139          return;
8140        }
8141        var data = getData(editor, cells);
8142        var dialogTabPanel = {
8143          type: 'tabpanel',
8144          tabs: [
8145            {
8146              title: 'General',
8147              name: 'general',
8148              items: getItems$2(editor)
8149            },
8150            getAdvancedTab(editor, 'cell')
8151          ]
8152        };
8153        var dialogPanel = {
8154          type: 'panel',
8155          items: [{
8156              type: 'grid',
8157              columns: 2,
8158              items: getItems$2(editor)
8159            }]
8160        };
8161        editor.windowManager.open({
8162          title: 'Cell Properties',
8163          size: 'normal',
8164          body: hasAdvancedCellTab(editor) ? dialogTabPanel : dialogPanel,
8165          buttons: [
8166            {
8167              type: 'cancel',
8168              name: 'cancel',
8169              text: 'Cancel'
8170            },
8171            {
8172              type: 'submit',
8173              name: 'save',
8174              text: 'Save',
8175              primary: true
8176            }
8177          ],
8178          initialData: data,
8179          onSubmit: curry(onSubmitCellForm, editor, cells, data)
8180        });
8181      };
8182  
8183      var getClassList = function (editor) {
8184        var classes = buildListItems(getRowClassList(editor));
8185        if (classes.length > 0) {
8186          return Optional.some({
8187            name: 'class',
8188            type: 'listbox',
8189            label: 'Class',
8190            items: classes
8191          });
8192        }
8193        return Optional.none();
8194      };
8195      var formChildren = [
8196        {
8197          type: 'listbox',
8198          name: 'type',
8199          label: 'Row type',
8200          items: [
8201            {
8202              text: 'Header',
8203              value: 'header'
8204            },
8205            {
8206              text: 'Body',
8207              value: 'body'
8208            },
8209            {
8210              text: 'Footer',
8211              value: 'footer'
8212            }
8213          ]
8214        },
8215        {
8216          type: 'listbox',
8217          name: 'align',
8218          label: 'Alignment',
8219          items: [
8220            {
8221              text: 'None',
8222              value: ''
8223            },
8224            {
8225              text: 'Left',
8226              value: 'left'
8227            },
8228            {
8229              text: 'Center',
8230              value: 'center'
8231            },
8232            {
8233              text: 'Right',
8234              value: 'right'
8235            }
8236          ]
8237        },
8238        {
8239          label: 'Height',
8240          name: 'height',
8241          type: 'input'
8242        }
8243      ];
8244      var getItems$1 = function (editor) {
8245        return formChildren.concat(getClassList(editor).toArray());
8246      };
8247  
8248      var updateSimpleProps = function (modifier, data) {
8249        modifier.setAttrib('class', data.class);
8250        modifier.setStyle('height', addPxSuffix(data.height));
8251      };
8252      var updateAdvancedProps = function (modifier, data) {
8253        modifier.setStyle('background-color', data.backgroundcolor);
8254        modifier.setStyle('border-color', data.bordercolor);
8255        modifier.setStyle('border-style', data.borderstyle);
8256      };
8257      var applyStyleData = function (editor, rows, data, oldData) {
8258        var isSingleRow = rows.length === 1;
8259        each$2(rows, function (rowElm) {
8260          var modifier = isSingleRow ? DomModifier.normal(editor, rowElm) : DomModifier.ifTruthy(editor, rowElm);
8261          updateSimpleProps(modifier, data);
8262          if (hasAdvancedRowTab(editor)) {
8263            updateAdvancedProps(modifier, data);
8264          }
8265          if (data.align !== oldData.align) {
8266            unApplyAlign(editor, rowElm);
8267            applyAlign(editor, rowElm, data.align);
8268          }
8269        });
8270      };
8271      var applyStructureData = function (editor, data) {
8272        editor.execCommand('mceTableRowType', false, {
8273          type: data.type,
8274          no_events: true
8275        });
8276      };
8277      var applyRowData = function (editor, rows, oldData, data) {
8278        var modifiedData = filter$1(data, function (value, key) {
8279          return oldData[key] !== value;
8280        });
8281        if (size(modifiedData) > 0) {
8282          var typeModified_1 = has$1(modifiedData, 'type');
8283          var styleModified_1 = typeModified_1 ? size(modifiedData) > 1 : true;
8284          if (styleModified_1) {
8285            applyStyleData(editor, rows, data, oldData);
8286          }
8287          if (typeModified_1) {
8288            applyStructureData(editor, data);
8289          }
8290          table(SugarElement.fromDom(rows[0])).each(function (table) {
8291            return fireTableModified(editor, table.dom, {
8292              structure: typeModified_1,
8293              style: styleModified_1
8294            });
8295          });
8296        }
8297      };
8298      var onSubmitRowForm = function (editor, rows, oldData, api) {
8299        var data = api.getData();
8300        api.close();
8301        editor.undoManager.transact(function () {
8302          applyRowData(editor, rows, oldData, data);
8303          editor.focus();
8304        });
8305      };
8306      var open$1 = function (editor) {
8307        var rows = getRowsFromSelection(getSelectionStart(editor), ephemera.selected);
8308        if (rows.length === 0) {
8309          return;
8310        }
8311        var rowsData = map$1(rows, function (rowElm) {
8312          return extractDataFromRowElement(editor, rowElm.dom, hasAdvancedRowTab(editor));
8313        });
8314        var data = getSharedValues(rowsData);
8315        var dialogTabPanel = {
8316          type: 'tabpanel',
8317          tabs: [
8318            {
8319              title: 'General',
8320              name: 'general',
8321              items: getItems$1(editor)
8322            },
8323            getAdvancedTab(editor, 'row')
8324          ]
8325        };
8326        var dialogPanel = {
8327          type: 'panel',
8328          items: [{
8329              type: 'grid',
8330              columns: 2,
8331              items: getItems$1(editor)
8332            }]
8333        };
8334        editor.windowManager.open({
8335          title: 'Row Properties',
8336          size: 'normal',
8337          body: hasAdvancedRowTab(editor) ? dialogTabPanel : dialogPanel,
8338          buttons: [
8339            {
8340              type: 'cancel',
8341              name: 'cancel',
8342              text: 'Cancel'
8343            },
8344            {
8345              type: 'submit',
8346              name: 'save',
8347              text: 'Save',
8348              primary: true
8349            }
8350          ],
8351          initialData: data,
8352          onSubmit: curry(onSubmitRowForm, editor, map$1(rows, function (r) {
8353            return r.dom;
8354          }), data)
8355        });
8356      };
8357  
8358      var getItems = function (editor, classes, insertNewTable) {
8359        var rowColCountItems = !insertNewTable ? [] : [
8360          {
8361            type: 'input',
8362            name: 'cols',
8363            label: 'Cols',
8364            inputMode: 'numeric'
8365          },
8366          {
8367            type: 'input',
8368            name: 'rows',
8369            label: 'Rows',
8370            inputMode: 'numeric'
8371          }
8372        ];
8373        var alwaysItems = [
8374          {
8375            type: 'input',
8376            name: 'width',
8377            label: 'Width'
8378          },
8379          {
8380            type: 'input',
8381            name: 'height',
8382            label: 'Height'
8383          }
8384        ];
8385        var appearanceItems = hasAppearanceOptions(editor) ? [
8386          {
8387            type: 'input',
8388            name: 'cellspacing',
8389            label: 'Cell spacing',
8390            inputMode: 'numeric'
8391          },
8392          {
8393            type: 'input',
8394            name: 'cellpadding',
8395            label: 'Cell padding',
8396            inputMode: 'numeric'
8397          },
8398          {
8399            type: 'input',
8400            name: 'border',
8401            label: 'Border width'
8402          },
8403          {
8404            type: 'label',
8405            label: 'Caption',
8406            items: [{
8407                type: 'checkbox',
8408                name: 'caption',
8409                label: 'Show caption'
8410              }]
8411          }
8412        ] : [];
8413        var alignmentItem = [{
8414            type: 'listbox',
8415            name: 'align',
8416            label: 'Alignment',
8417            items: [
8418              {
8419                text: 'None',
8420                value: ''
8421              },
8422              {
8423                text: 'Left',
8424                value: 'left'
8425              },
8426              {
8427                text: 'Center',
8428                value: 'center'
8429              },
8430              {
8431                text: 'Right',
8432                value: 'right'
8433              }
8434            ]
8435          }];
8436        var classListItem = classes.length > 0 ? [{
8437            type: 'listbox',
8438            name: 'class',
8439            label: 'Class',
8440            items: classes
8441          }] : [];
8442        return rowColCountItems.concat(alwaysItems).concat(appearanceItems).concat(alignmentItem).concat(classListItem);
8443      };
8444  
8445      var styleTDTH = function (dom, elm, name, value) {
8446        if (elm.tagName === 'TD' || elm.tagName === 'TH') {
8447          if (isString(name)) {
8448            dom.setStyle(elm, name, value);
8449          } else {
8450            dom.setStyle(elm, name);
8451          }
8452        } else {
8453          if (elm.children) {
8454            for (var i = 0; i < elm.children.length; i++) {
8455              styleTDTH(dom, elm.children[i], name, value);
8456            }
8457          }
8458        }
8459      };
8460      var applyDataToElement = function (editor, tableElm, data) {
8461        var dom = editor.dom;
8462        var attrs = {};
8463        var styles = {};
8464        attrs.class = data.class;
8465        styles.height = addPxSuffix(data.height);
8466        if (dom.getAttrib(tableElm, 'width') && !shouldStyleWithCss(editor)) {
8467          attrs.width = removePxSuffix(data.width);
8468        } else {
8469          styles.width = addPxSuffix(data.width);
8470        }
8471        if (shouldStyleWithCss(editor)) {
8472          styles['border-width'] = addPxSuffix(data.border);
8473          styles['border-spacing'] = addPxSuffix(data.cellspacing);
8474        } else {
8475          attrs.border = data.border;
8476          attrs.cellpadding = data.cellpadding;
8477          attrs.cellspacing = data.cellspacing;
8478        }
8479        if (shouldStyleWithCss(editor) && tableElm.children) {
8480          for (var i = 0; i < tableElm.children.length; i++) {
8481            styleTDTH(dom, tableElm.children[i], {
8482              'border-width': addPxSuffix(data.border),
8483              'padding': addPxSuffix(data.cellpadding)
8484            });
8485            if (hasAdvancedTableTab(editor)) {
8486              styleTDTH(dom, tableElm.children[i], { 'border-color': data.bordercolor });
8487            }
8488          }
8489        }
8490        if (hasAdvancedTableTab(editor)) {
8491          styles['background-color'] = data.backgroundcolor;
8492          styles['border-color'] = data.bordercolor;
8493          styles['border-style'] = data.borderstyle;
8494        }
8495        attrs.style = dom.serializeStyle(__assign(__assign({}, getDefaultStyles(editor)), styles));
8496        dom.setAttribs(tableElm, __assign(__assign({}, getDefaultAttributes(editor)), attrs));
8497      };
8498      var onSubmitTableForm = function (editor, tableElm, oldData, api) {
8499        var dom = editor.dom;
8500        var data = api.getData();
8501        var modifiedData = filter$1(data, function (value, key) {
8502          return oldData[key] !== value;
8503        });
8504        api.close();
8505        if (data.class === '') {
8506          delete data.class;
8507        }
8508        editor.undoManager.transact(function () {
8509          if (!tableElm) {
8510            var cols = parseInt(data.cols, 10) || 1;
8511            var rows = parseInt(data.rows, 10) || 1;
8512            tableElm = insert(editor, cols, rows, 0, 0);
8513          }
8514          if (size(modifiedData) > 0) {
8515            applyDataToElement(editor, tableElm, data);
8516            var captionElm = dom.select('caption', tableElm)[0];
8517            if (captionElm && !data.caption || !captionElm && data.caption) {
8518              editor.execCommand('mceTableToggleCaption');
8519            }
8520            if (data.align === '') {
8521              unApplyAlign(editor, tableElm);
8522            } else {
8523              applyAlign(editor, tableElm, data.align);
8524            }
8525          }
8526          editor.focus();
8527          editor.addVisual();
8528          if (size(modifiedData) > 0) {
8529            var captionModified = has$1(modifiedData, 'caption');
8530            var styleModified = captionModified ? size(modifiedData) > 1 : true;
8531            fireTableModified(editor, tableElm, {
8532              structure: captionModified,
8533              style: styleModified
8534            });
8535          }
8536        });
8537      };
8538      var open = function (editor, insertNewTable) {
8539        var dom = editor.dom;
8540        var tableElm;
8541        var data = extractDataFromSettings(editor, hasAdvancedTableTab(editor));
8542        if (insertNewTable === false) {
8543          tableElm = dom.getParent(editor.selection.getStart(), 'table', editor.getBody());
8544          if (tableElm) {
8545            data = extractDataFromTableElement(editor, tableElm, hasAdvancedTableTab(editor));
8546          } else {
8547            if (hasAdvancedTableTab(editor)) {
8548              data.borderstyle = '';
8549              data.bordercolor = '';
8550              data.backgroundcolor = '';
8551            }
8552          }
8553        } else {
8554          data.cols = '1';
8555          data.rows = '1';
8556          if (hasAdvancedTableTab(editor)) {
8557            data.borderstyle = '';
8558            data.bordercolor = '';
8559            data.backgroundcolor = '';
8560          }
8561        }
8562        var classes = buildListItems(getTableClassList(editor));
8563        if (classes.length > 0) {
8564          if (data.class) {
8565            data.class = data.class.replace(/\s*mce\-item\-table\s*/g, '');
8566          }
8567        }
8568        var generalPanel = {
8569          type: 'grid',
8570          columns: 2,
8571          items: getItems(editor, classes, insertNewTable)
8572        };
8573        var nonAdvancedForm = function () {
8574          return {
8575            type: 'panel',
8576            items: [generalPanel]
8577          };
8578        };
8579        var advancedForm = function () {
8580          return {
8581            type: 'tabpanel',
8582            tabs: [
8583              {
8584                title: 'General',
8585                name: 'general',
8586                items: [generalPanel]
8587              },
8588              getAdvancedTab(editor, 'table')
8589            ]
8590          };
8591        };
8592        var dialogBody = hasAdvancedTableTab(editor) ? advancedForm() : nonAdvancedForm();
8593        editor.windowManager.open({
8594          title: 'Table Properties',
8595          size: 'normal',
8596          body: dialogBody,
8597          onSubmit: curry(onSubmitTableForm, editor, tableElm, data),
8598          buttons: [
8599            {
8600              type: 'cancel',
8601              name: 'cancel',
8602              text: 'Cancel'
8603            },
8604            {
8605              type: 'submit',
8606              name: 'save',
8607              text: 'Save',
8608              primary: true
8609            }
8610          ],
8611          initialData: data
8612        });
8613      };
8614  
8615      var getSelectionStartCellOrCaption = function (editor) {
8616        return getSelectionCellOrCaption(getSelectionStart(editor), getIsRoot(editor));
8617      };
8618      var getSelectionStartCell = function (editor) {
8619        return getSelectionCell(getSelectionStart(editor), getIsRoot(editor));
8620      };
8621      var registerCommands = function (editor, actions, cellSelection, selections, clipboard) {
8622        var isRoot = getIsRoot(editor);
8623        var eraseTable = function () {
8624          return getSelectionStartCellOrCaption(editor).each(function (cellOrCaption) {
8625            table(cellOrCaption, isRoot).filter(not(isRoot)).each(function (table) {
8626              var cursor = SugarElement.fromText('');
8627              after$5(table, cursor);
8628              remove$5(table);
8629              if (editor.dom.isEmpty(editor.getBody())) {
8630                editor.setContent('');
8631                editor.selection.setCursorLocation();
8632              } else {
8633                var rng = editor.dom.createRng();
8634                rng.setStart(cursor.dom, 0);
8635                rng.setEnd(cursor.dom, 0);
8636                editor.selection.setRng(rng);
8637                editor.nodeChanged();
8638              }
8639            });
8640          });
8641        };
8642        var setSizingMode = function (sizing) {
8643          return getSelectionStartCellOrCaption(editor).each(function (cellOrCaption) {
8644            var isForcedSizing = isResponsiveForced(editor) || isPixelsForced(editor) || isPercentagesForced(editor);
8645            if (!isForcedSizing) {
8646              table(cellOrCaption, isRoot).each(function (table) {
8647                if (sizing === 'relative' && !isPercentSizing(table)) {
8648                  enforcePercentage(table);
8649                } else if (sizing === 'fixed' && !isPixelSizing(table)) {
8650                  enforcePixels(table);
8651                } else if (sizing === 'responsive' && !isNoneSizing(table)) {
8652                  enforceNone(table);
8653                }
8654                removeDataStyle(table);
8655                fireTableModified(editor, table.dom, structureModified);
8656              });
8657            }
8658          });
8659        };
8660        var getTableFromCell = function (cell) {
8661          return table(cell, isRoot);
8662        };
8663        var performActionOnSelection = function (action) {
8664          return getSelectionStartCell(editor).bind(function (cell) {
8665            return getTableFromCell(cell).map(function (table) {
8666              return action(table, cell);
8667            });
8668          });
8669        };
8670        var toggleTableClass = function (_ui, clazz) {
8671          performActionOnSelection(function (table) {
8672            editor.formatter.toggle('tableclass', { value: clazz }, table.dom);
8673            fireTableModified(editor, table.dom, styleModified);
8674          });
8675        };
8676        var toggleTableCellClass = function (_ui, clazz) {
8677          performActionOnSelection(function (table) {
8678            var selectedCells = getCellsFromSelection(selections);
8679            var allHaveClass = forall(selectedCells, function (cell) {
8680              return editor.formatter.match('tablecellclass', { value: clazz }, cell.dom);
8681            });
8682            var formatterAction = allHaveClass ? editor.formatter.remove : editor.formatter.apply;
8683            each$2(selectedCells, function (cell) {
8684              return formatterAction('tablecellclass', { value: clazz }, cell.dom);
8685            });
8686            fireTableModified(editor, table.dom, styleModified);
8687          });
8688        };
8689        var toggleCaption = function () {
8690          getSelectionStartCellOrCaption(editor).each(function (cellOrCaption) {
8691            table(cellOrCaption, isRoot).each(function (table) {
8692              child$1(table, 'caption').fold(function () {
8693                var caption = SugarElement.fromTag('caption');
8694                append$1(caption, SugarElement.fromText('Caption'));
8695                appendAt(table, caption, 0);
8696                editor.selection.setCursorLocation(caption.dom, 0);
8697              }, function (caption) {
8698                if (isTag('caption')(cellOrCaption)) {
8699                  one('td', table).each(function (td) {
8700                    return editor.selection.setCursorLocation(td.dom, 0);
8701                  });
8702                }
8703                remove$5(caption);
8704              });
8705              fireTableModified(editor, table.dom, structureModified);
8706            });
8707          });
8708        };
8709        var postExecute = function (_data) {
8710          editor.focus();
8711        };
8712        var actOnSelection = function (execute, noEvents) {
8713          if (noEvents === void 0) {
8714            noEvents = false;
8715          }
8716          return performActionOnSelection(function (table, startCell) {
8717            var targets = forMenu(selections, table, startCell);
8718            execute(table, targets, noEvents).each(postExecute);
8719          });
8720        };
8721        var copyRowSelection = function () {
8722          return performActionOnSelection(function (table, startCell) {
8723            var targets = forMenu(selections, table, startCell);
8724            var generators = cellOperations(noop, SugarElement.fromDom(editor.getDoc()), Optional.none());
8725            return copyRows(table, targets, generators);
8726          });
8727        };
8728        var copyColSelection = function () {
8729          return performActionOnSelection(function (table, startCell) {
8730            var targets = forMenu(selections, table, startCell);
8731            return copyCols(table, targets);
8732          });
8733        };
8734        var pasteOnSelection = function (execute, getRows) {
8735          return getRows().each(function (rows) {
8736            var clonedRows = map$1(rows, function (row) {
8737              return deep(row);
8738            });
8739            performActionOnSelection(function (table, startCell) {
8740              var generators = paste$1(SugarElement.fromDom(editor.getDoc()));
8741              var targets = pasteRows(selections, startCell, clonedRows, generators);
8742              execute(table, targets).each(postExecute);
8743            });
8744          });
8745        };
8746        var actOnType = function (getAction) {
8747          return function (_ui, args) {
8748            return get$c(args, 'type').each(function (type) {
8749              actOnSelection(getAction(type), args.no_events);
8750            });
8751          };
8752        };
8753        each$1({
8754          mceTableSplitCells: function () {
8755            return actOnSelection(actions.unmergeCells);
8756          },
8757          mceTableMergeCells: function () {
8758            return actOnSelection(actions.mergeCells);
8759          },
8760          mceTableInsertRowBefore: function () {
8761            return actOnSelection(actions.insertRowsBefore);
8762          },
8763          mceTableInsertRowAfter: function () {
8764            return actOnSelection(actions.insertRowsAfter);
8765          },
8766          mceTableInsertColBefore: function () {
8767            return actOnSelection(actions.insertColumnsBefore);
8768          },
8769          mceTableInsertColAfter: function () {
8770            return actOnSelection(actions.insertColumnsAfter);
8771          },
8772          mceTableDeleteCol: function () {
8773            return actOnSelection(actions.deleteColumn);
8774          },
8775          mceTableDeleteRow: function () {
8776            return actOnSelection(actions.deleteRow);
8777          },
8778          mceTableCutCol: function () {
8779            return copyColSelection().each(function (selection) {
8780              clipboard.setColumns(selection);
8781              actOnSelection(actions.deleteColumn);
8782            });
8783          },
8784          mceTableCutRow: function () {
8785            return copyRowSelection().each(function (selection) {
8786              clipboard.setRows(selection);
8787              actOnSelection(actions.deleteRow);
8788            });
8789          },
8790          mceTableCopyCol: function () {
8791            return copyColSelection().each(function (selection) {
8792              return clipboard.setColumns(selection);
8793            });
8794          },
8795          mceTableCopyRow: function () {
8796            return copyRowSelection().each(function (selection) {
8797              return clipboard.setRows(selection);
8798            });
8799          },
8800          mceTablePasteColBefore: function () {
8801            return pasteOnSelection(actions.pasteColsBefore, clipboard.getColumns);
8802          },
8803          mceTablePasteColAfter: function () {
8804            return pasteOnSelection(actions.pasteColsAfter, clipboard.getColumns);
8805          },
8806          mceTablePasteRowBefore: function () {
8807            return pasteOnSelection(actions.pasteRowsBefore, clipboard.getRows);
8808          },
8809          mceTablePasteRowAfter: function () {
8810            return pasteOnSelection(actions.pasteRowsAfter, clipboard.getRows);
8811          },
8812          mceTableDelete: eraseTable,
8813          mceTableCellToggleClass: toggleTableCellClass,
8814          mceTableToggleClass: toggleTableClass,
8815          mceTableToggleCaption: toggleCaption,
8816          mceTableSizingMode: function (_ui, sizing) {
8817            return setSizingMode(sizing);
8818          },
8819          mceTableCellType: actOnType(function (type) {
8820            return type === 'th' ? actions.makeCellsHeader : actions.unmakeCellsHeader;
8821          }),
8822          mceTableColType: actOnType(function (type) {
8823            return type === 'th' ? actions.makeColumnsHeader : actions.unmakeColumnsHeader;
8824          }),
8825          mceTableRowType: actOnType(function (type) {
8826            switch (type) {
8827            case 'header':
8828              return actions.makeRowsHeader;
8829            case 'footer':
8830              return actions.makeRowsFooter;
8831            default:
8832              return actions.makeRowsBody;
8833            }
8834          })
8835        }, function (func, name) {
8836          return editor.addCommand(name, func);
8837        });
8838        each$1({
8839          mceTableProps: curry(open, editor, false),
8840          mceTableRowProps: curry(open$1, editor),
8841          mceTableCellProps: curry(open$2, editor, selections)
8842        }, function (func, name) {
8843          return editor.addCommand(name, function () {
8844            return func();
8845          });
8846        });
8847        editor.addCommand('mceInsertTable', function (_ui, args) {
8848          if (isObject(args) && keys(args).length > 0) {
8849            insertTableWithDataValidation(editor, args.rows, args.columns, args.options, 'Invalid values for mceInsertTable - rows and columns values are required to insert a table.');
8850          } else {
8851            open(editor, true);
8852          }
8853        });
8854        editor.addCommand('mceTableApplyCellStyle', function (_ui, args) {
8855          var getFormatName = function (style) {
8856            return 'tablecell' + style.toLowerCase().replace('-', '');
8857          };
8858          if (!isObject(args)) {
8859            return;
8860          }
8861          var cells = getCellsFromSelection(selections);
8862          if (cells.length === 0) {
8863            return;
8864          }
8865          var validArgs = filter$1(args, function (value, style) {
8866            return editor.formatter.has(getFormatName(style)) && isString(value);
8867          });
8868          if (isEmpty(validArgs)) {
8869            return;
8870          }
8871          each$1(validArgs, function (value, style) {
8872            each$2(cells, function (cell) {
8873              DomModifier.normal(editor, cell.dom).setFormat(getFormatName(style), value);
8874            });
8875          });
8876          getTableFromCell(cells[0]).each(function (table) {
8877            return fireTableModified(editor, table.dom, styleModified);
8878          });
8879        });
8880      };
8881  
8882      var registerQueryCommands = function (editor, actions, selections) {
8883        var isRoot = getIsRoot(editor);
8884        var lookupOnSelection = function (action) {
8885          return getSelectionCell(getSelectionStart(editor)).bind(function (cell) {
8886            return table(cell, isRoot).map(function (table) {
8887              var targets = forMenu(selections, table, cell);
8888              return action(table, targets);
8889            });
8890          }).getOr('');
8891        };
8892        each$1({
8893          mceTableRowType: function () {
8894            return lookupOnSelection(actions.getTableRowType);
8895          },
8896          mceTableCellType: function () {
8897            return lookupOnSelection(actions.getTableCellType);
8898          },
8899          mceTableColType: function () {
8900            return lookupOnSelection(actions.getTableColType);
8901          }
8902        }, function (func, name) {
8903          return editor.addQueryValueHandler(name, func);
8904        });
8905      };
8906  
8907      var Clipboard = function () {
8908        var rows = value();
8909        var cols = value();
8910        return {
8911          getRows: rows.get,
8912          setRows: function (r) {
8913            r.fold(rows.clear, rows.set);
8914            cols.clear();
8915          },
8916          clearRows: rows.clear,
8917          getColumns: cols.get,
8918          setColumns: function (c) {
8919            c.fold(cols.clear, cols.set);
8920            rows.clear();
8921          },
8922          clearColumns: cols.clear
8923        };
8924      };
8925  
8926      var genericBase = {
8927        remove_similar: true,
8928        inherit: false
8929      };
8930      var cellBase = __assign({ selector: 'td,th' }, genericBase);
8931      var cellFormats = {
8932        tablecellbackgroundcolor: __assign({ styles: { backgroundColor: '%value' } }, cellBase),
8933        tablecellverticalalign: __assign({ styles: { 'vertical-align': '%value' } }, cellBase),
8934        tablecellbordercolor: __assign({ styles: { borderColor: '%value' } }, cellBase),
8935        tablecellclass: __assign({ classes: ['%value'] }, cellBase),
8936        tableclass: __assign({
8937          selector: 'table',
8938          classes: ['%value']
8939        }, genericBase),
8940        tablecellborderstyle: __assign({ styles: { borderStyle: '%value' } }, cellBase),
8941        tablecellborderwidth: __assign({ styles: { borderWidth: '%value' } }, cellBase)
8942      };
8943      var registerFormats = function (editor) {
8944        editor.formatter.register(cellFormats);
8945      };
8946  
8947      var adt$5 = Adt.generate([
8948        { none: ['current'] },
8949        { first: ['current'] },
8950        {
8951          middle: [
8952            'current',
8953            'target'
8954          ]
8955        },
8956        { last: ['current'] }
8957      ]);
8958      var none = function (current) {
8959        if (current === void 0) {
8960          current = undefined;
8961        }
8962        return adt$5.none(current);
8963      };
8964      var CellLocation = __assign(__assign({}, adt$5), { none: none });
8965  
8966      var walk = function (all, current, index, direction, isEligible) {
8967        if (isEligible === void 0) {
8968          isEligible = always;
8969        }
8970        var forwards = direction === 1;
8971        if (!forwards && index <= 0) {
8972          return CellLocation.first(all[0]);
8973        } else if (forwards && index >= all.length - 1) {
8974          return CellLocation.last(all[all.length - 1]);
8975        } else {
8976          var newIndex = index + direction;
8977          var elem = all[newIndex];
8978          return isEligible(elem) ? CellLocation.middle(current, elem) : walk(all, current, newIndex, direction, isEligible);
8979        }
8980      };
8981      var detect$1 = function (current, isRoot) {
8982        return table(current, isRoot).bind(function (table) {
8983          var all = cells$1(table);
8984          var index = findIndex(all, function (x) {
8985            return eq$1(current, x);
8986          });
8987          return index.map(function (index) {
8988            return {
8989              index: index,
8990              all: all
8991            };
8992          });
8993        });
8994      };
8995      var next = function (current, isEligible, isRoot) {
8996        var detection = detect$1(current, isRoot);
8997        return detection.fold(function () {
8998          return CellLocation.none(current);
8999        }, function (info) {
9000          return walk(info.all, current, info.index, 1, isEligible);
9001        });
9002      };
9003      var prev = function (current, isEligible, isRoot) {
9004        var detection = detect$1(current, isRoot);
9005        return detection.fold(function () {
9006          return CellLocation.none();
9007        }, function (info) {
9008          return walk(info.all, current, info.index, -1, isEligible);
9009        });
9010      };
9011  
9012      var create$2 = function (start, soffset, finish, foffset) {
9013        return {
9014          start: start,
9015          soffset: soffset,
9016          finish: finish,
9017          foffset: foffset
9018        };
9019      };
9020      var SimRange = { create: create$2 };
9021  
9022      var adt$4 = Adt.generate([
9023        { before: ['element'] },
9024        {
9025          on: [
9026            'element',
9027            'offset'
9028          ]
9029        },
9030        { after: ['element'] }
9031      ]);
9032      var cata$1 = function (subject, onBefore, onOn, onAfter) {
9033        return subject.fold(onBefore, onOn, onAfter);
9034      };
9035      var getStart$1 = function (situ) {
9036        return situ.fold(identity, identity, identity);
9037      };
9038      var before$2 = adt$4.before;
9039      var on = adt$4.on;
9040      var after$3 = adt$4.after;
9041      var Situ = {
9042        before: before$2,
9043        on: on,
9044        after: after$3,
9045        cata: cata$1,
9046        getStart: getStart$1
9047      };
9048  
9049      var adt$3 = Adt.generate([
9050        { domRange: ['rng'] },
9051        {
9052          relative: [
9053            'startSitu',
9054            'finishSitu'
9055          ]
9056        },
9057        {
9058          exact: [
9059            'start',
9060            'soffset',
9061            'finish',
9062            'foffset'
9063          ]
9064        }
9065      ]);
9066      var exactFromRange = function (simRange) {
9067        return adt$3.exact(simRange.start, simRange.soffset, simRange.finish, simRange.foffset);
9068      };
9069      var getStart = function (selection) {
9070        return selection.match({
9071          domRange: function (rng) {
9072            return SugarElement.fromDom(rng.startContainer);
9073          },
9074          relative: function (startSitu, _finishSitu) {
9075            return Situ.getStart(startSitu);
9076          },
9077          exact: function (start, _soffset, _finish, _foffset) {
9078            return start;
9079          }
9080        });
9081      };
9082      var domRange = adt$3.domRange;
9083      var relative = adt$3.relative;
9084      var exact = adt$3.exact;
9085      var getWin = function (selection) {
9086        var start = getStart(selection);
9087        return defaultView(start);
9088      };
9089      var range = SimRange.create;
9090      var SimSelection = {
9091        domRange: domRange,
9092        relative: relative,
9093        exact: exact,
9094        exactFromRange: exactFromRange,
9095        getWin: getWin,
9096        range: range
9097      };
9098  
9099      var selectNode = function (win, element) {
9100        var rng = win.document.createRange();
9101        rng.selectNode(element.dom);
9102        return rng;
9103      };
9104      var selectNodeContents = function (win, element) {
9105        var rng = win.document.createRange();
9106        selectNodeContentsUsing(rng, element);
9107        return rng;
9108      };
9109      var selectNodeContentsUsing = function (rng, element) {
9110        return rng.selectNodeContents(element.dom);
9111      };
9112      var setStart = function (rng, situ) {
9113        situ.fold(function (e) {
9114          rng.setStartBefore(e.dom);
9115        }, function (e, o) {
9116          rng.setStart(e.dom, o);
9117        }, function (e) {
9118          rng.setStartAfter(e.dom);
9119        });
9120      };
9121      var setFinish = function (rng, situ) {
9122        situ.fold(function (e) {
9123          rng.setEndBefore(e.dom);
9124        }, function (e, o) {
9125          rng.setEnd(e.dom, o);
9126        }, function (e) {
9127          rng.setEndAfter(e.dom);
9128        });
9129      };
9130      var relativeToNative = function (win, startSitu, finishSitu) {
9131        var range = win.document.createRange();
9132        setStart(range, startSitu);
9133        setFinish(range, finishSitu);
9134        return range;
9135      };
9136      var exactToNative = function (win, start, soffset, finish, foffset) {
9137        var rng = win.document.createRange();
9138        rng.setStart(start.dom, soffset);
9139        rng.setEnd(finish.dom, foffset);
9140        return rng;
9141      };
9142      var toRect = function (rect) {
9143        return {
9144          left: rect.left,
9145          top: rect.top,
9146          right: rect.right,
9147          bottom: rect.bottom,
9148          width: rect.width,
9149          height: rect.height
9150        };
9151      };
9152      var getFirstRect$1 = function (rng) {
9153        var rects = rng.getClientRects();
9154        var rect = rects.length > 0 ? rects[0] : rng.getBoundingClientRect();
9155        return rect.width > 0 || rect.height > 0 ? Optional.some(rect).map(toRect) : Optional.none();
9156      };
9157  
9158      var adt$2 = Adt.generate([
9159        {
9160          ltr: [
9161            'start',
9162            'soffset',
9163            'finish',
9164            'foffset'
9165          ]
9166        },
9167        {
9168          rtl: [
9169            'start',
9170            'soffset',
9171            'finish',
9172            'foffset'
9173          ]
9174        }
9175      ]);
9176      var fromRange = function (win, type, range) {
9177        return type(SugarElement.fromDom(range.startContainer), range.startOffset, SugarElement.fromDom(range.endContainer), range.endOffset);
9178      };
9179      var getRanges = function (win, selection) {
9180        return selection.match({
9181          domRange: function (rng) {
9182            return {
9183              ltr: constant(rng),
9184              rtl: Optional.none
9185            };
9186          },
9187          relative: function (startSitu, finishSitu) {
9188            return {
9189              ltr: cached(function () {
9190                return relativeToNative(win, startSitu, finishSitu);
9191              }),
9192              rtl: cached(function () {
9193                return Optional.some(relativeToNative(win, finishSitu, startSitu));
9194              })
9195            };
9196          },
9197          exact: function (start, soffset, finish, foffset) {
9198            return {
9199              ltr: cached(function () {
9200                return exactToNative(win, start, soffset, finish, foffset);
9201              }),
9202              rtl: cached(function () {
9203                return Optional.some(exactToNative(win, finish, foffset, start, soffset));
9204              })
9205            };
9206          }
9207        });
9208      };
9209      var doDiagnose = function (win, ranges) {
9210        var rng = ranges.ltr();
9211        if (rng.collapsed) {
9212          var reversed = ranges.rtl().filter(function (rev) {
9213            return rev.collapsed === false;
9214          });
9215          return reversed.map(function (rev) {
9216            return adt$2.rtl(SugarElement.fromDom(rev.endContainer), rev.endOffset, SugarElement.fromDom(rev.startContainer), rev.startOffset);
9217          }).getOrThunk(function () {
9218            return fromRange(win, adt$2.ltr, rng);
9219          });
9220        } else {
9221          return fromRange(win, adt$2.ltr, rng);
9222        }
9223      };
9224      var diagnose = function (win, selection) {
9225        var ranges = getRanges(win, selection);
9226        return doDiagnose(win, ranges);
9227      };
9228      var asLtrRange = function (win, selection) {
9229        var diagnosis = diagnose(win, selection);
9230        return diagnosis.match({
9231          ltr: function (start, soffset, finish, foffset) {
9232            var rng = win.document.createRange();
9233            rng.setStart(start.dom, soffset);
9234            rng.setEnd(finish.dom, foffset);
9235            return rng;
9236          },
9237          rtl: function (start, soffset, finish, foffset) {
9238            var rng = win.document.createRange();
9239            rng.setStart(finish.dom, foffset);
9240            rng.setEnd(start.dom, soffset);
9241            return rng;
9242          }
9243        });
9244      };
9245      adt$2.ltr;
9246      adt$2.rtl;
9247  
9248      var searchForPoint = function (rectForOffset, x, y, maxX, length) {
9249        if (length === 0) {
9250          return 0;
9251        } else if (x === maxX) {
9252          return length - 1;
9253        }
9254        var xDelta = maxX;
9255        for (var i = 1; i < length; i++) {
9256          var rect = rectForOffset(i);
9257          var curDeltaX = Math.abs(x - rect.left);
9258          if (y <= rect.bottom) {
9259            if (y < rect.top || curDeltaX > xDelta) {
9260              return i - 1;
9261            } else {
9262              xDelta = curDeltaX;
9263            }
9264          }
9265        }
9266        return 0;
9267      };
9268      var inRect = function (rect, x, y) {
9269        return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
9270      };
9271  
9272      var locateOffset = function (doc, textnode, x, y, rect) {
9273        var rangeForOffset = function (o) {
9274          var r = doc.dom.createRange();
9275          r.setStart(textnode.dom, o);
9276          r.collapse(true);
9277          return r;
9278        };
9279        var rectForOffset = function (o) {
9280          var r = rangeForOffset(o);
9281          return r.getBoundingClientRect();
9282        };
9283        var length = get$9(textnode).length;
9284        var offset = searchForPoint(rectForOffset, x, y, rect.right, length);
9285        return rangeForOffset(offset);
9286      };
9287      var locate$1 = function (doc, node, x, y) {
9288        var r = doc.dom.createRange();
9289        r.selectNode(node.dom);
9290        var rects = r.getClientRects();
9291        var foundRect = findMap(rects, function (rect) {
9292          return inRect(rect, x, y) ? Optional.some(rect) : Optional.none();
9293        });
9294        return foundRect.map(function (rect) {
9295          return locateOffset(doc, node, x, y, rect);
9296        });
9297      };
9298  
9299      var searchInChildren = function (doc, node, x, y) {
9300        var r = doc.dom.createRange();
9301        var nodes = children$3(node);
9302        return findMap(nodes, function (n) {
9303          r.selectNode(n.dom);
9304          return inRect(r.getBoundingClientRect(), x, y) ? locateNode(doc, n, x, y) : Optional.none();
9305        });
9306      };
9307      var locateNode = function (doc, node, x, y) {
9308        return isText(node) ? locate$1(doc, node, x, y) : searchInChildren(doc, node, x, y);
9309      };
9310      var locate = function (doc, node, x, y) {
9311        var r = doc.dom.createRange();
9312        r.selectNode(node.dom);
9313        var rect = r.getBoundingClientRect();
9314        var boundedX = Math.max(rect.left, Math.min(rect.right, x));
9315        var boundedY = Math.max(rect.top, Math.min(rect.bottom, y));
9316        return locateNode(doc, node, boundedX, boundedY);
9317      };
9318  
9319      var COLLAPSE_TO_LEFT = true;
9320      var COLLAPSE_TO_RIGHT = false;
9321      var getCollapseDirection = function (rect, x) {
9322        return x - rect.left < rect.right - x ? COLLAPSE_TO_LEFT : COLLAPSE_TO_RIGHT;
9323      };
9324      var createCollapsedNode = function (doc, target, collapseDirection) {
9325        var r = doc.dom.createRange();
9326        r.selectNode(target.dom);
9327        r.collapse(collapseDirection);
9328        return r;
9329      };
9330      var locateInElement = function (doc, node, x) {
9331        var cursorRange = doc.dom.createRange();
9332        cursorRange.selectNode(node.dom);
9333        var rect = cursorRange.getBoundingClientRect();
9334        var collapseDirection = getCollapseDirection(rect, x);
9335        var f = collapseDirection === COLLAPSE_TO_LEFT ? first : last$1;
9336        return f(node).map(function (target) {
9337          return createCollapsedNode(doc, target, collapseDirection);
9338        });
9339      };
9340      var locateInEmpty = function (doc, node, x) {
9341        var rect = node.dom.getBoundingClientRect();
9342        var collapseDirection = getCollapseDirection(rect, x);
9343        return Optional.some(createCollapsedNode(doc, node, collapseDirection));
9344      };
9345      var search = function (doc, node, x) {
9346        var f = children$3(node).length === 0 ? locateInEmpty : locateInElement;
9347        return f(doc, node, x);
9348      };
9349  
9350      var caretPositionFromPoint = function (doc, x, y) {
9351        var _a, _b;
9352        return Optional.from((_b = (_a = doc.dom).caretPositionFromPoint) === null || _b === void 0 ? void 0 : _b.call(_a, x, y)).bind(function (pos) {
9353          if (pos.offsetNode === null) {
9354            return Optional.none();
9355          }
9356          var r = doc.dom.createRange();
9357          r.setStart(pos.offsetNode, pos.offset);
9358          r.collapse();
9359          return Optional.some(r);
9360        });
9361      };
9362      var caretRangeFromPoint = function (doc, x, y) {
9363        var _a, _b;
9364        return Optional.from((_b = (_a = doc.dom).caretRangeFromPoint) === null || _b === void 0 ? void 0 : _b.call(_a, x, y));
9365      };
9366      var searchTextNodes = function (doc, node, x, y) {
9367        var r = doc.dom.createRange();
9368        r.selectNode(node.dom);
9369        var rect = r.getBoundingClientRect();
9370        var boundedX = Math.max(rect.left, Math.min(rect.right, x));
9371        var boundedY = Math.max(rect.top, Math.min(rect.bottom, y));
9372        return locate(doc, node, boundedX, boundedY);
9373      };
9374      var searchFromPoint = function (doc, x, y) {
9375        return SugarElement.fromPoint(doc, x, y).bind(function (elem) {
9376          var fallback = function () {
9377            return search(doc, elem, x);
9378          };
9379          return children$3(elem).length === 0 ? fallback() : searchTextNodes(doc, elem, x, y).orThunk(fallback);
9380        });
9381      };
9382      var availableSearch = function () {
9383        if (document.caretPositionFromPoint) {
9384          return caretPositionFromPoint;
9385        } else if (document.caretRangeFromPoint) {
9386          return caretRangeFromPoint;
9387        } else {
9388          return searchFromPoint;
9389        }
9390      }();
9391      var fromPoint = function (win, x, y) {
9392        var doc = SugarElement.fromDom(win.document);
9393        return availableSearch(doc, x, y).map(function (rng) {
9394          return SimRange.create(SugarElement.fromDom(rng.startContainer), rng.startOffset, SugarElement.fromDom(rng.endContainer), rng.endOffset);
9395        });
9396      };
9397  
9398      var beforeSpecial = function (element, offset) {
9399        var name$1 = name(element);
9400        if ('input' === name$1) {
9401          return Situ.after(element);
9402        } else if (!contains$2([
9403            'br',
9404            'img'
9405          ], name$1)) {
9406          return Situ.on(element, offset);
9407        } else {
9408          return offset === 0 ? Situ.before(element) : Situ.after(element);
9409        }
9410      };
9411      var preprocessRelative = function (startSitu, finishSitu) {
9412        var start = startSitu.fold(Situ.before, beforeSpecial, Situ.after);
9413        var finish = finishSitu.fold(Situ.before, beforeSpecial, Situ.after);
9414        return SimSelection.relative(start, finish);
9415      };
9416      var preprocessExact = function (start, soffset, finish, foffset) {
9417        var startSitu = beforeSpecial(start, soffset);
9418        var finishSitu = beforeSpecial(finish, foffset);
9419        return SimSelection.relative(startSitu, finishSitu);
9420      };
9421      var preprocess = function (selection) {
9422        return selection.match({
9423          domRange: function (rng) {
9424            var start = SugarElement.fromDom(rng.startContainer);
9425            var finish = SugarElement.fromDom(rng.endContainer);
9426            return preprocessExact(start, rng.startOffset, finish, rng.endOffset);
9427          },
9428          relative: preprocessRelative,
9429          exact: preprocessExact
9430        });
9431      };
9432  
9433      var makeRange = function (start, soffset, finish, foffset) {
9434        var doc = owner(start);
9435        var rng = doc.dom.createRange();
9436        rng.setStart(start.dom, soffset);
9437        rng.setEnd(finish.dom, foffset);
9438        return rng;
9439      };
9440      var after$2 = function (start, soffset, finish, foffset) {
9441        var r = makeRange(start, soffset, finish, foffset);
9442        var same = eq$1(start, finish) && soffset === foffset;
9443        return r.collapsed && !same;
9444      };
9445  
9446      var getNativeSelection = function (win) {
9447        return Optional.from(win.getSelection());
9448      };
9449      var doSetNativeRange = function (win, rng) {
9450        getNativeSelection(win).each(function (selection) {
9451          selection.removeAllRanges();
9452          selection.addRange(rng);
9453        });
9454      };
9455      var doSetRange = function (win, start, soffset, finish, foffset) {
9456        var rng = exactToNative(win, start, soffset, finish, foffset);
9457        doSetNativeRange(win, rng);
9458      };
9459      var setLegacyRtlRange = function (win, selection, start, soffset, finish, foffset) {
9460        selection.collapse(start.dom, soffset);
9461        selection.extend(finish.dom, foffset);
9462      };
9463      var setRangeFromRelative = function (win, relative) {
9464        return diagnose(win, relative).match({
9465          ltr: function (start, soffset, finish, foffset) {
9466            doSetRange(win, start, soffset, finish, foffset);
9467          },
9468          rtl: function (start, soffset, finish, foffset) {
9469            getNativeSelection(win).each(function (selection) {
9470              if (selection.setBaseAndExtent) {
9471                selection.setBaseAndExtent(start.dom, soffset, finish.dom, foffset);
9472              } else if (selection.extend) {
9473                try {
9474                  setLegacyRtlRange(win, selection, start, soffset, finish, foffset);
9475                } catch (e) {
9476                  doSetRange(win, finish, foffset, start, soffset);
9477                }
9478              } else {
9479                doSetRange(win, finish, foffset, start, soffset);
9480              }
9481            });
9482          }
9483        });
9484      };
9485      var setExact = function (win, start, soffset, finish, foffset) {
9486        var relative = preprocessExact(start, soffset, finish, foffset);
9487        setRangeFromRelative(win, relative);
9488      };
9489      var setRelative = function (win, startSitu, finishSitu) {
9490        var relative = preprocessRelative(startSitu, finishSitu);
9491        setRangeFromRelative(win, relative);
9492      };
9493      var toNative = function (selection) {
9494        var win = SimSelection.getWin(selection).dom;
9495        var getDomRange = function (start, soffset, finish, foffset) {
9496          return exactToNative(win, start, soffset, finish, foffset);
9497        };
9498        var filtered = preprocess(selection);
9499        return diagnose(win, filtered).match({
9500          ltr: getDomRange,
9501          rtl: getDomRange
9502        });
9503      };
9504      var readRange = function (selection) {
9505        if (selection.rangeCount > 0) {
9506          var firstRng = selection.getRangeAt(0);
9507          var lastRng = selection.getRangeAt(selection.rangeCount - 1);
9508          return Optional.some(SimRange.create(SugarElement.fromDom(firstRng.startContainer), firstRng.startOffset, SugarElement.fromDom(lastRng.endContainer), lastRng.endOffset));
9509        } else {
9510          return Optional.none();
9511        }
9512      };
9513      var doGetExact = function (selection) {
9514        if (selection.anchorNode === null || selection.focusNode === null) {
9515          return readRange(selection);
9516        } else {
9517          var anchor = SugarElement.fromDom(selection.anchorNode);
9518          var focus_1 = SugarElement.fromDom(selection.focusNode);
9519          return after$2(anchor, selection.anchorOffset, focus_1, selection.focusOffset) ? Optional.some(SimRange.create(anchor, selection.anchorOffset, focus_1, selection.focusOffset)) : readRange(selection);
9520        }
9521      };
9522      var setToElement = function (win, element, selectNodeContents$1) {
9523        if (selectNodeContents$1 === void 0) {
9524          selectNodeContents$1 = true;
9525        }
9526        var rngGetter = selectNodeContents$1 ? selectNodeContents : selectNode;
9527        var rng = rngGetter(win, element);
9528        doSetNativeRange(win, rng);
9529      };
9530      var getExact = function (win) {
9531        return getNativeSelection(win).filter(function (sel) {
9532          return sel.rangeCount > 0;
9533        }).bind(doGetExact);
9534      };
9535      var get$1 = function (win) {
9536        return getExact(win).map(function (range) {
9537          return SimSelection.exact(range.start, range.soffset, range.finish, range.foffset);
9538        });
9539      };
9540      var getFirstRect = function (win, selection) {
9541        var rng = asLtrRange(win, selection);
9542        return getFirstRect$1(rng);
9543      };
9544      var getAtPoint = function (win, x, y) {
9545        return fromPoint(win, x, y);
9546      };
9547      var clear = function (win) {
9548        getNativeSelection(win).each(function (selection) {
9549          return selection.removeAllRanges();
9550        });
9551      };
9552  
9553      var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK');
9554  
9555      var forward = function (editor, isRoot, cell) {
9556        return go$1(editor, isRoot, next(cell, isEditable$1));
9557      };
9558      var backward = function (editor, isRoot, cell) {
9559        return go$1(editor, isRoot, prev(cell, isEditable$1));
9560      };
9561      var getCellFirstCursorPosition = function (editor, cell) {
9562        var selection = SimSelection.exact(cell, 0, cell, 0);
9563        return toNative(selection);
9564      };
9565      var go$1 = function (editor, isRoot, cell) {
9566        return cell.fold(Optional.none, Optional.none, function (current, next) {
9567          return first(next).map(function (cell) {
9568            return getCellFirstCursorPosition(editor, cell);
9569          });
9570        }, function (current) {
9571          editor.execCommand('mceTableInsertRowAfter');
9572          return forward(editor, isRoot, current);
9573        });
9574      };
9575      var rootElements = [
9576        'table',
9577        'li',
9578        'dl'
9579      ];
9580      var handle$1 = function (event, editor, cellSelection) {
9581        if (event.keyCode === global$1.TAB) {
9582          var body_1 = getBody(editor);
9583          var isRoot_1 = function (element) {
9584            var name$1 = name(element);
9585            return eq$1(element, body_1) || contains$2(rootElements, name$1);
9586          };
9587          var rng = editor.selection.getRng();
9588          var container = SugarElement.fromDom(event.shiftKey ? rng.startContainer : rng.endContainer);
9589          cell(container, isRoot_1).each(function (cell) {
9590            event.preventDefault();
9591            table(cell, isRoot_1).each(cellSelection.clear);
9592            editor.selection.collapse(event.shiftKey);
9593            var navigation = event.shiftKey ? backward : forward;
9594            var rng = navigation(editor, isRoot_1, cell);
9595            rng.each(function (range) {
9596              editor.selection.setRng(range);
9597            });
9598          });
9599        }
9600      };
9601  
9602      var create$1 = function (selection, kill) {
9603        return {
9604          selection: selection,
9605          kill: kill
9606        };
9607      };
9608      var Response = { create: create$1 };
9609  
9610      var create = function (start, soffset, finish, foffset) {
9611        return {
9612          start: Situ.on(start, soffset),
9613          finish: Situ.on(finish, foffset)
9614        };
9615      };
9616      var Situs = { create: create };
9617  
9618      var convertToRange = function (win, selection) {
9619        var rng = asLtrRange(win, selection);
9620        return SimRange.create(SugarElement.fromDom(rng.startContainer), rng.startOffset, SugarElement.fromDom(rng.endContainer), rng.endOffset);
9621      };
9622      var makeSitus = Situs.create;
9623  
9624      var sync = function (container, isRoot, start, soffset, finish, foffset, selectRange) {
9625        if (!(eq$1(start, finish) && soffset === foffset)) {
9626          return closest$1(start, 'td,th', isRoot).bind(function (s) {
9627            return closest$1(finish, 'td,th', isRoot).bind(function (f) {
9628              return detect(container, isRoot, s, f, selectRange);
9629            });
9630          });
9631        } else {
9632          return Optional.none();
9633        }
9634      };
9635      var detect = function (container, isRoot, start, finish, selectRange) {
9636        if (!eq$1(start, finish)) {
9637          return identify(start, finish, isRoot).bind(function (cellSel) {
9638            var boxes = cellSel.boxes.getOr([]);
9639            if (boxes.length > 1) {
9640              selectRange(container, boxes, cellSel.start, cellSel.finish);
9641              return Optional.some(Response.create(Optional.some(makeSitus(start, 0, start, getEnd(start))), true));
9642            } else {
9643              return Optional.none();
9644            }
9645          });
9646        } else {
9647          return Optional.none();
9648        }
9649      };
9650      var update = function (rows, columns, container, selected, annotations) {
9651        var updateSelection = function (newSels) {
9652          annotations.clearBeforeUpdate(container);
9653          annotations.selectRange(container, newSels.boxes, newSels.start, newSels.finish);
9654          return newSels.boxes;
9655        };
9656        return shiftSelection(selected, rows, columns, annotations.firstSelectedSelector, annotations.lastSelectedSelector).map(updateSelection);
9657      };
9658  
9659      var traverse = function (item, mode) {
9660        return {
9661          item: item,
9662          mode: mode
9663        };
9664      };
9665      var backtrack = function (universe, item, _direction, transition) {
9666        if (transition === void 0) {
9667          transition = sidestep;
9668        }
9669        return universe.property().parent(item).map(function (p) {
9670          return traverse(p, transition);
9671        });
9672      };
9673      var sidestep = function (universe, item, direction, transition) {
9674        if (transition === void 0) {
9675          transition = advance;
9676        }
9677        return direction.sibling(universe, item).map(function (p) {
9678          return traverse(p, transition);
9679        });
9680      };
9681      var advance = function (universe, item, direction, transition) {
9682        if (transition === void 0) {
9683          transition = advance;
9684        }
9685        var children = universe.property().children(item);
9686        var result = direction.first(children);
9687        return result.map(function (r) {
9688          return traverse(r, transition);
9689        });
9690      };
9691      var successors = [
9692        {
9693          current: backtrack,
9694          next: sidestep,
9695          fallback: Optional.none()
9696        },
9697        {
9698          current: sidestep,
9699          next: advance,
9700          fallback: Optional.some(backtrack)
9701        },
9702        {
9703          current: advance,
9704          next: advance,
9705          fallback: Optional.some(sidestep)
9706        }
9707      ];
9708      var go = function (universe, item, mode, direction, rules) {
9709        if (rules === void 0) {
9710          rules = successors;
9711        }
9712        var ruleOpt = find$1(rules, function (succ) {
9713          return succ.current === mode;
9714        });
9715        return ruleOpt.bind(function (rule) {
9716          return rule.current(universe, item, direction, rule.next).orThunk(function () {
9717            return rule.fallback.bind(function (fb) {
9718              return go(universe, item, fb, direction);
9719            });
9720          });
9721        });
9722      };
9723  
9724      var left$1 = function () {
9725        var sibling = function (universe, item) {
9726          return universe.query().prevSibling(item);
9727        };
9728        var first = function (children) {
9729          return children.length > 0 ? Optional.some(children[children.length - 1]) : Optional.none();
9730        };
9731        return {
9732          sibling: sibling,
9733          first: first
9734        };
9735      };
9736      var right$1 = function () {
9737        var sibling = function (universe, item) {
9738          return universe.query().nextSibling(item);
9739        };
9740        var first = function (children) {
9741          return children.length > 0 ? Optional.some(children[0]) : Optional.none();
9742        };
9743        return {
9744          sibling: sibling,
9745          first: first
9746        };
9747      };
9748      var Walkers = {
9749        left: left$1,
9750        right: right$1
9751      };
9752  
9753      var hone = function (universe, item, predicate, mode, direction, isRoot) {
9754        var next = go(universe, item, mode, direction);
9755        return next.bind(function (n) {
9756          if (isRoot(n.item)) {
9757            return Optional.none();
9758          } else {
9759            return predicate(n.item) ? Optional.some(n.item) : hone(universe, n.item, predicate, n.mode, direction, isRoot);
9760          }
9761        });
9762      };
9763      var left = function (universe, item, predicate, isRoot) {
9764        return hone(universe, item, predicate, sidestep, Walkers.left(), isRoot);
9765      };
9766      var right = function (universe, item, predicate, isRoot) {
9767        return hone(universe, item, predicate, sidestep, Walkers.right(), isRoot);
9768      };
9769  
9770      var isLeaf = function (universe) {
9771        return function (element) {
9772          return universe.property().children(element).length === 0;
9773        };
9774      };
9775      var before$1 = function (universe, item, isRoot) {
9776        return seekLeft$1(universe, item, isLeaf(universe), isRoot);
9777      };
9778      var after$1 = function (universe, item, isRoot) {
9779        return seekRight$1(universe, item, isLeaf(universe), isRoot);
9780      };
9781      var seekLeft$1 = left;
9782      var seekRight$1 = right;
9783  
9784      var universe = DomUniverse();
9785      var before = function (element, isRoot) {
9786        return before$1(universe, element, isRoot);
9787      };
9788      var after = function (element, isRoot) {
9789        return after$1(universe, element, isRoot);
9790      };
9791      var seekLeft = function (element, predicate, isRoot) {
9792        return seekLeft$1(universe, element, predicate, isRoot);
9793      };
9794      var seekRight = function (element, predicate, isRoot) {
9795        return seekRight$1(universe, element, predicate, isRoot);
9796      };
9797  
9798      var ancestor = function (scope, predicate, isRoot) {
9799        return ancestor$2(scope, predicate, isRoot).isSome();
9800      };
9801  
9802      var adt$1 = Adt.generate([
9803        { none: ['message'] },
9804        { success: [] },
9805        { failedUp: ['cell'] },
9806        { failedDown: ['cell'] }
9807      ]);
9808      var isOverlapping = function (bridge, before, after) {
9809        var beforeBounds = bridge.getRect(before);
9810        var afterBounds = bridge.getRect(after);
9811        return afterBounds.right > beforeBounds.left && afterBounds.left < beforeBounds.right;
9812      };
9813      var isRow = function (elem) {
9814        return closest$1(elem, 'tr');
9815      };
9816      var verify = function (bridge, before, beforeOffset, after, afterOffset, failure, isRoot) {
9817        return closest$1(after, 'td,th', isRoot).bind(function (afterCell) {
9818          return closest$1(before, 'td,th', isRoot).map(function (beforeCell) {
9819            if (!eq$1(afterCell, beforeCell)) {
9820              return sharedOne(isRow, [
9821                afterCell,
9822                beforeCell
9823              ]).fold(function () {
9824                return isOverlapping(bridge, beforeCell, afterCell) ? adt$1.success() : failure(beforeCell);
9825              }, function (_sharedRow) {
9826                return failure(beforeCell);
9827              });
9828            } else {
9829              return eq$1(after, afterCell) && getEnd(afterCell) === afterOffset ? failure(beforeCell) : adt$1.none('in same cell');
9830            }
9831          });
9832        }).getOr(adt$1.none('default'));
9833      };
9834      var cata = function (subject, onNone, onSuccess, onFailedUp, onFailedDown) {
9835        return subject.fold(onNone, onSuccess, onFailedUp, onFailedDown);
9836      };
9837      var BeforeAfter = __assign(__assign({}, adt$1), {
9838        verify: verify,
9839        cata: cata
9840      });
9841  
9842      var inParent = function (parent, children, element, index) {
9843        return {
9844          parent: parent,
9845          children: children,
9846          element: element,
9847          index: index
9848        };
9849      };
9850      var indexInParent = function (element) {
9851        return parent(element).bind(function (parent) {
9852          var children = children$3(parent);
9853          return indexOf(children, element).map(function (index) {
9854            return inParent(parent, children, element, index);
9855          });
9856        });
9857      };
9858      var indexOf = function (elements, element) {
9859        return findIndex(elements, curry(eq$1, element));
9860      };
9861  
9862      var isBr = function (elem) {
9863        return name(elem) === 'br';
9864      };
9865      var gatherer = function (cand, gather, isRoot) {
9866        return gather(cand, isRoot).bind(function (target) {
9867          return isText(target) && get$9(target).trim().length === 0 ? gatherer(target, gather, isRoot) : Optional.some(target);
9868        });
9869      };
9870      var handleBr = function (isRoot, element, direction) {
9871        return direction.traverse(element).orThunk(function () {
9872          return gatherer(element, direction.gather, isRoot);
9873        }).map(direction.relative);
9874      };
9875      var findBr = function (element, offset) {
9876        return child$3(element, offset).filter(isBr).orThunk(function () {
9877          return child$3(element, offset - 1).filter(isBr);
9878        });
9879      };
9880      var handleParent = function (isRoot, element, offset, direction) {
9881        return findBr(element, offset).bind(function (br) {
9882          return direction.traverse(br).fold(function () {
9883            return gatherer(br, direction.gather, isRoot).map(direction.relative);
9884          }, function (adjacent) {
9885            return indexInParent(adjacent).map(function (info) {
9886              return Situ.on(info.parent, info.index);
9887            });
9888          });
9889        });
9890      };
9891      var tryBr = function (isRoot, element, offset, direction) {
9892        var target = isBr(element) ? handleBr(isRoot, element, direction) : handleParent(isRoot, element, offset, direction);
9893        return target.map(function (tgt) {
9894          return {
9895            start: tgt,
9896            finish: tgt
9897          };
9898        });
9899      };
9900      var process = function (analysis) {
9901        return BeforeAfter.cata(analysis, function (_message) {
9902          return Optional.none();
9903        }, function () {
9904          return Optional.none();
9905        }, function (cell) {
9906          return Optional.some(point(cell, 0));
9907        }, function (cell) {
9908          return Optional.some(point(cell, getEnd(cell)));
9909        });
9910      };
9911  
9912      var moveDown = function (caret, amount) {
9913        return {
9914          left: caret.left,
9915          top: caret.top + amount,
9916          right: caret.right,
9917          bottom: caret.bottom + amount
9918        };
9919      };
9920      var moveUp = function (caret, amount) {
9921        return {
9922          left: caret.left,
9923          top: caret.top - amount,
9924          right: caret.right,
9925          bottom: caret.bottom - amount
9926        };
9927      };
9928      var translate = function (caret, xDelta, yDelta) {
9929        return {
9930          left: caret.left + xDelta,
9931          top: caret.top + yDelta,
9932          right: caret.right + xDelta,
9933          bottom: caret.bottom + yDelta
9934        };
9935      };
9936      var getTop = function (caret) {
9937        return caret.top;
9938      };
9939      var getBottom = function (caret) {
9940        return caret.bottom;
9941      };
9942  
9943      var getPartialBox = function (bridge, element, offset) {
9944        if (offset >= 0 && offset < getEnd(element)) {
9945          return bridge.getRangedRect(element, offset, element, offset + 1);
9946        } else if (offset > 0) {
9947          return bridge.getRangedRect(element, offset - 1, element, offset);
9948        }
9949        return Optional.none();
9950      };
9951      var toCaret = function (rect) {
9952        return {
9953          left: rect.left,
9954          top: rect.top,
9955          right: rect.right,
9956          bottom: rect.bottom
9957        };
9958      };
9959      var getElemBox = function (bridge, element) {
9960        return Optional.some(bridge.getRect(element));
9961      };
9962      var getBoxAt = function (bridge, element, offset) {
9963        if (isElement(element)) {
9964          return getElemBox(bridge, element).map(toCaret);
9965        } else if (isText(element)) {
9966          return getPartialBox(bridge, element, offset).map(toCaret);
9967        } else {
9968          return Optional.none();
9969        }
9970      };
9971      var getEntireBox = function (bridge, element) {
9972        if (isElement(element)) {
9973          return getElemBox(bridge, element).map(toCaret);
9974        } else if (isText(element)) {
9975          return bridge.getRangedRect(element, 0, element, getEnd(element)).map(toCaret);
9976        } else {
9977          return Optional.none();
9978        }
9979      };
9980  
9981      var JUMP_SIZE = 5;
9982      var NUM_RETRIES = 100;
9983      var adt = Adt.generate([
9984        { none: [] },
9985        { retry: ['caret'] }
9986      ]);
9987      var isOutside = function (caret, box) {
9988        return caret.left < box.left || Math.abs(box.right - caret.left) < 1 || caret.left > box.right;
9989      };
9990      var inOutsideBlock = function (bridge, element, caret) {
9991        return closest$2(element, isBlock).fold(never, function (cell) {
9992          return getEntireBox(bridge, cell).exists(function (box) {
9993            return isOutside(caret, box);
9994          });
9995        });
9996      };
9997      var adjustDown = function (bridge, element, guessBox, original, caret) {
9998        var lowerCaret = moveDown(caret, JUMP_SIZE);
9999        if (Math.abs(guessBox.bottom - original.bottom) < 1) {
10000          return adt.retry(lowerCaret);
10001        } else if (guessBox.top > caret.bottom) {
10002          return adt.retry(lowerCaret);
10003        } else if (guessBox.top === caret.bottom) {
10004          return adt.retry(moveDown(caret, 1));
10005        } else {
10006          return inOutsideBlock(bridge, element, caret) ? adt.retry(translate(lowerCaret, JUMP_SIZE, 0)) : adt.none();
10007        }
10008      };
10009      var adjustUp = function (bridge, element, guessBox, original, caret) {
10010        var higherCaret = moveUp(caret, JUMP_SIZE);
10011        if (Math.abs(guessBox.top - original.top) < 1) {
10012          return adt.retry(higherCaret);
10013        } else if (guessBox.bottom < caret.top) {
10014          return adt.retry(higherCaret);
10015        } else if (guessBox.bottom === caret.top) {
10016          return adt.retry(moveUp(caret, 1));
10017        } else {
10018          return inOutsideBlock(bridge, element, caret) ? adt.retry(translate(higherCaret, JUMP_SIZE, 0)) : adt.none();
10019        }
10020      };
10021      var upMovement = {
10022        point: getTop,
10023        adjuster: adjustUp,
10024        move: moveUp,
10025        gather: before
10026      };
10027      var downMovement = {
10028        point: getBottom,
10029        adjuster: adjustDown,
10030        move: moveDown,
10031        gather: after
10032      };
10033      var isAtTable = function (bridge, x, y) {
10034        return bridge.elementFromPoint(x, y).filter(function (elm) {
10035          return name(elm) === 'table';
10036        }).isSome();
10037      };
10038      var adjustForTable = function (bridge, movement, original, caret, numRetries) {
10039        return adjustTil(bridge, movement, original, movement.move(caret, JUMP_SIZE), numRetries);
10040      };
10041      var adjustTil = function (bridge, movement, original, caret, numRetries) {
10042        if (numRetries === 0) {
10043          return Optional.some(caret);
10044        }
10045        if (isAtTable(bridge, caret.left, movement.point(caret))) {
10046          return adjustForTable(bridge, movement, original, caret, numRetries - 1);
10047        }
10048        return bridge.situsFromPoint(caret.left, movement.point(caret)).bind(function (guess) {
10049          return guess.start.fold(Optional.none, function (element) {
10050            return getEntireBox(bridge, element).bind(function (guessBox) {
10051              return movement.adjuster(bridge, element, guessBox, original, caret).fold(Optional.none, function (newCaret) {
10052                return adjustTil(bridge, movement, original, newCaret, numRetries - 1);
10053              });
10054            }).orThunk(function () {
10055              return Optional.some(caret);
10056            });
10057          }, Optional.none);
10058        });
10059      };
10060      var ieTryDown = function (bridge, caret) {
10061        return bridge.situsFromPoint(caret.left, caret.bottom + JUMP_SIZE);
10062      };
10063      var ieTryUp = function (bridge, caret) {
10064        return bridge.situsFromPoint(caret.left, caret.top - JUMP_SIZE);
10065      };
10066      var checkScroll = function (movement, adjusted, bridge) {
10067        if (movement.point(adjusted) > bridge.getInnerHeight()) {
10068          return Optional.some(movement.point(adjusted) - bridge.getInnerHeight());
10069        } else if (movement.point(adjusted) < 0) {
10070          return Optional.some(-movement.point(adjusted));
10071        } else {
10072          return Optional.none();
10073        }
10074      };
10075      var retry = function (movement, bridge, caret) {
10076        var moved = movement.move(caret, JUMP_SIZE);
10077        var adjusted = adjustTil(bridge, movement, caret, moved, NUM_RETRIES).getOr(moved);
10078        return checkScroll(movement, adjusted, bridge).fold(function () {
10079          return bridge.situsFromPoint(adjusted.left, movement.point(adjusted));
10080        }, function (delta) {
10081          bridge.scrollBy(0, delta);
10082          return bridge.situsFromPoint(adjusted.left, movement.point(adjusted) - delta);
10083        });
10084      };
10085      var Retries = {
10086        tryUp: curry(retry, upMovement),
10087        tryDown: curry(retry, downMovement),
10088        ieTryUp: ieTryUp,
10089        ieTryDown: ieTryDown,
10090        getJumpSize: constant(JUMP_SIZE)
10091      };
10092  
10093      var MAX_RETRIES = 20;
10094      var findSpot = function (bridge, isRoot, direction) {
10095        return bridge.getSelection().bind(function (sel) {
10096          return tryBr(isRoot, sel.finish, sel.foffset, direction).fold(function () {
10097            return Optional.some(point(sel.finish, sel.foffset));
10098          }, function (brNeighbour) {
10099            var range = bridge.fromSitus(brNeighbour);
10100            var analysis = BeforeAfter.verify(bridge, sel.finish, sel.foffset, range.finish, range.foffset, direction.failure, isRoot);
10101            return process(analysis);
10102          });
10103        });
10104      };
10105      var scan = function (bridge, isRoot, element, offset, direction, numRetries) {
10106        if (numRetries === 0) {
10107          return Optional.none();
10108        }
10109        return tryCursor(bridge, isRoot, element, offset, direction).bind(function (situs) {
10110          var range = bridge.fromSitus(situs);
10111          var analysis = BeforeAfter.verify(bridge, element, offset, range.finish, range.foffset, direction.failure, isRoot);
10112          return BeforeAfter.cata(analysis, function () {
10113            return Optional.none();
10114          }, function () {
10115            return Optional.some(situs);
10116          }, function (cell) {
10117            if (eq$1(element, cell) && offset === 0) {
10118              return tryAgain(bridge, element, offset, moveUp, direction);
10119            } else {
10120              return scan(bridge, isRoot, cell, 0, direction, numRetries - 1);
10121            }
10122          }, function (cell) {
10123            if (eq$1(element, cell) && offset === getEnd(cell)) {
10124              return tryAgain(bridge, element, offset, moveDown, direction);
10125            } else {
10126              return scan(bridge, isRoot, cell, getEnd(cell), direction, numRetries - 1);
10127            }
10128          });
10129        });
10130      };
10131      var tryAgain = function (bridge, element, offset, move, direction) {
10132        return getBoxAt(bridge, element, offset).bind(function (box) {
10133          return tryAt(bridge, direction, move(box, Retries.getJumpSize()));
10134        });
10135      };
10136      var tryAt = function (bridge, direction, box) {
10137        var browser = detect$3().browser;
10138        if (browser.isChrome() || browser.isSafari() || browser.isFirefox() || browser.isEdge()) {
10139          return direction.otherRetry(bridge, box);
10140        } else if (browser.isIE()) {
10141          return direction.ieRetry(bridge, box);
10142        } else {
10143          return Optional.none();
10144        }
10145      };
10146      var tryCursor = function (bridge, isRoot, element, offset, direction) {
10147        return getBoxAt(bridge, element, offset).bind(function (box) {
10148          return tryAt(bridge, direction, box);
10149        });
10150      };
10151      var handle = function (bridge, isRoot, direction) {
10152        return findSpot(bridge, isRoot, direction).bind(function (spot) {
10153          return scan(bridge, isRoot, spot.element, spot.offset, direction, MAX_RETRIES).map(bridge.fromSitus);
10154        });
10155      };
10156  
10157      var inSameTable = function (elem, table) {
10158        return ancestor(elem, function (e) {
10159          return parent(e).exists(function (p) {
10160            return eq$1(p, table);
10161          });
10162        });
10163      };
10164      var simulate = function (bridge, isRoot, direction, initial, anchor) {
10165        return closest$1(initial, 'td,th', isRoot).bind(function (start) {
10166          return closest$1(start, 'table', isRoot).bind(function (table) {
10167            if (!inSameTable(anchor, table)) {
10168              return Optional.none();
10169            }
10170            return handle(bridge, isRoot, direction).bind(function (range) {
10171              return closest$1(range.finish, 'td,th', isRoot).map(function (finish) {
10172                return {
10173                  start: start,
10174                  finish: finish,
10175                  range: range
10176                };
10177              });
10178            });
10179          });
10180        });
10181      };
10182      var navigate = function (bridge, isRoot, direction, initial, anchor, precheck) {
10183        if (detect$3().browser.isIE()) {
10184          return Optional.none();
10185        } else {
10186          return precheck(initial, isRoot).orThunk(function () {
10187            return simulate(bridge, isRoot, direction, initial, anchor).map(function (info) {
10188              var range = info.range;
10189              return Response.create(Optional.some(makeSitus(range.start, range.soffset, range.finish, range.foffset)), true);
10190            });
10191          });
10192        }
10193      };
10194      var firstUpCheck = function (initial, isRoot) {
10195        return closest$1(initial, 'tr', isRoot).bind(function (startRow) {
10196          return closest$1(startRow, 'table', isRoot).bind(function (table) {
10197            var rows = descendants(table, 'tr');
10198            if (eq$1(startRow, rows[0])) {
10199              return seekLeft(table, function (element) {
10200                return last$1(element).isSome();
10201              }, isRoot).map(function (last) {
10202                var lastOffset = getEnd(last);
10203                return Response.create(Optional.some(makeSitus(last, lastOffset, last, lastOffset)), true);
10204              });
10205            } else {
10206              return Optional.none();
10207            }
10208          });
10209        });
10210      };
10211      var lastDownCheck = function (initial, isRoot) {
10212        return closest$1(initial, 'tr', isRoot).bind(function (startRow) {
10213          return closest$1(startRow, 'table', isRoot).bind(function (table) {
10214            var rows = descendants(table, 'tr');
10215            if (eq$1(startRow, rows[rows.length - 1])) {
10216              return seekRight(table, function (element) {
10217                return first(element).isSome();
10218              }, isRoot).map(function (first) {
10219                return Response.create(Optional.some(makeSitus(first, 0, first, 0)), true);
10220              });
10221            } else {
10222              return Optional.none();
10223            }
10224          });
10225        });
10226      };
10227      var select = function (bridge, container, isRoot, direction, initial, anchor, selectRange) {
10228        return simulate(bridge, isRoot, direction, initial, anchor).bind(function (info) {
10229          return detect(container, isRoot, info.start, info.finish, selectRange);
10230        });
10231      };
10232  
10233      var findCell = function (target, isRoot) {
10234        return closest$1(target, 'td,th', isRoot);
10235      };
10236      var MouseSelection = function (bridge, container, isRoot, annotations) {
10237        var cursor = value();
10238        var clearstate = cursor.clear;
10239        var applySelection = function (event) {
10240          cursor.on(function (start) {
10241            annotations.clearBeforeUpdate(container);
10242            findCell(event.target, isRoot).each(function (finish) {
10243              identify(start, finish, isRoot).each(function (cellSel) {
10244                var boxes = cellSel.boxes.getOr([]);
10245                if (boxes.length === 1) {
10246                  var singleCell = boxes[0];
10247                  var isNonEditableCell = getRaw(singleCell) === 'false';
10248                  var isCellClosestContentEditable = is(closest(event.target), singleCell, eq$1);
10249                  if (isNonEditableCell && isCellClosestContentEditable) {
10250                    annotations.selectRange(container, boxes, singleCell, singleCell);
10251                    bridge.selectContents(singleCell);
10252                  }
10253                } else if (boxes.length > 1) {
10254                  annotations.selectRange(container, boxes, cellSel.start, cellSel.finish);
10255                  bridge.selectContents(finish);
10256                }
10257              });
10258            });
10259          });
10260        };
10261        var mousedown = function (event) {
10262          annotations.clear(container);
10263          findCell(event.target, isRoot).each(cursor.set);
10264        };
10265        var mouseover = function (event) {
10266          applySelection(event);
10267        };
10268        var mouseup = function (event) {
10269          applySelection(event);
10270          clearstate();
10271        };
10272        return {
10273          clearstate: clearstate,
10274          mousedown: mousedown,
10275          mouseover: mouseover,
10276          mouseup: mouseup
10277        };
10278      };
10279  
10280      var down = {
10281        traverse: nextSibling,
10282        gather: after,
10283        relative: Situ.before,
10284        otherRetry: Retries.tryDown,
10285        ieRetry: Retries.ieTryDown,
10286        failure: BeforeAfter.failedDown
10287      };
10288      var up = {
10289        traverse: prevSibling,
10290        gather: before,
10291        relative: Situ.before,
10292        otherRetry: Retries.tryUp,
10293        ieRetry: Retries.ieTryUp,
10294        failure: BeforeAfter.failedUp
10295      };
10296  
10297      var isKey = function (key) {
10298        return function (keycode) {
10299          return keycode === key;
10300        };
10301      };
10302      var isUp = isKey(38);
10303      var isDown = isKey(40);
10304      var isNavigation = function (keycode) {
10305        return keycode >= 37 && keycode <= 40;
10306      };
10307      var ltr = {
10308        isBackward: isKey(37),
10309        isForward: isKey(39)
10310      };
10311      var rtl = {
10312        isBackward: isKey(39),
10313        isForward: isKey(37)
10314      };
10315  
10316      var get = function (_DOC) {
10317        var doc = _DOC !== undefined ? _DOC.dom : document;
10318        var x = doc.body.scrollLeft || doc.documentElement.scrollLeft;
10319        var y = doc.body.scrollTop || doc.documentElement.scrollTop;
10320        return SugarPosition(x, y);
10321      };
10322      var by = function (x, y, _DOC) {
10323        var doc = _DOC !== undefined ? _DOC.dom : document;
10324        var win = doc.defaultView;
10325        if (win) {
10326          win.scrollBy(x, y);
10327        }
10328      };
10329  
10330      var WindowBridge = function (win) {
10331        var elementFromPoint = function (x, y) {
10332          return SugarElement.fromPoint(SugarElement.fromDom(win.document), x, y);
10333        };
10334        var getRect = function (element) {
10335          return element.dom.getBoundingClientRect();
10336        };
10337        var getRangedRect = function (start, soffset, finish, foffset) {
10338          var sel = SimSelection.exact(start, soffset, finish, foffset);
10339          return getFirstRect(win, sel);
10340        };
10341        var getSelection = function () {
10342          return get$1(win).map(function (exactAdt) {
10343            return convertToRange(win, exactAdt);
10344          });
10345        };
10346        var fromSitus = function (situs) {
10347          var relative = SimSelection.relative(situs.start, situs.finish);
10348          return convertToRange(win, relative);
10349        };
10350        var situsFromPoint = function (x, y) {
10351          return getAtPoint(win, x, y).map(function (exact) {
10352            return Situs.create(exact.start, exact.soffset, exact.finish, exact.foffset);
10353          });
10354        };
10355        var clearSelection = function () {
10356          clear(win);
10357        };
10358        var collapseSelection = function (toStart) {
10359          if (toStart === void 0) {
10360            toStart = false;
10361          }
10362          get$1(win).each(function (sel) {
10363            return sel.fold(function (rng) {
10364              return rng.collapse(toStart);
10365            }, function (startSitu, finishSitu) {
10366              var situ = toStart ? startSitu : finishSitu;
10367              setRelative(win, situ, situ);
10368            }, function (start, soffset, finish, foffset) {
10369              var node = toStart ? start : finish;
10370              var offset = toStart ? soffset : foffset;
10371              setExact(win, node, offset, node, offset);
10372            });
10373          });
10374        };
10375        var selectNode = function (element) {
10376          setToElement(win, element, false);
10377        };
10378        var selectContents = function (element) {
10379          setToElement(win, element);
10380        };
10381        var setSelection = function (sel) {
10382          setExact(win, sel.start, sel.soffset, sel.finish, sel.foffset);
10383        };
10384        var setRelativeSelection = function (start, finish) {
10385          setRelative(win, start, finish);
10386        };
10387        var getInnerHeight = function () {
10388          return win.innerHeight;
10389        };
10390        var getScrollY = function () {
10391          var pos = get(SugarElement.fromDom(win.document));
10392          return pos.top;
10393        };
10394        var scrollBy = function (x, y) {
10395          by(x, y, SugarElement.fromDom(win.document));
10396        };
10397        return {
10398          elementFromPoint: elementFromPoint,
10399          getRect: getRect,
10400          getRangedRect: getRangedRect,
10401          getSelection: getSelection,
10402          fromSitus: fromSitus,
10403          situsFromPoint: situsFromPoint,
10404          clearSelection: clearSelection,
10405          collapseSelection: collapseSelection,
10406          setSelection: setSelection,
10407          setRelativeSelection: setRelativeSelection,
10408          selectNode: selectNode,
10409          selectContents: selectContents,
10410          getInnerHeight: getInnerHeight,
10411          getScrollY: getScrollY,
10412          scrollBy: scrollBy
10413        };
10414      };
10415  
10416      var rc = function (rows, cols) {
10417        return {
10418          rows: rows,
10419          cols: cols
10420        };
10421      };
10422      var mouse = function (win, container, isRoot, annotations) {
10423        var bridge = WindowBridge(win);
10424        var handlers = MouseSelection(bridge, container, isRoot, annotations);
10425        return {
10426          clearstate: handlers.clearstate,
10427          mousedown: handlers.mousedown,
10428          mouseover: handlers.mouseover,
10429          mouseup: handlers.mouseup
10430        };
10431      };
10432      var keyboard = function (win, container, isRoot, annotations) {
10433        var bridge = WindowBridge(win);
10434        var clearToNavigate = function () {
10435          annotations.clear(container);
10436          return Optional.none();
10437        };
10438        var keydown = function (event, start, soffset, finish, foffset, direction) {
10439          var realEvent = event.raw;
10440          var keycode = realEvent.which;
10441          var shiftKey = realEvent.shiftKey === true;
10442          var handler = retrieve$1(container, annotations.selectedSelector).fold(function () {
10443            if (isNavigation(keycode) && !shiftKey) {
10444              annotations.clearBeforeUpdate(container);
10445            }
10446            if (isDown(keycode) && shiftKey) {
10447              return curry(select, bridge, container, isRoot, down, finish, start, annotations.selectRange);
10448            } else if (isUp(keycode) && shiftKey) {
10449              return curry(select, bridge, container, isRoot, up, finish, start, annotations.selectRange);
10450            } else if (isDown(keycode)) {
10451              return curry(navigate, bridge, isRoot, down, finish, start, lastDownCheck);
10452            } else if (isUp(keycode)) {
10453              return curry(navigate, bridge, isRoot, up, finish, start, firstUpCheck);
10454            } else {
10455              return Optional.none;
10456            }
10457          }, function (selected) {
10458            var update$1 = function (attempts) {
10459              return function () {
10460                var navigation = findMap(attempts, function (delta) {
10461                  return update(delta.rows, delta.cols, container, selected, annotations);
10462                });
10463                return navigation.fold(function () {
10464                  return getEdges(container, annotations.firstSelectedSelector, annotations.lastSelectedSelector).map(function (edges) {
10465                    var relative = isDown(keycode) || direction.isForward(keycode) ? Situ.after : Situ.before;
10466                    bridge.setRelativeSelection(Situ.on(edges.first, 0), relative(edges.table));
10467                    annotations.clear(container);
10468                    return Response.create(Optional.none(), true);
10469                  });
10470                }, function (_) {
10471                  return Optional.some(Response.create(Optional.none(), true));
10472                });
10473              };
10474            };
10475            if (isDown(keycode) && shiftKey) {
10476              return update$1([rc(+1, 0)]);
10477            } else if (isUp(keycode) && shiftKey) {
10478              return update$1([rc(-1, 0)]);
10479            } else if (direction.isBackward(keycode) && shiftKey) {
10480              return update$1([
10481                rc(0, -1),
10482                rc(-1, 0)
10483              ]);
10484            } else if (direction.isForward(keycode) && shiftKey) {
10485              return update$1([
10486                rc(0, +1),
10487                rc(+1, 0)
10488              ]);
10489            } else if (isNavigation(keycode) && !shiftKey) {
10490              return clearToNavigate;
10491            } else {
10492              return Optional.none;
10493            }
10494          });
10495          return handler();
10496        };
10497        var keyup = function (event, start, soffset, finish, foffset) {
10498          return retrieve$1(container, annotations.selectedSelector).fold(function () {
10499            var realEvent = event.raw;
10500            var keycode = realEvent.which;
10501            var shiftKey = realEvent.shiftKey === true;
10502            if (!shiftKey) {
10503              return Optional.none();
10504            }
10505            if (isNavigation(keycode)) {
10506              return sync(container, isRoot, start, soffset, finish, foffset, annotations.selectRange);
10507            } else {
10508              return Optional.none();
10509            }
10510          }, Optional.none);
10511        };
10512        return {
10513          keydown: keydown,
10514          keyup: keyup
10515        };
10516      };
10517      var external = function (win, container, isRoot, annotations) {
10518        var bridge = WindowBridge(win);
10519        return function (start, finish) {
10520          annotations.clearBeforeUpdate(container);
10521          identify(start, finish, isRoot).each(function (cellSel) {
10522            var boxes = cellSel.boxes.getOr([]);
10523            annotations.selectRange(container, boxes, cellSel.start, cellSel.finish);
10524            bridge.selectContents(finish);
10525            bridge.collapseSelection();
10526          });
10527        };
10528      };
10529  
10530      var remove = function (element, classes) {
10531        each$2(classes, function (x) {
10532          remove$2(element, x);
10533        });
10534      };
10535  
10536      var addClass = function (clazz) {
10537        return function (element) {
10538          add(element, clazz);
10539        };
10540      };
10541      var removeClasses = function (classes) {
10542        return function (element) {
10543          remove(element, classes);
10544        };
10545      };
10546  
10547      var byClass = function (ephemera) {
10548        var addSelectionClass = addClass(ephemera.selected);
10549        var removeSelectionClasses = removeClasses([
10550          ephemera.selected,
10551          ephemera.lastSelected,
10552          ephemera.firstSelected
10553        ]);
10554        var clear = function (container) {
10555          var sels = descendants(container, ephemera.selectedSelector);
10556          each$2(sels, removeSelectionClasses);
10557        };
10558        var selectRange = function (container, cells, start, finish) {
10559          clear(container);
10560          each$2(cells, addSelectionClass);
10561          add(start, ephemera.firstSelected);
10562          add(finish, ephemera.lastSelected);
10563        };
10564        return {
10565          clearBeforeUpdate: clear,
10566          clear: clear,
10567          selectRange: selectRange,
10568          selectedSelector: ephemera.selectedSelector,
10569          firstSelectedSelector: ephemera.firstSelectedSelector,
10570          lastSelectedSelector: ephemera.lastSelectedSelector
10571        };
10572      };
10573      var byAttr = function (ephemera, onSelection, onClear) {
10574        var removeSelectionAttributes = function (element) {
10575          remove$7(element, ephemera.selected);
10576          remove$7(element, ephemera.firstSelected);
10577          remove$7(element, ephemera.lastSelected);
10578        };
10579        var addSelectionAttribute = function (element) {
10580          set$2(element, ephemera.selected, '1');
10581        };
10582        var clear = function (container) {
10583          clearBeforeUpdate(container);
10584          onClear();
10585        };
10586        var clearBeforeUpdate = function (container) {
10587          var sels = descendants(container, ephemera.selectedSelector + ',' + ephemera.firstSelectedSelector + ',' + ephemera.lastSelectedSelector);
10588          each$2(sels, removeSelectionAttributes);
10589        };
10590        var selectRange = function (container, cells, start, finish) {
10591          clear(container);
10592          each$2(cells, addSelectionAttribute);
10593          set$2(start, ephemera.firstSelected, '1');
10594          set$2(finish, ephemera.lastSelected, '1');
10595          onSelection(cells, start, finish);
10596        };
10597        return {
10598          clearBeforeUpdate: clearBeforeUpdate,
10599          clear: clear,
10600          selectRange: selectRange,
10601          selectedSelector: ephemera.selectedSelector,
10602          firstSelectedSelector: ephemera.firstSelectedSelector,
10603          lastSelectedSelector: ephemera.lastSelectedSelector
10604        };
10605      };
10606      var SelectionAnnotation = {
10607        byClass: byClass,
10608        byAttr: byAttr
10609      };
10610  
10611      var getUpOrLeftCells = function (grid, selectedCells) {
10612        var upGrid = grid.slice(0, selectedCells[selectedCells.length - 1].row + 1);
10613        var upDetails = toDetailList(upGrid);
10614        return bind$2(upDetails, function (detail) {
10615          var slicedCells = detail.cells.slice(0, selectedCells[selectedCells.length - 1].column + 1);
10616          return map$1(slicedCells, function (cell) {
10617            return cell.element;
10618          });
10619        });
10620      };
10621      var getDownOrRightCells = function (grid, selectedCells) {
10622        var downGrid = grid.slice(selectedCells[0].row + selectedCells[0].rowspan - 1, grid.length);
10623        var downDetails = toDetailList(downGrid);
10624        return bind$2(downDetails, function (detail) {
10625          var slicedCells = detail.cells.slice(selectedCells[0].column + selectedCells[0].colspan - 1, detail.cells.length);
10626          return map$1(slicedCells, function (cell) {
10627            return cell.element;
10628          });
10629        });
10630      };
10631      var getOtherCells = function (table, target, generators) {
10632        var warehouse = Warehouse.fromTable(table);
10633        var details = onCells(warehouse, target);
10634        return details.map(function (selectedCells) {
10635          var grid = toGrid(warehouse, generators, false);
10636          var upOrLeftCells = getUpOrLeftCells(grid, selectedCells);
10637          var downOrRightCells = getDownOrRightCells(grid, selectedCells);
10638          return {
10639            upOrLeftCells: upOrLeftCells,
10640            downOrRightCells: downOrRightCells
10641          };
10642        });
10643      };
10644  
10645      var global = tinymce.util.Tools.resolve('tinymce.Env');
10646  
10647      var hasInternalTarget = function (e) {
10648        return has(SugarElement.fromDom(e.target), 'ephox-snooker-resizer-bar') === false;
10649      };
10650      function CellSelection (editor, lazyResize, selectionTargets) {
10651        var onSelection = function (cells, start, finish) {
10652          selectionTargets.targets().each(function (targets) {
10653            var tableOpt = table(start);
10654            tableOpt.each(function (table) {
10655              var cloneFormats = getCloneElements(editor);
10656              var generators = cellOperations(noop, SugarElement.fromDom(editor.getDoc()), cloneFormats);
10657              var otherCells = getOtherCells(table, targets, generators);
10658              fireTableSelectionChange(editor, cells, start, finish, otherCells);
10659            });
10660          });
10661        };
10662        var onClear = function () {
10663          return fireTableSelectionClear(editor);
10664        };
10665        var annotations = SelectionAnnotation.byAttr(ephemera, onSelection, onClear);
10666        editor.on('init', function (_e) {
10667          var win = editor.getWin();
10668          var body = getBody(editor);
10669          var isRoot = getIsRoot(editor);
10670          var syncSelection = function () {
10671            var sel = editor.selection;
10672            var start = SugarElement.fromDom(sel.getStart());
10673            var end = SugarElement.fromDom(sel.getEnd());
10674            var shared = sharedOne(table, [
10675              start,
10676              end
10677            ]);
10678            shared.fold(function () {
10679              return annotations.clear(body);
10680            }, noop);
10681          };
10682          var mouseHandlers = mouse(win, body, isRoot, annotations);
10683          var keyHandlers = keyboard(win, body, isRoot, annotations);
10684          var external$1 = external(win, body, isRoot, annotations);
10685          var hasShiftKey = function (event) {
10686            return event.raw.shiftKey === true;
10687          };
10688          editor.on('TableSelectorChange', function (e) {
10689            return external$1(e.start, e.finish);
10690          });
10691          var handleResponse = function (event, response) {
10692            if (!hasShiftKey(event)) {
10693              return;
10694            }
10695            if (response.kill) {
10696              event.kill();
10697            }
10698            response.selection.each(function (ns) {
10699              var relative = SimSelection.relative(ns.start, ns.finish);
10700              var rng = asLtrRange(win, relative);
10701              editor.selection.setRng(rng);
10702            });
10703          };
10704          var keyup = function (event) {
10705            var wrappedEvent = fromRawEvent(event);
10706            if (wrappedEvent.raw.shiftKey && isNavigation(wrappedEvent.raw.which)) {
10707              var rng = editor.selection.getRng();
10708              var start = SugarElement.fromDom(rng.startContainer);
10709              var end = SugarElement.fromDom(rng.endContainer);
10710              keyHandlers.keyup(wrappedEvent, start, rng.startOffset, end, rng.endOffset).each(function (response) {
10711                handleResponse(wrappedEvent, response);
10712              });
10713            }
10714          };
10715          var keydown = function (event) {
10716            var wrappedEvent = fromRawEvent(event);
10717            lazyResize().each(function (resize) {
10718              return resize.hideBars();
10719            });
10720            var rng = editor.selection.getRng();
10721            var start = SugarElement.fromDom(rng.startContainer);
10722            var end = SugarElement.fromDom(rng.endContainer);
10723            var direction = onDirection(ltr, rtl)(SugarElement.fromDom(editor.selection.getStart()));
10724            keyHandlers.keydown(wrappedEvent, start, rng.startOffset, end, rng.endOffset, direction).each(function (response) {
10725              handleResponse(wrappedEvent, response);
10726            });
10727            lazyResize().each(function (resize) {
10728              return resize.showBars();
10729            });
10730          };
10731          var isLeftMouse = function (raw) {
10732            return raw.button === 0;
10733          };
10734          var isLeftButtonPressed = function (raw) {
10735            if (raw.buttons === undefined) {
10736              return true;
10737            }
10738            if (global.browser.isEdge() && raw.buttons === 0) {
10739              return true;
10740            }
10741            return (raw.buttons & 1) !== 0;
10742          };
10743          var dragStart = function (_e) {
10744            mouseHandlers.clearstate();
10745          };
10746          var mouseDown = function (e) {
10747            if (isLeftMouse(e) && hasInternalTarget(e)) {
10748              mouseHandlers.mousedown(fromRawEvent(e));
10749            }
10750          };
10751          var mouseOver = function (e) {
10752            if (isLeftButtonPressed(e) && hasInternalTarget(e)) {
10753              mouseHandlers.mouseover(fromRawEvent(e));
10754            }
10755          };
10756          var mouseUp = function (e) {
10757            if (isLeftMouse(e) && hasInternalTarget(e)) {
10758              mouseHandlers.mouseup(fromRawEvent(e));
10759            }
10760          };
10761          var getDoubleTap = function () {
10762            var lastTarget = Cell(SugarElement.fromDom(body));
10763            var lastTimeStamp = Cell(0);
10764            var touchEnd = function (t) {
10765              var target = SugarElement.fromDom(t.target);
10766              if (name(target) === 'td' || name(target) === 'th') {
10767                var lT = lastTarget.get();
10768                var lTS = lastTimeStamp.get();
10769                if (eq$1(lT, target) && t.timeStamp - lTS < 300) {
10770                  t.preventDefault();
10771                  external$1(target, target);
10772                }
10773              }
10774              lastTarget.set(target);
10775              lastTimeStamp.set(t.timeStamp);
10776            };
10777            return { touchEnd: touchEnd };
10778          };
10779          var doubleTap = getDoubleTap();
10780          editor.on('dragstart', dragStart);
10781          editor.on('mousedown', mouseDown);
10782          editor.on('mouseover', mouseOver);
10783          editor.on('mouseup', mouseUp);
10784          editor.on('touchend', doubleTap.touchEnd);
10785          editor.on('keyup', keyup);
10786          editor.on('keydown', keydown);
10787          editor.on('NodeChange', syncSelection);
10788        });
10789        return { clear: annotations.clear };
10790      }
10791  
10792      var child = function (scope, selector) {
10793        return child$1(scope, selector).isSome();
10794      };
10795  
10796      var getSelectionTargets = function (editor, selections) {
10797        var targets = Cell(Optional.none());
10798        var changeHandlers = Cell([]);
10799        var selectionDetails = Optional.none();
10800        var isCaption = isTag('caption');
10801        var isDisabledForSelection = function (key) {
10802          return selectionDetails.forall(function (details) {
10803            return !details[key];
10804          });
10805        };
10806        var getStart = function () {
10807          return getSelectionCellOrCaption(getSelectionStart(editor), getIsRoot(editor));
10808        };
10809        var getEnd = function () {
10810          return getSelectionCellOrCaption(getSelectionEnd(editor), getIsRoot(editor));
10811        };
10812        var findTargets = function () {
10813          return getStart().bind(function (startCellOrCaption) {
10814            return flatten(lift2(table(startCellOrCaption), getEnd().bind(table), function (startTable, endTable) {
10815              if (eq$1(startTable, endTable)) {
10816                if (isCaption(startCellOrCaption)) {
10817                  return Optional.some(noMenu(startCellOrCaption));
10818                } else {
10819                  return Optional.some(forMenu(selections, startTable, startCellOrCaption));
10820                }
10821              }
10822              return Optional.none();
10823            }));
10824          });
10825        };
10826        var getExtractedDetails = function (targets) {
10827          var tableOpt = table(targets.element);
10828          return tableOpt.map(function (table) {
10829            var warehouse = Warehouse.fromTable(table);
10830            var selectedCells = onCells(warehouse, targets).getOr([]);
10831            var locked = foldl(selectedCells, function (acc, cell) {
10832              if (cell.isLocked) {
10833                acc.onAny = true;
10834                if (cell.column === 0) {
10835                  acc.onFirst = true;
10836                } else if (cell.column + cell.colspan >= warehouse.grid.columns) {
10837                  acc.onLast = true;
10838                }
10839              }
10840              return acc;
10841            }, {
10842              onAny: false,
10843              onFirst: false,
10844              onLast: false
10845            });
10846            return {
10847              mergeable: onUnlockedMergable(warehouse, targets).isSome(),
10848              unmergeable: onUnlockedUnmergable(warehouse, targets).isSome(),
10849              locked: locked
10850            };
10851          });
10852        };
10853        var resetTargets = function () {
10854          targets.set(cached(findTargets)());
10855          selectionDetails = targets.get().bind(getExtractedDetails);
10856          each$2(changeHandlers.get(), function (handler) {
10857            return handler();
10858          });
10859        };
10860        var setupHandler = function (handler) {
10861          handler();
10862          changeHandlers.set(changeHandlers.get().concat([handler]));
10863          return function () {
10864            changeHandlers.set(filter$2(changeHandlers.get(), function (h) {
10865              return h !== handler;
10866            }));
10867          };
10868        };
10869        var onSetup = function (api, isDisabled) {
10870          return setupHandler(function () {
10871            return targets.get().fold(function () {
10872              api.setDisabled(true);
10873            }, function (targets) {
10874              api.setDisabled(isDisabled(targets));
10875            });
10876          });
10877        };
10878        var onSetupWithToggle = function (api, isDisabled, isActive) {
10879          return setupHandler(function () {
10880            return targets.get().fold(function () {
10881              api.setDisabled(true);
10882              api.setActive(false);
10883            }, function (targets) {
10884              api.setDisabled(isDisabled(targets));
10885              api.setActive(isActive(targets));
10886            });
10887          });
10888        };
10889        var isDisabledFromLocked = function (lockedDisable) {
10890          return selectionDetails.exists(function (details) {
10891            return details.locked[lockedDisable];
10892          });
10893        };
10894        var onSetupTable = function (api) {
10895          return onSetup(api, function (_) {
10896            return false;
10897          });
10898        };
10899        var onSetupCellOrRow = function (api) {
10900          return onSetup(api, function (targets) {
10901            return isCaption(targets.element);
10902          });
10903        };
10904        var onSetupColumn = function (lockedDisable) {
10905          return function (api) {
10906            return onSetup(api, function (targets) {
10907              return isCaption(targets.element) || isDisabledFromLocked(lockedDisable);
10908            });
10909          };
10910        };
10911        var onSetupPasteable = function (getClipboardData) {
10912          return function (api) {
10913            return onSetup(api, function (targets) {
10914              return isCaption(targets.element) || getClipboardData().isNone();
10915            });
10916          };
10917        };
10918        var onSetupPasteableColumn = function (getClipboardData, lockedDisable) {
10919          return function (api) {
10920            return onSetup(api, function (targets) {
10921              return isCaption(targets.element) || getClipboardData().isNone() || isDisabledFromLocked(lockedDisable);
10922            });
10923          };
10924        };
10925        var onSetupMergeable = function (api) {
10926          return onSetup(api, function (_targets) {
10927            return isDisabledForSelection('mergeable');
10928          });
10929        };
10930        var onSetupUnmergeable = function (api) {
10931          return onSetup(api, function (_targets) {
10932            return isDisabledForSelection('unmergeable');
10933          });
10934        };
10935        var onSetupTableWithCaption = function (api) {
10936          return onSetupWithToggle(api, never, function (targets) {
10937            var tableOpt = table(targets.element, getIsRoot(editor));
10938            return tableOpt.exists(function (table) {
10939              return child(table, 'caption');
10940            });
10941          });
10942        };
10943        var onSetupTableHeaders = function (command, headerType) {
10944          return function (api) {
10945            return onSetupWithToggle(api, function (targets) {
10946              return isCaption(targets.element);
10947            }, function () {
10948              return editor.queryCommandValue(command) === headerType;
10949            });
10950          };
10951        };
10952        var onSetupTableRowHeaders = onSetupTableHeaders('mceTableRowType', 'header');
10953        var onSetupTableColumnHeaders = onSetupTableHeaders('mceTableColType', 'th');
10954        editor.on('NodeChange ExecCommand TableSelectorChange', resetTargets);
10955        return {
10956          onSetupTable: onSetupTable,
10957          onSetupCellOrRow: onSetupCellOrRow,
10958          onSetupColumn: onSetupColumn,
10959          onSetupPasteable: onSetupPasteable,
10960          onSetupPasteableColumn: onSetupPasteableColumn,
10961          onSetupMergeable: onSetupMergeable,
10962          onSetupUnmergeable: onSetupUnmergeable,
10963          resetTargets: resetTargets,
10964          onSetupTableWithCaption: onSetupTableWithCaption,
10965          onSetupTableRowHeaders: onSetupTableRowHeaders,
10966          onSetupTableColumnHeaders: onSetupTableColumnHeaders,
10967          targets: targets.get
10968        };
10969      };
10970  
10971      var addButtons = function (editor, selections, selectionTargets, clipboard) {
10972        editor.ui.registry.addMenuButton('table', {
10973          tooltip: 'Table',
10974          icon: 'table',
10975          fetch: function (callback) {
10976            return callback('inserttable | cell row column | advtablesort | tableprops deletetable');
10977          }
10978        });
10979        var cmd = function (command) {
10980          return function () {
10981            return editor.execCommand(command);
10982          };
10983        };
10984        editor.ui.registry.addButton('tableprops', {
10985          tooltip: 'Table properties',
10986          onAction: cmd('mceTableProps'),
10987          icon: 'table',
10988          onSetup: selectionTargets.onSetupTable
10989        });
10990        editor.ui.registry.addButton('tabledelete', {
10991          tooltip: 'Delete table',
10992          onAction: cmd('mceTableDelete'),
10993          icon: 'table-delete-table',
10994          onSetup: selectionTargets.onSetupTable
10995        });
10996        editor.ui.registry.addButton('tablecellprops', {
10997          tooltip: 'Cell properties',
10998          onAction: cmd('mceTableCellProps'),
10999          icon: 'table-cell-properties',
11000          onSetup: selectionTargets.onSetupCellOrRow
11001        });
11002        editor.ui.registry.addButton('tablemergecells', {
11003          tooltip: 'Merge cells',
11004          onAction: cmd('mceTableMergeCells'),
11005          icon: 'table-merge-cells',
11006          onSetup: selectionTargets.onSetupMergeable
11007        });
11008        editor.ui.registry.addButton('tablesplitcells', {
11009          tooltip: 'Split cell',
11010          onAction: cmd('mceTableSplitCells'),
11011          icon: 'table-split-cells',
11012          onSetup: selectionTargets.onSetupUnmergeable
11013        });
11014        editor.ui.registry.addButton('tableinsertrowbefore', {
11015          tooltip: 'Insert row before',
11016          onAction: cmd('mceTableInsertRowBefore'),
11017          icon: 'table-insert-row-above',
11018          onSetup: selectionTargets.onSetupCellOrRow
11019        });
11020        editor.ui.registry.addButton('tableinsertrowafter', {
11021          tooltip: 'Insert row after',
11022          onAction: cmd('mceTableInsertRowAfter'),
11023          icon: 'table-insert-row-after',
11024          onSetup: selectionTargets.onSetupCellOrRow
11025        });
11026        editor.ui.registry.addButton('tabledeleterow', {
11027          tooltip: 'Delete row',
11028          onAction: cmd('mceTableDeleteRow'),
11029          icon: 'table-delete-row',
11030          onSetup: selectionTargets.onSetupCellOrRow
11031        });
11032        editor.ui.registry.addButton('tablerowprops', {
11033          tooltip: 'Row properties',
11034          onAction: cmd('mceTableRowProps'),
11035          icon: 'table-row-properties',
11036          onSetup: selectionTargets.onSetupCellOrRow
11037        });
11038        editor.ui.registry.addButton('tableinsertcolbefore', {
11039          tooltip: 'Insert column before',
11040          onAction: cmd('mceTableInsertColBefore'),
11041          icon: 'table-insert-column-before',
11042          onSetup: selectionTargets.onSetupColumn('onFirst')
11043        });
11044        editor.ui.registry.addButton('tableinsertcolafter', {
11045          tooltip: 'Insert column after',
11046          onAction: cmd('mceTableInsertColAfter'),
11047          icon: 'table-insert-column-after',
11048          onSetup: selectionTargets.onSetupColumn('onLast')
11049        });
11050        editor.ui.registry.addButton('tabledeletecol', {
11051          tooltip: 'Delete column',
11052          onAction: cmd('mceTableDeleteCol'),
11053          icon: 'table-delete-column',
11054          onSetup: selectionTargets.onSetupColumn('onAny')
11055        });
11056        editor.ui.registry.addButton('tablecutrow', {
11057          tooltip: 'Cut row',
11058          icon: 'cut-row',
11059          onAction: cmd('mceTableCutRow'),
11060          onSetup: selectionTargets.onSetupCellOrRow
11061        });
11062        editor.ui.registry.addButton('tablecopyrow', {
11063          tooltip: 'Copy row',
11064          icon: 'duplicate-row',
11065          onAction: cmd('mceTableCopyRow'),
11066          onSetup: selectionTargets.onSetupCellOrRow
11067        });
11068        editor.ui.registry.addButton('tablepasterowbefore', {
11069          tooltip: 'Paste row before',
11070          icon: 'paste-row-before',
11071          onAction: cmd('mceTablePasteRowBefore'),
11072          onSetup: selectionTargets.onSetupPasteable(clipboard.getRows)
11073        });
11074        editor.ui.registry.addButton('tablepasterowafter', {
11075          tooltip: 'Paste row after',
11076          icon: 'paste-row-after',
11077          onAction: cmd('mceTablePasteRowAfter'),
11078          onSetup: selectionTargets.onSetupPasteable(clipboard.getRows)
11079        });
11080        editor.ui.registry.addButton('tablecutcol', {
11081          tooltip: 'Cut column',
11082          icon: 'cut-column',
11083          onAction: cmd('mceTableCutCol'),
11084          onSetup: selectionTargets.onSetupColumn('onAny')
11085        });
11086        editor.ui.registry.addButton('tablecopycol', {
11087          tooltip: 'Copy column',
11088          icon: 'duplicate-column',
11089          onAction: cmd('mceTableCopyCol'),
11090          onSetup: selectionTargets.onSetupColumn('onAny')
11091        });
11092        editor.ui.registry.addButton('tablepastecolbefore', {
11093          tooltip: 'Paste column before',
11094          icon: 'paste-column-before',
11095          onAction: cmd('mceTablePasteColBefore'),
11096          onSetup: selectionTargets.onSetupPasteableColumn(clipboard.getColumns, 'onFirst')
11097        });
11098        editor.ui.registry.addButton('tablepastecolafter', {
11099          tooltip: 'Paste column after',
11100          icon: 'paste-column-after',
11101          onAction: cmd('mceTablePasteColAfter'),
11102          onSetup: selectionTargets.onSetupPasteableColumn(clipboard.getColumns, 'onLast')
11103        });
11104        editor.ui.registry.addButton('tableinsertdialog', {
11105          tooltip: 'Insert table',
11106          onAction: cmd('mceInsertTable'),
11107          icon: 'table'
11108        });
11109        var tableClassList = filterNoneItem(getTableClassList(editor));
11110        if (tableClassList.length !== 0) {
11111          editor.ui.registry.addMenuButton('tableclass', {
11112            icon: 'table-classes',
11113            tooltip: 'Table styles',
11114            fetch: generateMenuItemsCallback(editor, selections, tableClassList, 'tableclass', function (value) {
11115              return editor.execCommand('mceTableToggleClass', false, value);
11116            }),
11117            onSetup: selectionTargets.onSetupTable
11118          });
11119        }
11120        var tableCellClassList = filterNoneItem(getCellClassList(editor));
11121        if (tableCellClassList.length !== 0) {
11122          editor.ui.registry.addMenuButton('tablecellclass', {
11123            icon: 'table-cell-classes',
11124            tooltip: 'Cell styles',
11125            fetch: generateMenuItemsCallback(editor, selections, tableCellClassList, 'tablecellclass', function (value) {
11126              return editor.execCommand('mceTableCellToggleClass', false, value);
11127            }),
11128            onSetup: selectionTargets.onSetupCellOrRow
11129          });
11130        }
11131        editor.ui.registry.addMenuButton('tablecellvalign', {
11132          icon: 'vertical-align',
11133          tooltip: 'Vertical align',
11134          fetch: generateMenuItemsCallback(editor, selections, verticalAlignValues, 'tablecellverticalalign', applyTableCellStyle(editor, 'vertical-align')),
11135          onSetup: selectionTargets.onSetupCellOrRow
11136        });
11137        editor.ui.registry.addMenuButton('tablecellborderwidth', {
11138          icon: 'border-width',
11139          tooltip: 'Border width',
11140          fetch: generateMenuItemsCallback(editor, selections, getTableBorderWidths(editor), 'tablecellborderwidth', applyTableCellStyle(editor, 'border-width')),
11141          onSetup: selectionTargets.onSetupCellOrRow
11142        });
11143        editor.ui.registry.addMenuButton('tablecellborderstyle', {
11144          icon: 'border-style',
11145          tooltip: 'Border style',
11146          fetch: generateMenuItemsCallback(editor, selections, getTableBorderStyles(editor), 'tablecellborderstyle', applyTableCellStyle(editor, 'border-style')),
11147          onSetup: selectionTargets.onSetupCellOrRow
11148        });
11149        editor.ui.registry.addToggleButton('tablecaption', {
11150          tooltip: 'Table caption',
11151          onAction: cmd('mceTableToggleCaption'),
11152          icon: 'table-caption',
11153          onSetup: selectionTargets.onSetupTableWithCaption
11154        });
11155        editor.ui.registry.addMenuButton('tablecellbackgroundcolor', {
11156          icon: 'cell-background-color',
11157          tooltip: 'Background color',
11158          fetch: function (callback) {
11159            return callback(buildColorMenu(editor, getTableBackgroundColorMap(editor), 'background-color'));
11160          },
11161          onSetup: selectionTargets.onSetupCellOrRow
11162        });
11163        editor.ui.registry.addMenuButton('tablecellbordercolor', {
11164          icon: 'cell-border-color',
11165          tooltip: 'Border color',
11166          fetch: function (callback) {
11167            return callback(buildColorMenu(editor, getTableBorderColorMap(editor), 'border-color'));
11168          },
11169          onSetup: selectionTargets.onSetupCellOrRow
11170        });
11171        editor.ui.registry.addToggleButton('tablerowheader', {
11172          tooltip: 'Row header',
11173          icon: 'table-top-header',
11174          onAction: changeRowHeader(editor),
11175          onSetup: selectionTargets.onSetupTableRowHeaders
11176        });
11177        editor.ui.registry.addToggleButton('tablecolheader', {
11178          tooltip: 'Column header',
11179          icon: 'table-left-header',
11180          onAction: changeColumnHeader(editor),
11181          onSetup: selectionTargets.onSetupTableColumnHeaders
11182        });
11183      };
11184      var addToolbars = function (editor) {
11185        var isTable = function (table) {
11186          return editor.dom.is(table, 'table') && editor.getBody().contains(table);
11187        };
11188        var toolbar = getToolbar(editor);
11189        if (toolbar.length > 0) {
11190          editor.ui.registry.addContextToolbar('table', {
11191            predicate: isTable,
11192            items: toolbar,
11193            scope: 'node',
11194            position: 'node'
11195          });
11196        }
11197      };
11198  
11199      var addMenuItems = function (editor, selections, selectionTargets, clipboard) {
11200        var cmd = function (command) {
11201          return function () {
11202            return editor.execCommand(command);
11203          };
11204        };
11205        var insertTableAction = function (data) {
11206          editor.execCommand('mceInsertTable', false, {
11207            rows: data.numRows,
11208            columns: data.numColumns
11209          });
11210        };
11211        var tableProperties = {
11212          text: 'Table properties',
11213          onSetup: selectionTargets.onSetupTable,
11214          onAction: cmd('mceTableProps')
11215        };
11216        var deleteTable = {
11217          text: 'Delete table',
11218          icon: 'table-delete-table',
11219          onSetup: selectionTargets.onSetupTable,
11220          onAction: cmd('mceTableDelete')
11221        };
11222        editor.ui.registry.addMenuItem('tableinsertrowbefore', {
11223          text: 'Insert row before',
11224          icon: 'table-insert-row-above',
11225          onAction: cmd('mceTableInsertRowBefore'),
11226          onSetup: selectionTargets.onSetupCellOrRow
11227        });
11228        editor.ui.registry.addMenuItem('tableinsertrowafter', {
11229          text: 'Insert row after',
11230          icon: 'table-insert-row-after',
11231          onAction: cmd('mceTableInsertRowAfter'),
11232          onSetup: selectionTargets.onSetupCellOrRow
11233        });
11234        editor.ui.registry.addMenuItem('tabledeleterow', {
11235          text: 'Delete row',
11236          icon: 'table-delete-row',
11237          onAction: cmd('mceTableDeleteRow'),
11238          onSetup: selectionTargets.onSetupCellOrRow
11239        });
11240        editor.ui.registry.addMenuItem('tablerowprops', {
11241          text: 'Row properties',
11242          icon: 'table-row-properties',
11243          onAction: cmd('mceTableRowProps'),
11244          onSetup: selectionTargets.onSetupCellOrRow
11245        });
11246        editor.ui.registry.addMenuItem('tablecutrow', {
11247          text: 'Cut row',
11248          icon: 'cut-row',
11249          onAction: cmd('mceTableCutRow'),
11250          onSetup: selectionTargets.onSetupCellOrRow
11251        });
11252        editor.ui.registry.addMenuItem('tablecopyrow', {
11253          text: 'Copy row',
11254          icon: 'duplicate-row',
11255          onAction: cmd('mceTableCopyRow'),
11256          onSetup: selectionTargets.onSetupCellOrRow
11257        });
11258        editor.ui.registry.addMenuItem('tablepasterowbefore', {
11259          text: 'Paste row before',
11260          icon: 'paste-row-before',
11261          onAction: cmd('mceTablePasteRowBefore'),
11262          onSetup: selectionTargets.onSetupPasteable(clipboard.getRows)
11263        });
11264        editor.ui.registry.addMenuItem('tablepasterowafter', {
11265          text: 'Paste row after',
11266          icon: 'paste-row-after',
11267          onAction: cmd('mceTablePasteRowAfter'),
11268          onSetup: selectionTargets.onSetupPasteable(clipboard.getRows)
11269        });
11270        var row = {
11271          type: 'nestedmenuitem',
11272          text: 'Row',
11273          getSubmenuItems: constant('tableinsertrowbefore tableinsertrowafter tabledeleterow tablerowprops | tablecutrow tablecopyrow tablepasterowbefore tablepasterowafter')
11274        };
11275        editor.ui.registry.addMenuItem('tableinsertcolumnbefore', {
11276          text: 'Insert column before',
11277          icon: 'table-insert-column-before',
11278          onAction: cmd('mceTableInsertColBefore'),
11279          onSetup: selectionTargets.onSetupColumn('onFirst')
11280        });
11281        editor.ui.registry.addMenuItem('tableinsertcolumnafter', {
11282          text: 'Insert column after',
11283          icon: 'table-insert-column-after',
11284          onAction: cmd('mceTableInsertColAfter'),
11285          onSetup: selectionTargets.onSetupColumn('onLast')
11286        });
11287        editor.ui.registry.addMenuItem('tabledeletecolumn', {
11288          text: 'Delete column',
11289          icon: 'table-delete-column',
11290          onAction: cmd('mceTableDeleteCol'),
11291          onSetup: selectionTargets.onSetupColumn('onAny')
11292        });
11293        editor.ui.registry.addMenuItem('tablecutcolumn', {
11294          text: 'Cut column',
11295          icon: 'cut-column',
11296          onAction: cmd('mceTableCutCol'),
11297          onSetup: selectionTargets.onSetupColumn('onAny')
11298        });
11299        editor.ui.registry.addMenuItem('tablecopycolumn', {
11300          text: 'Copy column',
11301          icon: 'duplicate-column',
11302          onAction: cmd('mceTableCopyCol'),
11303          onSetup: selectionTargets.onSetupColumn('onAny')
11304        });
11305        editor.ui.registry.addMenuItem('tablepastecolumnbefore', {
11306          text: 'Paste column before',
11307          icon: 'paste-column-before',
11308          onAction: cmd('mceTablePasteColBefore'),
11309          onSetup: selectionTargets.onSetupPasteableColumn(clipboard.getColumns, 'onFirst')
11310        });
11311        editor.ui.registry.addMenuItem('tablepastecolumnafter', {
11312          text: 'Paste column after',
11313          icon: 'paste-column-after',
11314          onAction: cmd('mceTablePasteColAfter'),
11315          onSetup: selectionTargets.onSetupPasteableColumn(clipboard.getColumns, 'onLast')
11316        });
11317        var column = {
11318          type: 'nestedmenuitem',
11319          text: 'Column',
11320          getSubmenuItems: constant('tableinsertcolumnbefore tableinsertcolumnafter tabledeletecolumn | tablecutcolumn tablecopycolumn tablepastecolumnbefore tablepastecolumnafter')
11321        };
11322        editor.ui.registry.addMenuItem('tablecellprops', {
11323          text: 'Cell properties',
11324          icon: 'table-cell-properties',
11325          onAction: cmd('mceTableCellProps'),
11326          onSetup: selectionTargets.onSetupCellOrRow
11327        });
11328        editor.ui.registry.addMenuItem('tablemergecells', {
11329          text: 'Merge cells',
11330          icon: 'table-merge-cells',
11331          onAction: cmd('mceTableMergeCells'),
11332          onSetup: selectionTargets.onSetupMergeable
11333        });
11334        editor.ui.registry.addMenuItem('tablesplitcells', {
11335          text: 'Split cell',
11336          icon: 'table-split-cells',
11337          onAction: cmd('mceTableSplitCells'),
11338          onSetup: selectionTargets.onSetupUnmergeable
11339        });
11340        var cell = {
11341          type: 'nestedmenuitem',
11342          text: 'Cell',
11343          getSubmenuItems: constant('tablecellprops tablemergecells tablesplitcells')
11344        };
11345        if (hasTableGrid(editor) === false) {
11346          editor.ui.registry.addMenuItem('inserttable', {
11347            text: 'Table',
11348            icon: 'table',
11349            onAction: cmd('mceInsertTable')
11350          });
11351        } else {
11352          editor.ui.registry.addNestedMenuItem('inserttable', {
11353            text: 'Table',
11354            icon: 'table',
11355            getSubmenuItems: function () {
11356              return [{
11357                  type: 'fancymenuitem',
11358                  fancytype: 'inserttable',
11359                  onAction: insertTableAction
11360                }];
11361            }
11362          });
11363        }
11364        editor.ui.registry.addMenuItem('inserttabledialog', {
11365          text: 'Insert table',
11366          icon: 'table',
11367          onAction: cmd('mceInsertTable')
11368        });
11369        editor.ui.registry.addMenuItem('tableprops', tableProperties);
11370        editor.ui.registry.addMenuItem('deletetable', deleteTable);
11371        editor.ui.registry.addNestedMenuItem('row', row);
11372        editor.ui.registry.addNestedMenuItem('column', column);
11373        editor.ui.registry.addNestedMenuItem('cell', cell);
11374        editor.ui.registry.addContextMenu('table', {
11375          update: function () {
11376            selectionTargets.resetTargets();
11377            return selectionTargets.targets().fold(constant(''), function (targets) {
11378              if (name(targets.element) === 'caption') {
11379                return 'tableprops deletetable';
11380              } else {
11381                return 'cell row column | advtablesort | tableprops deletetable';
11382              }
11383            });
11384          }
11385        });
11386        var tableClassList = filterNoneItem(getTableClassList(editor));
11387        if (tableClassList.length !== 0) {
11388          editor.ui.registry.addNestedMenuItem('tableclass', {
11389            icon: 'table-classes',
11390            text: 'Table styles',
11391            getSubmenuItems: function () {
11392              return buildMenuItems(editor, selections, tableClassList, 'tableclass', function (value) {
11393                return editor.execCommand('mceTableToggleClass', false, value);
11394              });
11395            },
11396            onSetup: selectionTargets.onSetupTable
11397          });
11398        }
11399        var tableCellClassList = filterNoneItem(getCellClassList(editor));
11400        if (tableCellClassList.length !== 0) {
11401          editor.ui.registry.addNestedMenuItem('tablecellclass', {
11402            icon: 'table-cell-classes',
11403            text: 'Cell styles',
11404            getSubmenuItems: function () {
11405              return buildMenuItems(editor, selections, tableCellClassList, 'tablecellclass', function (value) {
11406                return editor.execCommand('mceTableCellToggleClass', false, value);
11407              });
11408            },
11409            onSetup: selectionTargets.onSetupCellOrRow
11410          });
11411        }
11412        editor.ui.registry.addNestedMenuItem('tablecellvalign', {
11413          icon: 'vertical-align',
11414          text: 'Vertical align',
11415          getSubmenuItems: function () {
11416            return buildMenuItems(editor, selections, verticalAlignValues, 'tablecellverticalalign', applyTableCellStyle(editor, 'vertical-align'));
11417          },
11418          onSetup: selectionTargets.onSetupCellOrRow
11419        });
11420        editor.ui.registry.addNestedMenuItem('tablecellborderwidth', {
11421          icon: 'border-width',
11422          text: 'Border width',
11423          getSubmenuItems: function () {
11424            return buildMenuItems(editor, selections, getTableBorderWidths(editor), 'tablecellborderwidth', applyTableCellStyle(editor, 'border-width'));
11425          },
11426          onSetup: selectionTargets.onSetupCellOrRow
11427        });
11428        editor.ui.registry.addNestedMenuItem('tablecellborderstyle', {
11429          icon: 'border-style',
11430          text: 'Border style',
11431          getSubmenuItems: function () {
11432            return buildMenuItems(editor, selections, getTableBorderStyles(editor), 'tablecellborderstyle', applyTableCellStyle(editor, 'border-style'));
11433          },
11434          onSetup: selectionTargets.onSetupCellOrRow
11435        });
11436        editor.ui.registry.addToggleMenuItem('tablecaption', {
11437          icon: 'table-caption',
11438          text: 'Table caption',
11439          onAction: cmd('mceTableToggleCaption'),
11440          onSetup: selectionTargets.onSetupTableWithCaption
11441        });
11442        editor.ui.registry.addNestedMenuItem('tablecellbackgroundcolor', {
11443          icon: 'cell-background-color',
11444          text: 'Background color',
11445          getSubmenuItems: function () {
11446            return buildColorMenu(editor, getTableBackgroundColorMap(editor), 'background-color');
11447          },
11448          onSetup: selectionTargets.onSetupCellOrRow
11449        });
11450        editor.ui.registry.addNestedMenuItem('tablecellbordercolor', {
11451          icon: 'cell-border-color',
11452          text: 'Border color',
11453          getSubmenuItems: function () {
11454            return buildColorMenu(editor, getTableBorderColorMap(editor), 'border-color');
11455          },
11456          onSetup: selectionTargets.onSetupCellOrRow
11457        });
11458        editor.ui.registry.addToggleMenuItem('tablerowheader', {
11459          text: 'Row header',
11460          icon: 'table-top-header',
11461          onAction: changeRowHeader(editor),
11462          onSetup: selectionTargets.onSetupTableRowHeaders
11463        });
11464        editor.ui.registry.addToggleMenuItem('tablecolheader', {
11465          text: 'Column header',
11466          icon: 'table-left-header',
11467          onAction: changeColumnHeader(editor),
11468          onSetup: selectionTargets.onSetupTableColumnHeaders
11469        });
11470      };
11471  
11472      var Plugin = function (editor) {
11473        var selections = Selections(function () {
11474          return getBody(editor);
11475        }, function () {
11476          return getSelectionCell(getSelectionStart(editor), getIsRoot(editor));
11477        }, ephemera.selectedSelector);
11478        var selectionTargets = getSelectionTargets(editor, selections);
11479        var resizeHandler = getResizeHandler(editor);
11480        var cellSelection = CellSelection(editor, resizeHandler.lazyResize, selectionTargets);
11481        var actions = TableActions(editor, cellSelection, resizeHandler.lazyWire);
11482        var clipboard = Clipboard();
11483        registerCommands(editor, actions, cellSelection, selections, clipboard);
11484        registerQueryCommands(editor, actions, selections);
11485        registerEvents(editor, selections, actions);
11486        addMenuItems(editor, selections, selectionTargets, clipboard);
11487        addButtons(editor, selections, selectionTargets, clipboard);
11488        addToolbars(editor);
11489        editor.on('PreInit', function () {
11490          editor.serializer.addTempAttr(ephemera.firstSelected);
11491          editor.serializer.addTempAttr(ephemera.lastSelected);
11492          registerFormats(editor);
11493        });
11494        if (hasTabNavigation(editor)) {
11495          editor.on('keydown', function (e) {
11496            handle$1(e, editor, cellSelection);
11497          });
11498        }
11499        editor.on('remove', function () {
11500          resizeHandler.destroy();
11501        });
11502        return getApi(editor, clipboard, resizeHandler, selectionTargets);
11503      };
11504      function Plugin$1 () {
11505        global$3.add('table', Plugin);
11506      }
11507  
11508      Plugin$1();
11509  
11510  }());


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer